Conversation
…agingCluster` and `quitAndInstall`
…s it, trim the checksum value before validating it
0ef7892 to
5ca1de6
Compare
ravicious
left a comment
There was a problem hiding this comment.
I managed to look through the new commits and the old ones until "Expose new APIs through Electron IPC", I'll try to finish the review by the end of this day.
ravicious
left a comment
There was a problem hiding this comment.
I'll do some light QA tomorrow as so far I've mostly just read the code.
| // after quitting the app. | ||
| // We may revisit this behavior in the future. For example, if we introduce | ||
| // a UI notification indicating that there's an update to be installed. | ||
| await this.checkForUpdates({ noAutoDownload: true }); |
There was a problem hiding this comment.
Is there any way we can create tests for this? It feels quite brittle, as in we don't directly discard any updates here but rather we depend on this.checkForUpdates doing this somewhere underneath when called with noAutoDownload. It'd be at least nice to cover that it in fact does this when noAutoDownload is used.
Is it possible to mock/fake autoUpdater? The logic in this file is already rather complex and we just don't have any tests for it, meaning that even this edge case here would need to be covered by the test plan.
There was a problem hiding this comment.
I thought it would a pain to mock autoUpdater, but it wasn't that bad!
I added tests for updates auto download and discarding them when the latest check returns a new update or no update, as this part feels the most brittle.
There was a problem hiding this comment.
Improvement for the future: It'd be nice if after downloading the update there was a button to abort the update.
There was a problem hiding this comment.
I was considering it, but I was afraid of making auto updates too complex. Also, I don't think I know any app/system that would allow it 😅
Do you see a specific scenario where this would be useful?
There was a problem hiding this comment.
My original comment might have been a result of a developer brain. I was testing the feature and it downloaded an update that I didn't really need, but I couldn't skip it once it's been downloaded.
But this got me thinking: the newest version of my editor is currently broken. The updater fortunately offers a "Skip this update" feature (I think it's supported OOTB in one of the popular macOS updaters). What if we release a bugged version of Connect? The cluster admin would probably need to turn off auto-updates, but why would they need to do that if there's a problem only with Connect and not tsh? Or say the bug affects only a specific platform. As the end user, can I skip it somehow? Is setting an env var the only available workaround?
There was a problem hiding this comment.
For the CLI tools, the official workaround is the env var:
An environment variable TELEPORT_TOOLS_VERSION can be used as an emergency workaround for a known issue, pinning to a specific version in CI/CD, for debugging, or for manual updates.
The same one will be available in Connect. I know it's a bit inconvenient for desktop apps, but I also feel it's acceptable for the updater v1.
I can open an issue to add a UI option in the future that will allow users to skip an update or maybe even revert to a previous version.
There was a problem hiding this comment.
My original comment might have been a result of a developer brain. I was testing the feature and it downloaded an update that I didn't really need, but I couldn't skip it once it's been downloaded.
But this got me thinking: the newest version of my editor is currently broken. The updater fortunately offers a "Skip this update" feature (I think it's supported OOTB in one of the popular macOS updaters). What if we release a bugged version of Connect? The cluster admin would probably need to turn off auto-updates, but why would they need to do that if there's a problem only with Connect and not tsh? Or say the bug affects only a specific platform. As the end user, can I skip it somehow? Is setting an env var the only available workaround?
* Implement `checkForUpdates`, `download`, `cancelDownload`, `changeManagingCluster` and `quitAndInstall` * Expose new APIs through Electron IPC * Add app updater context to store updater state * Add `AppUpdates` dialog * Switch "Download" button to "Starting Download..." immediately after clicking it * Clear managing cluster on logout * Return correct error in `GetClusterVersions` * Do not prepend `https://` to file URL, DefaultBaseURL already contains it, trim the checksum value before validating it * Only try to download an update if it's available * Remove separate `will-quit` handler * Clarify comment * Invert condition in `preventInstallingOutdatedUpdates` * Add comments * Move `closeAllConnections()` out of try catch * Add specialized functions to serialize/deserialize errors * Add tests * Leave TODO * Do not wait for `maybeRemoveAppUpdatesManagingCluster` in `useClusterLogout` * Hide app updater for .tar.gz which is not supported * Add missing mock (cherry picked from commit 13aa750)
* Implement `checkForUpdates`, `download`, `cancelDownload`, `changeManagingCluster` and `quitAndInstall` * Expose new APIs through Electron IPC * Add app updater context to store updater state * Add `AppUpdates` dialog * Switch "Download" button to "Starting Download..." immediately after clicking it * Clear managing cluster on logout * Return correct error in `GetClusterVersions` * Do not prepend `https://` to file URL, DefaultBaseURL already contains it, trim the checksum value before validating it * Only try to download an update if it's available * Remove separate `will-quit` handler * Clarify comment * Invert condition in `preventInstallingOutdatedUpdates` * Add comments * Move `closeAllConnections()` out of try catch * Add specialized functions to serialize/deserialize errors * Add tests * Leave TODO * Do not wait for `maybeRemoveAppUpdatesManagingCluster` in `useClusterLogout` * Hide app updater for .tar.gz which is not supported * Add missing mock (cherry picked from commit 13aa750)
* Integrate app updater with UI (#57491) * Implement `checkForUpdates`, `download`, `cancelDownload`, `changeManagingCluster` and `quitAndInstall` * Expose new APIs through Electron IPC * Add app updater context to store updater state * Add `AppUpdates` dialog * Switch "Download" button to "Starting Download..." immediately after clicking it * Clear managing cluster on logout * Return correct error in `GetClusterVersions` * Do not prepend `https://` to file URL, DefaultBaseURL already contains it, trim the checksum value before validating it * Only try to download an update if it's available * Remove separate `will-quit` handler * Clarify comment * Invert condition in `preventInstallingOutdatedUpdates` * Add comments * Move `closeAllConnections()` out of try catch * Add specialized functions to serialize/deserialize errors * Add tests * Leave TODO * Do not wait for `maybeRemoveAppUpdatesManagingCluster` in `useClusterLogout` * Hide app updater for .tar.gz which is not supported * Add missing mock (cherry picked from commit 13aa750) * Show update widget in login dialog (#57695) * Add app updates widget to login dialog * Adjust compatibility warning to app updates * Simplify widget error state, do not show full error message * Make the widget take up 100% width both in login modal an in story * Fix LocalWithPasswordless story * Use `alignItems="stretch"` * Use `SpaceProps` instead of redefining `mx` manually * Infer type * Display buttons in the bottom of Alert * Avoid moving content when scrollbar appears * Destructure `Promise.all` result * Add comment --------- Co-authored-by: Rafał Cieślak <rafal.cieslak@goteleport.com> (cherry picked from commit c59a4e6) * Simplify auto updates multi-cluster view (#57709) * Simplify auto updates multi-cluster view * Improve labels * Fix tests (cherry picked from commit b574045) * Connect: Force focus after a successful SSO login * Move login functions from ClustersService to useClusterLogin * Remove no longer used GetResourcesParams * Remove clusters/types.ts * Force focus on Connect after successful SSO login * Update SSO prompt after login but before sync * Add test for SSO prompts * Use `Promise.withResolvers` Co-authored-by: Grzegorz Zdunek <gzdunek@users.noreply.github.com> * Update wait-for-sync prompt message --------- Co-authored-by: Grzegorz Zdunek <gzdunek@users.noreply.github.com> * Hardcode the lowest supported Connect versions that support managed updates (#58348) * Provide the lowest supported app versions for managed updates * Deserialize errors in the UI code, not in preload Otherwise, the error name is lost. * Bump version in tests * Lint * Show exact version in error message * Do not hide UnsupportedVersionError * Fix margin * Make alert take 100% width (cherry picked from commit d7e1352) --------- Co-authored-by: Rafał Cieślak <rafal.cieslak@goteleport.com>
* Integrate app updater with UI (#57491) * Implement `checkForUpdates`, `download`, `cancelDownload`, `changeManagingCluster` and `quitAndInstall` * Expose new APIs through Electron IPC * Add app updater context to store updater state * Add `AppUpdates` dialog * Switch "Download" button to "Starting Download..." immediately after clicking it * Clear managing cluster on logout * Return correct error in `GetClusterVersions` * Do not prepend `https://` to file URL, DefaultBaseURL already contains it, trim the checksum value before validating it * Only try to download an update if it's available * Remove separate `will-quit` handler * Clarify comment * Invert condition in `preventInstallingOutdatedUpdates` * Add comments * Move `closeAllConnections()` out of try catch * Add specialized functions to serialize/deserialize errors * Add tests * Leave TODO * Do not wait for `maybeRemoveAppUpdatesManagingCluster` in `useClusterLogout` * Hide app updater for .tar.gz which is not supported * Add missing mock (cherry picked from commit 13aa750) * Show update widget in login dialog (#57695) * Add app updates widget to login dialog * Adjust compatibility warning to app updates * Simplify widget error state, do not show full error message * Make the widget take up 100% width both in login modal an in story * Fix LocalWithPasswordless story * Use `alignItems="stretch"` * Use `SpaceProps` instead of redefining `mx` manually * Infer type * Display buttons in the bottom of Alert * Avoid moving content when scrollbar appears * Destructure `Promise.all` result * Add comment --------- Co-authored-by: Rafał Cieślak <rafal.cieslak@goteleport.com> (cherry picked from commit c59a4e6) * Simplify auto updates multi-cluster view (#57709) * Simplify auto updates multi-cluster view * Improve labels * Fix tests (cherry picked from commit b574045) * Connect: Force focus after a successful SSO login * Move login functions from ClustersService to useClusterLogin * Remove no longer used GetResourcesParams * Remove clusters/types.ts * Force focus on Connect after successful SSO login * Update SSO prompt after login but before sync * Add test for SSO prompts * Use `Promise.withResolvers` Co-authored-by: Grzegorz Zdunek <gzdunek@users.noreply.github.com> * Update wait-for-sync prompt message --------- Co-authored-by: Grzegorz Zdunek <gzdunek@users.noreply.github.com> * Hardcode the lowest supported Connect versions that support managed updates (#58348) * Provide the lowest supported app versions for managed updates * Deserialize errors in the UI code, not in preload Otherwise, the error name is lost. * Bump version in tests * Lint * Show exact version in error message * Do not hide UnsupportedVersionError * Fix margin * Make alert take 100% width (cherry picked from commit d7e1352) --------- Co-authored-by: Rafał Cieślak <rafal.cieslak@goteleport.com>
Part 5 of #50948. RFD.
This PR adds a dialog to check for updates and integrates it with the updater service (the widget will be added in the next PR).
This first commit is most important one. It implements updater methods that will be used by the UI. Unfortunately, I found some bugs in
electron-updater, so I had to add extra logic to resolve them. I've left comments inAppUpdater.tsto explain what wasn't working and how those issues were addressed. If anything is unclear, please let me know.While testing, I also realized that the UI in the multi-cluster scenario may be too complex when we show errors/warning about unreachable clusters (although it seemed fine in Storybook to me). I'll address this separately by reducing alerts and making inline errors more prominent.
How to test it (on macOS)
I prepared two dev builds with different versions (
19.0.0-dev.connect.updates.1and19.0.0-dev.connect.updates.2) to test the updates.launchctl setenv TELEPORT_CDN_BASE_URL https://cdn.cloud.gravitational.io.tctl autoupdate client-tools target 19.0.0-dev.connect.updates.2.19.0.0-dev.connect.updates.1build from https://cdn.cloud.gravitational.io/Teleport%20Connect-19.0.0-dev.connect.updates.1.dmg.