Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add different release channels for autoupdater #2362

Merged
merged 1 commit into from
Mar 1, 2017

Conversation

ctrlaltca
Copy link
Contributor

@ctrlaltca ctrlaltca commented Jan 15, 2017

Fix #1784

This is an initial implementation of #2321.
Currently two release channels are implemented: "stable releases" and "development snapshot", respectively pointing to our stable releases and git builds on bintray.

Users can choose their preferred release channel from the settings:
schermata 2017-01-15 alle 15 20 20

Their choice is reflected in the update dialog:
schermata 2017-01-15 alle 15 20 38

Also, remove the wrong commit hash from update dialog and show version name instead (fix #2247);
Still to be fixed / reworked, but maybe in another PR: don't use release date to determine if a newer version is available (aka avoid #2338)

@ZeldaZach
Copy link
Member

Just a thought to go with; git rev-list --count HEAD will give us a count of how many commits were made to the HEAD, which we can possibly use a confirmation. When a client starts up, it can run that commit and compare the counts. If they're not equal (aka HEAD > version string) then we show them update message.

$ git rev-list --count 784a75db
3539
$ git rev-list --count HEAD
3545

updateNotificationCheckBox.setText(tr("Notify when new client features are available"));
clearDownloadedPicsButton.setText(tr("Reset/clear downloaded pictures"));
updateReleaseChannelLabel.setText(tr("Update channel"));
updateNotificationCheckBox.setText(tr("Notify when a new version is available"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have any logic for automatic update checks yet?! First time I hear about that. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really; it still works that when you connect to a server and it tells you that you are missing some feature, we suppose that probably a new version supporting that feature is out.
I't just that imho the old text, even if formally correct, made no sense at all to an average user.

Copy link
Member

@tooomm tooomm Jan 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the wording is still misleading...

Maybe add a "on connect" and rephrase a bit?
"On connect, notify everytime a feature supported by the server is missing in my client"
or "repeatedly" instead everytime

Copy link
Contributor Author

@ctrlaltca ctrlaltca Jan 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tried to change the sentence, but it's so long that it forces the settings window to be wider. So the candidates are:

# original wording
Notify when new client features are available
# short, misleading wording
Notify when a new version is available
# Precise but too long wording
On connect, notify everytime a feature supported by the server is missing in my client
# Other attempts
Notify if a feature supported by the server is missing in my client
Notify if the server reports that a feature is missing in my client

Others?

EDIT: i found out a way to make the sentence can take up more space in the window without affecting its size, so even the longer version is viable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notify if a feature supported by the server is missing in my client

I really like this one but I don't have strong feelings - use your judgement

@tooomm
Copy link
Member

tooomm commented Jan 15, 2017

@ctrlaltca

Also, remove the wrong commit hash from update dialog and show version name instead (fix #2247);

Can you show a picture, please?

I want to throw in #2359 again.
Now we should introduce the propper wording for the os on mac computers and scrap legacy terms.
We need to make sure that the app itself checks the new/right location though.

@ctrlaltca
Copy link
Contributor Author

Just a thought to go with; git rev-list --count HEAD will give us a count of how many commits were made to the HEAD, which we can possibly use a confirmation. When a client starts up, it can run that commit and compare the counts. If they're not equal (aka HEAD > version string) then we show them update message.

That could work, unless if the user want to switch back from a development version to a stable version; just checking for HEAD != version string could be a simple workaround.
Anyway, the main problem is being able to push a value inside is the file that we load from bintray when checking for new versions (https://api.bintray.com/packages/cockatrice/Cockatrice/Cockatrice/files), so that Cockatrice is able to get this information. I'll dig into bintray's documentation, hopefully we can customize that file.
As an alternative, we could host a json file on cockatrice's repo.

Can you show a picture, please?

Development snapshot update
schermata 2017-01-16 alle 21 17 58

Stable update:
schermata 2017-01-16 alle 21 18 22

I want to throw in #2359 again.

Please, let me fix this once before we break it again ;)

@ZeldaZach
Copy link
Member

I like the option with the dev/release channels; Looks good. If you're on a dev channel, will it allow you to go back to release and download the latest release with a notification or will you have to hit "download anyway?"

Having a JSON file tell which is the releases could be done, and we can host it on the /latest/release portion of the client as an uploaded file (github.com/cockatrice/cockatrice/releases/latest)

@Daenyth
Copy link
Member

Daenyth commented Jan 18, 2017 via email

@ctrlaltca
Copy link
Contributor Author

I don't think we need to do a manual releases file, we should be able to
get the information from the releases page on github, or via the releases
api.

How can we link the release information from github to the downloadable files from bintray?

@Daenyth
Copy link
Member

Daenyth commented Jan 18, 2017 via email

@tooomm
Copy link
Member

tooomm commented Jan 18, 2017

Regarding the release notes there is a Release notes tab on bintray, I'm pretty sure it used to display information from github releases the same as it's displaying information from the README.md file in the corresponding tab once. Not working anymore though?!

@woogerboy21
Copy link
Contributor

Compiled and tinkered a bit. Any chance you could throw some info in the debug log when the update gets checked with some type of usable info? Like maybe current version, versions found and results? Something like that.

@ctrlaltca
Copy link
Contributor Author

We could use a git tag with a specific structure. We talked about using
semver in another ticket, if we put that info into the git tags it would be
enough to determine new releases.

So, for stable releases:

  1. Cockatrice grabs https://api.github.com/repos/Cockatrice/Cockatrice/releases/latest
  2. We show the user the update popup with
  1. Cockatrice will note the tag name: "tag_name": "2016-12-31-Release" and look for the same tag name on bintray: https://api.bintray.com/packages/cockatrice/Cockatrice/Cockatrice/files (this will be easier if we tag using semver instead of plain names)
  2. cockatrice will download a matching package from bintray

For development releases:

  1. Grab https://api.github.com/repos/Cockatrice/Cockatrice/commits , only consider the most recent one
  2. We show the user the update popup with
  1. Cockatrice will note the commit "sha": "ae5fc1fe2c7d89af7e9899f0af3f8728971eb073", trucate it to the short hash "ae5fc1f" and look for the same tag name on bintray: https://api.bintray.com/packages/cockatrice/Cockatrice/Cockatrice-git/files
  2. cockatrice will download a matching package from bintray

Is this what you mean? If we want to take this route i'll start working on it

Regarding the release notes there is a Release notes tab on bintray, I'm pretty sure it used to display information from github releases the same as it's displaying information from the README.md file in the corresponding tab once. Not working anymore though?!

Probably someone copypasted them manually. Bintray can be configured to fetch data from github, but imho we'd better redirect people on github, since all the informations are already here.

Compiled and tinkered a bit. Any chance you could throw some info in the debug log when the update gets checked with some type of usable info? Like maybe current version, versions found and results? Something like that.

Sure, i will add some debug!

@Daenyth
Copy link
Member

Daenyth commented Jan 19, 2017

Yes, that's exactly what I mean

@tooomm
Copy link
Member

tooomm commented Jan 20, 2017

Probably someone copypasted them manually. Bintray can be configured to fetch (release notes) data from github, but imho we'd better redirect people on github, since all the informations are already here.

Link within the release notes tab of stable releases to https://github.com/Cockatrice/Cockatrice/releases/latest ?


You asked in gitter: Regarding release names we had a discussion here: #2341

Edit:
Can we explain the different channels somewhere? Put an information "(i)" next to it in settings which gives some information on moues over for example?
Especially since the development branch is most likely out of date all the time, people should know about it for sure, and that they are running "on the edge".

It would be better to have (additionally) a beta and/or release candidate channel, which both make way more sense to the users and the project in general.
People will get bored and annoyed by updates all the time in the development branch, so they most likely won't stay there. But we want some parts of the userbase to use beta/rc builds to give feedback and actually test+report things. Once people realize that bugs are fixed faster there, and that they don't have to wait weeks/month for fixes in the next stable it's also a good benefit for them.
We could put folders in the normal cockatrice project on bintray or use the extendend file names as talked about in #2341 to destinguish them for example.

@ZeldaZach
Copy link
Member

Any word on what we should do with this @Daenyth ?

@ctrlaltca
Copy link
Contributor Author

Any word on what we should do with this @Daenyth ?

I'm still (slowly) working on implementing the changes

@ctrlaltca
Copy link
Contributor Author

Still work in progress, but updates for the development version are now implemented as discussed in #2362 (comment)

@ctrlaltca
Copy link
Contributor Author

Both updates for the stable channel and the development channel have been implemented, and debug messages added as requested. This can be tested by reviewers.

On the stable channel it always download the last stable release available on bintray, since there's no way to actually link these files to the release on github, since both the release and the files are created manually; you may think of naming it the same and use this as a link, but this is fragile and a big con is the fact that on bintray the release can't be modified after the creation. We would risk to end up with the same problem of the last 2 releases where a not-matching date broke the update procedure.

@woogerboy21
Copy link
Contributor

woogerboy21 commented Feb 25, 2017

Tinkered around some more. Curious about something. When running the most recent commit level with this PR rolled in and using the stable release option I have a popup that shows an update is available and lists the current stable release version that has been published. Is this by design? What I mean by this is since I am running a newer client than what is available in the stable version are we expecting the client to say "hey there is a more recent stable version than what your running (since your not running a stable release)" or are we wanting it to say "hey this client is newer than the stable release available, do you want to install the stable release?"

Just want to make sure 1, the logic isnt actually failing to identify the correct versions and not informing people of updates when there is none and 2, expected behavior.

@ctrlaltca
Copy link
Contributor Author

ctrlaltca commented Feb 26, 2017

This PR is not using the "release date" to compare the current running version with the last version available for download, since we can't really control that information on bintray. This was the problem that caused the "update loop" in the two last releases.
The code from this PR is using the git commit hash embedded in cockatrice, comparing it to the "last version" commit hash obtained from github.
If you run cockatrice from a release channel (stable or dev) and you decide to change it to the other release channel you'll always find a different "last" version available, since it will surely have a different git commit hash.
There is no concept of a "newer" release, since dates are not involved in comparing the currently running version and the one available online.

@Daenyth
Copy link
Member

Daenyth commented Feb 27, 2017

@ctrlaltca What's the status of this at the moment? Are you waiting for code review, waiting for manual testing, or still making changes? I'd love to help push this through so if it's code review let me know and I'll get to it as I have time

@ctrlaltca
Copy link
Contributor Author

@Daenyth Waiting for review/test

Copy link
Member

@Daenyth Daenyth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only have minor feedback points - once they are addressed and this is tested manually please go ahead and merge unless you think you need more specific feedback from me.

publishDate = release->getPublishDate().toString(Qt::DefaultLocaleLongDate);

QMessageBox::StandardButton reply;
reply = QMessageBox::question(this, "Update Available",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like this is mixing UI and business logic together. An alternate approach might be to have the release updater not use any UI components but instead provide a function of UpdateCheckResult checkForUpdates() where UpdateCheckResult can be a tagged union with success+download_url, success-but-no-url-for-your-OS, you-are-up-to-date, or error-updating+the_error.

Does that make sense?

That would allow us to unit test in isolation from the UI.

Anyway I'm not going to block the PR on that change, but I'd like to hear your thoughts on it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also it seems like tagged unions are a goddamn PITA in cpp: http://en.cppreference.com/w/cpp/language/union

Thoughts on rust? I do have some docs on incorporating rust into a cpp app. I'd be perfectly willing to start extracting all the core bits to safer rust libraries and leave the Qt parts for just UI calling functions exposed from rust FFI.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The business logic is mostly implemented in releasechannel.cpp, but these last checks ust be made in the UI since it's good to have the QMessageBox instanciated with a valid parent widget.
basically we are calling settingsCache->getUpdateReleaseChannel()->checkForUpdates(); to start the check for updates and then waiting on the DlgUpdate::finishedUpdateCheck() slot for the result. It must be an async call anyway since the network is involved, so we cant just call a method and get the result directly.

#define DEVMANUALDOWNLOAD_URL "https://bintray.com/cockatrice/Cockatrice/Cockatrice-git/_latestVersion#files"
#define GIT_SHORT_HASH_LEN 7

ReleaseChannel::ReleaseChannel(int _index, QString _name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the last 2 fields may want to be an UpdateResponse type object instead of the checker class itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved them inside the Release channels in the last update.


if(!(resultMap.contains("object") &&
resultMap["object"].toMap().contains("sha"))) {
qDebug() << "Invalid received from the tag update server";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it easy to include the contents of resultMap here? Might help. Also probably should be qWarning at least

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done 👍

void DevReleaseChannel::checkForUpdates()
{
qDebug() << "Searching for updates on the dev channel: " << DEVRELEASE_URL;
response = netMan->get(QNetworkRequest(QString(DEVRELEASE_URL)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is almost identical to the other class - it seems like url and log message are the only difference. Might be good to make it a method of the base interface they both extend and take the urls as parameters

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Done

QString tmp = QString(reply->readAll());
reply->deleteLater();

// Errors are incapsulated in an object, check for them first
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

encapsulated

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the comment altogether, it was a leftover from a copypaste

@@ -162,7 +164,16 @@ SettingsCache::SettingsCache()
if(!QFile(settingsPath+"global.ini").exists())
translateLegacySettings();

// updates
dummy = QT_TRANSLATE_NOOP("i18n", "Stable releases");
dummy = QT_TRANSLATE_NOOP("i18n", "Development snapshots");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's that do?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was used to force qt's l'update to find and extract these translatable strings.
I moved the strings inside the *ReleaseChannel classes and removed this trick.

@@ -23,7 +23,9 @@ SET(oracle_SOURCES
../cockatrice/src/settings/layoutssettings.cpp
../cockatrice/src/thememanager.cpp
../cockatrice/src/qt-json/json.cpp
)
../cockatrice/src/releasechannel.cpp
${VERSION_STRING_CPP}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

version cpp wasn't here already? How silly. We should probably make cockatrice's about menu reusable and call the same code from cockatrice and oracle. Not in this pr though

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was not included in oracle yet; now it's a dependency since oracle uses cockatrice's settingscache.

tr("Cockatrice was not built with SSL support, so cannot download updates! "
"Please visit the download page and update manually."));
QMessageBox::critical(this, tr("Error"),
tr("Cockatrice was not built with SSL support, so cannot download updates! "
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Cockatrice was not build with SSL support, so you cannot download updates automatically! Please visit the download page to update manually."

foreach(QVariant file, resultList)
{
QVariantMap map = file.toMap();
// TODO: map github version to bintray version
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any word on this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explained in the 2nd paragraph of #2362 (comment)
Unfortunately i've not found a "perfect solution" yet, even though it's working anyway.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good for now, if we have to change uploads what will we do though? Have to publish a new revision?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Publish a new revision to make cockatrice "find" the update.
Then, it will always download the "latest" stable release available on bintray.

~ReleaseChannel();
protected:
int index;
QString name;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tabs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, thank you

Copy link
Member

@ZeldaZach ZeldaZach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After my review, as long as the small nitty gritty stuff is fixed up, I'm good to see this go in. Glad to finally have something like this after all the years :)

@ZeldaZach
Copy link
Member

Builds seem to be failing @ctrlaltca

@Daenyth
Copy link
Member

Daenyth commented Feb 28, 2017

Seems likely to be aws-related given that it's a connection error

@Nightfirecat
Copy link

AWS has been facing a lot of issues today, most notably S3 being nearly fully out of operation for a few hours. That said, the error seems to be with a failing Invoke-WebRequest to download compiled protobuf 2.6.1 code: https://ci.appveyor.com/project/Daenyth/cockatrice-8k7y5/build/0.0.1-branch-master-build-565/job/2jfjveibhmpp2xof#L282, https://ci.appveyor.com/project/Daenyth/cockatrice-8k7y5/build/0.0.1-branch-master-build-565/job/df442gc7xk7rgavd#L282

Fetch releases from github and find corresponding installers on bintray
@ctrlaltca
Copy link
Contributor Author

ctrlaltca commented Mar 1, 2017

I've squashed down commits and pushed to the PR to force the builds to run again.
If everything's ok then i'll merge.

@ZeldaZach
Copy link
Member

I'll be looking into publishing a release on ~ March 14th (Pi Day :D)

@ctrlaltca
Copy link
Contributor Author

ctrlaltca commented Mar 1, 2017

Looks like the travis-ci build didn't trigger.. anyway it worked on the very same commit for my branch: https://travis-ci.org/ctrlaltca/Cockatrice/builds/206512853

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Wrong commit number in "new update available" dialog Missing information in the client updater
6 participants