From fb63c0cd220d3f768e1d8d54741beff5657fc919 Mon Sep 17 00:00:00 2001 From: Anmol Sethi Date: Mon, 23 Nov 2020 21:06:45 -0500 Subject: [PATCH 1/5] vscode: Show notification when upgrade is available And link to the release notes. --- ci/dev/vscode.patch | 54 ++++++++++++++++++++++++++++++++++++--- src/node/routes/update.ts | 2 +- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/ci/dev/vscode.patch b/ci/dev/vscode.patch index 8d193980..54676c49 100644 --- a/ci/dev/vscode.patch +++ b/ci/dev/vscode.patch @@ -769,10 +769,10 @@ index 096b9e23493539c9937940a56e555d95bbae38d9..ef37e614004f550f7b64eacd362f6894 remove(key: string, scope: StorageScope): void { diff --git a/src/vs/server/browser/client.ts b/src/vs/server/browser/client.ts new file mode 100644 -index 0000000000000000000000000000000000000000..3c0703b7174ad792a4b42841e96ee93765d71601 +index 0000000000000000000000000000000000000000..667ca961830feaf6fc5e5bb7ef2df3b8be97b176 --- /dev/null +++ b/src/vs/server/browser/client.ts -@@ -0,0 +1,189 @@ +@@ -0,0 +1,237 @@ +import { Emitter } from 'vs/base/common/event'; +import { URI } from 'vs/base/common/uri'; +import { localize } from 'vs/nls'; @@ -791,6 +791,7 @@ index 0000000000000000000000000000000000000000..3c0703b7174ad792a4b42841e96ee937 +import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; +import { Options } from 'vs/server/ipc.d'; +import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; ++import { ILogService } from 'vs/platform/log/common/log'; + +class TelemetryService extends TelemetryChannelClient { + public constructor( @@ -922,8 +923,55 @@ index 0000000000000000000000000000000000000000..3c0703b7174ad792a4b42841e96ee937 + }); + } + ++ const logService = (services.get(ILogService) as ILogService); ++ const storageService = (services.get(IStorageService) as IStorageService) ++ const getUpdate = async (): Promise => { ++ logService.debug("Checking for update..."); ++ ++ const response = await fetch("update/check", { ++ headers: { "Accept": "application/json" }, ++ }); ++ if (!response.ok) { ++ throw new Error(response.statusText); ++ } ++ const json = await response.json(); ++ if (json.error) { ++ throw new Error(json.error); ++ } ++ if (json.isLatest) { ++ return; ++ } ++ ++ const lastNoti = storageService.getNumber("csLastUpdateNotification", StorageScope.GLOBAL); ++ if (lastNoti) { ++ // Only remind them again after two days. ++ const timeout = 1000*60*24*2 ++ const threshold = lastNoti + timeout; ++ if (Date.now() < threshold) { ++ return; ++ } ++ } ++ ++ storageService.store("csLastUpdateNotification", Date.now(), StorageScope.GLOBAL); ++ (services.get(INotificationService) as INotificationService).notify({ ++ severity: Severity.Info, ++ message: `[code-server v${json.latest}](https://github.com/cdr/code-server/releases/tag/v${json.latest}) has been released!`, ++ }); ++ }; ++ ++ const updateLoop = (): void => { ++ getUpdate().catch((error) => { ++ logService.debug(`failed to check for update: ${error}`); ++ }).finally(() => { ++ // Check again every 6 hours. ++ setTimeout(updateLoop, 1000*60*6); ++ }); ++ }; ++ ++ updateLoop(); ++ + // This will be used to set the background color while VS Code loads. -+ const theme = (services.get(IStorageService) as IStorageService).get("colorThemeData", StorageScope.GLOBAL); ++ const theme = storageService.get("colorThemeData", StorageScope.GLOBAL); + if (theme) { + localStorage.setItem("colorThemeData", theme); + } diff --git a/src/node/routes/update.ts b/src/node/routes/update.ts index ac1ddc41..5c9aa181 100644 --- a/src/node/routes/update.ts +++ b/src/node/routes/update.ts @@ -7,7 +7,7 @@ export const router = Router() const provider = new UpdateProvider() -router.get("/", ensureAuthenticated, async (req, res) => { +router.get("/check", ensureAuthenticated, async (req, res) => { const update = await provider.getUpdate(req.query.force === "true") res.json({ checked: update.checked, From f74f1721e69a722ff0a90757ec89e64ed34b4711 Mon Sep 17 00:00:00 2001 From: Anmol Sethi Date: Mon, 23 Nov 2020 21:07:02 -0500 Subject: [PATCH 2/5] doc: Add note on upgrading into release notes and install.md Closes #1652 Closes #2221 --- ci/build/release-github-draft.sh | 4 ++++ doc/install.md | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/ci/build/release-github-draft.sh b/ci/build/release-github-draft.sh index 71cbb714..4e077a35 100755 --- a/ci/build/release-github-draft.sh +++ b/ci/build/release-github-draft.sh @@ -15,6 +15,10 @@ v$VERSION VS Code v$(vscode_version) +Upgrading is as easy as installing the new version over the old one. code-server +maintains all user data in \`~/.local/share/code-server\` so that it is preserved in between +installations. + ## New Features - ⭐ Summarize new features here with references to issues diff --git a/doc/install.md b/doc/install.md index 7515db45..e18d27d0 100644 --- a/doc/install.md +++ b/doc/install.md @@ -2,6 +2,7 @@ # Install +- [Upgrading](#upgrading) - [install.sh](#installsh) - [Flags](#flags) - [Detection Reference](#detection-reference) @@ -19,6 +20,12 @@ This document demonstrates how to install `code-server` on various distros and operating systems. +## Upgrading + +When upgrading you can just install the new version over the old one. code-server +maintains all user data in `~/.local/share/code-server` so that it is preserved in between +installations. + ## install.sh We have a [script](../install.sh) to install code-server for Linux, macOS and FreeBSD. From be37821ab9dbd88ab4d78805e6e6df228c2426e7 Mon Sep 17 00:00:00 2001 From: Anmol Sethi Date: Mon, 23 Nov 2020 21:09:27 -0500 Subject: [PATCH 3/5] update.ts: Simplify comparison --- src/node/update.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/update.ts b/src/node/update.ts index 13ac73c3..a156aad6 100644 --- a/src/node/update.ts +++ b/src/node/update.ts @@ -75,7 +75,7 @@ export class UpdateProvider { public isLatestVersion(latest: Update): boolean { logger.debug("comparing versions", field("current", version), field("latest", latest.version)) try { - return latest.version === version || semver.lt(latest.version, version) + return semver.lte(latest.version, version) } catch (error) { return true } From 37c80c9bbd4a01ce0dabbd010b3b73831af9d3db Mon Sep 17 00:00:00 2001 From: Anmol Sethi Date: Tue, 24 Nov 2020 12:47:58 -0500 Subject: [PATCH 4/5] vscode: Add missing semicolons See #2359 --- ci/dev/vscode.patch | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ci/dev/vscode.patch b/ci/dev/vscode.patch index 54676c49..4f249d36 100644 --- a/ci/dev/vscode.patch +++ b/ci/dev/vscode.patch @@ -769,7 +769,7 @@ index 096b9e23493539c9937940a56e555d95bbae38d9..ef37e614004f550f7b64eacd362f6894 remove(key: string, scope: StorageScope): void { diff --git a/src/vs/server/browser/client.ts b/src/vs/server/browser/client.ts new file mode 100644 -index 0000000000000000000000000000000000000000..667ca961830feaf6fc5e5bb7ef2df3b8be97b176 +index 0000000000000000000000000000000000000000..c6eef331346ebc244a26e8b1e5919d192225b971 --- /dev/null +++ b/src/vs/server/browser/client.ts @@ -0,0 +1,237 @@ @@ -924,7 +924,7 @@ index 0000000000000000000000000000000000000000..667ca961830feaf6fc5e5bb7ef2df3b8 + } + + const logService = (services.get(ILogService) as ILogService); -+ const storageService = (services.get(IStorageService) as IStorageService) ++ const storageService = (services.get(IStorageService) as IStorageService); + const getUpdate = async (): Promise => { + logService.debug("Checking for update..."); + @@ -945,7 +945,7 @@ index 0000000000000000000000000000000000000000..667ca961830feaf6fc5e5bb7ef2df3b8 + const lastNoti = storageService.getNumber("csLastUpdateNotification", StorageScope.GLOBAL); + if (lastNoti) { + // Only remind them again after two days. -+ const timeout = 1000*60*24*2 ++ const timeout = 1000*60*24*2; + const threshold = lastNoti + timeout; + if (Date.now() < threshold) { + return; @@ -3906,7 +3906,7 @@ index 738ce140c1af76ee0017c59cc883578e966f5348..80833b7023ed5795bb3de303b54ec08d .monaco-workbench .part.editor > .content .welcomePage .splash ul { diff --git a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts -index 4a61a79fe447e2aa238af568791bff1e0cec4d29..791b63342f476f1baba9d31b040d3ef589e3f70a 100644 +index 4a61a79fe447e2aa238af568791bff1e0cec4d29..69cc2e4331a3b04d05d79632920f5c5bbfa924e8 100644 --- a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts +++ b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts @@ -328,7 +328,7 @@ class WelcomePage extends Disposable { @@ -3914,7 +3914,7 @@ index 4a61a79fe447e2aa238af568791bff1e0cec4d29..791b63342f476f1baba9d31b040d3ef5 const prodName = container.querySelector('.welcomePage .title .caption') as HTMLElement; if (prodName) { - prodName.textContent = this.productService.nameLong; -+ prodName.textContent = `code-server v${this.productService.codeServerVersion}` ++ prodName.textContent = `code-server v${this.productService.codeServerVersion}`; } recentlyOpened.then(({ workspaces }) => { From def81245a425178578318f3ec80d301c4c30f6b9 Mon Sep 17 00:00:00 2001 From: Anmol Sethi Date: Tue, 24 Nov 2020 12:59:06 -0500 Subject: [PATCH 5/5] vscode: Check updates with absolute path In case the window location path changes. Not entirely sure if it can but best to be on the safe side. --- ci/dev/vscode.patch | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ci/dev/vscode.patch b/ci/dev/vscode.patch index 4f249d36..df3f673e 100644 --- a/ci/dev/vscode.patch +++ b/ci/dev/vscode.patch @@ -769,10 +769,10 @@ index 096b9e23493539c9937940a56e555d95bbae38d9..ef37e614004f550f7b64eacd362f6894 remove(key: string, scope: StorageScope): void { diff --git a/src/vs/server/browser/client.ts b/src/vs/server/browser/client.ts new file mode 100644 -index 0000000000000000000000000000000000000000..c6eef331346ebc244a26e8b1e5919d192225b971 +index 0000000000000000000000000000000000000000..385b9da491d38a9f5d10fab6e4666c84a892f49d --- /dev/null +++ b/src/vs/server/browser/client.ts -@@ -0,0 +1,237 @@ +@@ -0,0 +1,240 @@ +import { Emitter } from 'vs/base/common/event'; +import { URI } from 'vs/base/common/uri'; +import { localize } from 'vs/nls'; @@ -792,6 +792,7 @@ index 0000000000000000000000000000000000000000..c6eef331346ebc244a26e8b1e5919d19 +import { Options } from 'vs/server/ipc.d'; +import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; +import { ILogService } from 'vs/platform/log/common/log'; ++import * as path from 'vs/base/common/path'; + +class TelemetryService extends TelemetryChannelClient { + public constructor( @@ -925,10 +926,12 @@ index 0000000000000000000000000000000000000000..c6eef331346ebc244a26e8b1e5919d19 + + const logService = (services.get(ILogService) as ILogService); + const storageService = (services.get(IStorageService) as IStorageService); ++ // We set this here first in case the path changes. ++ const updateCheckEndpoint = path.join(window.location.pathname, "/update/check") + const getUpdate = async (): Promise => { + logService.debug("Checking for update..."); + -+ const response = await fetch("update/check", { ++ const response = await fetch(updateCheckEndpoint, { + headers: { "Accept": "application/json" }, + }); + if (!response.ok) {