From be0fe10a6a884cbfc93620aa29174c7d166980ad Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 30 Mar 2022 08:26:59 -0700 Subject: [PATCH 01/55] docs(README): point docs to website (#5041) * docs(README): point docs to website * Update docs/README.md --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index c028d281b..b5fc7c7e1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ # code-server -[!["GitHub Discussions"](https://img.shields.io/badge/%20GitHub-%20Discussions-gray.svg?longCache=true&logo=github&colorB=purple)](https://github.com/coder/code-server/discussions) [!["Join us on Slack"](https://img.shields.io/badge/join-us%20on%20slack-gray.svg?longCache=true&logo=slack&colorB=brightgreen)](https://coder.com/community) [![Twitter Follow](https://img.shields.io/twitter/follow/CoderHQ?label=%40CoderHQ&style=social)](https://twitter.com/coderhq) [![codecov](https://codecov.io/gh/coder/code-server/branch/main/graph/badge.svg?token=5iM9farjnC)](https://codecov.io/gh/coder/code-server) [![See v4.2.0 docs](https://img.shields.io/static/v1?label=Docs&message=see%20v4.2.0%20&color=blue)](https://github.com/coder/code-server/tree/v4.2.0/docs) +[!["GitHub Discussions"](https://img.shields.io/badge/%20GitHub-%20Discussions-gray.svg?longCache=true&logo=github&colorB=purple)](https://github.com/coder/code-server/discussions) [!["Join us on Slack"](https://img.shields.io/badge/join-us%20on%20slack-gray.svg?longCache=true&logo=slack&colorB=brightgreen)](https://coder.com/community) [![Twitter Follow](https://img.shields.io/twitter/follow/CoderHQ?label=%40CoderHQ&style=social)](https://twitter.com/coderhq) [![codecov](https://codecov.io/gh/coder/code-server/branch/main/graph/badge.svg?token=5iM9farjnC)](https://codecov.io/gh/coder/code-server) [![See latest](https://img.shields.io/static/v1?label=Docs&message=see%20latest&color=blue)](https://coder.com/docs/code-server/latest) Run [VS Code](https://github.com/Microsoft/vscode) on any machine anywhere and access it in the browser. From 06e36b42bb00bcdd31bb20afffcbb0e5d771f372 Mon Sep 17 00:00:00 2001 From: Asher Date: Wed, 30 Mar 2022 10:35:22 -0500 Subject: [PATCH 02/55] fix: add missing package.json and source maps (#5040) * Use --exclude to skip node_modules Instead of copying and then deleting them. This will also catch some node_modules directories that were missed. * Remove per-extension dependency install Code packages all the dependencies using webpack for each extension so there are no dependencies to install. * Include source maps I also moved this to its own patch because it feels sufficiently standalone. Fixes #5026. * Refresh language patch The base is slightly different so it needed to be refreshed. * Add missing package.json This was caused by switching to Code's package step which does not include the package.json. Fixes #5019. * Include keytar It seems this actually is used now. --- ci/build/build-release.sh | 38 ++++++++++++++++++++----------- ci/build/npm-postinstall.sh | 8 ------- patches/display-language.diff | 2 +- patches/integration.diff | 14 ------------ patches/series | 1 + patches/sourcemaps.diff | 43 +++++++++++++++++++++++++++++++++++ 6 files changed, 70 insertions(+), 36 deletions(-) create mode 100644 patches/sourcemaps.diff diff --git a/ci/build/build-release.sh b/ci/build/build-release.sh index 53e13a557..e876f1268 100755 --- a/ci/build/build-release.sh +++ b/ci/build/build-release.sh @@ -78,11 +78,25 @@ EOF bundle_vscode() { mkdir -p "$VSCODE_OUT_PATH" - # - Some extensions have a .gitignore which excludes their built source from - # the npm package so exclude any .gitignore files. - # - Exclude Node as we will add it ourselves for the standalone and will not - # need it for the npm package. - rsync -avh --exclude .gitignore --exclude /node ./lib/vscode-reh-web-*/ "$VSCODE_OUT_PATH" + local rsync_opts=() + if [[ ${DEBUG-} = 1 ]]; then + rsync_opts+=(-vh) + fi + + # Some extensions have a .gitignore which excludes their built source from the + # npm package so exclude any .gitignore files. + rsync_opts+=(--exclude .gitignore) + + # Exclude Node as we will add it ourselves for the standalone and will not + # need it for the npm package. + rsync_opts+=(--exclude /node) + + # Exclude Node modules. + if [[ $KEEP_MODULES = 0 ]]; then + rsync_opts+=(--exclude node_modules) + fi + + rsync "${rsync_opts[@]}" ./lib/vscode-reh-web-*/ "$VSCODE_OUT_PATH" # Add the commit, date, our name, links, and enable telemetry. This just makes # telemetry available; telemetry can still be disabled by flag or setting. @@ -122,19 +136,17 @@ EOF ) > "$VSCODE_OUT_PATH/product.json" # Use the package.json for the web/remote server. It does not have the right - # version though so pull that from the main package.json. Also remove keytar - # since the web does not rely on it and that removes the dependency on - # libsecret. - jq --slurp '.[0] * {version: .[1].version} | del(.dependencies.keytar)' \ + # version though so pull that from the main package.json. + jq --slurp '.[0] * {version: .[1].version}' \ "$VSCODE_SRC_PATH/remote/package.json" \ "$VSCODE_SRC_PATH/package.json" > "$VSCODE_OUT_PATH/package.json" rsync "$VSCODE_SRC_PATH/remote/yarn.lock" "$VSCODE_OUT_PATH/yarn.lock" - if [ "$KEEP_MODULES" = 0 ]; then - rm -Rf "$VSCODE_OUT_PATH/extensions/node_modules" - rm -Rf "$VSCODE_OUT_PATH/node_modules" - fi + # Include global extension dependencies as well. + rsync "$VSCODE_SRC_PATH/extensions/package.json" "$VSCODE_OUT_PATH/extensions/package.json" + rsync "$VSCODE_SRC_PATH/extensions/yarn.lock" "$VSCODE_OUT_PATH/extensions/yarn.lock" + rsync "$VSCODE_SRC_PATH/extensions/postinstall.js" "$VSCODE_OUT_PATH/extensions/postinstall.js" pushd "$VSCODE_OUT_PATH" symlink_asar diff --git a/ci/build/npm-postinstall.sh b/ci/build/npm-postinstall.sh index 123b56dfb..fd437a652 100755 --- a/ci/build/npm-postinstall.sh +++ b/ci/build/npm-postinstall.sh @@ -98,14 +98,6 @@ vscode_yarn() { cd extensions yarn --production --frozen-lockfile - - for ext in */; do - ext="${ext%/}" - echo "extensions/$ext: installing dependencies" - cd "$ext" - yarn --production --frozen-lockfile - cd "$OLDPWD" - done } main "$@" diff --git a/patches/display-language.diff b/patches/display-language.diff index d5ddfa785..bbcaa6731 100644 --- a/patches/display-language.diff +++ b/patches/display-language.diff @@ -79,7 +79,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html + } catch (error) { /* Probably fine. */ } Object.keys(self.webPackagePaths).map(function (key, index) { self.webPackagePaths[key] = new URL( - `{{VS_BASE}}/static/remote/web/node_modules/${key}/${self.webPackagePaths[key]}`, + `{{VS_BASE}}/static/node_modules/${key}/${self.webPackagePaths[key]}`, @@ -52,7 +76,8 @@ return value; } diff --git a/patches/integration.diff b/patches/integration.diff index 81db69f18..6f629c2e2 100644 --- a/patches/integration.diff +++ b/patches/integration.diff @@ -7,7 +7,6 @@ Prepare Code for integration with code-server 3. Add the code-server version to the help dialog. 4. Add ready events for use in an iframe. 5. Add our icons. -6. Remove sourcemap host since we cannot upload ours there. Index: code-server/lib/vscode/src/vs/server/node/server.main.ts =================================================================== @@ -254,16 +253,3 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html -Index: code-server/lib/vscode/build/gulpfile.reh.js -=================================================================== ---- code-server.orig/lib/vscode/build/gulpfile.reh.js -+++ code-server/lib/vscode/build/gulpfile.reh.js -@@ -365,7 +365,7 @@ function packageTask(type, platform, arc - const minifyTask = task.define(`minify-vscode-${type}`, task.series( - optimizeTask, - util.rimraf(`out-vscode-${type}-min`), -- common.minifyTask(`out-vscode-${type}`, `https://ticino.blob.core.windows.net/sourcemaps/${commit}/core`) -+ common.minifyTask(`out-vscode-${type}`, ``) - )); - gulp.task(minifyTask); - diff --git a/patches/series b/patches/series index e7d291ab1..d812592b1 100644 --- a/patches/series +++ b/patches/series @@ -18,3 +18,4 @@ local-storage.diff service-worker.diff last-opened.diff connection-type.diff +sourcemaps.diff diff --git a/patches/sourcemaps.diff b/patches/sourcemaps.diff new file mode 100644 index 000000000..fe0e26074 --- /dev/null +++ b/patches/sourcemaps.diff @@ -0,0 +1,43 @@ +Make sourcemaps self-hosted + +Normally source maps get removed as part of the build process so prevent that +from happening. Also avoid using the windows.net host since obviously we can +not host our source maps there and want them to be self-hosted even if we could. + +To test try debugging/browsing the source of a build in a browser. + +Index: code-server/lib/vscode/build/gulpfile.reh.js +=================================================================== +--- code-server.orig/lib/vscode/build/gulpfile.reh.js ++++ code-server/lib/vscode/build/gulpfile.reh.js +@@ -195,8 +195,7 @@ function packageTask(type, platform, arc + + const src = gulp.src(sourceFolderName + '/**', { base: '.' }) + .pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + sourceFolderName), 'out'); })) +- .pipe(util.setExecutableBit(['**/*.sh'])) +- .pipe(filter(['**', '!**/*.js.map'])); ++ .pipe(util.setExecutableBit(['**/*.sh'])); + + const workspaceExtensionPoints = ['debuggers', 'jsonValidation']; + const isUIExtension = (manifest) => { +@@ -235,9 +234,9 @@ function packageTask(type, platform, arc + .map(name => `.build/extensions/${name}/**`); + + const extensions = gulp.src(extensionPaths, { base: '.build', dot: true }); +- const extensionsCommonDependencies = gulp.src('.build/extensions/node_modules/**', { base: '.build', dot: true }); +- const sources = es.merge(src, extensions, extensionsCommonDependencies) ++ const extensionsCommonDependencies = gulp.src('.build/extensions/node_modules/**', { base: '.build', dot: true }) + .pipe(filter(['**', '!**/*.js.map'], { dot: true })); ++ const sources = es.merge(src, extensions, extensionsCommonDependencies); + + let version = packageJson.version; + const quality = product.quality; +@@ -363,7 +362,7 @@ function packageTask(type, platform, arc + const minifyTask = task.define(`minify-vscode-${type}`, task.series( + optimizeTask, + util.rimraf(`out-vscode-${type}-min`), +- common.minifyTask(`out-vscode-${type}`, `https://ticino.blob.core.windows.net/sourcemaps/${commit}/core`) ++ common.minifyTask(`out-vscode-${type}`, '') + )); + gulp.task(minifyTask); + From 5341294d2d7c6e435676768622aba88fad8ee56d Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 30 Mar 2022 10:47:46 -0700 Subject: [PATCH 03/55] fix(workflows): docs-preview and npm job (#5042) * fix(ci): add GITHUB_TOKEN to docs-preview workflow * feat(ci): comment npm dev build instructions on PR --- .github/workflows/ci.yaml | 20 ++++++++++++++++++++ .github/workflows/docs-preview.yaml | 1 + 2 files changed, 21 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index cb7a4e87e..4fdbc1fcd 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -217,6 +217,26 @@ jobs: # Instead, itis determined in publish-npm.sh script # using GITHUB environment variables + - name: Comment npm information + uses: marocchino/sticky-pull-request-comment@v2 + with: + GITHUB_TOKEN: ${{ github.token }} + header: npm-dev-build + message: | + ✨ code-server dev build published to npm for PR #${{ github.event.number }}! + * _Last publish status_: success + * _Commit_: ${{ github.event.pull_request.head.sha }} + + To install in a local project, run: + ```shell-session + npm install @coder/code-server-pr@${{ github.event.number }} + ``` + + To install globally, run: + ```shell-session + npm install -g @coder/code-server-pr@${{ github.event.number }} + ``` + # TODO: cache building yarn --production # possibly 2m30s of savings(?) # this requires refactoring our release scripts diff --git a/.github/workflows/docs-preview.yaml b/.github/workflows/docs-preview.yaml index 42021b540..1856fe34a 100644 --- a/.github/workflows/docs-preview.yaml +++ b/.github/workflows/docs-preview.yaml @@ -31,6 +31,7 @@ jobs: - name: Comment Credentials uses: marocchino/sticky-pull-request-comment@v2 with: + GITHUB_TOKEN: ${{ github.token }} header: codercom-preview-docs message: | ✨ code-server docs for PR #${{ github.event.number }} is ready! It will be updated on every commit. From 9c4f41d7846dea07a3ed77d9270398bb3fecf7f1 Mon Sep 17 00:00:00 2001 From: cjtim Date: Thu, 31 Mar 2022 01:19:58 +0700 Subject: [PATCH 04/55] docs(helm): add example env required for docker-in-docker (#5045) Co-authored-by: Joe Previte --- ci/helm-chart/values.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ci/helm-chart/values.yaml b/ci/helm-chart/values.yaml index a0c2f134f..4113b2a16 100644 --- a/ci/helm-chart/values.yaml +++ b/ci/helm-chart/values.yaml @@ -70,6 +70,8 @@ extraArgs: [] extraVars: [] # - name: DISABLE_TELEMETRY # value: true +# - name: DOCKER_HOST +# value: "tcp://localhost:2375" ## ## Init containers parameters: @@ -126,6 +128,7 @@ persistence: ## Enable an Specify container in extraContainers. ## This is meant to allow adding code-server dependencies, like docker-dind. extraContainers: | +# If docker-dind is used, DOCKER_HOST env is mandatory to set in "extraVars" #- name: docker-dind # image: docker:19.03-dind # imagePullPolicy: IfNotPresent From cd6d740dc31040946acc5b8c93a65b971a6836db Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 30 Mar 2022 13:25:37 -0700 Subject: [PATCH 05/55] chore(rennovate): ignore updates for express (#5044) --- renovate.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/renovate.json b/renovate.json index f3a956425..4679ebcc9 100644 --- a/renovate.json +++ b/renovate.json @@ -10,5 +10,6 @@ ], "vulnerabilityAlerts": { "enabled": "true" - } + }, + "ignoreDeps": ["express"] } From 7f884203f0674bac5894c8b8dc33874662b505be Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 30 Mar 2022 13:45:35 -0700 Subject: [PATCH 06/55] chore(ci): disable docs-preview on forks (#5046) --- .github/workflows/docs-preview.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/docs-preview.yaml b/.github/workflows/docs-preview.yaml index 1856fe34a..7f89c9c70 100644 --- a/.github/workflows/docs-preview.yaml +++ b/.github/workflows/docs-preview.yaml @@ -30,6 +30,9 @@ jobs: - name: Comment Credentials uses: marocchino/sticky-pull-request-comment@v2 + # Only run if PR comes from base repo + # Reason: forks cannot access secrets and this will always fail + if: github.event.pull_request.head.repo.full_name == github.repository with: GITHUB_TOKEN: ${{ github.token }} header: codercom-preview-docs From d5d7c519e80838fcce9e0e81e5e2f00b9b9916d8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 30 Mar 2022 15:41:26 -0700 Subject: [PATCH 07/55] chore(deps): update dependency minimist to v2.2.1 (#5013) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index f92db040f..87ce22da5 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ "follow-redirects": "^1.14.8", "node-fetch": "^2.6.7", "nanoid": "^3.1.31", - "minimist": "npm:minimist-lite@2.2.0" + "minimist": "npm:minimist-lite@2.2.1" }, "dependencies": { "@coder/logger": "1.1.16", diff --git a/yarn.lock b/yarn.lock index 4ea286721..cc6865ef2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2926,10 +2926,10 @@ minimist-options@4.1.0: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist@^1.2.0, minimist@^1.2.5, "minimist@npm:minimist-lite@2.2.0", minimist@~1.2.5: - version "2.2.0" - resolved "https://registry.yarnpkg.com/minimist-lite/-/minimist-lite-2.2.0.tgz#43992acac6bb17e78acb6eee784d1da2f7cc3216" - integrity sha512-o9M0Iz5ELqCT4NzeaZHBBlV4+ruOGGWV6lVxFoghC6Wvp4W6ECbBBpmDRHdk72O/sMh3QT0c/0XDKhtGlztRZw== +minimist@^1.2.0, minimist@^1.2.5, "minimist@npm:minimist-lite@2.2.1", minimist@~1.2.5: + version "2.2.1" + resolved "https://registry.yarnpkg.com/minimist-lite/-/minimist-lite-2.2.1.tgz#abb71db2c9b454d7cf4496868c03e9802de9934d" + integrity sha512-RSrWIRWGYoM2TDe102s7aIyeSipXMIXKb1fSHYx1tAbxAV0z4g2xR6ra3oPzkTqFb0EIUz1H3A/qvYYeDd+/qQ== minipass@^3.0.0: version "3.1.3" From 0fceb128f7d4f8769a8c0d1bcdbeee90ab81c1ba Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 30 Mar 2022 16:11:11 -0700 Subject: [PATCH 08/55] fix(npm): write npm package name to file (#5049) --- ci/steps/publish-npm.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ci/steps/publish-npm.sh b/ci/steps/publish-npm.sh index 702540875..5b01f627d 100755 --- a/ci/steps/publish-npm.sh +++ b/ci/steps/publish-npm.sh @@ -137,7 +137,10 @@ main() { # Use the development package name # This is so we don't clutter the code-server versions on npm # with development versions. - jq ".name |= \"$PACKAGE_NAME\"" package.json + # jq can't edit in place so we must store in memory and echo + local contents + contents="$(jq ".name |= \"$PACKAGE_NAME\"" package.json)" + echo "${contents}" > package.json popd fi From d796cc20e0cb6fa231173e93d8d2df654f8e7e40 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 30 Mar 2022 16:33:58 -0700 Subject: [PATCH 09/55] chore(Code): upgrade to 1.65 (#5047) * docs(CONTRIBUTING): update Code workflow * chore: update vscode to release/1.65 * chore(quilt): ignore patch backup files * chore: refresh/update patches for 1.65 --- .gitignore | 1 + docs/CONTRIBUTING.md | 4 ++-- lib/vscode | 2 +- patches/base-path.diff | 12 ++++++------ patches/display-language.diff | 8 ++++---- patches/integration.diff | 4 ++-- patches/last-opened.diff | 24 ------------------------ patches/local-storage.diff | 2 +- patches/logout.diff | 2 +- patches/marketplace.diff | 4 ++-- patches/node-version.diff | 7 ++++--- patches/proposed-api.diff | 4 ++-- patches/proxy-uri.diff | 4 ++-- patches/series | 1 - patches/service-worker.diff | 4 ++-- patches/sourcemaps.diff | 6 +++--- patches/unique-db.diff | 2 +- patches/update-check.diff | 2 +- patches/webview.diff | 10 +++++----- 19 files changed, 40 insertions(+), 63 deletions(-) diff --git a/.gitignore b/.gitignore index e615ec464..d453ee2e9 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ test/test-results # Quilt's internal data. /.pc +/patches/*.diff~ diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 205311558..eaa4b736a 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -96,10 +96,10 @@ re-apply the patches. ### Version updates to Code 1. Update the `lib/vscode` submodule to the desired upstream version branch. -2. From the code-server **project root**, run `yarn install`. -3. Apply the patches (`quilt push -a`) or restore your stashed changes. At this +2. Apply the patches (`quilt push -a`) or restore your stashed changes. At this stage you may need to resolve conflicts. For example use `quilt push -f`, manually apply the rejected portions, then `quilt refresh`. +3. From the code-server **project root**, run `yarn install`. 4. Test code-server locally to make sure everything works. 5. Check the Node.js version that's used by Electron (which is shipped with VS Code. If necessary, update your version of Node.js to match. diff --git a/lib/vscode b/lib/vscode index f80445acd..c722ca6c7 160000 --- a/lib/vscode +++ b/lib/vscode @@ -1 +1 @@ -Subproject commit f80445acd5a3dadef24aa209168452a3d97cc326 +Subproject commit c722ca6c7eed3d7987c0d5c3df5c45f6b15e77d1 diff --git a/patches/base-path.diff b/patches/base-path.diff index 715f8a215..eb3008eb2 100644 --- a/patches/base-path.diff +++ b/patches/base-path.diff @@ -185,10 +185,10 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, productConfiguration: >{ + rootEndpoint: base, + embedderIdentifier: 'server-distro', extensionsGallery: this._webExtensionResourceUrlTemplate ? { ...this._productService.extensionsGallery, - 'resourceUrlTemplate': this._webExtensionResourceUrlTemplate.with({ -@@ -289,7 +295,9 @@ export class WebClientServer { +@@ -290,7 +296,9 @@ export class WebClientServer { } : undefined } }))) @@ -199,7 +199,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts const cspDirectives = [ 'default-src \'self\';', -@@ -368,3 +376,70 @@ export class WebClientServer { +@@ -369,3 +377,70 @@ export class WebClientServer { return res.end(data); } } @@ -286,7 +286,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/code/browser/workbench/workbench.ts +++ code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts -@@ -504,6 +504,7 @@ function doCreateUri(path: string, query +@@ -482,6 +482,7 @@ function doCreateUri(path: string, query }); } @@ -294,11 +294,11 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts return URI.parse(window.location.href).with({ path, query }); } -@@ -515,7 +516,7 @@ function doCreateUri(path: string, query +@@ -493,7 +494,7 @@ function doCreateUri(path: string, query if (!configElement || !configElementAttribute) { throw new Error('Missing web configuration element'); } -- const config: IWorkbenchConstructionOptions & { folderUri?: UriComponents, workspaceUri?: UriComponents } = JSON.parse(configElementAttribute); +- const config: IWorkbenchConstructionOptions & { folderUri?: UriComponents; workspaceUri?: UriComponents } = JSON.parse(configElementAttribute); + const config: IWorkbenchConstructionOptions & { folderUri?: UriComponents, workspaceUri?: UriComponents } = { ...JSON.parse(configElementAttribute), remoteAuthority: location.host } // Create workbench diff --git a/patches/display-language.diff b/patches/display-language.diff index bbcaa6731..999c29b13 100644 --- a/patches/display-language.diff +++ b/patches/display-language.diff @@ -6,7 +6,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/serverServices.ts +++ code-server/lib/vscode/src/vs/server/node/serverServices.ts -@@ -198,6 +198,9 @@ export async function setupServerService +@@ -188,6 +188,9 @@ export async function setupServerService const channel = new ExtensionManagementChannel(extensionManagementService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority)); socketServer.registerChannel('extensions', channel); @@ -20,7 +20,7 @@ Index: code-server/lib/vscode/src/vs/base/common/platform.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/base/common/platform.ts +++ code-server/lib/vscode/src/vs/base/common/platform.ts -@@ -83,6 +83,17 @@ if (typeof navigator === 'object' && !is +@@ -84,6 +84,17 @@ if (typeof navigator === 'object' && !is _isWeb = true; _locale = navigator.language; _language = _locale; @@ -185,7 +185,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts const data = (await util.promisify(fs.readFile)(filePath)).toString() .replace('{{WORKBENCH_WEB_CONFIGURATION}}', escapeAttribute(JSON.stringify({ remoteAuthority, -@@ -301,7 +304,8 @@ export class WebClientServer { +@@ -302,7 +305,8 @@ export class WebClientServer { }))) .replace('{{WORKBENCH_AUTH_SESSION}}', () => authSessionInfo ? escapeAttribute(JSON.stringify(authSessionInfo)) : '') .replace(/{{BASE}}/g, base) @@ -252,7 +252,7 @@ Index: code-server/lib/vscode/src/vs/workbench/workbench.web.main.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/workbench.web.main.ts +++ code-server/lib/vscode/src/vs/workbench/workbench.web.main.ts -@@ -109,6 +109,10 @@ registerSingleton(ICustomEndpointTelemet +@@ -111,6 +111,10 @@ registerSingleton(IDiagnosticsService, N //#region --- workbench contributions diff --git a/patches/integration.diff b/patches/integration.diff index 6f629c2e2..1be03618d 100644 --- a/patches/integration.diff +++ b/patches/integration.diff @@ -174,10 +174,10 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.main.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/web.main.ts +++ code-server/lib/vscode/src/vs/workbench/browser/web.main.ts -@@ -69,6 +69,7 @@ import { ICredentialsService } from 'vs/ - import { IndexedDB } from 'vs/base/browser/indexedDB'; +@@ -69,6 +69,7 @@ import { IndexedDB } from 'vs/base/brows import { BrowserCredentialsService } from 'vs/workbench/services/credentials/browser/credentialsService'; import { IWorkspace } from 'vs/workbench/services/host/browser/browserHostService'; + import { WebFileSystemAccess } from 'vs/platform/files/browser/webFileSystemAccess'; +import { CodeServerClient } from 'vs/workbench/browser/client'; export class BrowserMain extends Disposable { diff --git a/patches/last-opened.diff b/patches/last-opened.diff index 83fafe291..71a1c9980 100644 --- a/patches/last-opened.diff +++ b/patches/last-opened.diff @@ -6,27 +6,3 @@ respect it here then remove our own redirction code that handles this. Our version might be better anyway since it puts the workspace in the URL. -Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts -=================================================================== ---- code-server.orig/lib/vscode/src/vs/code/browser/workbench/workbench.ts -+++ code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts -@@ -410,19 +410,6 @@ class WorkspaceProvider implements IWork - workspace = { folderUri: URI.revive(config.folderUri) }; - } else if (config.workspaceUri) { - workspace = { workspaceUri: URI.revive(config.workspaceUri) }; -- } else { -- workspace = (() => { -- const lastWorkspaceRaw = window.localStorage.getItem(WorkspaceProvider.LAST_WORKSPACE_STORAGE_KEY); -- if (lastWorkspaceRaw) { -- try { -- return parse(lastWorkspaceRaw); // use marshalling#parse() to revive potential URIs -- } catch (error) { -- // Ignore -- } -- } -- -- return undefined; -- })(); - } - } - diff --git a/patches/local-storage.diff b/patches/local-storage.diff index 8da6393cd..4c3c90da1 100644 --- a/patches/local-storage.diff +++ b/patches/local-storage.diff @@ -48,7 +48,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts +++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts -@@ -126,7 +126,14 @@ export class BrowserWorkbenchEnvironment +@@ -52,7 +52,14 @@ export class BrowserWorkbenchEnvironment get logFile(): URI { return joinPath(this.logsHome, 'window.log'); } @memoize diff --git a/patches/logout.diff b/patches/logout.diff index 94c03086e..7bbf73ef8 100644 --- a/patches/logout.diff +++ b/patches/logout.diff @@ -45,9 +45,9 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts rootEndpoint: base, updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, + logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined, + embedderIdentifier: 'server-distro', extensionsGallery: { ...this._productService.extensionsGallery, - 'resourceUrlTemplate': this._webExtensionResourceUrlTemplate ? this._webExtensionResourceUrlTemplate.with({ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/client.ts diff --git a/patches/marketplace.diff b/patches/marketplace.diff index 024c4bbb5..17442fc1f 100644 --- a/patches/marketplace.diff +++ b/patches/marketplace.diff @@ -32,10 +32,10 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -285,14 +285,14 @@ export class WebClientServer { - settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, +@@ -286,14 +286,14 @@ export class WebClientServer { productConfiguration: >{ rootEndpoint: base, + embedderIdentifier: 'server-distro', - extensionsGallery: this._webExtensionResourceUrlTemplate ? { + extensionsGallery: { ...this._productService.extensionsGallery, diff --git a/patches/node-version.diff b/patches/node-version.diff index a3e58f51e..9ee48e87f 100644 --- a/patches/node-version.diff +++ b/patches/node-version.diff @@ -11,7 +11,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js =================================================================== --- code-server.orig/lib/vscode/build/gulpfile.reh.js +++ code-server/lib/vscode/build/gulpfile.reh.js -@@ -122,9 +122,7 @@ const serverWithWebEntryPoints = [ +@@ -124,9 +124,7 @@ const serverWithWebEntryPoints = [ ]; function getNodeVersion() { @@ -71,7 +71,7 @@ Index: code-server/lib/vscode/build/lib/util.ts =================================================================== --- code-server.orig/lib/vscode/build/lib/util.ts +++ code-server/lib/vscode/build/lib/util.ts -@@ -371,9 +371,7 @@ export function streamToPromise(stream: +@@ -371,9 +371,7 @@ export function streamToPromise(stream: } export function getElectronVersion(): string { @@ -91,10 +91,11 @@ Index: code-server/lib/vscode/remote/.yarnrc =================================================================== --- code-server.orig/lib/vscode/remote/.yarnrc +++ /dev/null -@@ -1,3 +0,0 @@ +@@ -1,4 +0,0 @@ -disturl "http://nodejs.org/dist" -target "14.16.0" -runtime "node" +-build_from_source "true" Index: code-server/lib/vscode/.yarnrc =================================================================== --- code-server.orig/lib/vscode/.yarnrc diff --git a/patches/proposed-api.diff b/patches/proposed-api.diff index 015f43ba2..5971d714e 100644 --- a/patches/proposed-api.diff +++ b/patches/proposed-api.diff @@ -9,7 +9,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/extensions/common/abstra =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/services/extensions/common/abstractExtensionService.ts +++ code-server/lib/vscode/src/vs/workbench/services/extensions/common/abstractExtensionService.ts -@@ -1134,7 +1134,7 @@ class ProposedApiController { +@@ -1163,7 +1163,7 @@ class ProposedApiController { this._envEnabledExtensions = new Set((_environmentService.extensionEnabledProposedApi ?? []).map(id => ExtensionIdentifier.toKey(id))); @@ -22,7 +22,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/extensions/common/extens =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/services/extensions/common/extensions.ts +++ code-server/lib/vscode/src/vs/workbench/services/extensions/common/extensions.ts -@@ -135,10 +135,7 @@ export interface IExtensionHost { +@@ -134,10 +134,7 @@ export interface IExtensionHost { } export function isProposedApiEnabled(extension: IExtensionDescription, proposal: ApiProposalName): boolean { diff --git a/patches/proxy-uri.diff b/patches/proxy-uri.diff index 9a960a799..b46d733d9 100644 --- a/patches/proxy-uri.diff +++ b/patches/proxy-uri.diff @@ -73,9 +73,9 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined, + proxyEndpointTemplate: base + '/proxy/{{port}}', + embedderIdentifier: 'server-distro', extensionsGallery: { ...this._productService.extensionsGallery, - 'resourceUrlTemplate': this._webExtensionResourceUrlTemplate ? this._webExtensionResourceUrlTemplate.with({ Index: code-server/lib/vscode/src/vs/workbench/browser/web.main.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/web.main.ts @@ -93,7 +93,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalE =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts -@@ -388,7 +388,7 @@ export function createTerminalEnvironmen +@@ -390,7 +390,7 @@ export function createTerminalEnvironmen // Sanitize the environment, removing any undesirable VS Code and Electron environment // variables diff --git a/patches/series b/patches/series index d812592b1..87e8f3948 100644 --- a/patches/series +++ b/patches/series @@ -16,6 +16,5 @@ post-install.diff log-level.diff local-storage.diff service-worker.diff -last-opened.diff connection-type.diff sourcemaps.diff diff --git a/patches/service-worker.diff b/patches/service-worker.diff index 200555538..18cdc6c90 100644 --- a/patches/service-worker.diff +++ b/patches/service-worker.diff @@ -21,10 +21,10 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -296,6 +296,10 @@ export class WebClientServer { - updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, +@@ -297,6 +297,10 @@ export class WebClientServer { logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined, proxyEndpointTemplate: base + '/proxy/{{port}}', + embedderIdentifier: 'server-distro', + serviceWorker: { + scope: vscodeBase + '/', + path: base + '/_static/out/browser/serviceWorker.js', diff --git a/patches/sourcemaps.diff b/patches/sourcemaps.diff index fe0e26074..cb2367e6a 100644 --- a/patches/sourcemaps.diff +++ b/patches/sourcemaps.diff @@ -10,7 +10,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js =================================================================== --- code-server.orig/lib/vscode/build/gulpfile.reh.js +++ code-server/lib/vscode/build/gulpfile.reh.js -@@ -195,8 +195,7 @@ function packageTask(type, platform, arc +@@ -197,8 +197,7 @@ function packageTask(type, platform, arc const src = gulp.src(sourceFolderName + '/**', { base: '.' }) .pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + sourceFolderName), 'out'); })) @@ -20,7 +20,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js const workspaceExtensionPoints = ['debuggers', 'jsonValidation']; const isUIExtension = (manifest) => { -@@ -235,9 +234,9 @@ function packageTask(type, platform, arc +@@ -237,9 +236,9 @@ function packageTask(type, platform, arc .map(name => `.build/extensions/${name}/**`); const extensions = gulp.src(extensionPaths, { base: '.build', dot: true }); @@ -32,7 +32,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js let version = packageJson.version; const quality = product.quality; -@@ -363,7 +362,7 @@ function packageTask(type, platform, arc +@@ -374,7 +373,7 @@ function tweakProductForServerWeb(produc const minifyTask = task.define(`minify-vscode-${type}`, task.series( optimizeTask, util.rimraf(`out-vscode-${type}-min`), diff --git a/patches/unique-db.diff b/patches/unique-db.diff index 5ea2fac38..ca3cc1aff 100644 --- a/patches/unique-db.diff +++ b/patches/unique-db.diff @@ -21,7 +21,7 @@ Index: code-server/lib/vscode/src/vs/platform/storage/browser/storageService.ts @@ -13,6 +13,7 @@ import { InMemoryStorageDatabase, isStor import { ILogService } from 'vs/platform/log/common/log'; import { AbstractStorageService, IS_NEW_KEY, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; - import { IWorkspaceInitializationPayload } from 'vs/platform/workspaces/common/workspaces'; + import { IAnyWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; +import { hash } from 'vs/base/common/hash'; export class BrowserStorageService extends AbstractStorageService { diff --git a/patches/update-check.diff b/patches/update-check.diff index f9720da6c..ccfd39d1b 100644 --- a/patches/update-check.diff +++ b/patches/update-check.diff @@ -105,9 +105,9 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts productConfiguration: >{ rootEndpoint: base, + updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, + embedderIdentifier: 'server-distro', extensionsGallery: { ...this._productService.extensionsGallery, - 'resourceUrlTemplate': this._webExtensionResourceUrlTemplate ? this._webExtensionResourceUrlTemplate.with({ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts diff --git a/patches/webview.diff b/patches/webview.diff index c104034bf..a46901141 100644 --- a/patches/webview.diff +++ b/patches/webview.diff @@ -10,7 +10,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts +++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts -@@ -240,7 +240,7 @@ export class BrowserWorkbenchEnvironment +@@ -176,7 +176,7 @@ export class BrowserWorkbenchEnvironment @memoize get webviewExternalEndpoint(): string { @@ -31,11 +31,11 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts _wrapWebWorkerExtHostInIframe, developmentOptions: { enableSmokeTestDriver: this._environmentService.driverHandle === 'web' ? true : undefined }, settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, -Index: code-server/lib/vscode/src/vs/workbench/api/common/shared/webview.ts +Index: code-server/lib/vscode/src/vs/workbench/common/webview.ts =================================================================== ---- code-server.orig/lib/vscode/src/vs/workbench/api/common/shared/webview.ts -+++ code-server/lib/vscode/src/vs/workbench/api/common/shared/webview.ts -@@ -25,7 +25,7 @@ export const webviewResourceBaseHost = ' +--- code-server.orig/lib/vscode/src/vs/workbench/common/webview.ts ++++ code-server/lib/vscode/src/vs/workbench/common/webview.ts +@@ -24,7 +24,7 @@ export const webviewResourceBaseHost = ' export const webviewRootResourceAuthority = `vscode-resource.${webviewResourceBaseHost}`; From 5bc26e90cbf17c9e79d5646fd93838fc0082d9ab Mon Sep 17 00:00:00 2001 From: Asher Date: Thu, 31 Mar 2022 16:14:03 -0500 Subject: [PATCH 10/55] fix: version in about dialog (#5057) * Fix code-server version not appearing in other languages It needs to be separate from the localize call since the language version of that string is used and it will not include a spot for the code-server version. I also moved the "v" so we do not get "vUnknown". * Add code-server version to product configuration Before 1.64 the entire product configuration was sent to the client but that was removed so we have to add anything we want to use on the client, like the code-server version (used in the about dialog). Fixes #5027. * Refresh patches * Change version test to look for specific version This will catch if we are not sending the actual version to the client. --- patches/base-path.diff | 6 +++--- patches/display-language.diff | 2 +- patches/integration.diff | 24 ++++++++++++++++++++---- patches/logout.diff | 2 +- patches/marketplace.diff | 4 ++-- patches/proxy-uri.diff | 2 +- patches/service-worker.diff | 4 ++-- patches/update-check.diff | 2 +- test/e2e/openHelpAbout.test.ts | 7 ++++++- 9 files changed, 37 insertions(+), 16 deletions(-) diff --git a/patches/base-path.diff b/patches/base-path.diff index eb3008eb2..9f3be6ed5 100644 --- a/patches/base-path.diff +++ b/patches/base-path.diff @@ -185,10 +185,10 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, productConfiguration: >{ + rootEndpoint: base, + codeServerVersion: this._productService.codeServerVersion, embedderIdentifier: 'server-distro', extensionsGallery: this._webExtensionResourceUrlTemplate ? { - ...this._productService.extensionsGallery, -@@ -290,7 +296,9 @@ export class WebClientServer { +@@ -291,7 +297,9 @@ export class WebClientServer { } : undefined } }))) @@ -199,7 +199,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts const cspDirectives = [ 'default-src \'self\';', -@@ -369,3 +377,70 @@ export class WebClientServer { +@@ -370,3 +378,70 @@ export class WebClientServer { return res.end(data); } } diff --git a/patches/display-language.diff b/patches/display-language.diff index 999c29b13..6bfc0c75d 100644 --- a/patches/display-language.diff +++ b/patches/display-language.diff @@ -185,7 +185,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts const data = (await util.promisify(fs.readFile)(filePath)).toString() .replace('{{WORKBENCH_WEB_CONFIGURATION}}', escapeAttribute(JSON.stringify({ remoteAuthority, -@@ -302,7 +305,8 @@ export class WebClientServer { +@@ -303,7 +306,8 @@ export class WebClientServer { }))) .replace('{{WORKBENCH_AUTH_SESSION}}', () => authSessionInfo ? escapeAttribute(JSON.stringify(authSessionInfo)) : '') .replace(/{{BASE}}/g, base) diff --git a/patches/integration.diff b/patches/integration.diff index 1be03618d..d5348f06a 100644 --- a/patches/integration.diff +++ b/patches/integration.diff @@ -104,18 +104,22 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandl =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts +++ code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts -@@ -144,11 +144,12 @@ export class BrowserDialogHandler implem +@@ -143,12 +143,15 @@ export class BrowserDialogHandler implem + async about(): Promise { const detailString = (useAgo: boolean): string => { - return localize('aboutDetail', +- return localize('aboutDetail', - "Version: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}", -+ "code-server: v{4}\nCode: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}", ++ return localize('aboutCodeServerDetail', ++ "code-server: {0}", ++ this.productService.codeServerVersion ? `v${this.productService.codeServerVersion}` : 'Unknown' ++ ) + '\n' + localize('aboutDetail', ++ "Code: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}", this.productService.version || 'Unknown', this.productService.commit || 'Unknown', this.productService.date ? `${this.productService.date}${useAgo ? ' (' + fromNow(new Date(this.productService.date), true) + ')' : ''}` : 'Unknown', - navigator.userAgent + navigator.userAgent, -+ this.productService.codeServerVersion || 'Unknown' ); }; @@ -253,3 +257,15 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html +Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts ++++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts +@@ -279,6 +279,7 @@ export class WebClientServer { + developmentOptions: { enableSmokeTestDriver: this._environmentService.driverHandle === 'web' ? true : undefined }, + settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, + productConfiguration: >{ ++ codeServerVersion: this._productService.codeServerVersion, + embedderIdentifier: 'server-distro', + extensionsGallery: this._webExtensionResourceUrlTemplate ? { + ...this._productService.extensionsGallery, diff --git a/patches/logout.diff b/patches/logout.diff index 7bbf73ef8..47bb41002 100644 --- a/patches/logout.diff +++ b/patches/logout.diff @@ -45,9 +45,9 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts rootEndpoint: base, updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, + logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined, + codeServerVersion: this._productService.codeServerVersion, embedderIdentifier: 'server-distro', extensionsGallery: { - ...this._productService.extensionsGallery, Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/client.ts diff --git a/patches/marketplace.diff b/patches/marketplace.diff index 17442fc1f..77f469f10 100644 --- a/patches/marketplace.diff +++ b/patches/marketplace.diff @@ -32,9 +32,9 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -286,14 +286,14 @@ export class WebClientServer { - productConfiguration: >{ +@@ -287,14 +287,14 @@ export class WebClientServer { rootEndpoint: base, + codeServerVersion: this._productService.codeServerVersion, embedderIdentifier: 'server-distro', - extensionsGallery: this._webExtensionResourceUrlTemplate ? { + extensionsGallery: { diff --git a/patches/proxy-uri.diff b/patches/proxy-uri.diff index b46d733d9..1227dfaf9 100644 --- a/patches/proxy-uri.diff +++ b/patches/proxy-uri.diff @@ -73,9 +73,9 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined, + proxyEndpointTemplate: base + '/proxy/{{port}}', + codeServerVersion: this._productService.codeServerVersion, embedderIdentifier: 'server-distro', extensionsGallery: { - ...this._productService.extensionsGallery, Index: code-server/lib/vscode/src/vs/workbench/browser/web.main.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/web.main.ts diff --git a/patches/service-worker.diff b/patches/service-worker.diff index 18cdc6c90..ed12d5449 100644 --- a/patches/service-worker.diff +++ b/patches/service-worker.diff @@ -21,9 +21,9 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -297,6 +297,10 @@ export class WebClientServer { - logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined, +@@ -298,6 +298,10 @@ export class WebClientServer { proxyEndpointTemplate: base + '/proxy/{{port}}', + codeServerVersion: this._productService.codeServerVersion, embedderIdentifier: 'server-distro', + serviceWorker: { + scope: vscodeBase + '/', diff --git a/patches/update-check.diff b/patches/update-check.diff index ccfd39d1b..3e4d1dc09 100644 --- a/patches/update-check.diff +++ b/patches/update-check.diff @@ -105,9 +105,9 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts productConfiguration: >{ rootEndpoint: base, + updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, + codeServerVersion: this._productService.codeServerVersion, embedderIdentifier: 'server-distro', extensionsGallery: { - ...this._productService.extensionsGallery, Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts diff --git a/test/e2e/openHelpAbout.test.ts b/test/e2e/openHelpAbout.test.ts index 3720828bc..74b54c812 100644 --- a/test/e2e/openHelpAbout.test.ts +++ b/test/e2e/openHelpAbout.test.ts @@ -1,3 +1,4 @@ +import { version } from "../../src/node/constants" import { describe, test, expect } from "./baseFixture" describe("Open Help > About", true, [], {}, () => { @@ -5,8 +6,12 @@ describe("Open Help > About", true, [], {}, () => { // Open using the menu. await codeServerPage.navigateMenus(["Help", "About"]) + const isDevMode = process.env.VSCODE_DEV === "1" + // Look for code-server info div. - const element = await codeServerPage.page.waitForSelector('div[role="dialog"] >> text=code-server') + const element = await codeServerPage.page.waitForSelector( + `div[role="dialog"] >> text=code-server: ${isDevMode ? "Unknown" : "v" + version}`, + ) expect(element).not.toBeNull() }) }) From 38e57a355bee0fd1e0176a0ee75961ee03de6ff5 Mon Sep 17 00:00:00 2001 From: David Wahler Date: Wed, 6 Apr 2022 17:45:06 -0500 Subject: [PATCH 11/55] Exclude .deb files from release Docker image (#5068) --- ci/release-image/Dockerfile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ci/release-image/Dockerfile b/ci/release-image/Dockerfile index cd82972aa..f665a1588 100644 --- a/ci/release-image/Dockerfile +++ b/ci/release-image/Dockerfile @@ -1,3 +1,8 @@ +# syntax=docker/dockerfile:experimental + +FROM scratch AS packages +COPY release-packages/code-server*.deb /tmp/ + FROM debian:11 RUN apt-get update \ @@ -34,9 +39,8 @@ RUN ARCH="$(dpkg --print-architecture)" && \ mkdir -p /etc/fixuid && \ printf "user: coder\ngroup: coder\n" > /etc/fixuid/config.yml -COPY release-packages/code-server*.deb /tmp/ COPY ci/release-image/entrypoint.sh /usr/bin/entrypoint.sh -RUN dpkg -i /tmp/code-server*$(dpkg --print-architecture).deb && rm /tmp/code-server*.deb +RUN --mount=from=packages,src=/tmp,dst=/tmp/packages dpkg -i /tmp/packages/code-server*$(dpkg --print-architecture).deb EXPOSE 8080 # This way, if someone sets $DOCKER_USER, docker-exec will still work as From f0bfd3b450393884d1d7aa9419465c738cf48665 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Thu, 7 Apr 2022 10:36:33 -0700 Subject: [PATCH 12/55] chore: remove file ext. from LICENSE (#5070) * chore: remove file ext. from LICENSE * fixup!: update LICENSE in missing places * Revert "fixup!: update LICENSE in missing places" This reverts commit baa47b68e63e6c885865b30397e984c5a8c34117. * fixup!: update LICENSE in build-release --- LICENSE.txt => LICENSE | 0 ci/build/build-release.sh | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename LICENSE.txt => LICENSE (100%) diff --git a/LICENSE.txt b/LICENSE similarity index 100% rename from LICENSE.txt rename to LICENSE diff --git a/ci/build/build-release.sh b/ci/build/build-release.sh index e876f1268..07a879c28 100755 --- a/ci/build/build-release.sh +++ b/ci/build/build-release.sh @@ -24,7 +24,7 @@ main() { bundle_vscode rsync ./docs/README.md "$RELEASE_PATH" - rsync LICENSE.txt "$RELEASE_PATH" + rsync LICENSE "$RELEASE_PATH" rsync ./lib/vscode/ThirdPartyNotices.txt "$RELEASE_PATH" } @@ -113,7 +113,7 @@ bundle_vscode() { "applicationName": "code-server", "dataFolderName": ".code-server", "win32MutexName": "codeserver", - "licenseUrl": "https://github.com/coder/code-server/blob/main/LICENSE.txt", + "licenseUrl": "https://github.com/coder/code-server/blob/main/LICENSE", "win32DirName": "code-server", "win32NameVersion": "code-server", "win32AppUserModelId": "coder.code-server", From 3ba3caa8a67a71f07054d515075f79d5efc621f7 Mon Sep 17 00:00:00 2001 From: Asher Date: Thu, 7 Apr 2022 15:15:30 -0500 Subject: [PATCH 13/55] docs: link upstream sync section in MAINTAINING to CONTRIBUTING (#5075) * Link upstream sync section in MAINTAINING to CONTRIBUTING * Update MAINTAINING.md table of contents Co-authored-by: Joe Previte --- docs/MAINTAINING.md | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/docs/MAINTAINING.md b/docs/MAINTAINING.md index 7281f02a9..6aed2919e 100644 --- a/docs/MAINTAINING.md +++ b/docs/MAINTAINING.md @@ -19,7 +19,7 @@ - [Docker](#docker) - [Homebrew](#homebrew) - [npm](#npm) -- [Syncing with Upstream VS Code](#syncing-with-upstream-vs-code) +- [Syncing with upstream Code](#syncing-with-upstream-code) - [Testing](#testing) - [Documentation](#documentation) - [Troubleshooting](#troubleshooting) @@ -214,18 +214,9 @@ We publish code-server as a npm package [here](https://www.npmjs.com/package/cod This is currently automated with the release process. -## Syncing with Upstream VS Code +## Syncing with upstream Code -The VS Code portion of code-server lives under [`coder/vscode`](https://github.com/coder/vscode). To update VS Code for code-server, follow these steps: - -1. `git checkout -b vscode-update` - Create a new branch locally based off `main` -2. `git fetch upstream` - Fetch upstream (VS Code)'s latest branches -3. `git merge upstream/release/1.64` - Merge it locally - 1. replace `1.64` with the version you're upgrading to - 1. If there are merge conflicts, commit first, then fix them locally. -4. Open a PR merging your branch (`vscode-update`) into `main` and add the code-server review team - -Ideally, our fork stays as close to upstream as possible. See the differences between our fork and upstream [here](https://github.com/microsoft/vscode/compare/main...coder:main). +Refer to the [contributing docs](https://coder.com/docs/code-server/latest/CONTRIBUTING#version-updates-to-code) for information on how to update Code within code-server. ## Testing From fd2a031c2162f74eb879fbc9417d0191ef480932 Mon Sep 17 00:00:00 2001 From: Riley Calhoun <99927421+rileycalhoun@users.noreply.github.com> Date: Tue, 12 Apr 2022 11:32:49 -0700 Subject: [PATCH 14/55] Update ios.md (#5079) --- docs/ios.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/ios.md b/docs/ios.md index d804a33c6..fc484e19b 100644 --- a/docs/ios.md +++ b/docs/ios.md @@ -1,7 +1,9 @@ # Using code-server on iOS with iSH 1. Install iSH from the [App Store](https://apps.apple.com/us/app/ish-shell/id1436902243) -2. Install `curl` with `apk add curl` -3. Install code-server with `curl -fsSL https://code-server.dev/install.sh | sh` -4. Run code-server with `code-server` -5. Access on localhost:8080 in your browser +2. Install `curl` and `nano` with `apk add curl nano` +3. Configure iSH to use an earlier version of NodeJS with `nano /etc/apk/repositories` and edit `v3.14` to `v3.12` on both repository links. +4. Install `nodejs` and `npm` with `apk add nodejs npm` +5. Install code-server with `curl -fsSL https://code-server.dev/install.sh | sh` +6. Run code-server with `code-server` +7. Access on localhost:8080 in your browser From f4569f0b48727105ff846c57e5476a0e6b6fad3c Mon Sep 17 00:00:00 2001 From: neilnaveen <42328488+neilnaveen@users.noreply.github.com> Date: Tue, 12 Apr 2022 13:59:11 -0500 Subject: [PATCH 15/55] Set permissions for GitHub actions (#5090) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Included permissions for the action. https://github.com/ossf/scorecard/blob/main/docs/checks.md#token-permissions https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs [Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/) Restrict the GitHub token permissions only to the required ones; this way, even if the attackers will succeed in compromising your workflow, they won’t be able to do much. Signed-off-by: neilnaveen <42328488+neilnaveen@users.noreply.github.com> Co-authored-by: Joe Previte --- .github/workflows/ci.yaml | 3 +++ .github/workflows/codeql-analysis.yml | 7 +++++++ .github/workflows/installer.yml | 3 +++ 3 files changed, 13 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4fdbc1fcd..31ccdacb6 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -495,6 +495,9 @@ jobs: run: rm -rf ./release-packages ./test/test-results trivy-scan-repo: + permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results runs-on: ubuntu-20.04 steps: - name: Checkout repo diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e4b02aaa0..efe068fbd 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -17,8 +17,15 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} +permissions: + contents: read + jobs: analyze: + permissions: + actions: read # for github/codeql-action/init to get workflow details + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/autobuild to send a status report name: Analyze runs-on: ubuntu-20.04 diff --git a/.github/workflows/installer.yml b/.github/workflows/installer.yml index 5002c3e81..bf0f4eaa0 100644 --- a/.github/workflows/installer.yml +++ b/.github/workflows/installer.yml @@ -19,6 +19,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} +permissions: + contents: read + jobs: ubuntu: name: Test installer on Ubuntu From 3bf470f19c0a354de47627f142229169b1749fb4 Mon Sep 17 00:00:00 2001 From: Joseph Reiter Date: Tue, 12 Apr 2022 18:42:22 -0400 Subject: [PATCH 16/55] docs: simplify termux installation process (#5078) * Update termux.md 1) Updated information to use PRoot (simpler than Andronix and the way supported by Termux) to create and access the Debian distro. 2) Added helpful information on using PRoot with your dev environment. 3) Cleaned up spelling, grammar, and made documentation more consistent between sections. * docs: Termux correct packages to install Updated some erroneously missing packages (vim and sudo) necessary for multi-user setup. * docs: cleaned up verbiage Co-authored-by: Joe Previte * docs: corrected punctuation Co-authored-by: Joe Previte * docs: correct punctuation Co-authored-by: Joe Previte * docs: clarify pkg command shorthand * Ran yarn fmt on docs Co-authored-by: Joe Previte --- docs/termux.md | 85 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 24 deletions(-) diff --git a/docs/termux.md b/docs/termux.md index 8a9b7a870..cfaec3607 100644 --- a/docs/termux.md +++ b/docs/termux.md @@ -10,40 +10,45 @@ - [Create a new user](#create-a-new-user) - [Install Go](#install-go) - [Install Python](#install-python) + - [Working with PRoot](#working-with-proot) ## Install 1. Get [Termux](https://f-droid.org/en/packages/com.termux/) from **F-Droid**. -2. Install Debian by running the following. +2. Install Debian by running the following: - Run `termux-setup-storage` to allow storage access, or else code-server won't be able to read from `/sdcard`.\ - If you used the Andronix command then you may have to edit the `start-debian.sh` script to mount `/sdcard` just as simple as uncommenting the `command+=" -b /sdcard"` line. - > The following command was extracted from [Andronix](https://andronix.app/) you can also use [proot-distro](https://github.com/termux/proot-distro). + > The following command is from [proot-distro](https://github.com/termux/proot-distro), but you can also use [Andronix](https://andronix.app/). > After Debian is installed the `~ $` will change to `root@localhost`. ```bash -pkg update -y && pkg install wget curl proot tar -y && wget https://raw.githubusercontent.com/AndronixApp/AndronixOrigin/master/Installer/Debian/debian.sh -O debian.sh && chmod +x debian.sh && bash debian.sh +pkg update -y && pkg install proot-distro -y && proot-distro install debian && proot-distro login debian ``` -3. Run the following commands to setup Debian. +3. Run the following commands to setup Debian: ```bash -apt update -apt upgrade -y -apt-get install nano vim sudo curl wget git -y +apt update && apt upgrade -y && apt-get install sudo vim git -y ``` -4. Install [NVM](https://github.com/nvm-sh/nvm) by following the install guide in the README, just a curl/wget command. -5. Set up NVM for multi-user. After installing NVM it automatically adds the necessary commands for it to work, but it will only work if you are logged in as root; +4. Install [NVM](https://github.com/nvm-sh/nvm#install--update-script) by following the install guide in the README, just a curl/wget command. + +5. Set up NVM for multi-user. After installing NVM it automatically adds the necessary commands for it to work, but it will only work if you are logged in as root: - Copy the lines NVM asks you to run after running the install script. - Run `nano /root/.bashrc` and comment out those lines by adding a `#` at the start. - - Run `nano /etc/profile` and paste those lines at the end and make sure to replace `$HOME` with `/root` - - Now run `exit` and start Debain again. + - Run `nano /etc/profile` and paste those lines at the end of the file. Make sure to replace `$HOME` with `/root` on the first line. + - Now run `exit` + - Start Debian again `proot-distro login debian` -6. After following the instructions and setting up NVM you can now install the [required node version](https://coder.com/docs/code-server/latest/npm#nodejs-version) using `nvm install version_here`. -7. To install `code-server` run the following. +6. After following the instructions and setting up NVM you can now install the [required node version](https://coder.com/docs/code-server/latest/npm#nodejs-version) by running: + +```bash +nvm install v +``` + +7. To install `code-server` run the following: > To check the install process (Will not actually install code-server) > If it all looks good, you can install code-server by running the second command @@ -82,11 +87,11 @@ Potential Workaround : To create a new user follow these simple steps - -1. Create a new user by running `useradd username -m`. -2. Change the password by running `passwd username`. -3. Give your new user sudo access by runnning `visudo`, scroll down to `User privilege specification` and add the following line after root `username ALL=(ALL:ALL) ALL`. -4. Now edit the `/etc/passwd` file with your commadline editor of choice and at the end of the line that specifies your user change `/bin/sh` to `/bin/bash`. -5. Now switch users, by running `su - username` +1. Create a new user by running `useradd -m`. +2. Change the password by running `passwd `. +3. Give your new user sudo access by running `visudo`, scroll down to `User privilege specification` and add the following line after root `username ALL=(ALL:ALL) ALL`. +4. Now edit the `/etc/passwd` file with your command line editor of choice and at the end of the line that specifies your user change `/bin/sh` to `/bin/bash`. +5. Now switch users by running `su - ` - Remember the `-` betweeen `su` and username is required to execute `/etc/profile`,\ since `/etc/profile` may have some necessary things to be executed you should always add a `-`. @@ -95,7 +100,7 @@ To create a new user follow these simple steps - > From https://golang.org/doc/install -1. Go to https://golang.org/dl/ and copy the download link for `linux arm` and run the following. +1. Go to https://golang.org/dl/ and copy the download link for `linux arm` and run the following: ```bash wget download_link @@ -115,7 +120,7 @@ rm -rf /usr/local/go && tar -C /usr/local -xzf archive_name > Run these commands as root -1. Run the following command to install required packages to build python. +1. Run the following commands to install required packages to build python: ```bash sudo apt-get update @@ -124,13 +129,13 @@ sudo apt-get install make build-essential libssl-dev zlib1g-dev \ libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev ``` -2. Install [pyenv](https://github.com/pyenv/pyenv/) from [pyenv-installer](https://github.com/pyenv/pyenv-installer) by running. +2. Install [pyenv](https://github.com/pyenv/pyenv/) from [pyenv-installer](https://github.com/pyenv/pyenv-installer) by running: ```bash curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash ``` -3. Run `nano /etc/profile` and add the following +3. Run `nano /etc/profile` and add the following: ```bash export PYENV_ROOT="/root/.pyenv" @@ -139,10 +144,42 @@ eval "$(pyenv init --path)" eval "$(pyenv virtualenv-init -)" ``` -4. Exit start Debian again. +4. Exit and start Debian again. 5. Run `pyenv versions` to list all installable versions. 6. Run `pyenv install version` to install the desired python version. > The build process may take some time (an hour or 2 depending on your device). 7. Run `touch /root/.pyenv/version && echo "your_version_here" > /root/.pyenv/version` 8. (You may have to start Debian again) Run `python3 -V` to verify if PATH works or not. > If `python3` doesn't work but pyenv says that the install was successful in step 6 then try running `$PYENV_ROOT/versions/your_version/bin/python3`. + +### Working with PRoot + +Debian PRoot Distro Dev Environment + +- Since Node and code-server are installed in the Debian PRoot distro, your `~/.ssh/` configuration, `~/.bashrc`, git, npm packages, etc. should be setup in PRoot as well. +- The terminal accessible in code-server will bring up the filesystem and `~/.bashrc` in the Debian PRoot distro. + +Accessing files in the Debian PRoot Distro + +- The `/data/data/com.termux/files/home` directory in PRoot accesses the termux home directory (`~`) +- The `/sdcard` directory in PRoot accesses the Android storage directory, though there are [known issues with git and files in the `/sdcard` path](#git-wont-work-in-sdcard) + +Accessing the Debian PRoot distro/Starting code-server + +- Run the following command to access the Debian PRoot distro, from the termux shell: + +```bash +proot-distro login debian +``` + +- Run the following command to start code-server directly in the Debian PRoot distro, from the termux shell: + +```bash +proot-distro login debian -- code-server +``` + +- If you [created a new user](#create-a-new-user), you'll need to insert the `--user ` option between `login` and `debian` in the commands above to run as the user instead of root in PRoot. + +Additional information on PRoot and Termux + +- Additional information on using your Debian PRoot Distro can be [found here](https://github.com/termux/proot-distro#functionality-overview). From c05b727c616e0563355cdd6c20479a8104ee5d61 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 12 Apr 2022 16:39:58 -0700 Subject: [PATCH 17/55] chore(deps): update minor dependency updates (#5060) Co-authored-by: Renovate Bot Co-authored-by: Joe Previte --- .github/workflows/ci.yaml | 2 +- .github/workflows/trivy-docker.yaml | 2 +- package.json | 2 +- yarn.lock | 97 +++++++++++++++++++++++++---- 4 files changed, 88 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 31ccdacb6..a977cd507 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -506,7 +506,7 @@ jobs: fetch-depth: 0 - name: Run Trivy vulnerability scanner in repo mode - uses: aquasecurity/trivy-action@296212627a1e693efa09c00adc3e03b2ba8edf18 + uses: aquasecurity/trivy-action@40c4ca9e7421287d0c5576712fdff370978f9c3c with: scan-type: "fs" scan-ref: "." diff --git a/.github/workflows/trivy-docker.yaml b/.github/workflows/trivy-docker.yaml index 827a9905a..840b85e1f 100644 --- a/.github/workflows/trivy-docker.yaml +++ b/.github/workflows/trivy-docker.yaml @@ -51,7 +51,7 @@ jobs: uses: actions/checkout@v3 - name: Run Trivy vulnerability scanner in image mode - uses: aquasecurity/trivy-action@296212627a1e693efa09c00adc3e03b2ba8edf18 + uses: aquasecurity/trivy-action@40c4ca9e7421287d0c5576712fdff370978f9c3c with: image-ref: "docker.io/codercom/code-server:latest" ignore-unfixed: true diff --git a/package.json b/package.json index 87ce22da5..e85d705fd 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "eslint-plugin-prettier": "^4.0.0", "json": "^11.0.0", "prettier": "^2.2.1", - "prettier-plugin-sh": "^0.8.0", + "prettier-plugin-sh": "^0.10.0", "shellcheck": "^1.0.0", "stylelint": "^13.0.0", "stylelint-config-recommended": "^5.0.0", diff --git a/yarn.lock b/yarn.lock index cc6865ef2..561b76cdc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -276,6 +276,18 @@ resolved "https://registry.yarnpkg.com/@phc/format/-/format-1.0.0.tgz#b5627003b3216dc4362125b13f48a4daa76680e4" integrity sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ== +"@pkgr/utils@^2.0.3": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.1.0.tgz#66a4be2df4fc8ae50d730666855f6a6df833a725" + integrity sha512-Va5LTLVoPIH8CrV170zXLSDtCJ6eG6uVXYwwsDYOOeec0MdkhvJzKaxvA+hGJRWFl5I4VBQBs5pwljaI4TG5OA== + dependencies: + cross-spawn "^7.0.3" + is-glob "^4.0.3" + open "^8.4.0" + picocolors "^1.0.0" + tiny-glob "^0.2.9" + tslib "^2.3.1" + "@schemastore/package@^0.0.6": version "0.0.6" resolved "https://registry.yarnpkg.com/@schemastore/package/-/package-0.0.6.tgz#9a76713da1c7551293b7e72e4f387f802bfd5d81" @@ -1270,6 +1282,11 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -2104,6 +2121,11 @@ globals@^13.6.0, globals@^13.9.0: dependencies: type-fest "^0.20.2" +globalyzer@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/globalyzer/-/globalyzer-0.1.0.tgz#cb76da79555669a1519d5a8edf093afaa0bf1465" + integrity sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q== + globby@^11.0.3: version "11.0.3" resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" @@ -2133,6 +2155,11 @@ globjoin@^0.1.4: resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43" integrity sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM= +globrex@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098" + integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg== + gonzales-pe@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/gonzales-pe/-/gonzales-pe-4.3.0.tgz#fe9dec5f3c557eead09ff868c65826be54d067b3" @@ -2434,6 +2461,11 @@ is-decimal@^1.0.0: resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + is-extendable@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -2543,6 +2575,13 @@ is-word-character@^1.0.0: resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.4.tgz#ce0e73216f98599060592f62ff31354ddbeb0230" integrity sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA== +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" @@ -2971,12 +3010,7 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -mvdan-sh@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/mvdan-sh/-/mvdan-sh-0.5.0.tgz#fa76f611a103595ad0f04f5d18e582892c46e87c" - integrity sha512-UWbdl4LHd2fUnaEcOUFVWRdWGLkNoV12cKVIPiirYd8qM5VkCoCTXErlDubevrkEG7kGohvjRxAlTQmOqG80tw== - -nanoid@^3.1.23, nanoid@^3.1.31: +nanoid@^3.1.23, nanoid@^3.1.31, nanoid@^3.3.2: version "3.2.0" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== @@ -3116,6 +3150,15 @@ once@^1.3.0: dependencies: wrappy "1" +open@^8.4.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" + integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + opencollective-postinstall@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259" @@ -3325,6 +3368,11 @@ pem@^1.14.2: os-tmpdir "^1.0.1" which "^2.0.2" +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" @@ -3444,12 +3492,13 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier-plugin-sh@^0.8.0: - version "0.8.1" - resolved "https://registry.yarnpkg.com/prettier-plugin-sh/-/prettier-plugin-sh-0.8.1.tgz#50698d95f2006c1b3eae570d430c3c1c05a31327" - integrity sha512-tz0g6y+ZaJF0PWaa1F7vhCv4nLgYYl2zYzYU4XJFD1McoY0oHI+l2osvXqv1s5yQdtjdlzKszN6VY7WTaw2Gqw== +prettier-plugin-sh@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/prettier-plugin-sh/-/prettier-plugin-sh-0.10.1.tgz#70951b933238803fa67a0d5752d6667963130057" + integrity sha512-bEcEMvgivqNB/9r9UIN6CTPoux7pmZKFtzDkEb/hSwj/j/PlHfNpiOwLtDZ44D8RtUAZloMz7j1ucqdPqcTawQ== dependencies: - mvdan-sh "^0.5.0" + sh-syntax "^0.1.4" + synckit "^0.7.0" prettier@^2.2.1: version "2.3.2" @@ -3838,6 +3887,14 @@ setprototypeof@1.2.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== +sh-syntax@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/sh-syntax/-/sh-syntax-0.1.4.tgz#a63eb87571161c89f4a027085be6745b0154429c" + integrity sha512-PbReZBaylc3YSo+SbZQd5b8/I0jh8CQTdy5YRBNSVtIyuJ+l1dCygR8UhWBMz3p431ZDs2Wp59qUpIUvPCcssA== + dependencies: + nanoid "^3.3.2" + tslib "^2.3.1" + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -4197,6 +4254,14 @@ svg-tags@^1.0.0: resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" integrity sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q= +synckit@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.7.0.tgz#59abd4ec3ee4e7b645dbd1e6e188920c9494392c" + integrity sha512-NbpamGIw1300xjPCLCVkhtSgGVfONitrmJA4CD54f2P47GxW5rlsCiajAYrqbz0H0PmVSPA2slZjEfJpUfap0Q== + dependencies: + "@pkgr/utils" "^2.0.3" + tslib "^2.3.1" + synp@^1.9.10: version "1.9.10" resolved "https://registry.yarnpkg.com/synp/-/synp-1.9.10.tgz#53163321a600418c9b06af0db499939ffce12907" @@ -4257,6 +4322,14 @@ through@2, "through@>=2.2.7 <3", through@^2.3.8, through@~2.3, through@~2.3.4: resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= +tiny-glob@^0.2.9: + version "0.2.9" + resolved "https://registry.yarnpkg.com/tiny-glob/-/tiny-glob-0.2.9.tgz#2212d441ac17928033b110f8b3640683129d31e2" + integrity sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg== + dependencies: + globalyzer "0.1.0" + globrex "^0.1.2" + to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -4340,7 +4413,7 @@ tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.1: +tslib@^2.0.1, tslib@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== From 0e1f396645cfdfa5209163fec370a8e53d4dae45 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 13 Apr 2022 09:39:05 -0700 Subject: [PATCH 18/55] feat: add option for disabling file downloads (#5055) * feat(cli): add disable-file-downloads to cli * feat(e2e): add download test * feat(e2e): add downloads disabled test * refactor(e2e): explain how to debug unexpected close * feat(patches): add disable file downloads * wip: update diff * Update src/node/cli.ts Co-authored-by: Asher * fixup! add missing common/contextkeys file to patch * fixup!: update patch * fixup!: default disable-file-downloads undefined * fixup!: combine e2e tests * fixup!: use different test names * feat: add CS_DISABLE_FILE_DOWNLOADS * fixup!: make explicit and cleanup test * fixup!: use beforeEach Co-authored-by: Asher --- patches/disable-downloads.diff | 183 +++++++++++++++++++++++++++++++++ patches/series | 1 + src/node/cli.ts | 9 ++ test/e2e/downloads.test.ts | 48 +++++++++ test/e2e/models/CodeServer.ts | 2 +- test/unit/node/cli.test.ts | 16 +++ test/unit/node/plugin.test.ts | 1 + 7 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 patches/disable-downloads.diff create mode 100644 test/e2e/downloads.test.ts diff --git a/patches/disable-downloads.diff b/patches/disable-downloads.diff new file mode 100644 index 000000000..3c4b87da9 --- /dev/null +++ b/patches/disable-downloads.diff @@ -0,0 +1,183 @@ +Add option to disable file downloads via CLI + +This patch adds support for a new CLI flag called `--disable-file-downloads` +which allows a user to remove the "Download..." option that shows up when you +right-click files in Code. The default value for this is `false`. + +To test this, start code-server with `--disable-file-downloads`, open editor, +right-click on a file (not a folder) and you should **not** see the +"Download..." option. + +Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts ++++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts +@@ -210,6 +210,11 @@ export interface IWorkbenchConstructionO + */ + readonly userDataPath?: string + ++ /** ++ * Whether the "Download..." option is enabled for files. ++ */ ++ readonly isEnabledFileDownloads?: boolean ++ + //#endregion + + +Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts ++++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts +@@ -30,6 +30,11 @@ export interface IBrowserWorkbenchEnviro + * Options used to configure the workbench. + */ + readonly options?: IWorkbenchConstructionOptions; ++ ++ /** ++ * Enable downloading files via menu actions. ++ */ ++ readonly isEnabledFileDownloads?: boolean; + } + + export class BrowserWorkbenchEnvironmentService implements IBrowserWorkbenchEnvironmentService { +@@ -61,6 +66,13 @@ export class BrowserWorkbenchEnvironment + return this.options.userDataPath; + } + ++ get isEnabledFileDownloads(): boolean { ++ if (typeof this.options.isEnabledFileDownloads === "undefined") { ++ throw new Error('isEnabledFileDownloads was not provided to the browser'); ++ } ++ return this.options.isEnabledFileDownloads; ++ } ++ + @memoize + get settingsResource(): URI { return joinPath(this.userRoamingDataHome, 'settings.json'); } + +Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts ++++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts +@@ -15,6 +15,7 @@ export const serverOptions: OptionDescri + 'disable-update-check': { type: 'boolean' }, + 'auth': { type: 'string' }, + 'locale': { type: 'string' }, ++ 'disable-file-downloads': { type: 'boolean' }, + + /* ----- server setup ----- */ + +@@ -92,6 +93,7 @@ export interface ServerParsedArgs { + 'disable-update-check'?: boolean; + 'auth'?: string + 'locale'?: string ++ 'disable-file-downloads'?: boolean; + + /* ----- server setup ----- */ + +Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts ++++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts +@@ -290,6 +290,7 @@ export class WebClientServer { + logLevel: this._logService.getLevel(), + }, + userDataPath: this._environmentService.userDataPath, ++ isEnabledFileDownloads: !this._environmentService.args['disable-file-downloads'], + settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, + productConfiguration: >{ + rootEndpoint: base, +Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/workbench/browser/contextkeys.ts ++++ code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts +@@ -7,12 +7,11 @@ import { Event } from 'vs/base/common/ev + import { Disposable } from 'vs/base/common/lifecycle'; + import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; + import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext } from 'vs/platform/contextkey/common/contextkeys'; +-import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, EditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext } from 'vs/workbench/common/contextkeys'; ++import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, EditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, IsEnabledFileDownloads } from 'vs/workbench/common/contextkeys'; + import { TEXT_DIFF_EDITOR_ID, EditorInputCapabilities, SIDE_BY_SIDE_EDITOR_ID, DEFAULT_EDITOR_ASSOCIATION } from 'vs/workbench/common/editor'; + import { trackFocus, addDisposableListener, EventType } from 'vs/base/browser/dom'; + import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; + import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +-import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; + import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; + import { WorkbenchState, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; + import { IWorkbenchLayoutService, Parts, positionToString } from 'vs/workbench/services/layout/browser/layoutService'; +@@ -24,6 +23,7 @@ import { IEditorResolverService } from ' + import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite'; + import { Schemas } from 'vs/base/common/network'; + import { WebFileSystemAccess } from 'vs/platform/files/browser/webFileSystemAccess'; ++import { IBrowserWorkbenchEnvironmentService } from '../services/environment/browser/environmentService'; + + export class WorkbenchContextKeysHandler extends Disposable { + private inputFocusedContext: IContextKey; +@@ -75,7 +75,7 @@ export class WorkbenchContextKeysHandler + @IContextKeyService private readonly contextKeyService: IContextKeyService, + @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, + @IConfigurationService private readonly configurationService: IConfigurationService, +- @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService, ++ @IBrowserWorkbenchEnvironmentService private readonly environmentService: IBrowserWorkbenchEnvironmentService, + @IEditorService private readonly editorService: IEditorService, + @IEditorResolverService private readonly editorResolverService: IEditorResolverService, + @IEditorGroupsService private readonly editorGroupService: IEditorGroupsService, +@@ -194,6 +194,9 @@ export class WorkbenchContextKeysHandler + this.auxiliaryBarVisibleContext = AuxiliaryBarVisibleContext.bindTo(this.contextKeyService); + this.auxiliaryBarVisibleContext.set(this.layoutService.isVisible(Parts.AUXILIARYBAR_PART)); + ++ // code-server ++ IsEnabledFileDownloads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileDownloads ?? true) ++ + this.registerListeners(); + } + +Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts ++++ code-server/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts +@@ -21,7 +21,7 @@ import { CLOSE_SAVED_EDITORS_COMMAND_ID, + import { AutoSaveAfterShortDelayContext } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; + import { WorkbenchListDoubleSelection } from 'vs/platform/list/browser/listService'; + import { Schemas } from 'vs/base/common/network'; +-import { DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, WorkbenchStateContext, WorkspaceFolderCountContext, SidebarFocusContext, ActiveEditorCanRevertContext, ActiveEditorContext, ResourceContextKey } from 'vs/workbench/common/contextkeys'; ++import { DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, WorkbenchStateContext, WorkspaceFolderCountContext, SidebarFocusContext, ActiveEditorCanRevertContext, ActiveEditorContext, ResourceContextKey, IsEnabledFileDownloads } from 'vs/workbench/common/contextkeys'; + import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys'; + import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; + import { ThemeIcon } from 'vs/platform/theme/common/themeService'; +@@ -475,13 +475,16 @@ MenuRegistry.appendMenuItem(MenuId.Explo + id: DOWNLOAD_COMMAND_ID, + title: DOWNLOAD_LABEL + }, +- when: ContextKeyExpr.or( +- // native: for any remote resource +- ContextKeyExpr.and(IsWebContext.toNegated(), ResourceContextKey.Scheme.notEqualsTo(Schemas.file)), +- // web: for any files +- ContextKeyExpr.and(IsWebContext, ExplorerFolderContext.toNegated(), ExplorerRootContext.toNegated()), +- // web: for any folders if file system API support is provided +- ContextKeyExpr.and(IsWebContext, HasWebFileSystemAccess) ++ when: ContextKeyExpr.and( ++ IsEnabledFileDownloads, ++ ContextKeyExpr.or( ++ // native: for any remote resource ++ ContextKeyExpr.and(IsWebContext.toNegated(), ResourceContextKey.Scheme.notEqualsTo(Schemas.file)), ++ // web: for any files ++ ContextKeyExpr.and(IsWebContext, ExplorerFolderContext.toNegated(), ExplorerRootContext.toNegated()), ++ // web: for any folders if file system API support is provided ++ ContextKeyExpr.and(IsWebContext, HasWebFileSystemAccess) ++ ) + ) + })); + +Index: code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts ++++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts +@@ -30,6 +30,8 @@ export const IsFullscreenContext = new R + + export const HasWebFileSystemAccess = new RawContextKey('hasWebFileSystemAccess', false, true); // Support for FileSystemAccess web APIs (https://wicg.github.io/file-system-access) + ++export const IsEnabledFileDownloads = new RawContextKey('isEnabledFileDownloads', true, true); ++ + //#endregion + + diff --git a/patches/series b/patches/series index 87e8f3948..79da7efda 100644 --- a/patches/series +++ b/patches/series @@ -18,3 +18,4 @@ local-storage.diff service-worker.diff connection-type.diff sourcemaps.diff +disable-downloads.diff diff --git a/src/node/cli.ts b/src/node/cli.ts index 6dd260c19..2522a6268 100644 --- a/src/node/cli.ts +++ b/src/node/cli.ts @@ -49,6 +49,7 @@ export interface UserProvidedCodeArgs { category?: string "github-auth"?: string "disable-update-check"?: boolean + "disable-file-downloads"?: boolean } /** @@ -157,6 +158,10 @@ export const options: Options> = { "Disable update check. Without this flag, code-server checks every 6 hours against the latest github release and \n" + "then notifies you once every week that a new release is available.", }, + "disable-file-downloads": { + type: "boolean", + description: "Disable file downloads from Code.", + }, // --enable can be used to enable experimental features. These features // provide no guarantees. enable: { type: "string[]" }, @@ -537,6 +542,10 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config args.password = process.env.PASSWORD } + if (process.env.CS_DISABLE_FILE_DOWNLOADS === "1") { + args["disable-file-downloads"] = true + } + const usingEnvHashedPassword = !!process.env.HASHED_PASSWORD if (process.env.HASHED_PASSWORD) { args["hashed-password"] = process.env.HASHED_PASSWORD diff --git a/test/e2e/downloads.test.ts b/test/e2e/downloads.test.ts new file mode 100644 index 000000000..4503e076c --- /dev/null +++ b/test/e2e/downloads.test.ts @@ -0,0 +1,48 @@ +import * as path from "path" +import { promises as fs } from "fs" +import { clean } from "../utils/helpers" +import { describe, test, expect } from "./baseFixture" + +describe("Downloads (enabled)", true, [], {}, async () => { + const testName = "downloads-enabled" + test.beforeAll(async () => { + await clean(testName) + }) + + test("should see the 'Download...' option", async ({ codeServerPage }) => { + // Setup + const workspaceDir = await codeServerPage.workspaceDir + const tmpFilePath = path.join(workspaceDir, "unique-file.txt") + await fs.writeFile(tmpFilePath, "hello world") + + // Action + const fileInExplorer = await codeServerPage.page.waitForSelector("text=unique-file.txt") + await fileInExplorer.click({ + button: "right", + }) + + expect(await codeServerPage.page.isVisible("text=Download...")).toBe(true) + }) +}) + +describe("Downloads (disabled)", true, ["--disable-file-downloads"], {}, async () => { + const testName = "downloads-disabled" + test.beforeAll(async () => { + await clean(testName) + }) + + test("should not see the 'Download...' option", async ({ codeServerPage }) => { + // Setup + const workspaceDir = await codeServerPage.workspaceDir + const tmpFilePath = path.join(workspaceDir, "unique-file.txt") + await fs.writeFile(tmpFilePath, "hello world") + + // Action + const fileInExplorer = await codeServerPage.page.waitForSelector("text=unique-file.txt") + await fileInExplorer.click({ + button: "right", + }) + + expect(await codeServerPage.page.isVisible("text=Download...")).toBe(false) + }) +}) diff --git a/test/e2e/models/CodeServer.ts b/test/e2e/models/CodeServer.ts index e2bbdc1d6..53e2208d2 100644 --- a/test/e2e/models/CodeServer.ts +++ b/test/e2e/models/CodeServer.ts @@ -134,7 +134,7 @@ export class CodeServer { }) proc.on("close", (code) => { - const error = new Error("code-server closed unexpectedly") + const error = new Error("code-server closed unexpectedly. Try running with LOG_LEVEL=debug to see more info.") if (!this.closed) { this.logger.error(error.message, field("code", code)) } diff --git a/test/unit/node/cli.test.ts b/test/unit/node/cli.test.ts index 0b04adadb..dab47b4cf 100644 --- a/test/unit/node/cli.test.ts +++ b/test/unit/node/cli.test.ts @@ -42,6 +42,7 @@ describe("parser", () => { beforeEach(() => { delete process.env.LOG_LEVEL delete process.env.PASSWORD + delete process.env.CS_DISABLE_FILE_DOWNLOADS console.log = jest.fn() }) @@ -92,6 +93,8 @@ describe("parser", () => { "--port=8081", + "--disable-file-downloads", + ["--host", "0.0.0.0"], "4", "--", @@ -108,6 +111,7 @@ describe("parser", () => { cert: { value: path.resolve("path/to/cert"), }, + "disable-file-downloads": true, enable: ["feature1", "feature2"], help: true, host: "0.0.0.0", @@ -346,6 +350,18 @@ describe("parser", () => { expect(process.env.GITHUB_TOKEN).toBe(undefined) }) + it("should use env var CS_DISABLE_FILE_DOWNLOADS", async () => { + process.env.CS_DISABLE_FILE_DOWNLOADS = "1" + const args = parse([]) + expect(args).toEqual({}) + + const defaultArgs = await setDefaults(args) + expect(defaultArgs).toEqual({ + ...defaults, + "disable-file-downloads": true, + }) + }) + it("should error if password passed in", () => { expect(() => parse(["--password", "supersecret123"])).toThrowError( "--password can only be set in the config file or passed in via $PASSWORD", diff --git a/test/unit/node/plugin.test.ts b/test/unit/node/plugin.test.ts index 73923415b..88210fd85 100644 --- a/test/unit/node/plugin.test.ts +++ b/test/unit/node/plugin.test.ts @@ -38,6 +38,7 @@ describe("plugin", () => { "proxy-domain": [], config: "~/.config/code-server/config.yaml", verbose: false, + "disable-file-downloads": false, usingEnvPassword: false, usingEnvHashedPassword: false, "extensions-dir": "", From e7e6c163edc8d7c87be046e571874ad2dd64b8c8 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 13 Apr 2022 10:15:21 -0700 Subject: [PATCH 19/55] revert(docs): partially revert 326a1d1862872955cec062030df2bd103799a1eb (#5095) We tried to switch from `yarn` to `npm` because `yarn` ignores lockfiles but learned that we missed a few key things. For now, we are reverting docs and a few other changes that suggested using `npm` instead of `yarn` until we fully remove `yarn` from the codebase. t Please enter the commit message for your changes. Lines starting --- .github/ISSUE_TEMPLATE/bug-report.yml | 2 +- ci/steps/publish-npm.sh | 12 ++++----- docs/android.md | 2 +- docs/install.md | 38 ++++++++++++++++----------- docs/manifest.json | 2 +- docs/npm.md | 20 +++++++------- 6 files changed, 41 insertions(+), 35 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index c1ab7c4c9..b2ad1b7b0 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -57,7 +57,7 @@ body: id: logs attributes: label: Logs - description: Run code-server with the --verbose flag and then paste any relevant logs from the server, from the browser console and/or the browser network tab. For issues with installation, include installation logs (i.e. output of `npm install -g code-server`). + description: Run code-server with the --verbose flag and then paste any relevant logs from the server, from the browser console and/or the browser network tab. For issues with installation, include installation logs (i.e. output of `yarn global add code-server`). - type: textarea attributes: label: Screenshot/Video diff --git a/ci/steps/publish-npm.sh b/ci/steps/publish-npm.sh index 5b01f627d..847c46ab5 100755 --- a/ci/steps/publish-npm.sh +++ b/ci/steps/publish-npm.sh @@ -59,11 +59,11 @@ main() { # This string is used to determine how we should tag the npm release. # Environment can be one of three choices: # "development" - this means we tag with the PR number, allowing - # a developer to install this version with `npm install code-server@` + # a developer to install this version with `yarn add code-server@` # "staging" - this means we tag with `beta`, allowing - # a developer to install this version with `npm install code-server@beta` + # a developer to install this version with `yarn add code-server@beta` # "production" - this means we tag with `latest` (default), allowing - # a developer to install this version with `npm install code-server@latest` + # a developer to install this version with `yarn add code-server@latest` if ! is_env_var_set "NPM_ENVIRONMENT"; then echo "NPM_ENVIRONMENT is not set. Determining in script based on GITHUB environment variables." @@ -96,7 +96,7 @@ main() { if [[ "$NPM_ENVIRONMENT" == "production" ]]; then NPM_VERSION="$VERSION" # This means the npm version will be published as "stable" - # and installed when a user runs `npm install code-server` + # and installed when a user runs `yarn install code-server` NPM_TAG="latest" else COMMIT_SHA="$GITHUB_SHA" @@ -107,7 +107,7 @@ main() { if [[ "$NPM_ENVIRONMENT" == "staging" ]]; then NPM_VERSION="$VERSION-beta-$COMMIT_SHA" # This means the npm version will be tagged with "beta" - # and installed when a user runs `npm install code-server@beta` + # and installed when a user runs `yarn install code-server@beta` NPM_TAG="beta" fi @@ -117,7 +117,7 @@ main() { NPM_VERSION="$VERSION-$PR_NUMBER-$COMMIT_SHA" PACKAGE_NAME="@coder/code-server-pr" # This means the npm version will be tagged with "" - # and installed when a user runs `npm install code-server@` + # and installed when a user runs `yarn install code-server@` NPM_TAG="$PR_NUMBER" fi diff --git a/docs/android.md b/docs/android.md index 5971d54e6..41fd92dbe 100644 --- a/docs/android.md +++ b/docs/android.md @@ -3,7 +3,7 @@ 1. Install UserLAnd from [Google Play](https://play.google.com/store/apps/details?id=tech.ula&hl=en_US&gl=US) 2. Install an Ubuntu VM 3. Start app -4. Install Node.js, `curl` and `npm` using `sudo apt install nodejs npm curl -y` +4. Install Node.js, `curl` and `yarn` using `sudo apt install nodejs npm yarn curl -y` 5. Install `nvm`: ```shell diff --git a/docs/install.md b/docs/install.md index 80ff00c18..64c35ddbe 100644 --- a/docs/install.md +++ b/docs/install.md @@ -4,7 +4,7 @@ - [install.sh](#installsh) - [Detection reference](#detection-reference) -- [npm](#npm) +- [yarn, npm](#yarn-npm) - [Standalone releases](#standalone-releases) - [Debian, Ubuntu](#debian-ubuntu) - [Fedora, CentOS, RHEL, SUSE](#fedora-centos-rhel-suse) @@ -19,7 +19,7 @@ - [Uninstall](#uninstall) - [install.sh](#installsh-1) - [Homebrew](#homebrew) - - [npm](#npm-1) + - [yarn, npm](#yarn-npm-1) - [Debian, Ubuntu](#debian-ubuntu-1) @@ -87,16 +87,17 @@ _exact_ same commands presented in the rest of this document. - Ensure that you add `~/.local/bin` to your `$PATH` to run code-server. -- For FreeBSD, code-server will install the [npm package](#npm) with `npm`. +- For FreeBSD, code-server will install the [npm package](#yarn-npm) with `yarn` + or `npm`. - If you're installing code-server onto architecture with no releases, - code-server will install the [npm package](#npm) with `npm` + code-server will install the [npm package](#yarn-npm) with `yarn` or `npm` - We currently offer releases for amd64 and arm64. - - The [npm package](#npm) builds the native modules on post-install. + - The [npm package](#yarn-npm) builds the native modules on post-install. -## npm +## yarn, npm -We recommend installing with `npm` when: +We recommend installing with `yarn` or `npm` when: 1. You aren't using a machine with `amd64` or `arm64`. 1. You are installing code-server on Windows @@ -106,9 +107,9 @@ We recommend installing with `npm` when: [#1430](https://github.com/coder/code-server/issues/1430#issuecomment-629883198) for more information. -Installing code-server with `npm` builds native modules on install. +Installing code-server with `yarn` or `npm` builds native modules on install. -This process requires C dependencies; see our guide on [installing with `npm`][./npm.md](./npm.md) for more information. +This process requires C dependencies; see our guide on [installing with yarn and npm][./npm.md](./npm.md) for more information. ## Standalone releases @@ -116,7 +117,7 @@ We publish self-contained `.tar.gz` archives for every release on [GitHub](https://github.com/coder/code-server/releases). The archives bundle the node binary and node modules. -We create the standalone releases using the [npm package](#npm), and we +We create the standalone releases using the [npm package](#yarn-npm), and we then create the remaining releases using the standalone version. The only requirement to use the standalone release is `glibc` >= 2.17 and @@ -150,7 +151,7 @@ code-server ## Debian, Ubuntu > The standalone arm64 .deb does not support Ubuntu 16.04 or earlier. Please -> upgrade or [build with `npm`](#npm). +> upgrade or [build with yarn](#yarn-npm). ```bash curl -fOL https://github.com/coder/code-server/releases/download/v$VERSION/code-server_$VERSION_amd64.deb @@ -162,7 +163,7 @@ sudo systemctl enable --now code-server@$USER ## Fedora, CentOS, RHEL, SUSE > The standalone arm64 .rpm does not support CentOS 7. Please upgrade or [build -> with `npm`](#npm). +> with yarn](#yarn-npm). ```bash curl -fOL https://github.com/coder/code-server/releases/download/v$VERSION/code-server-$VERSION-amd64.rpm @@ -227,13 +228,14 @@ You can install code-server using the [Helm package manager](https://coder.com/d ## Windows -We currently [do not publish Windows releases](https://github.com/coder/code-server/issues/1397). We recommend installing code-server onto Windows with [`npm`](#npm). +We currently [do not publish Windows releases](https://github.com/coder/code-server/issues/1397). We recommend installing code-server onto Windows with [`yarn` or `npm`](#yarn-npm). > Note: You will also need to [build coder/cloud-agent manually](https://github.com/coder/cloud-agent/issues/17) if you would like to use `code-server --link` on Windows. ## Raspberry Pi -We recommend installing code-server onto Raspberry Pi with [`npm`](#npm). +We recommend installing code-server onto Raspberry Pi with [`yarn` or +`npm`](#yarn-npm). ## Termux @@ -275,10 +277,16 @@ brew remove code-server brew uninstall code-server ``` -### npm +### yarn, npm To remove the code-server global module, run: +```shell +yarn global remove code-server +``` + +or + ```shell npm uninstall -g code-server ``` diff --git a/docs/manifest.json b/docs/manifest.json index 801a7ef47..a637b72b6 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -21,7 +21,7 @@ "children": [ { "title": "npm", - "description": "How to install code-server using npm", + "description": "How to install code-server using npm or yarn", "path": "./npm.md" }, { diff --git a/docs/npm.md b/docs/npm.md index 726cadd48..27ceaf22f 100644 --- a/docs/npm.md +++ b/docs/npm.md @@ -20,11 +20,6 @@ If you're installing code-server via `npm`, you'll need to install additional dependencies required to build the native modules used by VS Code. This article includes installing instructions based on your operating system. -> **WARNING**: Do not use `yarn` to install code-server. Unlike `npm`, it does not respect -> lockfiles for distributed applications. It will instead use the latest version -> available at installation time - which might not be the one used for a given -> code-server release, and [might lead to unexpected behavior](https://github.com/coder/code-server/issues/4927). - ## Node.js version We use the same major version of Node.js shipped with VSCode's Electron, @@ -77,7 +72,7 @@ Proceed to [installing](#installing) ## FreeBSD ```sh -pkg install -y git python npm-node14 pkgconf +pkg install -y git python npm-node14 yarn-node14 pkgconf pkg install -y libinotify ``` @@ -90,7 +85,8 @@ Installing code-server requires all of the [prerequisites for VS Code developmen Next, install code-server with: ```bash -npm install -g code-server +yarn global add code-server +# Or: npm install -g code-server code-server # Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml ``` @@ -100,7 +96,8 @@ A `postinstall.sh` script will attempt to run. Select your terminal (e.g., Git b If the `code-server` command is not found, you'll need to [add a directory to your PATH](https://www.architectryan.com/2018/03/17/add-to-the-path-on-windows-10/). To find the directory, use the following command: ```shell -npm config get prefix +yarn global bin +# Or: npm config get prefix ``` For help and additional troubleshooting, see [#1397](https://github.com/coder/code-server/issues/1397). @@ -110,7 +107,8 @@ For help and additional troubleshooting, see [#1397](https://github.com/coder/co After adding the dependencies for your OS, install the code-server package globally: ```bash -npm install -g code-server +yarn global add code-server +# Or: npm install -g code-server code-server # Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml ``` @@ -124,7 +122,7 @@ page](https://github.com/coder/code-server/discussions). Occasionally, you may run into issues with Node.js. -If you install code-server using `npm`, and you upgrade your Node.js +If you install code-server using `yarn` or `npm`, and you upgrade your Node.js version, you may need to reinstall code-server to recompile native modules. Sometimes, you can get around this by navigating into code-server's `lib/vscode` directory and running `npm rebuild` to recompile the modules. @@ -138,7 +136,7 @@ A step-by-step example of how you might do this is: ### Debugging install issues with npm -To debug installation issues: +`yarn` suppresses logs when running `yarn global add`, so to debug installation issues, install with `npm` instead: ```shell # Uninstall From b62a68ac37d6ff3a32e55adedb3108bdb1b27fd8 Mon Sep 17 00:00:00 2001 From: Asher Date: Thu, 14 Apr 2022 13:02:52 -0500 Subject: [PATCH 20/55] fix: webviews failing to load the iframe HTML (#5103) Code added in 1.65.0 broke webviews when you are hosting them from the same domain. --- patches/webview.diff | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/patches/webview.diff b/patches/webview.diff index a46901141..a4506b03b 100644 --- a/patches/webview.diff +++ b/patches/webview.diff @@ -6,6 +6,17 @@ self-hosted. When doing this CSP will block resources (for example when viewing images) so add 'self' to the CSP to fix that. +Additionally the service worker defaults to handling *all* requests made to the +current host but when self-hosting the webview this will end up including the +webview HTML itself which means these requests will fail since the communication +channel between the webview and the main thread has not been set up yet as the +webview itself is not ready yet (it has no HTML and therefore no script either). +Since this code exists only for the authentication case we can just skip it when +it is served from the current host as authentication is not a problem if the +request is not cross-origin. + +To test, open a few types of webviews (images, markdown, extension details, etc). + Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts @@ -44,3 +55,22 @@ Index: code-server/lib/vscode/src/vs/workbench/common/webview.ts /** * Construct a uri that can load resources inside a webview +Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/service-worker.js +=================================================================== +--- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/service-worker.js ++++ code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/service-worker.js +@@ -188,9 +188,11 @@ sw.addEventListener('fetch', (event) => + } + } + +- // If we're making a request against the remote authority, we want to go +- // back through VS Code itself so that we are authenticated properly +- if (requestUrl.host === remoteAuthority) { ++ // If we're making a request against the remote authority, we want to go back ++ // through VS Code itself so that we are authenticated properly. If the ++ // service worker is hosted on the same origin we will have cookies and ++ // authentication will not be an issue. ++ if (requestUrl.origin !== sw.origin && requestUrl.host === remoteAuthority) { + switch (event.request.method) { + case 'GET': + case 'HEAD': From fd42b951640f911108ae809448522ab3bc3e44ee Mon Sep 17 00:00:00 2001 From: Asher Date: Thu, 14 Apr 2022 16:00:10 -0500 Subject: [PATCH 21/55] fix: use current location for web extension resource endpoint (#5104) This makes it work behind a rewriting proxy as well as make it use the correct remote authority. --- patches/base-path.diff | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/patches/base-path.diff b/patches/base-path.diff index 9f3be6ed5..c7d032b18 100644 --- a/patches/base-path.diff +++ b/patches/base-path.diff @@ -303,3 +303,24 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts // Create workbench create(document.body, { +Index: code-server/lib/vscode/src/vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader.ts ++++ code-server/lib/vscode/src/vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader.ts +@@ -16,7 +16,6 @@ import { getServiceMachineId } from 'vs/ + import { IStorageService } from 'vs/platform/storage/common/storage'; + import { TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; + import { getTelemetryLevel, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils'; +-import { RemoteAuthorities } from 'vs/base/common/network'; + + export const WEB_EXTENSION_RESOURCE_END_POINT = 'web-extension-resource'; + +@@ -72,7 +71,7 @@ export abstract class AbstractExtensionR + public getExtensionGalleryResourceURL(galleryExtension: { publisher: string; name: string; version: string }, path?: string): URI | undefined { + if (this._extensionGalleryResourceUrlTemplate) { + const uri = URI.parse(format2(this._extensionGalleryResourceUrlTemplate, { publisher: galleryExtension.publisher, name: galleryExtension.name, version: galleryExtension.version, path: 'extension' })); +- return this._isWebExtensionResourceEndPoint(uri) ? uri.with({ scheme: RemoteAuthorities.getPreferredWebSchema() }) : uri; ++ return this._isWebExtensionResourceEndPoint(uri) ? URI.joinPath(URI.parse(window.location.href), uri.path) : uri; + } + return undefined; + } From 09fc64a4f0629f134108d061a36f0b3976c962bd Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Thu, 14 Apr 2022 15:37:25 -0700 Subject: [PATCH 22/55] v4.3.0 (#5099) * chore(release): bump version to 4.3.0 * fix(release-prep.sh): ignore lib/vscode * docs(CHANGELOG): add 4.3.0 * chore: bump chart version * fixup!: remove change in postinstall * fixup!: bullets in CHANGELOG * fixup!: formatting * fixup! typo in changelog * fixup!: update date in changelog Co-authored-by: Asher --- CHANGELOG.md | 30 ++++++++++++++++++++++++++++-- ci/build/release-prep.sh | 2 +- ci/helm-chart/Chart.yaml | 4 ++-- ci/helm-chart/values.yaml | 2 +- docs/MAINTAINING.md | 2 +- docs/collaboration.md | 2 +- docs/helm.md | 4 ++-- docs/manifest.json | 2 +- package.json | 2 +- 9 files changed, 38 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b6b5f4ca..b994c6d7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,10 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [9.99.999] - 9090-09-09 -VS Code v99.99.999 +Code v99.99.999 -### Changed ### Added +### Changed ### Deprecated ### Removed ### Fixed @@ -20,6 +20,32 @@ VS Code v99.99.999 --> +## [4.3.0](https://github.com/coder/code-server/releases/tag/v4.3.0) - 2022-04-14 + +Code v1.65.2 + +### Changed + +- Excluded .deb files from release Docker image which drops the compressed and + uncompressed size by 58% and 34%. +- Upgraded to Code 1.65.2. + +### Added + +- Added a new CLI flag called `--disable-file-downloads` which allows you to + disable the "Download..." option that shows in the UI when right-clicking on a + file. This can also set by running `CS_DISABLE_FILE_DOWNLOADS=1`. +- Aligned the dependencies for binary and npm release artifacts. + +### Fixed + +- Fixed the code-server version from not displaying in the Help > About dialog. +- Fixed issues with the TypeScript and JavaScript Language Features Extension + failing to activate. +- Fixed missing files in ipynb extension. +- Fixed the homebrew release workflow. +- Fixed the Docker release workflow from not always publishing version tags. + ## [4.2.0](https://github.com/coder/code-server/releases/tag/v4.2.0) - 2022-03-22 Code v1.64.2 diff --git a/ci/build/release-prep.sh b/ci/build/release-prep.sh index a7f9967a5..173dd2db1 100755 --- a/ci/build/release-prep.sh +++ b/ci/build/release-prep.sh @@ -81,7 +81,7 @@ main() { read -r -p "What version of code-server do you want to update to?"$'\n' CODE_SERVER_VERSION_TO_UPDATE echo -e "Great! We'll prep a PR for updating to $CODE_SERVER_VERSION_TO_UPDATE\n" - $CMD rg -g '!yarn.lock' -g '!*.svg' -g '!CHANGELOG.md' --files-with-matches --fixed-strings "${CODE_SERVER_CURRENT_VERSION}" | $CMD xargs sd "$CODE_SERVER_CURRENT_VERSION" "$CODE_SERVER_VERSION_TO_UPDATE" + $CMD rg -g '!yarn.lock' -g '!*.svg' -g '!CHANGELOG.md' -g '!lib/vscode/**' --files-with-matches --fixed-strings "${CODE_SERVER_CURRENT_VERSION}" | $CMD xargs sd "$CODE_SERVER_CURRENT_VERSION" "$CODE_SERVER_VERSION_TO_UPDATE" $CMD git commit --no-verify -am "chore(release): bump version to $CODE_SERVER_VERSION_TO_UPDATE" diff --git a/ci/helm-chart/Chart.yaml b/ci/helm-chart/Chart.yaml index 5b5252263..3eeb0584b 100644 --- a/ci/helm-chart/Chart.yaml +++ b/ci/helm-chart/Chart.yaml @@ -15,9 +15,9 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 2.3.0 +version: 2.4.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. -appVersion: 4.2.0 +appVersion: 4.3.0 diff --git a/ci/helm-chart/values.yaml b/ci/helm-chart/values.yaml index 4113b2a16..6ea263c7f 100644 --- a/ci/helm-chart/values.yaml +++ b/ci/helm-chart/values.yaml @@ -6,7 +6,7 @@ replicaCount: 1 image: repository: codercom/code-server - tag: '4.2.0' + tag: '4.3.0' pullPolicy: Always # Specifies one or more secrets to be used when pulling images from a diff --git a/docs/MAINTAINING.md b/docs/MAINTAINING.md index 6aed2919e..0c55d4cff 100644 --- a/docs/MAINTAINING.md +++ b/docs/MAINTAINING.md @@ -164,7 +164,7 @@ If you're the current release manager, follow these steps: ### Publishing a release -1. Create a new branch called `v0.0.0` (replace 0s with actual version aka v4.2.0) +1. Create a new branch called `v0.0.0` (replace 0s with actual version aka v4.3.0) 1. Run `yarn release:prep` and type in the new version (e.g., `3.8.1`) 1. GitHub Actions will generate the `npm-package`, `release-packages` and `release-images` artifacts. You do not have to wait for this step to complete diff --git a/docs/collaboration.md b/docs/collaboration.md index 52b1c87d2..dda091545 100644 --- a/docs/collaboration.md +++ b/docs/collaboration.md @@ -60,6 +60,6 @@ As `code-server` is based on VS Code, you can follow the steps described on Duck code-server --enable-proposed-api genuitecllc.codetogether ``` - Another option would be to add a value in code-server's [config file](https://coder.com/docs/code-server/v4.2.0/FAQ#how-does-the-config-file-work). + Another option would be to add a value in code-server's [config file](https://coder.com/docs/code-server/v4.3.0/FAQ#how-does-the-config-file-work). 3. Refresh code-server and navigate to the CodeTogether icon in the sidebar to host or join a coding session. diff --git a/docs/helm.md b/docs/helm.md index 2282ae964..7f3dfb7ab 100644 --- a/docs/helm.md +++ b/docs/helm.md @@ -1,6 +1,6 @@ # code-server Helm Chart -[![Version: 1.0.0](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square)](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square) [![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)](https://img.shields.io/badge/Type-application-informational?style=flat-square) [![AppVersion: 4.2.0](https://img.shields.io/badge/AppVersion-4.2.0-informational?style=flat-square)](https://img.shields.io/badge/AppVersion-4.2.0-informational?style=flat-square) +[![Version: 1.0.0](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square)](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square) [![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)](https://img.shields.io/badge/Type-application-informational?style=flat-square) [![AppVersion: 4.3.0](https://img.shields.io/badge/AppVersion-4.3.0-informational?style=flat-square)](https://img.shields.io/badge/AppVersion-4.3.0-informational?style=flat-square) [code-server](https://github.com/coder/code-server) code-server is VS Code running on a remote server, accessible through the browser. @@ -73,7 +73,7 @@ and their default values. | hostnameOverride | string | `""` | | image.pullPolicy | string | `"Always"` | | image.repository | string | `"codercom/code-server"` | -| image.tag | string | `"4.2.0"` | +| image.tag | string | `"4.3.0"` | | imagePullSecrets | list | `[]` | | ingress.enabled | bool | `false` | | nameOverride | string | `""` | diff --git a/docs/manifest.json b/docs/manifest.json index a637b72b6..890ede663 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -1,5 +1,5 @@ { - "versions": ["v4.2.0"], + "versions": ["v4.3.0"], "routes": [ { "title": "Home", diff --git a/package.json b/package.json index e85d705fd..f9fece378 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-server", "license": "MIT", - "version": "4.2.0", + "version": "4.3.0", "description": "Run VS Code on a remote server.", "homepage": "https://github.com/coder/code-server", "bugs": { From dea6a40ea8e5601949d8884760a83a04b5294e26 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Thu, 14 Apr 2022 17:02:03 -0700 Subject: [PATCH 23/55] chore: attempt to fix docker (#5106) * chore: attempt to fix docker * Update .github/workflows/docker.yaml Co-authored-by: Asher * chore: add publish:docker to scripts Co-authored-by: Asher --- .github/workflows/docker.yaml | 18 ++++++++---------- package.json | 1 + 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 23e08c245..4000c43c9 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -39,17 +39,15 @@ jobs: id: version run: echo "::set-output name=version::$(jq -r .version package.json)" - - name: Download artifact - uses: dawidd6/action-download-artifact@v2 - id: download + - name: Download release artifacts + uses: robinraju/release-downloader@v1.3 with: - branch: v${{ steps.version.outputs.version }} - workflow: ci.yaml - workflow_conclusion: completed - name: "release-packages" - path: release-packages + repository: "coder/code-server" + tag: v${{ steps.version.outputs.version }} + fileName: "*.deb" + out-file-path: "release-packages" - - name: Run ./ci/steps/docker-buildx-push.sh - run: ./ci/steps/docker-buildx-push.sh + - name: Publish to Docker + run: yarn publish:docker env: GITHUB_TOKEN: ${{ github.token }} diff --git a/package.json b/package.json index f9fece378..0d9e7ad93 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "package": "./ci/build/build-packages.sh", "postinstall": "./ci/dev/postinstall.sh", "publish:npm": "./ci/steps/publish-npm.sh", + "publish:docker": "./ci/steps/docker-buildx-push.sh", "_audit": "./ci/dev/audit.sh", "fmt": "./ci/dev/fmt.sh", "lint": "./ci/dev/lint.sh", From 7780a13cce203922cb95899f29bc925869251f54 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 19 Apr 2022 11:37:47 -0700 Subject: [PATCH 24/55] chore(deps): update aquasecurity/trivy-action digest to 2b30463 (#5098) Co-authored-by: Renovate Bot --- .github/workflows/ci.yaml | 2 +- .github/workflows/trivy-docker.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index a977cd507..f8b0859c8 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -506,7 +506,7 @@ jobs: fetch-depth: 0 - name: Run Trivy vulnerability scanner in repo mode - uses: aquasecurity/trivy-action@40c4ca9e7421287d0c5576712fdff370978f9c3c + uses: aquasecurity/trivy-action@2b30463ddb3d11724a04e760e020c7d9af24d8b3 with: scan-type: "fs" scan-ref: "." diff --git a/.github/workflows/trivy-docker.yaml b/.github/workflows/trivy-docker.yaml index 840b85e1f..d12e7ad62 100644 --- a/.github/workflows/trivy-docker.yaml +++ b/.github/workflows/trivy-docker.yaml @@ -51,7 +51,7 @@ jobs: uses: actions/checkout@v3 - name: Run Trivy vulnerability scanner in image mode - uses: aquasecurity/trivy-action@40c4ca9e7421287d0c5576712fdff370978f9c3c + uses: aquasecurity/trivy-action@2b30463ddb3d11724a04e760e020c7d9af24d8b3 with: image-ref: "docker.io/codercom/code-server:latest" ignore-unfixed: true From c35bf1311e85d031e40ca42fe0342a47c2c254a8 Mon Sep 17 00:00:00 2001 From: Asher Date: Tue, 19 Apr 2022 15:46:23 -0500 Subject: [PATCH 25/55] chore: provide details when `update.checked` tests fail (#5115) Using the toBe* functions will let us know what the actual values are rather than just telling us true does not equal false. --- test/unit/node/update.test.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/test/unit/node/update.test.ts b/test/unit/node/update.test.ts index d2f62531a..9aa6f75d7 100644 --- a/test/unit/node/update.test.ts +++ b/test/unit/node/update.test.ts @@ -145,7 +145,7 @@ describe("update", () => { await expect(settings().read()).resolves.toEqual({ update }) expect(isNaN(update.checked)).toStrictEqual(false) - expect(update.checked < now).toBe(true) + expect(update.checked).toBeLessThan(now) expect(update.version).toStrictEqual("2.1.0") expect(spy).toEqual([]) }) @@ -159,7 +159,8 @@ describe("update", () => { await expect(settings().read()).resolves.toEqual({ update }) expect(isNaN(update.checked)).toStrictEqual(false) - expect(update.checked < Date.now() && update.checked >= now).toStrictEqual(true) + expect(update.checked).toBeGreaterThanOrEqual(now) + expect(update.checked).toBeLessThan(Date.now()) expect(update.version).toStrictEqual("4.1.1") expect(spy).toStrictEqual(["/latest"]) }) @@ -204,14 +205,16 @@ describe("update", () => { let now = Date.now() let update = await provider.getUpdate(true) expect(isNaN(update.checked)).toStrictEqual(false) - expect(update.checked < Date.now() && update.checked >= now).toEqual(true) + expect(update.checked).toBeGreaterThanOrEqual(now) + expect(update.checked).toBeLessThan(Date.now()) expect(update.version).toStrictEqual("unknown") provider = new UpdateProvider("http://probably.invalid.dev.localhost/latest", settings()) now = Date.now() update = await provider.getUpdate(true) expect(isNaN(update.checked)).toStrictEqual(false) - expect(update.checked < Date.now() && update.checked >= now).toEqual(true) + expect(update.checked).toBeGreaterThanOrEqual(now) + expect(update.checked).toBeLessThan(Date.now()) expect(update.version).toStrictEqual("unknown") }) From ed7bd2e65b71ef2f5c6656e694f53db3c4253c6b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 25 Apr 2022 15:39:32 -0700 Subject: [PATCH 26/55] chore(deps): update github/codeql-action action to v2 (#5129) Co-authored-by: Renovate Bot --- .github/workflows/ci.yaml | 2 +- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/trivy-docker.yaml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f8b0859c8..ea9ea2664 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -517,6 +517,6 @@ jobs: severity: "HIGH,CRITICAL" - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v1 + uses: github/codeql-action/upload-sarif@v2 with: sarif_file: "trivy-repo-results.sarif" diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index efe068fbd..56339a1cc 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -35,13 +35,13 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: config-file: ./.github/codeql-config.yml languages: javascript - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v2 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/trivy-docker.yaml b/.github/workflows/trivy-docker.yaml index d12e7ad62..e54f02c21 100644 --- a/.github/workflows/trivy-docker.yaml +++ b/.github/workflows/trivy-docker.yaml @@ -60,6 +60,6 @@ jobs: severity: "HIGH,CRITICAL" - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v1 + uses: github/codeql-action/upload-sarif@v2 with: sarif_file: "trivy-image-results.sarif" From 18ff99693bfb4d77ccc94c1a21ba40aa50ac2f60 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Tue, 26 Apr 2022 11:35:40 -0500 Subject: [PATCH 27/55] feat: add tests for node/heart.ts (#5122) * refactor(heart): extract logic into heartbeatTimer fn To make it easier to test, I extract heartbeatTimer into it's own function. * feat(testing): add tests for heart.ts * fixup * fixup!: remove unneeded heart call * Update src/node/heart.ts Co-authored-by: Asher * fixup!: use mockResolvedValue everywhere * fixup!: add stat test for timestamp check Co-authored-by: Asher --- src/node/heart.ts | 29 ++++++---- test/e2e/downloads.test.ts | 2 +- test/unit/node/heart.test.ts | 100 +++++++++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+), 12 deletions(-) create mode 100644 test/unit/node/heart.test.ts diff --git a/src/node/heart.ts b/src/node/heart.ts index 1eada79b3..a03802035 100644 --- a/src/node/heart.ts +++ b/src/node/heart.ts @@ -33,17 +33,7 @@ export class Heart { if (typeof this.heartbeatTimer !== "undefined") { clearTimeout(this.heartbeatTimer) } - this.heartbeatTimer = setTimeout(() => { - this.isActive() - .then((active) => { - if (active) { - this.beat() - } - }) - .catch((error) => { - logger.warn(error.message) - }) - }, this.heartbeatInterval) + this.heartbeatTimer = setTimeout(() => heartbeatTimer(this.isActive, this.beat), this.heartbeatInterval) } /** @@ -55,3 +45,20 @@ export class Heart { } } } + +/** + * Helper function for the heartbeatTimer. + * + * If heartbeat is active, call beat. Otherwise do nothing. + * + * Extracted to make it easier to test. + */ +export async function heartbeatTimer(isActive: Heart["isActive"], beat: Heart["beat"]) { + try { + if (await isActive()) { + beat() + } + } catch (error: unknown) { + logger.warn((error as Error).message) + } +} diff --git a/test/e2e/downloads.test.ts b/test/e2e/downloads.test.ts index 4503e076c..2079c7eba 100644 --- a/test/e2e/downloads.test.ts +++ b/test/e2e/downloads.test.ts @@ -1,5 +1,5 @@ -import * as path from "path" import { promises as fs } from "fs" +import * as path from "path" import { clean } from "../utils/helpers" import { describe, test, expect } from "./baseFixture" diff --git a/test/unit/node/heart.test.ts b/test/unit/node/heart.test.ts new file mode 100644 index 000000000..7996fdab5 --- /dev/null +++ b/test/unit/node/heart.test.ts @@ -0,0 +1,100 @@ +import { logger } from "@coder/logger" +import { readFile, writeFile, stat } from "fs/promises" +import { Heart, heartbeatTimer } from "../../../src/node/heart" +import { clean, mockLogger, tmpdir } from "../../utils/helpers" + +const mockIsActive = (resolveTo: boolean) => jest.fn().mockResolvedValue(resolveTo) + +describe("Heart", () => { + const testName = "heartTests" + let testDir = "" + let heart: Heart + + beforeAll(async () => { + mockLogger() + await clean(testName) + testDir = await tmpdir(testName) + }) + beforeEach(() => { + heart = new Heart(`${testDir}/shutdown.txt`, mockIsActive(true)) + }) + afterAll(() => { + jest.restoreAllMocks() + }) + afterEach(() => { + jest.resetAllMocks() + if (heart) { + heart.dispose() + } + }) + it("should write to a file when given a valid file path", async () => { + // Set up heartbeat file with contents + const text = "test" + const pathToFile = `${testDir}/file.txt` + await writeFile(pathToFile, text) + const fileContents = await readFile(pathToFile, { encoding: "utf8" }) + const fileStatusBeforeEdit = await stat(pathToFile) + expect(fileContents).toBe(text) + + heart = new Heart(pathToFile, mockIsActive(true)) + heart.beat() + // Check that the heart wrote to the heartbeatFilePath and overwrote our text + const fileContentsAfterBeat = await readFile(pathToFile, { encoding: "utf8" }) + expect(fileContentsAfterBeat).not.toBe(text) + // Make sure the modified timestamp was updated. + const fileStatusAfterEdit = await stat(pathToFile) + expect(fileStatusAfterEdit.mtimeMs).toBeGreaterThan(fileStatusBeforeEdit.mtimeMs) + }) + it("should log a warning when given an invalid file path", async () => { + heart = new Heart(`fakeDir/fake.txt`, mockIsActive(false)) + heart.beat() + // HACK@jsjoeio - beat has some async logic but is not an async method + // Therefore, we have to create an artificial wait in order to make sure + // all async code has completed before asserting + await new Promise((r) => setTimeout(r, 100)) + // expect(logger.trace).toHaveBeenCalled() + expect(logger.warn).toHaveBeenCalled() + }) + it("should be active after calling beat", () => { + heart.beat() + + const isAlive = heart.alive() + expect(isAlive).toBe(true) + }) + it("should not be active after dispose is called", () => { + heart.dispose() + + const isAlive = heart.alive() + expect(isAlive).toBe(false) + }) +}) + +describe("heartbeatTimer", () => { + beforeAll(() => { + mockLogger() + }) + afterAll(() => { + jest.restoreAllMocks() + }) + afterEach(() => { + jest.resetAllMocks() + }) + it("should call beat when isActive resolves to true", async () => { + const isActive = true + const mockIsActive = jest.fn().mockResolvedValue(isActive) + const mockBeatFn = jest.fn() + await heartbeatTimer(mockIsActive, mockBeatFn) + expect(mockIsActive).toHaveBeenCalled() + expect(mockBeatFn).toHaveBeenCalled() + }) + it("should log a warning when isActive rejects", async () => { + const errorMsg = "oh no" + const error = new Error(errorMsg) + const mockIsActive = jest.fn().mockRejectedValue(error) + const mockBeatFn = jest.fn() + await heartbeatTimer(mockIsActive, mockBeatFn) + expect(mockIsActive).toHaveBeenCalled() + expect(mockBeatFn).not.toHaveBeenCalled() + expect(logger.warn).toHaveBeenCalledWith(errorMsg) + }) +}) From 683412cb016b935f4211c13ab6de95187a6d1490 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Tue, 26 Apr 2022 12:39:37 -0500 Subject: [PATCH 28/55] refactor: add timeout for race condition in heart test (#5131) * refactor: add timeout for race condition in heart test * fixup!: set mtime to 0 and check for update * fixup!: use utimes directly instead of file open * fixup!: remove import --- test/unit/node/heart.test.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/test/unit/node/heart.test.ts b/test/unit/node/heart.test.ts index 7996fdab5..5360c865e 100644 --- a/test/unit/node/heart.test.ts +++ b/test/unit/node/heart.test.ts @@ -1,5 +1,5 @@ import { logger } from "@coder/logger" -import { readFile, writeFile, stat } from "fs/promises" +import { readFile, writeFile, stat, utimes } from "fs/promises" import { Heart, heartbeatTimer } from "../../../src/node/heart" import { clean, mockLogger, tmpdir } from "../../utils/helpers" @@ -33,17 +33,26 @@ describe("Heart", () => { const pathToFile = `${testDir}/file.txt` await writeFile(pathToFile, text) const fileContents = await readFile(pathToFile, { encoding: "utf8" }) - const fileStatusBeforeEdit = await stat(pathToFile) + // Explicitly set the modified time to 0 so that we can check + // that the file was indeed modified after calling heart.beat(). + // This works around any potential race conditions. + // Docs: https://nodejs.org/api/fs.html#fspromisesutimespath-atime-mtime + await utimes(pathToFile, 0, 0) + expect(fileContents).toBe(text) heart = new Heart(pathToFile, mockIsActive(true)) heart.beat() + // HACK@jsjoeio - beat has some async logic but is not an async method + // Therefore, we have to create an artificial wait in order to make sure + // all async code has completed before asserting + await new Promise((r) => setTimeout(r, 100)) // Check that the heart wrote to the heartbeatFilePath and overwrote our text const fileContentsAfterBeat = await readFile(pathToFile, { encoding: "utf8" }) expect(fileContentsAfterBeat).not.toBe(text) // Make sure the modified timestamp was updated. const fileStatusAfterEdit = await stat(pathToFile) - expect(fileStatusAfterEdit.mtimeMs).toBeGreaterThan(fileStatusBeforeEdit.mtimeMs) + expect(fileStatusAfterEdit.mtimeMs).toBeGreaterThan(0) }) it("should log a warning when given an invalid file path", async () => { heart = new Heart(`fakeDir/fake.txt`, mockIsActive(false)) @@ -52,7 +61,6 @@ describe("Heart", () => { // Therefore, we have to create an artificial wait in order to make sure // all async code has completed before asserting await new Promise((r) => setTimeout(r, 100)) - // expect(logger.trace).toHaveBeenCalled() expect(logger.warn).toHaveBeenCalled() }) it("should be active after calling beat", () => { From a0b36147eaeeb5b8c4aa448247d269c70bae608d Mon Sep 17 00:00:00 2001 From: mooff Date: Tue, 26 Apr 2022 20:33:51 +0100 Subject: [PATCH 29/55] fix: listening on IPv6 address not possible (#5133) Wrap IPv6 addresses in square brackets when making URL in ensureAddress, fixing regression (#1582) --- src/node/app.ts | 3 ++- test/unit/node/app.test.ts | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/node/app.ts b/src/node/app.ts index c1b1006df..aece0432c 100644 --- a/src/node/app.ts +++ b/src/node/app.ts @@ -94,7 +94,8 @@ export const ensureAddress = (server: http.Server, protocol: string): URL | stri } if (typeof addr !== "string") { - return new URL(`${protocol}://${addr.address}:${addr.port}`) + const host = addr.family === "IPv6" ? `[${addr.address}]` : addr.address + return new URL(`${protocol}://${host}:${addr.port}`) } // If this is a string then it is a pipe or Unix socket. diff --git a/test/unit/node/app.test.ts b/test/unit/node/app.test.ts index 62b2887f6..56c0e70dd 100644 --- a/test/unit/node/app.test.ts +++ b/test/unit/node/app.test.ts @@ -152,10 +152,20 @@ describe("ensureAddress", () => { it("should throw and error if no address", () => { expect(() => ensureAddress(mockServer, "http")).toThrow("Server has no address") }) - it("should return the address if it exists", async () => { - mockServer.address = () => "http://localhost:8080/" + it("should return the address if it's a string", async () => { + mockServer.address = () => "/path/to/unix.sock" const address = ensureAddress(mockServer, "http") - expect(address.toString()).toBe(`http://localhost:8080/`) + expect(address.toString()).toBe(`/path/to/unix.sock`) + }) + it("should construct URL with an IPv4 address", async () => { + mockServer.address = () => ({ address: "1.2.3.4", port: 5678, family: "IPv4" }) + const address = ensureAddress(mockServer, "http") + expect(address.toString()).toBe(`http://1.2.3.4:5678/`) + }) + it("should construct URL with an IPv6 address", async () => { + mockServer.address = () => ({ address: "a:b:c:d::1234", port: 5678, family: "IPv6" }) + const address = ensureAddress(mockServer, "http") + expect(address.toString()).toBe(`http://[a:b:c:d::1234]:5678/`) }) }) From e3c8bd692ce00cee1108f6143f55af66430ce8e1 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Tue, 26 Apr 2022 15:09:53 -0500 Subject: [PATCH 30/55] feat(cli): support true for CS_DISABLE_FILE_DOWNLOADS (#5134) After some feedback, we realized it is more intuitive to disable file downloads by setting the environment variable `CS_DISABLE_FILE_DOWNLOADS` to `true` than `1`. This commit adds support for both. --- src/node/cli.ts | 2 +- test/unit/node/cli.test.ts | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/node/cli.ts b/src/node/cli.ts index 2522a6268..6c33060cd 100644 --- a/src/node/cli.ts +++ b/src/node/cli.ts @@ -542,7 +542,7 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config args.password = process.env.PASSWORD } - if (process.env.CS_DISABLE_FILE_DOWNLOADS === "1") { + if (process.env.CS_DISABLE_FILE_DOWNLOADS?.match(/^(1|true)$/)) { args["disable-file-downloads"] = true } diff --git a/test/unit/node/cli.test.ts b/test/unit/node/cli.test.ts index dab47b4cf..76ebb610f 100644 --- a/test/unit/node/cli.test.ts +++ b/test/unit/node/cli.test.ts @@ -362,6 +362,18 @@ describe("parser", () => { }) }) + it("should use env var CS_DISABLE_FILE_DOWNLOADS set to true", async () => { + process.env.CS_DISABLE_FILE_DOWNLOADS = "true" + const args = parse([]) + expect(args).toEqual({}) + + const defaultArgs = await setDefaults(args) + expect(defaultArgs).toEqual({ + ...defaults, + "disable-file-downloads": true, + }) + }) + it("should error if password passed in", () => { expect(() => parse(["--password", "supersecret123"])).toThrowError( "--password can only be set in the config file or passed in via $PASSWORD", From fc75db6edccabb429d093ffe532ab15b6c8ca1de Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Apr 2022 21:48:39 +0000 Subject: [PATCH 31/55] chore(deps): update azure/setup-helm action to v2 (#5088) Co-authored-by: Renovate Bot Co-authored-by: Joe Previte --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ea9ea2664..9dfc0f7f5 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -39,7 +39,7 @@ jobs: node-version: "14" - name: Install helm - uses: azure/setup-helm@v1.1 + uses: azure/setup-helm@v2.1 - name: Fetch dependencies from cache id: cache-yarn From 4e93db5b955d899af880126d2ff76376f3dcf1aa Mon Sep 17 00:00:00 2001 From: Asher Date: Wed, 27 Apr 2022 10:10:48 -0500 Subject: [PATCH 32/55] feat: relaunch on SIGUSR2 (#4979) This is because Node uses SIGUSR1 to enable the debug listener so even if you just want to restart code-server you end up enabling the debug listener as well. Opted to leave the SIGUSR1 handler in to avoid breaking existing workflows even though it does mean even if you only want to enable the debug listener you will end up restarting code-server as well. We could consider removing it after a transition phase. --- src/node/wrapper.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/node/wrapper.ts b/src/node/wrapper.ts index c645fe835..42151ab1a 100644 --- a/src/node/wrapper.ts +++ b/src/node/wrapper.ts @@ -203,8 +203,9 @@ class ChildProcess extends Process { /** * Parent process wrapper that spawns the child process and performs a handshake - * with it. Will relaunch the child if it receives a SIGUSR1 or is asked to by - * the child. If the child otherwise exits the parent will also exit. + * with it. Will relaunch the child if it receives a SIGUSR1 or SIGUSR2 or is + * asked to by the child. If the child otherwise exits the parent will also + * exit. */ export class ParentProcess extends Process { public logger = logger.named(`parent:${process.pid}`) @@ -227,6 +228,11 @@ export class ParentProcess extends Process { this.relaunch() }) + process.on("SIGUSR2", async () => { + this.logger.info("Received SIGUSR2; hotswapping") + this.relaunch() + }) + const opts = { size: "10M", maxFiles: 10, From 7027ec7d608aa41227ea95cdc565dfd32c881d16 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 4 May 2022 14:58:49 -0700 Subject: [PATCH 33/55] chore: upgrade Code to 1.66 (#5135) * chore: upgrade Code to 1.66 * docs: update docs for Code upgrades * fixup!: docs * chore: update vscode submodule * chore: update integration patch * chore: update node-version patch * chore: update github-auth patch They completely changed how auth is handled for GitHub in https://github.com/microsoft/vscode/pull/145424 so our patch may not work. Will need to test and revisit. * refactor: remove postinstall patch It appears they renamed postinstall.js to postinstall.mjs and removed the use of `rimraf` which means our patch is no longer needed! :tada: https://github.com/microsoft/vscode/commit/b0e8554cced292871a67748a18926cfd02f4e840 * chore: refresh local-storage patch * chore: refresh service-worker patch * chore: bulk refresh patches * fixup!: docs formatting * refactor: remove unused last-opened patch * fixup!: formatting docs * fixup!: formatting docs * refactor: remove rsync postinstall * Revert "refactor: remove rsync postinstall" This reverts commit 8d6b613e9d779ba18d0297710614516cde108bcf. * refactor: update postinstall.js to .mjs * feat(patches): add parent-origin bypass * docs(patches): add notes for testing store-socket * docs(patches): update testing info for node-version * refactor(patches): delete github-auth.diff patch * docs(patches): add notes for testing connection-type * fixup!: delete github-auth patch * fixup!: update connection type testing * docs(patches): add notes to insecure-notification.diff * docs(patches): add nots for update-check.diff * fixup!: remove comma in integration patch * fix(e2e): disable workspace trust * refactor: add --no-default-rc for yarn install * feat(patches): remove yarnrc in presinstall * fixup!: silly mistake * docs: add note about KEEP_MODULES=1 * docs(patches): add testing notes for node-version * refactor(patches): remove node-version It appears this is no longer needed due to the `remote/package.json` now which targets node rather than electron. * fixup!: add cd ../.. to code upgrade instructions * fixup!: add note to yarn --production flag * fixup!: make parent-origin easier to upstream * Revert "refactor(patches): delete github-auth.diff patch" This reverts commit 31a354a34345309fadc475491b392d7601e51a32. * Revert "fixup!: delete github-auth patch" This reverts commit bdeb5212e8c7be6cadd109941b486a4bcdae69fa. * Merge webview origin patch into webview patch * Remove unused post-install patch * Prevent builtin extensions from updating * Refresh sourcemaps patch * Update Node to v16 This matches the version in ./lib/vscode/remote/.yarnrc. I changed the engine to exactly 16 since if you use any different version it will just not work since the modules will have been built for 16 (due to the .yarnrc). * Replace fs.rmdir with fs.rm Node is showing a deprecation warning about it. * Update github-auth patch The local credentials provider is no longer used when there is a remote so this code moved into the backend web credential provider. * Prevent fs.rm from erroring about non-existent files We were using fs.rmdir which presumably did not have the same behavior in v14 (in v16 fs.rmdir also errors). * Install Python 3 in CentOS CI container Co-authored-by: Asher --- .github/workflows/ci.yaml | 32 ++-- ci/build/build-release.sh | 2 +- ci/build/npm-postinstall.sh | 6 +- ci/dev/postinstall.sh | 3 + docs/CONTRIBUTING.md | 6 +- docs/android.md | 6 +- docs/npm.md | 6 +- lib/vscode | 2 +- package.json | 2 +- patches/base-path.diff | 14 +- patches/connection-type.diff | 8 +- patches/disable-builtin-ext-update.diff | 30 ++++ patches/disable-downloads.diff | 14 +- patches/display-language.diff | 14 +- patches/github-auth.diff | 192 +++++++++++------------- patches/insecure-notification.diff | 9 +- patches/integration.diff | 16 +- patches/last-opened.diff | 8 - patches/local-storage.diff | 10 +- patches/log-level.diff | 6 +- patches/logout.diff | 4 +- patches/marketplace.diff | 2 +- patches/node-version.diff | 107 ------------- patches/parent-origin.diff | 24 +++ patches/post-install.diff | 26 ---- patches/proposed-api.diff | 4 +- patches/proxy-uri.diff | 4 +- patches/series | 3 +- patches/service-worker.diff | 2 +- patches/sourcemaps.diff | 6 +- patches/store-socket.diff | 6 + patches/update-check.diff | 27 ++-- patches/webview.diff | 26 +++- src/node/socket.ts | 2 +- test/e2e/models/CodeServer.ts | 3 + test/unit/node/cli.test.ts | 2 +- test/unit/node/socket.test.ts | 2 +- test/utils/helpers.ts | 2 +- 38 files changed, 295 insertions(+), 343 deletions(-) create mode 100644 patches/disable-builtin-ext-update.diff delete mode 100644 patches/last-opened.diff delete mode 100644 patches/node-version.diff create mode 100644 patches/parent-origin.diff delete mode 100644 patches/post-install.diff diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9dfc0f7f5..1e213f0ad 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -33,10 +33,10 @@ jobs: fetch-depth: 0 submodules: true - - name: Install Node.js v14 + - name: Install Node.js v16 uses: actions/setup-node@v3 with: - node-version: "14" + node-version: "16" - name: Install helm uses: azure/setup-helm@v2.1 @@ -74,10 +74,10 @@ jobs: fetch-depth: 0 submodules: true - - name: Install Node.js v14 + - name: Install Node.js v16 uses: actions/setup-node@v3 with: - node-version: "14" + node-version: "16" - name: Fetch dependencies from cache id: cache-yarn @@ -116,10 +116,10 @@ jobs: - name: Patch Code run: quilt push -a - - name: Install Node.js v14 + - name: Install Node.js v16 uses: actions/setup-node@v3 with: - node-version: "14" + node-version: "16" - name: Fetch dependencies from cache id: cache-yarn @@ -253,15 +253,15 @@ jobs: with: fetch-depth: 0 - - name: Install Node.js v14 + - name: Install Node.js v16 uses: actions/setup-node@v3 with: - node-version: "14" + node-version: "16" - name: Install development tools run: | yum install -y epel-release centos-release-scl - yum install -y devtoolset-9-{make,gcc,gcc-c++} jq rsync + yum install -y devtoolset-9-{make,gcc,gcc-c++} jq rsync python3 - name: Install nfpm and envsubst run: | @@ -337,7 +337,7 @@ jobs: CXX: ${{ format('{0}-g++', matrix.prefix) }} LINK: ${{ format('{0}-g++', matrix.prefix) }} NPM_CONFIG_ARCH: ${{ matrix.arch }} - NODE_VERSION: v14.17.4 + NODE_VERSION: v16.13.0 steps: - name: Checkout repo @@ -345,10 +345,10 @@ jobs: with: fetch-depth: 0 - - name: Install Node.js v14 + - name: Install Node.js v16 uses: actions/setup-node@v3 with: - node-version: "14" + node-version: "16" - name: Install nfpm run: | @@ -397,10 +397,10 @@ jobs: with: fetch-depth: 0 - - name: Install Node.js v14 + - name: Install Node.js v16 uses: actions/setup-node@v3 with: - node-version: "14" + node-version: "16" - name: Install nfpm run: | @@ -446,10 +446,10 @@ jobs: fetch-depth: 0 submodules: true - - name: Install Node.js v14 + - name: Install Node.js v16 uses: actions/setup-node@v3 with: - node-version: "14" + node-version: "16" - name: Fetch dependencies from cache id: cache-yarn diff --git a/ci/build/build-release.sh b/ci/build/build-release.sh index 07a879c28..e484b2518 100755 --- a/ci/build/build-release.sh +++ b/ci/build/build-release.sh @@ -146,7 +146,7 @@ EOF # Include global extension dependencies as well. rsync "$VSCODE_SRC_PATH/extensions/package.json" "$VSCODE_OUT_PATH/extensions/package.json" rsync "$VSCODE_SRC_PATH/extensions/yarn.lock" "$VSCODE_OUT_PATH/extensions/yarn.lock" - rsync "$VSCODE_SRC_PATH/extensions/postinstall.js" "$VSCODE_OUT_PATH/extensions/postinstall.js" + rsync "$VSCODE_SRC_PATH/extensions/postinstall.mjs" "$VSCODE_OUT_PATH/extensions/postinstall.mjs" pushd "$VSCODE_OUT_PATH" symlink_asar diff --git a/ci/build/npm-postinstall.sh b/ci/build/npm-postinstall.sh index fd437a652..d98bd992d 100755 --- a/ci/build/npm-postinstall.sh +++ b/ci/build/npm-postinstall.sh @@ -33,8 +33,8 @@ main() { echo "USE AT YOUR OWN RISK!" fi - if [ "$major_node_version" -ne "${FORCE_NODE_VERSION:-14}" ]; then - echo "ERROR: code-server currently requires node v14." + if [ "$major_node_version" -ne "${FORCE_NODE_VERSION:-16}" ]; then + echo "ERROR: code-server currently requires node v16." if [ -n "$FORCE_NODE_VERSION" ]; then echo "However, you have overrided the version check to use v$FORCE_NODE_VERSION." fi @@ -92,7 +92,7 @@ symlink_asar() { vscode_yarn() { echo 'Installing Code dependencies...' cd lib/vscode - yarn --production --frozen-lockfile + yarn --production --frozen-lockfile --no-default-rc symlink_asar diff --git a/ci/dev/postinstall.sh b/ci/dev/postinstall.sh index 170cdb46f..a83fda555 100755 --- a/ci/dev/postinstall.sh +++ b/ci/dev/postinstall.sh @@ -7,6 +7,9 @@ install-deps() { if [[ ${CI-} ]]; then args+=(--frozen-lockfile) fi + if [[ "$1" == "lib/vscode" ]]; then + args+=(--no-default-rc) + fi # If there is no package.json then yarn will look upward and end up installing # from the root resulting in an infinite loop (this can happen if you have not # checked out the submodule yet for example). diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index eaa4b736a..c12ff3020 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -96,6 +96,8 @@ re-apply the patches. ### Version updates to Code 1. Update the `lib/vscode` submodule to the desired upstream version branch. + 1. `cd lib/vscode && git checkout release/1.66 && cd ../..` + 2. `git add lib && git commit -m "chore: update Code"` 2. Apply the patches (`quilt push -a`) or restore your stashed changes. At this stage you may need to resolve conflicts. For example use `quilt push -f`, manually apply the rejected portions, then `quilt refresh`. @@ -130,11 +132,13 @@ yarn build:vscode yarn release ``` +_NOTE: this does not keep `node_modules`. If you want them to be kept, use `KEEP_MODULES=1 yarn release` (if you're testing in Coder, you'll want to do this)_ + Run your build: ```shell cd release -yarn --production +yarn --production # Skip if you used KEEP_MODULES=1 # Runs the built JavaScript with Node. node . ``` diff --git a/docs/android.md b/docs/android.md index 41fd92dbe..74bbcf503 100644 --- a/docs/android.md +++ b/docs/android.md @@ -11,11 +11,11 @@ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash ``` 6. Exit the terminal using `exit` and then reopen the terminal -7. Install and use Node.js 14: +7. Install and use Node.js 16: ```shell -nvm install 14 -nvm use 14 +nvm install 16 +nvm use 16 ``` 8. Install code-server globally on device with: `npm i -g code-server` diff --git a/docs/npm.md b/docs/npm.md index 27ceaf22f..5b50235bb 100644 --- a/docs/npm.md +++ b/docs/npm.md @@ -22,8 +22,8 @@ includes installing instructions based on your operating system. ## Node.js version -We use the same major version of Node.js shipped with VSCode's Electron, -which is currently `14.x`. VS Code also [lists Node.js +We use the same major version of Node.js shipped with Code's remote, which is +currently `16.x`. VS Code also [lists Node.js requirements](https://github.com/microsoft/vscode/wiki/How-to-Contribute#prerequisites). Using other versions of Node.js [may lead to unexpected @@ -72,7 +72,7 @@ Proceed to [installing](#installing) ## FreeBSD ```sh -pkg install -y git python npm-node14 yarn-node14 pkgconf +pkg install -y git python npm-node16 yarn-node16 pkgconf pkg install -y libinotify ``` diff --git a/lib/vscode b/lib/vscode index c722ca6c7..dfd34e826 160000 --- a/lib/vscode +++ b/lib/vscode @@ -1 +1 @@ -Subproject commit c722ca6c7eed3d7987c0d5c3df5c45f6b15e77d1 +Subproject commit dfd34e8260c270da74b5c2d86d61aee4b6d56977 diff --git a/package.json b/package.json index 0d9e7ad93..be5253bb3 100644 --- a/package.json +++ b/package.json @@ -122,7 +122,7 @@ "browser-ide" ], "engines": { - "node": ">= 14" + "node": "16" }, "jest": { "transform": { diff --git a/patches/base-path.diff b/patches/base-path.diff index c7d032b18..95bb8388e 100644 --- a/patches/base-path.diff +++ b/patches/base-path.diff @@ -159,7 +159,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -252,7 +252,10 @@ export class WebClientServer { +@@ -253,7 +253,10 @@ export class WebClientServer { return res.end(); } @@ -171,7 +171,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts function escapeAttribute(value: string): string { return value.replace(/"/g, '"'); -@@ -272,6 +275,8 @@ export class WebClientServer { +@@ -275,6 +278,8 @@ export class WebClientServer { accessToken: this._environmentService.args['github-auth'], scopes: [['user:email'], ['repo']] } : undefined; @@ -180,15 +180,15 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts const data = (await util.promisify(fs.readFile)(filePath)).toString() .replace('{{WORKBENCH_WEB_CONFIGURATION}}', escapeAttribute(JSON.stringify({ remoteAuthority, -@@ -279,6 +284,7 @@ export class WebClientServer { - developmentOptions: { enableSmokeTestDriver: this._environmentService.driverHandle === 'web' ? true : undefined }, - settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, +@@ -285,6 +290,7 @@ export class WebClientServer { + folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']), + workspaceUri: resolveWorkspaceURI(this._environmentService.args['default-workspace']), productConfiguration: >{ + rootEndpoint: base, codeServerVersion: this._productService.codeServerVersion, embedderIdentifier: 'server-distro', extensionsGallery: this._webExtensionResourceUrlTemplate ? { -@@ -291,7 +297,9 @@ export class WebClientServer { +@@ -297,7 +303,9 @@ export class WebClientServer { } : undefined } }))) @@ -199,7 +199,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts const cspDirectives = [ 'default-src \'self\';', -@@ -370,3 +378,70 @@ export class WebClientServer { +@@ -376,3 +384,70 @@ export class WebClientServer { return res.end(data); } } diff --git a/patches/connection-type.diff b/patches/connection-type.diff index 9f04bc299..050715c90 100644 --- a/patches/connection-type.diff +++ b/patches/connection-type.diff @@ -4,12 +4,18 @@ This allows the backend to distinguish them. In our case we use them to count a single "open" of Code so we need to be able to distinguish between web sockets from two instances and two web sockets used in a single instance. +To test this, +1. Run code-server +2. Open Network tab in Browser DevTools and filter for websocket requests +3. You should see the `type=` in the request url + + Index: code-server/lib/vscode/src/vs/platform/remote/common/remoteAgentConnection.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/platform/remote/common/remoteAgentConnection.ts +++ code-server/lib/vscode/src/vs/platform/remote/common/remoteAgentConnection.ts @@ -231,7 +231,7 @@ async function connectToRemoteExtensionH - + let socket: ISocket; try { - socket = await createSocket(options.logService, options.socketFactory, options.host, options.port, `reconnectionToken=${options.reconnectionToken}&reconnection=${options.reconnectionProtocol ? 'true' : 'false'}`, `renderer-${connectionTypeToString(connectionType)}-${options.reconnectionToken}`, timeoutCancellationToken); diff --git a/patches/disable-builtin-ext-update.diff b/patches/disable-builtin-ext-update.diff new file mode 100644 index 000000000..4cee1361a --- /dev/null +++ b/patches/disable-builtin-ext-update.diff @@ -0,0 +1,30 @@ +Prevent builtin extensions from being updated + +Updating builtin extensions from the marketplace prevents us from patching them +(for example out GitHub authentication patches). + +Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts ++++ code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +@@ -206,6 +206,9 @@ export class Extension implements IExten + if (!this.gallery || !this.local) { + return false; + } ++ if (this.type !== ExtensionType.User) { ++ return false; ++ } + if (!this.local.preRelease && this.gallery.properties.isPreReleaseVersion) { + return false; + } +@@ -1057,6 +1060,10 @@ export class ExtensionsWorkbenchService + // Skip if check updates only for builtin extensions and current extension is not builtin. + continue; + } ++ if (installed.type !== ExtensionType.User) { ++ // Never update builtin extensions. ++ continue; ++ } + if (installed.isBuiltin && !installed.local?.identifier.uuid) { + // Skip if the builtin extension does not have Marketplace id + continue; diff --git a/patches/disable-downloads.diff b/patches/disable-downloads.diff index 3c4b87da9..7568fcd0b 100644 --- a/patches/disable-downloads.diff +++ b/patches/disable-downloads.diff @@ -12,7 +12,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts +++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts -@@ -210,6 +210,11 @@ export interface IWorkbenchConstructionO +@@ -215,6 +215,11 @@ export interface IWorkbenchConstructionO */ readonly userDataPath?: string @@ -66,7 +66,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts /* ----- server setup ----- */ -@@ -92,6 +93,7 @@ export interface ServerParsedArgs { +@@ -96,6 +97,7 @@ export interface ServerParsedArgs { 'disable-update-check'?: boolean; 'auth'?: string 'locale'?: string @@ -78,14 +78,14 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -290,6 +290,7 @@ export class WebClientServer { +@@ -293,6 +293,7 @@ export class WebClientServer { logLevel: this._logService.getLevel(), }, userDataPath: this._environmentService.userDataPath, + isEnabledFileDownloads: !this._environmentService.args['disable-file-downloads'], settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, - productConfiguration: >{ - rootEndpoint: base, + enableWorkspaceTrust: !this._environmentService.args['disable-workspace-trust'], + folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']), Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/contextkeys.ts @@ -135,7 +135,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts +++ code-server/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts -@@ -21,7 +21,7 @@ import { CLOSE_SAVED_EDITORS_COMMAND_ID, +@@ -22,7 +22,7 @@ import { CLOSE_SAVED_EDITORS_COMMAND_ID, import { AutoSaveAfterShortDelayContext } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { WorkbenchListDoubleSelection } from 'vs/platform/list/browser/listService'; import { Schemas } from 'vs/base/common/network'; @@ -144,7 +144,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { ThemeIcon } from 'vs/platform/theme/common/themeService'; -@@ -475,13 +475,16 @@ MenuRegistry.appendMenuItem(MenuId.Explo +@@ -476,13 +476,16 @@ MenuRegistry.appendMenuItem(MenuId.Explo id: DOWNLOAD_COMMAND_ID, title: DOWNLOAD_LABEL }, diff --git a/patches/display-language.diff b/patches/display-language.diff index 6bfc0c75d..aad709545 100644 --- a/patches/display-language.diff +++ b/patches/display-language.diff @@ -6,7 +6,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/serverServices.ts +++ code-server/lib/vscode/src/vs/server/node/serverServices.ts -@@ -188,6 +188,9 @@ export async function setupServerService +@@ -192,6 +192,9 @@ export async function setupServerService const channel = new ExtensionManagementChannel(extensionManagementService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority)); socketServer.registerChannel('extensions', channel); @@ -94,7 +94,7 @@ Index: code-server/lib/vscode/src/vs/platform/environment/common/environmentServ =================================================================== --- code-server.orig/lib/vscode/src/vs/platform/environment/common/environmentService.ts +++ code-server/lib/vscode/src/vs/platform/environment/common/environmentService.ts -@@ -105,7 +105,7 @@ export abstract class AbstractNativeEnvi +@@ -108,7 +108,7 @@ export abstract class AbstractNativeEnvi return URI.file(join(vscodePortable, 'argv.json')); } @@ -168,7 +168,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -26,6 +26,7 @@ import { URI } from 'vs/base/common/uri' +@@ -27,6 +27,7 @@ import { URI } from 'vs/base/common/uri' import { streamToBuffer } from 'vs/base/common/buffer'; import { IProductConfiguration } from 'vs/base/common/product'; import { isString } from 'vs/base/common/types'; @@ -176,7 +176,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts const textMimeType = { '.html': 'text/html', -@@ -277,6 +278,8 @@ export class WebClientServer { +@@ -280,6 +281,8 @@ export class WebClientServer { } : undefined; const base = relativeRoot(getOriginalUrl(req)) const vscodeBase = relativePath(getOriginalUrl(req)) @@ -185,7 +185,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts const data = (await util.promisify(fs.readFile)(filePath)).toString() .replace('{{WORKBENCH_WEB_CONFIGURATION}}', escapeAttribute(JSON.stringify({ remoteAuthority, -@@ -303,7 +306,8 @@ export class WebClientServer { +@@ -309,7 +312,8 @@ export class WebClientServer { }))) .replace('{{WORKBENCH_AUTH_SESSION}}', () => authSessionInfo ? escapeAttribute(JSON.stringify(authSessionInfo)) : '') .replace(/{{BASE}}/g, base) @@ -207,7 +207,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts /* ----- server setup ----- */ -@@ -90,6 +91,7 @@ export interface ServerParsedArgs { +@@ -94,6 +95,7 @@ export interface ServerParsedArgs { /* ----- code-server ----- */ 'disable-update-check'?: boolean; 'auth'?: string @@ -252,7 +252,7 @@ Index: code-server/lib/vscode/src/vs/workbench/workbench.web.main.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/workbench.web.main.ts +++ code-server/lib/vscode/src/vs/workbench/workbench.web.main.ts -@@ -111,6 +111,10 @@ registerSingleton(IDiagnosticsService, N +@@ -112,6 +112,10 @@ registerSingleton(IDiagnosticsService, N //#region --- workbench contributions diff --git a/patches/github-auth.diff b/patches/github-auth.diff index 9e0af8094..53b98d0f4 100644 --- a/patches/github-auth.diff +++ b/patches/github-auth.diff @@ -1,118 +1,104 @@ -Use our own GitHub auth relay server +Add the ability to provide a GitHub token -Microsoft's does not work with self-hosted instances so we run our own. +To test install the GitHub PR extension and start code-server with GITHUB_TOKEN +or set github-auth in the config file. The extension should be authenticated. -Also add an extra set of scopes so that tokens provided via --github-auth will -work for the PR extension. - -Index: code-server/lib/vscode/extensions/github-authentication/src/githubServer.ts +Index: code-server/lib/vscode/src/vs/platform/credentials/node/credentialsMainService.ts =================================================================== ---- code-server.orig/lib/vscode/extensions/github-authentication/src/githubServer.ts -+++ code-server/lib/vscode/extensions/github-authentication/src/githubServer.ts -@@ -17,7 +17,7 @@ const localize = nls.loadMessageBundle() - const CLIENT_ID = '01ab8ac9400c4e429b23'; +--- code-server.orig/lib/vscode/src/vs/platform/credentials/node/credentialsMainService.ts ++++ code-server/lib/vscode/src/vs/platform/credentials/node/credentialsMainService.ts +@@ -5,18 +5,32 @@ - const NETWORK_ERROR = 'network error'; --const AUTH_RELAY_SERVER = 'vscode-auth.github.com'; -+const AUTH_RELAY_SERVER = 'auth.code-server.dev'; - // const AUTH_RELAY_STAGING_SERVER = 'client-auth-staging-14a768b.herokuapp.com'; - - class UriEventHandler extends vscode.EventEmitter implements vscode.UriHandler { -Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts -=================================================================== ---- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts -+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -274,7 +274,7 @@ export class WebClientServer { - id: generateUuid(), - providerId: 'github', - accessToken: this._environmentService.args['github-auth'], -- scopes: [['user:email'], ['repo']] -+ scopes: [['read:user', 'user:email', 'repo'], ['user:email'], ['repo']] - } : undefined; - const base = relativeRoot(getOriginalUrl(req)) - const vscodeBase = relativePath(getOriginalUrl(req)) -Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts -=================================================================== ---- code-server.orig/lib/vscode/src/vs/code/browser/workbench/workbench.ts -+++ code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts -@@ -17,6 +17,7 @@ import { isFolderToOpen, isWorkspaceToOp - import { create, ICredentialsProvider, IURLCallbackProvider, IWorkbenchConstructionOptions, IWorkspace, IWorkspaceProvider } from 'vs/workbench/workbench.web.main'; - import { posix } from 'vs/base/common/path'; - import { ltrim } from 'vs/base/common/strings'; + import { InMemoryCredentialsProvider } from 'vs/platform/credentials/common/credentials'; + import { ILogService } from 'vs/platform/log/common/log'; +-import { INativeEnvironmentService } from 'vs/platform/environment/common/environment'; ++import { IServerEnvironmentService } from 'vs/server/node/serverEnvironmentService'; + import { IProductService } from 'vs/platform/product/common/productService'; + import { BaseCredentialsMainService, KeytarModule } from 'vs/platform/credentials/common/credentialsMainService'; ++import { generateUuid } from 'vs/base/common/uuid'; +import { equals as arrayEquals } from 'vs/base/common/arrays'; - - interface ICredential { - service: string; -@@ -24,6 +25,13 @@ interface ICredential { - password: string; - } - ++ +interface IToken { + accessToken: string + account?: { label: string } + id: string + scopes: string[] +} -+ - class LocalStorageCredentialsProvider implements ICredentialsProvider { - private static readonly CREDENTIALS_STORAGE_KEY = 'credentials.provider'; -@@ -51,6 +59,58 @@ class LocalStorageCredentialsProvider im - scopes, - accessToken: authSessionInfo!.accessToken - })))); -+ -+ // Add tokens for extensions to use. This works for extensions like the -+ // pull requests one or GitLens. -+ const extensionId = `vscode.${authSessionInfo.providerId}-authentication`; -+ const service = `${product.urlProtocol}${extensionId}`; -+ const account = `${authSessionInfo.providerId}.auth`; -+ // Oddly the scopes need to match exactly so we cannot just have one token -+ // with all the scopes, instead we have to duplicate the token for each -+ // expected set of scopes. -+ const tokens: IToken[] = authSessionInfo.scopes.map((scopes) => ({ -+ id: authSessionInfo!.id, -+ scopes: scopes.sort(), // Sort for comparing later. -+ accessToken: authSessionInfo!.accessToken, -+ })); -+ this.getPassword(service, account).then((raw) => { -+ let existing: { -+ content: IToken[] -+ } | undefined; -+ -+ if (raw) { -+ try { -+ const json = JSON.parse(raw); -+ json.content = JSON.parse(json.content); -+ existing = json; -+ } catch (error) { -+ console.log(error); -+ } -+ } -+ -+ // Keep tokens for account and scope combinations we do not have in case -+ // there is an extension that uses scopes we have not accounted for (in -+ // these cases the user will need to manually authenticate the extension -+ // through the UI) or the user has tokens for other accounts. -+ if (existing?.content) { -+ existing.content = existing.content.filter((existingToken) => { -+ const scopes = existingToken.scopes.sort(); -+ return !(tokens.find((token) => { -+ return arrayEquals(scopes, token.scopes) -+ && token.account?.label === existingToken.account?.label; -+ })) -+ }) -+ } -+ -+ return this.setPassword(service, account, JSON.stringify({ -+ extensionId, -+ ...(existing || {}), -+ content: JSON.stringify([ -+ ...tokens, -+ ...(existing?.content || []), -+ ]) -+ })); + export class CredentialsWebMainService extends BaseCredentialsMainService { + + constructor( + @ILogService logService: ILogService, +- @INativeEnvironmentService private readonly environmentMainService: INativeEnvironmentService, ++ @IServerEnvironmentService private readonly environmentMainService: IServerEnvironmentService, + @IProductService private readonly productService: IProductService, + ) { + super(logService); ++ if (this.environmentMainService.args["github-auth"]) { ++ this.storeGitHubToken(this.environmentMainService.args["github-auth"]).catch((error) => { ++ this.logService.error('Failed to store provided GitHub token', error) + }) - } ++ } } + // If the credentials service is running on the server, we add a suffix -server to differentiate from the location that the +@@ -45,4 +59,59 @@ export class CredentialsWebMainService e + } + return this._keytarCache; + } ++ ++ private async storeGitHubToken(githubToken: string): Promise { ++ const extensionId = 'vscode.github-authentication'; ++ const service = `${await this.getSecretStoragePrefix()}${extensionId}`; ++ const account = 'github.auth'; ++ const scopes = [['read:user', 'user:email', 'repo']] ++ ++ // Oddly the scopes need to match exactly so we cannot just have one token ++ // with all the scopes, instead we have to duplicate the token for each ++ // expected set of scopes. ++ const tokens: IToken[] = scopes.map((scopes) => ({ ++ id: generateUuid(), ++ scopes: scopes.sort(), // Sort for comparing later. ++ accessToken: githubToken, ++ })); ++ ++ const raw = await this.getPassword(service, account) ++ ++ let existing: { ++ content: IToken[] ++ } | undefined; ++ ++ if (raw) { ++ try { ++ const json = JSON.parse(raw); ++ json.content = JSON.parse(json.content); ++ existing = json; ++ } catch (error) { ++ this.logService.error('Failed to parse existing GitHub credentials', error) ++ } ++ } ++ ++ // Keep tokens for account and scope combinations we do not have in case ++ // there is an extension that uses scopes we have not accounted for (in ++ // these cases the user will need to manually authenticate the extension ++ // through the UI) or the user has tokens for other accounts. ++ if (existing?.content) { ++ existing.content = existing.content.filter((existingToken) => { ++ const scopes = existingToken.scopes.sort(); ++ return !(tokens.find((token) => { ++ return arrayEquals(scopes, token.scopes) ++ && token.account?.label === existingToken.account?.label; ++ })) ++ }) ++ } ++ ++ return this.setPassword(service, account, JSON.stringify({ ++ extensionId, ++ ...(existing || {}), ++ content: JSON.stringify([ ++ ...tokens, ++ ...(existing?.content || []), ++ ]) ++ })); ++ } + } diff --git a/patches/insecure-notification.diff b/patches/insecure-notification.diff index bc94e24b4..101836038 100644 --- a/patches/insecure-notification.diff +++ b/patches/insecure-notification.diff @@ -5,7 +5,12 @@ may think code-server is broken. Ideally there would be a notification at the point where these things are used instead of this though. To test access over something like an HTTP domain or an IP address (not -localhost). +localhost). For example: + +1. run code-server +2. use ngrok to expose code-server +3. access via HTTP +4. look for notification in bottom right Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts =================================================================== @@ -15,7 +20,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts import { Disposable } from 'vs/base/common/lifecycle'; +import { localize } from 'vs/nls'; +import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; - + export class CodeServerClient extends Disposable { constructor ( + @INotificationService private notificationService: INotificationService, diff --git a/patches/integration.diff b/patches/integration.diff index d5348f06a..e8c197238 100644 --- a/patches/integration.diff +++ b/patches/integration.diff @@ -21,7 +21,7 @@ Index: code-server/lib/vscode/src/vs/server/node/server.main.ts import product from 'vs/platform/product/common/product'; import * as perf from 'vs/base/common/performance'; -@@ -33,37 +33,42 @@ const errorReporter: ErrorReporter = { +@@ -33,38 +33,43 @@ const errorReporter: ErrorReporter = { } }; @@ -34,6 +34,7 @@ Index: code-server/lib/vscode/src/vs/server/node/server.main.ts -const USER_DATA_PATH = join(REMOTE_DATA_FOLDER, 'data'); -const APP_SETTINGS_HOME = join(USER_DATA_PATH, 'User'); -const GLOBAL_STORAGE_HOME = join(APP_SETTINGS_HOME, 'globalStorage'); +-const LOCAL_HISTORY_HOME = join(APP_SETTINGS_HOME, 'History'); -const MACHINE_SETTINGS_HOME = join(USER_DATA_PATH, 'Machine'); -args['user-data-dir'] = USER_DATA_PATH; -const APP_ROOT = dirname(FileAccess.asFileUri('', require).fsPath); @@ -41,7 +42,7 @@ Index: code-server/lib/vscode/src/vs/server/node/server.main.ts -args['builtin-extensions-dir'] = BUILTIN_EXTENSIONS_FOLDER_PATH; -args['extensions-dir'] = args['extensions-dir'] || join(REMOTE_DATA_FOLDER, 'extensions'); - --[REMOTE_DATA_FOLDER, args['extensions-dir'], USER_DATA_PATH, APP_SETTINGS_HOME, MACHINE_SETTINGS_HOME, GLOBAL_STORAGE_HOME].forEach(f => { +-[REMOTE_DATA_FOLDER, args['extensions-dir'], USER_DATA_PATH, APP_SETTINGS_HOME, MACHINE_SETTINGS_HOME, GLOBAL_STORAGE_HOME, LOCAL_HISTORY_HOME].forEach(f => { - try { - if (!fs.existsSync(f)) { - fs.mkdirSync(f, { mode: 0o700 }); @@ -53,6 +54,7 @@ Index: code-server/lib/vscode/src/vs/server/node/server.main.ts + const USER_DATA_PATH = args['user-data-dir'] || join(REMOTE_DATA_FOLDER, 'data'); + const APP_SETTINGS_HOME = join(USER_DATA_PATH, 'User'); + const GLOBAL_STORAGE_HOME = join(APP_SETTINGS_HOME, 'globalStorage'); ++ const LOCAL_HISTORY_HOME = join(APP_SETTINGS_HOME, 'History'); + const MACHINE_SETTINGS_HOME = join(USER_DATA_PATH, 'Machine'); + args['user-data-dir'] = USER_DATA_PATH; + const APP_ROOT = dirname(FileAccess.asFileUri('', require).fsPath); @@ -60,14 +62,14 @@ Index: code-server/lib/vscode/src/vs/server/node/server.main.ts + args['builtin-extensions-dir'] = BUILTIN_EXTENSIONS_FOLDER_PATH; + args['extensions-dir'] = args['extensions-dir'] || join(REMOTE_DATA_FOLDER, 'extensions'); + -+ [REMOTE_DATA_FOLDER, args['extensions-dir'], USER_DATA_PATH, APP_SETTINGS_HOME, MACHINE_SETTINGS_HOME, GLOBAL_STORAGE_HOME].forEach(f => { ++ [REMOTE_DATA_FOLDER, args['extensions-dir'], USER_DATA_PATH, APP_SETTINGS_HOME, MACHINE_SETTINGS_HOME, GLOBAL_STORAGE_HOME, LOCAL_HISTORY_HOME].forEach(f => { + try { + if (!fs.existsSync(f)) { + fs.mkdirSync(f, { mode: 0o700 }); + } + } catch (err) { console.error(err); } + }); -+ return REMOTE_DATA_FOLDER ++ return REMOTE_DATA_FOLDER; +} /** @@ -261,9 +263,9 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -279,6 +279,7 @@ export class WebClientServer { - developmentOptions: { enableSmokeTestDriver: this._environmentService.driverHandle === 'web' ? true : undefined }, - settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, +@@ -285,6 +285,7 @@ export class WebClientServer { + folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']), + workspaceUri: resolveWorkspaceURI(this._environmentService.args['default-workspace']), productConfiguration: >{ + codeServerVersion: this._productService.codeServerVersion, embedderIdentifier: 'server-distro', diff --git a/patches/last-opened.diff b/patches/last-opened.diff deleted file mode 100644 index 71a1c9980..000000000 --- a/patches/last-opened.diff +++ /dev/null @@ -1,8 +0,0 @@ -Remove last opened functionality - -This conflicts with our own handling of the last opened workspace. If we wanted -to switch to this we would need to pass through the disable-last-opened flag and -respect it here then remove our own redirction code that handles this. - -Our version might be better anyway since it puts the workspace in the URL. - diff --git a/patches/local-storage.diff b/patches/local-storage.diff index 4c3c90da1..744540bbf 100644 --- a/patches/local-storage.diff +++ b/patches/local-storage.diff @@ -20,19 +20,19 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -289,6 +289,7 @@ export class WebClientServer { +@@ -292,6 +292,7 @@ export class WebClientServer { enableSmokeTestDriver: this._environmentService.driverHandle === 'web' ? true : undefined, logLevel: this._logService.getLevel(), }, + userDataPath: this._environmentService.userDataPath, settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, - productConfiguration: >{ - rootEndpoint: base, + enableWorkspaceTrust: !this._environmentService.args['disable-workspace-trust'], + folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']), Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts +++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts -@@ -205,6 +205,11 @@ export interface IWorkbenchConstructionO +@@ -210,6 +210,11 @@ export interface IWorkbenchConstructionO */ readonly configurationDefaults?: Record; @@ -52,7 +52,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi get logFile(): URI { return joinPath(this.logsHome, 'window.log'); } @memoize -- get userRoamingDataHome(): URI { return URI.file('/User').with({ scheme: Schemas.userData }); } +- get userRoamingDataHome(): URI { return URI.file('/User').with({ scheme: Schemas.vscodeUserData }); } + get userRoamingDataHome(): URI { return joinPath(URI.file(this.userDataPath).with({ scheme: Schemas.vscodeRemote }), 'User'); } + + get userDataPath(): string { diff --git a/patches/log-level.diff b/patches/log-level.diff index ce99f08be..8b4f125b5 100644 --- a/patches/log-level.diff +++ b/patches/log-level.diff @@ -7,7 +7,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -285,7 +285,10 @@ export class WebClientServer { +@@ -288,7 +288,10 @@ export class WebClientServer { remoteAuthority, webviewEndpoint: vscodeBase + '/static/out/vs/workbench/contrib/webview/browser/pre', _wrapWebWorkerExtHostInIframe, @@ -17,5 +17,5 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts + logLevel: this._logService.getLevel(), + }, settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, - productConfiguration: >{ - rootEndpoint: base, + enableWorkspaceTrust: !this._environmentService.args['disable-workspace-trust'], + folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']), diff --git a/patches/logout.diff b/patches/logout.diff index 47bb41002..1a8d0f005 100644 --- a/patches/logout.diff +++ b/patches/logout.diff @@ -28,7 +28,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts /* ----- server setup ----- */ -@@ -88,6 +89,7 @@ export const serverOptions: OptionDescri +@@ -92,6 +93,7 @@ export const serverOptions: OptionDescri export interface ServerParsedArgs { /* ----- code-server ----- */ 'disable-update-check'?: boolean; @@ -40,7 +40,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -287,6 +287,7 @@ export class WebClientServer { +@@ -293,6 +293,7 @@ export class WebClientServer { productConfiguration: >{ rootEndpoint: base, updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, diff --git a/patches/marketplace.diff b/patches/marketplace.diff index 77f469f10..d6e799756 100644 --- a/patches/marketplace.diff +++ b/patches/marketplace.diff @@ -32,7 +32,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -287,14 +287,14 @@ export class WebClientServer { +@@ -293,14 +293,14 @@ export class WebClientServer { rootEndpoint: base, codeServerVersion: this._productService.codeServerVersion, embedderIdentifier: 'server-distro', diff --git a/patches/node-version.diff b/patches/node-version.diff deleted file mode 100644 index 9ee48e87f..000000000 --- a/patches/node-version.diff +++ /dev/null @@ -1,107 +0,0 @@ -Patch the Node version to use the current version of Node - -Previously it would use the yarnrc which results in builds that cannot run with -the version of Node they were built with because the native modules are -targeting the wrong version. - -One way test this is to build in a fresh Docker container, run the build, then -try opening the built-in terminal. - -Index: code-server/lib/vscode/build/gulpfile.reh.js -=================================================================== ---- code-server.orig/lib/vscode/build/gulpfile.reh.js -+++ code-server/lib/vscode/build/gulpfile.reh.js -@@ -124,9 +124,7 @@ const serverWithWebEntryPoints = [ - ]; - - function getNodeVersion() { -- const yarnrc = fs.readFileSync(path.join(REPO_ROOT, 'remote', '.yarnrc'), 'utf8'); -- const target = /^target "(.*)"$/m.exec(yarnrc)[1]; -- return target; -+ return process.versions.node; - } - - const nodeVersion = getNodeVersion(); -Index: code-server/lib/vscode/build/lib/node.js -=================================================================== ---- code-server.orig/lib/vscode/build/lib/node.js -+++ code-server/lib/vscode/build/lib/node.js -@@ -7,9 +7,7 @@ Object.defineProperty(exports, "__esModu - const path = require("path"); - const fs = require("fs"); - const root = path.dirname(path.dirname(__dirname)); --const yarnrcPath = path.join(root, 'remote', '.yarnrc'); --const yarnrc = fs.readFileSync(yarnrcPath, 'utf8'); --const version = /^target\s+"([^"]+)"$/m.exec(yarnrc)[1]; -+const version = process.versions.node; - const platform = process.platform; - const arch = platform === 'darwin' ? 'x64' : process.arch; - const node = platform === 'win32' ? 'node.exe' : 'node'; -Index: code-server/lib/vscode/build/lib/node.ts -=================================================================== ---- code-server.orig/lib/vscode/build/lib/node.ts -+++ code-server/lib/vscode/build/lib/node.ts -@@ -7,9 +7,7 @@ import * as path from 'path'; - import * as fs from 'fs'; - - const root = path.dirname(path.dirname(__dirname)); --const yarnrcPath = path.join(root, 'remote', '.yarnrc'); --const yarnrc = fs.readFileSync(yarnrcPath, 'utf8'); --const version = /^target\s+"([^"]+)"$/m.exec(yarnrc)![1]; -+const version = process.versions.node; - - const platform = process.platform; - const arch = platform === 'darwin' ? 'x64' : process.arch; -Index: code-server/lib/vscode/build/lib/util.js -=================================================================== ---- code-server.orig/lib/vscode/build/lib/util.js -+++ code-server/lib/vscode/build/lib/util.js -@@ -298,9 +298,7 @@ function streamToPromise(stream) { - } - exports.streamToPromise = streamToPromise; - function getElectronVersion() { -- const yarnrc = fs.readFileSync(path.join(root, '.yarnrc'), 'utf8'); -- const target = /^target "(.*)"$/m.exec(yarnrc)[1]; -- return target; -+ return process.versions.node; - } - exports.getElectronVersion = getElectronVersion; - function acquireWebNodePaths() { -Index: code-server/lib/vscode/build/lib/util.ts -=================================================================== ---- code-server.orig/lib/vscode/build/lib/util.ts -+++ code-server/lib/vscode/build/lib/util.ts -@@ -371,9 +371,7 @@ export function streamToPromise(stream: - } - - export function getElectronVersion(): string { -- const yarnrc = fs.readFileSync(path.join(root, '.yarnrc'), 'utf8'); -- const target = /^target "(.*)"$/m.exec(yarnrc)![1]; -- return target; -+ return process.versions.node; - } - - export function acquireWebNodePaths() { -@@ -455,4 +453,3 @@ export function buildWebNodePaths(outDir - result.taskName = 'build-web-node-paths'; - return result; - } -- -Index: code-server/lib/vscode/remote/.yarnrc -=================================================================== ---- code-server.orig/lib/vscode/remote/.yarnrc -+++ /dev/null -@@ -1,4 +0,0 @@ --disturl "http://nodejs.org/dist" --target "14.16.0" --runtime "node" --build_from_source "true" -Index: code-server/lib/vscode/.yarnrc -=================================================================== ---- code-server.orig/lib/vscode/.yarnrc -+++ /dev/null -@@ -1,4 +0,0 @@ --disturl "https://electronjs.org/headers" --target "13.5.2" --runtime "electron" --build_from_source "true" diff --git a/patches/parent-origin.diff b/patches/parent-origin.diff new file mode 100644 index 000000000..e49382483 --- /dev/null +++ b/patches/parent-origin.diff @@ -0,0 +1,24 @@ +Remove parentOriginHash checko + +This fixes webviews from not working properly due to a change upstream. +Upstream added a check to ensure parent authority is encoded into the webview +origin. Since our webview origin is the parent authority, we can bypass this +check. + +Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/main.js +=================================================================== +--- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/main.js ++++ code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/main.js +@@ -317,6 +317,12 @@ const hostMessaging = new class HostMess + const id = searchParams.get('id'); + + const hostname = location.hostname; ++ ++ // It is safe to run if we are on the same host. ++ const parent = new URL(parentOrigin) ++ if (parent.hostname == location.hostname) { ++ return start(parentOrigin) ++ } + + if (!crypto.subtle) { + // cannot validate, not running in a secure context diff --git a/patches/post-install.diff b/patches/post-install.diff deleted file mode 100644 index dc8334e6e..000000000 --- a/patches/post-install.diff +++ /dev/null @@ -1,26 +0,0 @@ -Replace rimraf with fs.rmSync in postinstall - -The postinstall gets ran when you install with npm but rimraf is a development -dependency so it will not exist. - -Index: code-server/lib/vscode/extensions/postinstall.js -=================================================================== ---- code-server.orig/lib/vscode/extensions/postinstall.js -+++ code-server/lib/vscode/extensions/postinstall.js -@@ -8,7 +8,6 @@ - - const fs = require('fs'); - const path = require('path'); --const rimraf = require('rimraf'); - - const root = path.join(__dirname, 'node_modules', 'typescript'); - -@@ -21,7 +20,7 @@ function processRoot() { - if (!toKeep.has(name)) { - const filePath = path.join(root, name); - console.log(`Removed ${filePath}`); -- rimraf.sync(filePath); -+ fs.rmSync(filePath, { recursive: true }); - } - } - } diff --git a/patches/proposed-api.diff b/patches/proposed-api.diff index 5971d714e..ebd5deb57 100644 --- a/patches/proposed-api.diff +++ b/patches/proposed-api.diff @@ -9,7 +9,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/extensions/common/abstra =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/services/extensions/common/abstractExtensionService.ts +++ code-server/lib/vscode/src/vs/workbench/services/extensions/common/abstractExtensionService.ts -@@ -1163,7 +1163,7 @@ class ProposedApiController { +@@ -1471,7 +1471,7 @@ class ProposedApiController { this._envEnabledExtensions = new Set((_environmentService.extensionEnabledProposedApi ?? []).map(id => ExtensionIdentifier.toKey(id))); @@ -22,7 +22,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/extensions/common/extens =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/services/extensions/common/extensions.ts +++ code-server/lib/vscode/src/vs/workbench/services/extensions/common/extensions.ts -@@ -134,10 +134,7 @@ export interface IExtensionHost { +@@ -163,10 +163,7 @@ export interface IExtensionHost { } export function isProposedApiEnabled(extension: IExtensionDescription, proposal: ApiProposalName): boolean { diff --git a/patches/proxy-uri.diff b/patches/proxy-uri.diff index 1227dfaf9..b153b20df 100644 --- a/patches/proxy-uri.diff +++ b/patches/proxy-uri.diff @@ -68,7 +68,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -288,6 +288,7 @@ export class WebClientServer { +@@ -294,6 +294,7 @@ export class WebClientServer { rootEndpoint: base, updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined, @@ -93,7 +93,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalE =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts -@@ -390,7 +390,7 @@ export function createTerminalEnvironmen +@@ -388,7 +388,7 @@ export function createTerminalEnvironmen // Sanitize the environment, removing any undesirable VS Code and Electron environment // variables diff --git a/patches/series b/patches/series index 79da7efda..5801db6ae 100644 --- a/patches/series +++ b/patches/series @@ -1,9 +1,9 @@ integration.diff -node-version.diff base-path.diff proposed-api.diff marketplace.diff webview.diff +disable-builtin-ext-update.diff insecure-notification.diff update-check.diff logout.diff @@ -12,7 +12,6 @@ proxy-uri.diff display-language.diff github-auth.diff unique-db.diff -post-install.diff log-level.diff local-storage.diff service-worker.diff diff --git a/patches/service-worker.diff b/patches/service-worker.diff index ed12d5449..db2bacd22 100644 --- a/patches/service-worker.diff +++ b/patches/service-worker.diff @@ -21,7 +21,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -298,6 +298,10 @@ export class WebClientServer { +@@ -304,6 +304,10 @@ export class WebClientServer { proxyEndpointTemplate: base + '/proxy/{{port}}', codeServerVersion: this._productService.codeServerVersion, embedderIdentifier: 'server-distro', diff --git a/patches/sourcemaps.diff b/patches/sourcemaps.diff index cb2367e6a..03502650c 100644 --- a/patches/sourcemaps.diff +++ b/patches/sourcemaps.diff @@ -10,7 +10,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js =================================================================== --- code-server.orig/lib/vscode/build/gulpfile.reh.js +++ code-server/lib/vscode/build/gulpfile.reh.js -@@ -197,8 +197,7 @@ function packageTask(type, platform, arc +@@ -191,8 +191,7 @@ function packageTask(type, platform, arc const src = gulp.src(sourceFolderName + '/**', { base: '.' }) .pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + sourceFolderName), 'out'); })) @@ -20,7 +20,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js const workspaceExtensionPoints = ['debuggers', 'jsonValidation']; const isUIExtension = (manifest) => { -@@ -237,9 +236,9 @@ function packageTask(type, platform, arc +@@ -231,9 +230,9 @@ function packageTask(type, platform, arc .map(name => `.build/extensions/${name}/**`); const extensions = gulp.src(extensionPaths, { base: '.build', dot: true }); @@ -32,7 +32,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js let version = packageJson.version; const quality = product.quality; -@@ -374,7 +373,7 @@ function tweakProductForServerWeb(produc +@@ -368,7 +367,7 @@ function tweakProductForServerWeb(produc const minifyTask = task.define(`minify-vscode-${type}`, task.series( optimizeTask, util.rimraf(`out-vscode-${type}-min`), diff --git a/patches/store-socket.diff b/patches/store-socket.diff index 2bc60652c..5aa40ec64 100644 --- a/patches/store-socket.diff +++ b/patches/store-socket.diff @@ -3,6 +3,12 @@ Store a static reference to the IPC socket This lets us use it to open files inside code-server from outside of code-server. +To test this: +1. run code-server +2. open file outside of code-server i.e. `code-server Application > Storage (top-level) +3. Click "Clear site data" +4. See update notification + Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/client.ts @@ -14,7 +19,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; +import { IProductService } from 'vs/platform/product/common/productService'; +import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; - + export class CodeServerClient extends Disposable { constructor ( + @ILogService private logService: ILogService, @@ -93,15 +98,15 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts readonly codeServerVersion?: string readonly rootEndpoint?: string + readonly updateEndpoint?: string - + readonly version: string; readonly date?: string; Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -286,6 +286,7 @@ export class WebClientServer { - settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, +@@ -292,6 +292,7 @@ export class WebClientServer { + workspaceUri: resolveWorkspaceURI(this._environmentService.args['default-workspace']), productConfiguration: >{ rootEndpoint: base, + updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, @@ -114,19 +119,19 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts +++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts @@ -11,6 +11,8 @@ import { refineServiceDecorator } from ' import { IEnvironmentService, INativeEnvironmentService } from 'vs/platform/environment/common/environment'; - + export const serverOptions: OptionDescriptions = { + /* ----- code-server ----- */ + 'disable-update-check': { type: 'boolean' }, - + /* ----- server setup ----- */ - -@@ -84,6 +86,8 @@ export const serverOptions: OptionDescri + +@@ -88,6 +90,8 @@ export const serverOptions: OptionDescri }; - + export interface ServerParsedArgs { + /* ----- code-server ----- */ + 'disable-update-check'?: boolean; - + /* ----- server setup ----- */ - + diff --git a/patches/webview.diff b/patches/webview.diff index a4506b03b..c04847e1b 100644 --- a/patches/webview.diff +++ b/patches/webview.diff @@ -15,13 +15,16 @@ Since this code exists only for the authentication case we can just skip it when it is served from the current host as authentication is not a problem if the request is not cross-origin. +There is also an origin check we bypass (this seems to be related to how the +webview host is separate by default but we serve on the same host). + To test, open a few types of webviews (images, markdown, extension details, etc). Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts +++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts -@@ -176,7 +176,7 @@ export class BrowserWorkbenchEnvironment +@@ -179,7 +179,7 @@ export class BrowserWorkbenchEnvironment @memoize get webviewExternalEndpoint(): string { @@ -34,7 +37,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -280,6 +280,7 @@ export class WebClientServer { +@@ -283,6 +283,7 @@ export class WebClientServer { const data = (await util.promisify(fs.readFile)(filePath)).toString() .replace('{{WORKBENCH_WEB_CONFIGURATION}}', escapeAttribute(JSON.stringify({ remoteAuthority, @@ -46,7 +49,7 @@ Index: code-server/lib/vscode/src/vs/workbench/common/webview.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/common/webview.ts +++ code-server/lib/vscode/src/vs/workbench/common/webview.ts -@@ -24,7 +24,7 @@ export const webviewResourceBaseHost = ' +@@ -22,7 +22,7 @@ export const webviewResourceBaseHost = ' export const webviewRootResourceAuthority = `vscode-resource.${webviewResourceBaseHost}`; @@ -74,3 +77,20 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/servi switch (event.request.method) { case 'GET': case 'HEAD': +Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/main.js +=================================================================== +--- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/main.js ++++ code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/main.js +@@ -318,6 +318,12 @@ const hostMessaging = new class HostMess + + const hostname = location.hostname; + ++ // It is safe to run if we are on the same host. ++ const parent = new URL(parentOrigin) ++ if (parent.hostname === location.hostname) { ++ return start(parentOrigin) ++ } ++ + if (!crypto.subtle) { + // cannot validate, not running in a secure context + throw new Error(`Cannot validate in current context!`); diff --git a/src/node/socket.ts b/src/node/socket.ts index 1651046d0..a56d9566e 100644 --- a/src/node/socket.ts +++ b/src/node/socket.ts @@ -77,7 +77,7 @@ export class SocketProxyProvider { this.proxyPipe = pipe return Promise.all([ fs.mkdir(path.dirname(this.proxyPipe), { recursive: true }), - fs.rmdir(this.proxyPipe, { recursive: true }), + fs.rm(this.proxyPipe, { force: true, recursive: true }), ]) }) .then(() => { diff --git a/test/e2e/models/CodeServer.ts b/test/e2e/models/CodeServer.ts index 53e2208d2..8b3c4a4af 100644 --- a/test/e2e/models/CodeServer.ts +++ b/test/e2e/models/CodeServer.ts @@ -81,6 +81,9 @@ export class CodeServer { path.join(dir, "User/settings.json"), JSON.stringify({ "workbench.startupEditor": "none", + // NOTE@jsjoeio - needed to prevent Trust Policy prompt + // in end-to-end tests. + "security.workspace.trust.enabled": false, }), "utf8", ) diff --git a/test/unit/node/cli.test.ts b/test/unit/node/cli.test.ts index 76ebb610f..51e707001 100644 --- a/test/unit/node/cli.test.ts +++ b/test/unit/node/cli.test.ts @@ -458,7 +458,7 @@ describe("cli", () => { beforeEach(async () => { delete process.env.VSCODE_IPC_HOOK_CLI - await fs.rmdir(vscodeIpcPath, { recursive: true }) + await fs.rm(vscodeIpcPath, { force: true, recursive: true }) }) it("should use existing if inside code-server", async () => { diff --git a/test/unit/node/socket.test.ts b/test/unit/node/socket.test.ts index b79696572..167691f7b 100644 --- a/test/unit/node/socket.test.ts +++ b/test/unit/node/socket.test.ts @@ -53,7 +53,7 @@ describe("SocketProxyProvider", () => { await fs.mkdir(path.join(tmpdir, "tests"), { recursive: true }) const socketPath = await provider.findFreeSocketPath(path.join(tmpdir, "tests/tls-socket-proxy")) - await fs.rmdir(socketPath, { recursive: true }) + await fs.rm(socketPath, { force: true, recursive: true }) return new Promise((_resolve) => { const resolved: { [key: string]: boolean } = { client: false, server: false } diff --git a/test/utils/helpers.ts b/test/utils/helpers.ts index be8f3a90d..3f9399d4b 100644 --- a/test/utils/helpers.ts +++ b/test/utils/helpers.ts @@ -29,7 +29,7 @@ export function mockLogger() { */ export async function clean(testName: string): Promise { const dir = path.join(os.tmpdir(), `code-server/tests/${testName}`) - await fs.rmdir(dir, { recursive: true }) + await fs.rm(dir, { force: true, recursive: true }) } /** From 88e971c609d112693d3c81851e31a2c44e1d27e2 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 4 May 2022 16:05:48 -0700 Subject: [PATCH 34/55] refactor(heart): bind class methods and make beat async (#5142) * feat: set up new test for beat twice * refactor: make Heart.beat() async This allows us to properly await heart.beat() in our tests and remove the HACK I added before. * refactor: bind heart methods .beat and .alive This allows the functions to maintain access to the Heart instance (or `this`) even when they are passed to other functions. We do this because we pass both `isActive` and `beat` to `heartbeatTimer`. * feat(heart): add test to ensure no warnings called * fixup!: revert setTimeout for heartbeatTimer * fixup!: return promise in beat --- src/node/heart.ts | 15 ++++++++++----- src/node/routes/index.ts | 2 ++ test/unit/node/heart.test.ts | 28 ++++++++++++++++------------ 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/node/heart.ts b/src/node/heart.ts index a03802035..19f9aa4ad 100644 --- a/src/node/heart.ts +++ b/src/node/heart.ts @@ -9,7 +9,10 @@ export class Heart { private heartbeatInterval = 60000 public lastHeartbeat = 0 - public constructor(private readonly heartbeatPath: string, private readonly isActive: () => Promise) {} + public constructor(private readonly heartbeatPath: string, private readonly isActive: () => Promise) { + this.beat = this.beat.bind(this) + this.alive = this.alive.bind(this) + } public alive(): boolean { const now = Date.now() @@ -20,20 +23,22 @@ export class Heart { * timeout and start or reset a timer that keeps running as long as there is * activity. Failures are logged as warnings. */ - public beat(): void { + public async beat(): Promise { if (this.alive()) { return } logger.trace("heartbeat") - fs.writeFile(this.heartbeatPath, "").catch((error) => { - logger.warn(error.message) - }) this.lastHeartbeat = Date.now() if (typeof this.heartbeatTimer !== "undefined") { clearTimeout(this.heartbeatTimer) } this.heartbeatTimer = setTimeout(() => heartbeatTimer(this.isActive, this.beat), this.heartbeatInterval) + try { + return await fs.writeFile(this.heartbeatPath, "") + } catch (error: any) { + logger.warn(error.message) + } } /** diff --git a/src/node/routes/index.ts b/src/node/routes/index.ts index 71ce557c5..13d53df86 100644 --- a/src/node/routes/index.ts +++ b/src/node/routes/index.ts @@ -56,6 +56,8 @@ export const register = async (app: App, args: DefaultedArgs): Promise { }) afterEach(() => { jest.resetAllMocks() + jest.useRealTimers() if (heart) { heart.dispose() } @@ -42,11 +43,7 @@ describe("Heart", () => { expect(fileContents).toBe(text) heart = new Heart(pathToFile, mockIsActive(true)) - heart.beat() - // HACK@jsjoeio - beat has some async logic but is not an async method - // Therefore, we have to create an artificial wait in order to make sure - // all async code has completed before asserting - await new Promise((r) => setTimeout(r, 100)) + await heart.beat() // Check that the heart wrote to the heartbeatFilePath and overwrote our text const fileContentsAfterBeat = await readFile(pathToFile, { encoding: "utf8" }) expect(fileContentsAfterBeat).not.toBe(text) @@ -56,15 +53,11 @@ describe("Heart", () => { }) it("should log a warning when given an invalid file path", async () => { heart = new Heart(`fakeDir/fake.txt`, mockIsActive(false)) - heart.beat() - // HACK@jsjoeio - beat has some async logic but is not an async method - // Therefore, we have to create an artificial wait in order to make sure - // all async code has completed before asserting - await new Promise((r) => setTimeout(r, 100)) + await heart.beat() expect(logger.warn).toHaveBeenCalled() }) - it("should be active after calling beat", () => { - heart.beat() + it("should be active after calling beat", async () => { + await heart.beat() const isAlive = heart.alive() expect(isAlive).toBe(true) @@ -75,6 +68,17 @@ describe("Heart", () => { const isAlive = heart.alive() expect(isAlive).toBe(false) }) + it("should beat twice without warnings", async () => { + // Use fake timers so we can speed up setTimeout + jest.useFakeTimers() + heart = new Heart(`${testDir}/hello.txt`, mockIsActive(true)) + await heart.beat() + // we need to speed up clocks, timeouts + // call heartbeat again (and it won't be alive I think) + // then assert no warnings were called + jest.runAllTimers() + expect(logger.warn).not.toHaveBeenCalled() + }) }) describe("heartbeatTimer", () => { From ef0d76bc16fad89ae951a94d616d41f0ab3bed57 Mon Sep 17 00:00:00 2001 From: Asher Date: Wed, 4 May 2022 18:32:12 -0500 Subject: [PATCH 35/55] fix: patch telemetry (#5158) This seems to have been dropped in the rewrite. --- patches/series | 1 + patches/telemetry.diff | 212 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 213 insertions(+) create mode 100644 patches/telemetry.diff diff --git a/patches/series b/patches/series index 5801db6ae..318ad7aba 100644 --- a/patches/series +++ b/patches/series @@ -18,3 +18,4 @@ service-worker.diff connection-type.diff sourcemaps.diff disable-downloads.diff +telemetry.diff diff --git a/patches/telemetry.diff b/patches/telemetry.diff new file mode 100644 index 000000000..2d0feabac --- /dev/null +++ b/patches/telemetry.diff @@ -0,0 +1,212 @@ +Add support for telemetry endpoint + +Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/server/node/serverServices.ts ++++ code-server/lib/vscode/src/vs/server/node/serverServices.ts +@@ -68,6 +68,7 @@ import { REMOTE_TERMINAL_CHANNEL_NAME } + import { RemoteExtensionLogFileName } from 'vs/workbench/services/remote/common/remoteAgentService'; + import { REMOTE_FILE_SYSTEM_CHANNEL_NAME } from 'vs/workbench/services/remote/common/remoteFileSystemProviderClient'; + import { ExtensionHostStatusService, IExtensionHostStatusService } from 'vs/server/node/extensionHostStatusService'; ++import { TelemetryClient } from "vs/server/node/telemetryClient"; + + const eventPrefix = 'monacoworkbench'; + +@@ -120,7 +121,11 @@ export async function setupServerService + let appInsightsAppender: ITelemetryAppender = NullAppender; + const machineId = await getMachineId(); + if (supportsTelemetry(productService, environmentService)) { +- if (productService.aiConfig && productService.aiConfig.asimovKey) { ++ const telemetryEndpoint = process.env.CS_TELEMETRY_URL || "https://v1.telemetry.coder.com/track"; ++ if (telemetryEndpoint) { ++ appInsightsAppender = new AppInsightsAppender(eventPrefix, null, () => new TelemetryClient(telemetryEndpoint) as any); ++ disposables.add(toDisposable(() => appInsightsAppender!.flush())); // Ensure the AI appender is disposed so that it flushes remaining data ++ } else if (productService.aiConfig && productService.aiConfig.asimovKey) { + appInsightsAppender = new AppInsightsAppender(eventPrefix, null, productService.aiConfig.asimovKey); + disposables.add(toDisposable(() => appInsightsAppender!.flush())); // Ensure the AI appender is disposed so that it flushes remaining data + } +Index: code-server/lib/vscode/src/vs/server/node/telemetryClient.ts +=================================================================== +--- /dev/null ++++ code-server/lib/vscode/src/vs/server/node/telemetryClient.ts +@@ -0,0 +1,135 @@ ++import * as appInsights from 'applicationinsights'; ++import * as https from 'https'; ++import * as http from 'http'; ++import * as os from 'os'; ++ ++class Channel { ++ public get _sender() { ++ throw new Error('unimplemented'); ++ } ++ public get _buffer() { ++ throw new Error('unimplemented'); ++ } ++ ++ public setUseDiskRetryCaching(): void { ++ throw new Error('unimplemented'); ++ } ++ public send(): void { ++ throw new Error('unimplemented'); ++ } ++ public triggerSend(): void { ++ throw new Error('unimplemented'); ++ } ++} ++ ++// Unable to use implements because TypeScript tells you a private property is ++// missing but if you add it then it complains they have different private ++// properties. Uncommenting it during development can be helpful though to see ++// if anything is missing. ++export class TelemetryClient /* implements appInsights.TelemetryClient */ { ++ private _telemetryProcessors: any = undefined; ++ public context: any = undefined; ++ public commonProperties: any = undefined; ++ public config: any = {}; ++ public quickPulseClient: any = undefined; ++ ++ public channel: any = new Channel(); ++ ++ public constructor(private readonly endpoint: string) { ++ // Nothing to do. ++ } ++ ++ public addTelemetryProcessor(): void { ++ throw new Error('unimplemented'); ++ } ++ ++ public clearTelemetryProcessors(): void { ++ if (this._telemetryProcessors) { ++ this._telemetryProcessors = undefined; ++ } ++ } ++ ++ public runTelemetryProcessors(): void { ++ throw new Error('unimplemented'); ++ } ++ ++ public trackTrace(): void { ++ throw new Error('unimplemented'); ++ } ++ ++ public trackMetric(): void { ++ throw new Error('unimplemented'); ++ } ++ ++ public trackException(): void { ++ throw new Error('unimplemented'); ++ } ++ ++ public trackRequest(): void { ++ throw new Error('unimplemented'); ++ } ++ ++ public trackDependency(): void { ++ throw new Error('unimplemented'); ++ } ++ ++ public track(): void { ++ throw new Error('unimplemented'); ++ } ++ ++ public trackNodeHttpRequestSync(): void { ++ throw new Error('unimplemented'); ++ } ++ ++ public trackNodeHttpRequest(): void { ++ throw new Error('unimplemented'); ++ } ++ ++ public trackNodeHttpDependency(): void { ++ throw new Error('unimplemented'); ++ } ++ ++ public trackEvent(options: appInsights.Contracts.EventTelemetry): void { ++ if (!options.properties) { ++ options.properties = {}; ++ } ++ if (!options.measurements) { ++ options.measurements = {}; ++ } ++ ++ try { ++ const cpus = os.cpus(); ++ options.measurements.cores = cpus.length; ++ options.properties['common.cpuModel'] = cpus[0].model; ++ } catch (error) {} ++ ++ try { ++ options.measurements.memoryFree = os.freemem(); ++ options.measurements.memoryTotal = os.totalmem(); ++ } catch (error) {} ++ ++ try { ++ options.properties['common.shell'] = os.userInfo().shell; ++ options.properties['common.release'] = os.release(); ++ options.properties['common.arch'] = os.arch(); ++ } catch (error) {} ++ ++ try { ++ const request = (/^http:/.test(this.endpoint) ? http : https).request(this.endpoint, { ++ method: 'POST', ++ headers: { ++ 'Content-Type': 'application/json', ++ }, ++ }); ++ request.on('error', () => { /* We don't care. */ }); ++ request.write(JSON.stringify(options)); ++ request.end(); ++ } catch (error) {} ++ } ++ ++ public flush(options: { callback: (v: string) => void }): void { ++ if (options.callback) { ++ options.callback(''); ++ } ++ } ++} +Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts ++++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts +@@ -304,6 +304,7 @@ export class WebClientServer { + logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined, + proxyEndpointTemplate: base + '/proxy/{{port}}', + codeServerVersion: this._productService.codeServerVersion, ++ enableTelemetry: this._productService.enableTelemetry, + embedderIdentifier: 'server-distro', + serviceWorker: { + scope: vscodeBase + '/', +Index: code-server/lib/vscode/src/vs/workbench/services/telemetry/browser/telemetryService.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/workbench/services/telemetry/browser/telemetryService.ts ++++ code-server/lib/vscode/src/vs/workbench/services/telemetry/browser/telemetryService.ts +@@ -119,16 +119,19 @@ export class TelemetryService extends Di + ) { + super(); + +- if (supportsTelemetry(productService, environmentService) && productService.aiConfig?.asimovKey) { ++ if (supportsTelemetry(productService, environmentService)) { + // If remote server is present send telemetry through that, else use the client side appender +- const telemetryProvider: ITelemetryAppender = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : new WebAppInsightsAppender('monacoworkbench', productService.aiConfig?.asimovKey); +- const config: ITelemetryServiceConfig = { +- appenders: [new WebTelemetryAppender(telemetryProvider), new TelemetryLogAppender(loggerService, environmentService)], +- commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.remoteAuthority, productService.embedderIdentifier, productService.removeTelemetryMachineId, environmentService.options && environmentService.options.resolveCommonTelemetryProperties), +- sendErrorTelemetry: this.sendErrorTelemetry, +- }; +- +- this.impl = this._register(new BaseTelemetryService(config, configurationService, productService)); ++ const telemetryProvider: ITelemetryAppender | undefined = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : productService.aiConfig?.asimovKey ? new WebAppInsightsAppender('monacoworkbench', productService.aiConfig?.asimovKey) : undefined; ++ if (telemetryProvider) { ++ const config: ITelemetryServiceConfig = { ++ appenders: [new WebTelemetryAppender(telemetryProvider), new TelemetryLogAppender(loggerService, environmentService)], ++ commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.remoteAuthority, productService.embedderIdentifier, productService.removeTelemetryMachineId, environmentService.options && environmentService.options.resolveCommonTelemetryProperties), ++ sendErrorTelemetry: this.sendErrorTelemetry, ++ }; ++ this.impl = this._register(new BaseTelemetryService(config, configurationService, productService)); ++ } else { ++ this.impl = NullTelemetryService; ++ } + } else { + this.impl = NullTelemetryService; + } From 66a364358a571deffaad27e4adf5c971db5d560a Mon Sep 17 00:00:00 2001 From: Feng Yu Date: Fri, 6 May 2022 22:57:19 +0800 Subject: [PATCH 36/55] chore: upgrade developmemt node version to v16 (#5167) Co-authored-by: yufeng.freeman --- .node-version | 2 +- docs/CONTRIBUTING.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.node-version b/.node-version index 8351c1939..b6a7d89c6 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -14 +16 diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index c12ff3020..0474de614 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -31,7 +31,7 @@ for [VS Code](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#prerequisites). Here is what is needed: -- `node` v14.x +- `node` v16.x - `git` v2.x or greater - [`git-lfs`](https://git-lfs.github.com) - [`yarn`](https://classic.yarnpkg.com/en/) From 5a5798e45f6bf79fccaaa1354af428cfe241178e Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Fri, 6 May 2022 09:51:44 -0700 Subject: [PATCH 37/55] fix(update): add OrEqual to update.checked test (#5171) * fix(update): add OrEqual to update.checked test * fixup!: change all instances to OrEqual * fixup!: add missing equals * fixup!: consistency --- test/unit/node/update.test.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/unit/node/update.test.ts b/test/unit/node/update.test.ts index 9aa6f75d7..d315e977c 100644 --- a/test/unit/node/update.test.ts +++ b/test/unit/node/update.test.ts @@ -131,7 +131,8 @@ describe("update", () => { await expect(settings().read()).resolves.toEqual({ update }) expect(isNaN(update.checked)).toEqual(false) - expect(update.checked < Date.now() && update.checked >= now).toEqual(true) + expect(update.checked).toBeGreaterThanOrEqual(now) + expect(update.checked).toBeLessThanOrEqual(Date.now()) expect(update.version).toStrictEqual("2.1.0") expect(spy).toEqual(["/latest"]) }) @@ -145,7 +146,7 @@ describe("update", () => { await expect(settings().read()).resolves.toEqual({ update }) expect(isNaN(update.checked)).toStrictEqual(false) - expect(update.checked).toBeLessThan(now) + expect(update.checked).toBeLessThanOrEqual(now) expect(update.version).toStrictEqual("2.1.0") expect(spy).toEqual([]) }) @@ -160,7 +161,7 @@ describe("update", () => { await expect(settings().read()).resolves.toEqual({ update }) expect(isNaN(update.checked)).toStrictEqual(false) expect(update.checked).toBeGreaterThanOrEqual(now) - expect(update.checked).toBeLessThan(Date.now()) + expect(update.checked).toBeLessThanOrEqual(Date.now()) expect(update.version).toStrictEqual("4.1.1") expect(spy).toStrictEqual(["/latest"]) }) @@ -206,7 +207,7 @@ describe("update", () => { let update = await provider.getUpdate(true) expect(isNaN(update.checked)).toStrictEqual(false) expect(update.checked).toBeGreaterThanOrEqual(now) - expect(update.checked).toBeLessThan(Date.now()) + expect(update.checked).toBeLessThanOrEqual(Date.now()) expect(update.version).toStrictEqual("unknown") provider = new UpdateProvider("http://probably.invalid.dev.localhost/latest", settings()) @@ -214,7 +215,7 @@ describe("update", () => { update = await provider.getUpdate(true) expect(isNaN(update.checked)).toStrictEqual(false) expect(update.checked).toBeGreaterThanOrEqual(now) - expect(update.checked).toBeLessThan(Date.now()) + expect(update.checked).toBeLessThanOrEqual(Date.now()) expect(update.version).toStrictEqual("unknown") }) From f735c87ac713c5c271c555579e432d5d6cb00831 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Fri, 6 May 2022 13:45:49 -0700 Subject: [PATCH 38/55] release: 4.4.0 (#5169) * chore(release): bump version to 4.4.0 * chore: update CHANGELOG with v4.4.0 * chore: bump version to 2.5.0 in Chart.yaml --- CHANGELOG.md | 27 ++++++++++++++++++++++++++- ci/helm-chart/Chart.yaml | 4 ++-- ci/helm-chart/values.yaml | 2 +- docs/MAINTAINING.md | 2 +- docs/collaboration.md | 2 +- docs/helm.md | 4 ++-- docs/manifest.json | 4 ++-- package.json | 2 +- 8 files changed, 36 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b994c6d7f..1ea050e25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,8 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Code v99.99.999 -### Added ### Changed +### Added ### Deprecated ### Removed ### Fixed @@ -20,6 +20,31 @@ Code v99.99.999 --> +## [4.4.0](https://github.com/coder/code-server/releases/tag/v4.4.0) - 2022-05-06 + +Code v1.66.2 + +### Changed + +- Refactored methods in `Heart` class and made `Heart.beat()` async to make + testing easier. +- Upgraded to Code 1.66.2. + +### Added + +- Added back telemetry patch which was removed in the Code reachitecture. +- Added support to use `true` for `CS_DISABLE_FILE_DOWNLOADS` environment + variable. This means you can disable file downloads by setting + `CS_DISABLE_FILE_DOWNLOADS` to `true` or `1`. +- Added tests for `Heart` class. + +### Fixed + +- Fixed installation issue in AUR after LICENSE rename. +- Fixed issue with listening on IPv6 addresses. +- Fixed issue with Docker publish action not being able to find artifacts. Now + it downloads the release assets from the release. + ## [4.3.0](https://github.com/coder/code-server/releases/tag/v4.3.0) - 2022-04-14 Code v1.65.2 diff --git a/ci/helm-chart/Chart.yaml b/ci/helm-chart/Chart.yaml index 3eeb0584b..8c7c21975 100644 --- a/ci/helm-chart/Chart.yaml +++ b/ci/helm-chart/Chart.yaml @@ -15,9 +15,9 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 2.4.0 +version: 2.5.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. -appVersion: 4.3.0 +appVersion: 4.4.0 diff --git a/ci/helm-chart/values.yaml b/ci/helm-chart/values.yaml index 6ea263c7f..898fd12b1 100644 --- a/ci/helm-chart/values.yaml +++ b/ci/helm-chart/values.yaml @@ -6,7 +6,7 @@ replicaCount: 1 image: repository: codercom/code-server - tag: '4.3.0' + tag: '4.4.0' pullPolicy: Always # Specifies one or more secrets to be used when pulling images from a diff --git a/docs/MAINTAINING.md b/docs/MAINTAINING.md index 0c55d4cff..ac7d03068 100644 --- a/docs/MAINTAINING.md +++ b/docs/MAINTAINING.md @@ -164,7 +164,7 @@ If you're the current release manager, follow these steps: ### Publishing a release -1. Create a new branch called `v0.0.0` (replace 0s with actual version aka v4.3.0) +1. Create a new branch called `v0.0.0` (replace 0s with actual version aka v4.4.0) 1. Run `yarn release:prep` and type in the new version (e.g., `3.8.1`) 1. GitHub Actions will generate the `npm-package`, `release-packages` and `release-images` artifacts. You do not have to wait for this step to complete diff --git a/docs/collaboration.md b/docs/collaboration.md index dda091545..e0ea18ef3 100644 --- a/docs/collaboration.md +++ b/docs/collaboration.md @@ -60,6 +60,6 @@ As `code-server` is based on VS Code, you can follow the steps described on Duck code-server --enable-proposed-api genuitecllc.codetogether ``` - Another option would be to add a value in code-server's [config file](https://coder.com/docs/code-server/v4.3.0/FAQ#how-does-the-config-file-work). + Another option would be to add a value in code-server's [config file](https://coder.com/docs/code-server/v4.4.0/FAQ#how-does-the-config-file-work). 3. Refresh code-server and navigate to the CodeTogether icon in the sidebar to host or join a coding session. diff --git a/docs/helm.md b/docs/helm.md index 7f3dfb7ab..078a3fa27 100644 --- a/docs/helm.md +++ b/docs/helm.md @@ -1,6 +1,6 @@ # code-server Helm Chart -[![Version: 1.0.0](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square)](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square) [![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)](https://img.shields.io/badge/Type-application-informational?style=flat-square) [![AppVersion: 4.3.0](https://img.shields.io/badge/AppVersion-4.3.0-informational?style=flat-square)](https://img.shields.io/badge/AppVersion-4.3.0-informational?style=flat-square) +[![Version: 1.0.0](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square)](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square) [![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)](https://img.shields.io/badge/Type-application-informational?style=flat-square) [![AppVersion: 4.4.0](https://img.shields.io/badge/AppVersion-4.4.0-informational?style=flat-square)](https://img.shields.io/badge/AppVersion-4.4.0-informational?style=flat-square) [code-server](https://github.com/coder/code-server) code-server is VS Code running on a remote server, accessible through the browser. @@ -73,7 +73,7 @@ and their default values. | hostnameOverride | string | `""` | | image.pullPolicy | string | `"Always"` | | image.repository | string | `"codercom/code-server"` | -| image.tag | string | `"4.3.0"` | +| image.tag | string | `"4.4.0"` | | imagePullSecrets | list | `[]` | | ingress.enabled | bool | `false` | | nameOverride | string | `""` | diff --git a/docs/manifest.json b/docs/manifest.json index 890ede663..30c9fde04 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -1,5 +1,5 @@ { - "versions": ["v4.3.0"], + "versions": ["v4.4.0"], "routes": [ { "title": "Home", @@ -73,7 +73,7 @@ { "title": "Upgrade", "description": "How to upgrade code-server.", - "icon": "", + "icon": "", "path": "./upgrade.md" }, { diff --git a/package.json b/package.json index be5253bb3..07e815d4b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-server", "license": "MIT", - "version": "4.3.0", + "version": "4.4.0", "description": "Run VS Code on a remote server.", "homepage": "https://github.com/coder/code-server", "bugs": { From 6cf607eab9d2da592795a7f8e9b30854492c2e80 Mon Sep 17 00:00:00 2001 From: Asher Date: Fri, 6 May 2022 16:57:22 -0500 Subject: [PATCH 39/55] fix: Docker push (#5175) The action actually does not support wildcards but it does support * for downloading all artifacts. --- .github/workflows/docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 4000c43c9..07c86dcb9 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -44,7 +44,7 @@ jobs: with: repository: "coder/code-server" tag: v${{ steps.version.outputs.version }} - fileName: "*.deb" + fileName: "*" out-file-path: "release-packages" - name: Publish to Docker From 60dd8ab37454aed0826e99d51073b477ee9604ee Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Fri, 6 May 2022 15:31:03 -0700 Subject: [PATCH 40/55] chore: configure git globally for brew publish (#5173) --- .github/workflows/npm-brew.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/npm-brew.yaml b/.github/workflows/npm-brew.yaml index 7ea182d8c..5df31ad99 100644 --- a/.github/workflows/npm-brew.yaml +++ b/.github/workflows/npm-brew.yaml @@ -60,8 +60,8 @@ jobs: - name: Configure git run: | - git config user.name cdrci - git config user.email opensource@coder.com + git config --global user.name cdrci + git config --global user.email opensource@coder.com - name: Bump code-server homebrew version env: From 7c1a45a8d806936839a4c1c374f750a39f1ed90b Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Fri, 6 May 2022 16:08:25 -0700 Subject: [PATCH 41/55] chore: update --help for disable-file-downloads (#5176) * chore: update --help for disable-file-downloads * fixup: formatting --- src/node/cli.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/node/cli.ts b/src/node/cli.ts index 6c33060cd..97d02a4e9 100644 --- a/src/node/cli.ts +++ b/src/node/cli.ts @@ -160,7 +160,8 @@ export const options: Options> = { }, "disable-file-downloads": { type: "boolean", - description: "Disable file downloads from Code.", + description: + "Disable file downloads from Code. This can also be set with CS_DISABLE_FILE_DOWNLOADS set to 'true' or '1'.", }, // --enable can be used to enable experimental features. These features // provide no guarantees. From 3207bfd4ada744be29e82e047916c174c96688a2 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Mon, 9 May 2022 16:24:40 -0700 Subject: [PATCH 42/55] feat: add test for isFile when error (#5182) This adds an additional test for the `isFile` utility function to ensure it returns `false` in the event of an error. --- test/unit/node/util.test.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/unit/node/util.test.ts b/test/unit/node/util.test.ts index a86e9d066..1455a7e07 100644 --- a/test/unit/node/util.test.ts +++ b/test/unit/node/util.test.ts @@ -446,6 +446,9 @@ describe("isFile", () => { it("should return true if is file", async () => { expect(await util.isFile(pathToFile)).toBe(true) }) + it("should return false if error", async () => { + expect(await util.isFile("fakefile.txt")).toBe(false) + }) }) describe("humanPath", () => { From cd78f32dc06f7f3ea518872df314b72f3cfafacd Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Mon, 9 May 2022 17:24:25 -0700 Subject: [PATCH 43/55] refactor(util): remove unused isObject function (#5183) --- src/node/util.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/node/util.ts b/src/node/util.ts index b53a4ecf6..e33ad95bf 100644 --- a/src/node/util.ts +++ b/src/node/util.ts @@ -435,10 +435,6 @@ export const buildAllowedMessage = (t: any): string => { return `Allowed value${values.length === 1 ? " is" : "s are"} ${values.map((t) => `'${t}'`).join(", ")}` } -export const isObject = (obj: T): obj is T => { - return !Array.isArray(obj) && typeof obj === "object" && obj !== null -} - /** * Return a promise that resolves with whether the socket path is active. */ From 55006ccb5a91bb0b888c8c0ffa1bd4ecf2fe3c64 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 10 May 2022 12:37:05 -0700 Subject: [PATCH 44/55] chore(deps): update docker/login-action action to v2 (#5163) Co-authored-by: Renovate Bot --- .github/workflows/docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 07c86dcb9..b7460d3f0 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -30,7 +30,7 @@ jobs: uses: docker/setup-buildx-action@v1 - name: Login to Docker Hub - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} From 53b5d41271820ac525132e1e808d25047feafae5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 10 May 2022 13:13:45 -0700 Subject: [PATCH 45/55] chore(deps): update docker/setup-buildx-action action to v2 (#5164) Co-authored-by: Renovate Bot Co-authored-by: Joe Previte --- .github/workflows/docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index b7460d3f0..b7659079f 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -27,7 +27,7 @@ jobs: uses: docker/setup-qemu-action@v1 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Login to Docker Hub uses: docker/login-action@v2 From 0155a12500d2b6b7fe1ec26b9b456f3e32178df2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 10 May 2022 20:35:25 +0000 Subject: [PATCH 46/55] chore(deps): update docker/setup-qemu-action action to v2 (#5166) Co-authored-by: Renovate Bot Co-authored-by: Joe Previte --- .github/workflows/docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index b7659079f..3d05e7543 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -24,7 +24,7 @@ jobs: uses: actions/checkout@v3 - name: Set up QEMU - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 From 1788537cce0df425b15e1e8e76c4faf05d1c0c89 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 10 May 2022 21:01:13 +0000 Subject: [PATCH 47/55] chore(deps): update minor dependency updates (#5181) Co-authored-by: Renovate Bot --- .github/workflows/ci.yaml | 2 +- .github/workflows/trivy-docker.yaml | 2 +- package.json | 2 +- yarn.lock | 97 ++++------------------------- 4 files changed, 15 insertions(+), 88 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 1e213f0ad..c7f7f6033 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -506,7 +506,7 @@ jobs: fetch-depth: 0 - name: Run Trivy vulnerability scanner in repo mode - uses: aquasecurity/trivy-action@2b30463ddb3d11724a04e760e020c7d9af24d8b3 + uses: aquasecurity/trivy-action@4b9b6fb4ef28b31450391a93ade098bb00de584e with: scan-type: "fs" scan-ref: "." diff --git a/.github/workflows/trivy-docker.yaml b/.github/workflows/trivy-docker.yaml index e54f02c21..e6eb4cc3a 100644 --- a/.github/workflows/trivy-docker.yaml +++ b/.github/workflows/trivy-docker.yaml @@ -51,7 +51,7 @@ jobs: uses: actions/checkout@v3 - name: Run Trivy vulnerability scanner in image mode - uses: aquasecurity/trivy-action@2b30463ddb3d11724a04e760e020c7d9af24d8b3 + uses: aquasecurity/trivy-action@4b9b6fb4ef28b31450391a93ade098bb00de584e with: image-ref: "docker.io/codercom/code-server:latest" ignore-unfixed: true diff --git a/package.json b/package.json index 07e815d4b..2cc17000a 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "eslint-plugin-prettier": "^4.0.0", "json": "^11.0.0", "prettier": "^2.2.1", - "prettier-plugin-sh": "^0.10.0", + "prettier-plugin-sh": "^0.11.0", "shellcheck": "^1.0.0", "stylelint": "^13.0.0", "stylelint-config-recommended": "^5.0.0", diff --git a/yarn.lock b/yarn.lock index 561b76cdc..6512f404d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -276,18 +276,6 @@ resolved "https://registry.yarnpkg.com/@phc/format/-/format-1.0.0.tgz#b5627003b3216dc4362125b13f48a4daa76680e4" integrity sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ== -"@pkgr/utils@^2.0.3": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.1.0.tgz#66a4be2df4fc8ae50d730666855f6a6df833a725" - integrity sha512-Va5LTLVoPIH8CrV170zXLSDtCJ6eG6uVXYwwsDYOOeec0MdkhvJzKaxvA+hGJRWFl5I4VBQBs5pwljaI4TG5OA== - dependencies: - cross-spawn "^7.0.3" - is-glob "^4.0.3" - open "^8.4.0" - picocolors "^1.0.0" - tiny-glob "^0.2.9" - tslib "^2.3.1" - "@schemastore/package@^0.0.6": version "0.0.6" resolved "https://registry.yarnpkg.com/@schemastore/package/-/package-0.0.6.tgz#9a76713da1c7551293b7e72e4f387f802bfd5d81" @@ -1282,11 +1270,6 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== -define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" - integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== - define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -2121,11 +2104,6 @@ globals@^13.6.0, globals@^13.9.0: dependencies: type-fest "^0.20.2" -globalyzer@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/globalyzer/-/globalyzer-0.1.0.tgz#cb76da79555669a1519d5a8edf093afaa0bf1465" - integrity sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q== - globby@^11.0.3: version "11.0.3" resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" @@ -2155,11 +2133,6 @@ globjoin@^0.1.4: resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43" integrity sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM= -globrex@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098" - integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg== - gonzales-pe@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/gonzales-pe/-/gonzales-pe-4.3.0.tgz#fe9dec5f3c557eead09ff868c65826be54d067b3" @@ -2461,11 +2434,6 @@ is-decimal@^1.0.0: resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== -is-docker@^2.0.0, is-docker@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - is-extendable@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -2575,13 +2543,6 @@ is-word-character@^1.0.0: resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.4.tgz#ce0e73216f98599060592f62ff31354ddbeb0230" integrity sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA== -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" @@ -3010,7 +2971,12 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -nanoid@^3.1.23, nanoid@^3.1.31, nanoid@^3.3.2: +mvdan-sh@^0.10.1: + version "0.10.1" + resolved "https://registry.yarnpkg.com/mvdan-sh/-/mvdan-sh-0.10.1.tgz#5b3a4462a89cf20739b12d851589342c875f4d1f" + integrity sha512-kMbrH0EObaKmK3nVRKUIIya1dpASHIEusM13S4V1ViHFuxuNxCo+arxoa6j/dbV22YBGjl7UKJm9QQKJ2Crzhg== + +nanoid@^3.1.23, nanoid@^3.1.31: version "3.2.0" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== @@ -3150,15 +3116,6 @@ once@^1.3.0: dependencies: wrappy "1" -open@^8.4.0: - version "8.4.0" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" - integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - opencollective-postinstall@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259" @@ -3368,11 +3325,6 @@ pem@^1.14.2: os-tmpdir "^1.0.1" which "^2.0.2" -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" @@ -3492,13 +3444,12 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier-plugin-sh@^0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/prettier-plugin-sh/-/prettier-plugin-sh-0.10.1.tgz#70951b933238803fa67a0d5752d6667963130057" - integrity sha512-bEcEMvgivqNB/9r9UIN6CTPoux7pmZKFtzDkEb/hSwj/j/PlHfNpiOwLtDZ44D8RtUAZloMz7j1ucqdPqcTawQ== +prettier-plugin-sh@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/prettier-plugin-sh/-/prettier-plugin-sh-0.11.0.tgz#b65974d49d93d7f303c3513e218741f2d4820e98" + integrity sha512-YwuWGYuf6UiF80BZ3Lrby2yot0zRcktcBl+VD/xSLoPrmiH/yXcopz3RBtNMNcBeP13ALim9N/LtlTCmvUziVQ== dependencies: - sh-syntax "^0.1.4" - synckit "^0.7.0" + mvdan-sh "^0.10.1" prettier@^2.2.1: version "2.3.2" @@ -3887,14 +3838,6 @@ setprototypeof@1.2.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== -sh-syntax@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/sh-syntax/-/sh-syntax-0.1.4.tgz#a63eb87571161c89f4a027085be6745b0154429c" - integrity sha512-PbReZBaylc3YSo+SbZQd5b8/I0jh8CQTdy5YRBNSVtIyuJ+l1dCygR8UhWBMz3p431ZDs2Wp59qUpIUvPCcssA== - dependencies: - nanoid "^3.3.2" - tslib "^2.3.1" - shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -4254,14 +4197,6 @@ svg-tags@^1.0.0: resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" integrity sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q= -synckit@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.7.0.tgz#59abd4ec3ee4e7b645dbd1e6e188920c9494392c" - integrity sha512-NbpamGIw1300xjPCLCVkhtSgGVfONitrmJA4CD54f2P47GxW5rlsCiajAYrqbz0H0PmVSPA2slZjEfJpUfap0Q== - dependencies: - "@pkgr/utils" "^2.0.3" - tslib "^2.3.1" - synp@^1.9.10: version "1.9.10" resolved "https://registry.yarnpkg.com/synp/-/synp-1.9.10.tgz#53163321a600418c9b06af0db499939ffce12907" @@ -4322,14 +4257,6 @@ through@2, "through@>=2.2.7 <3", through@^2.3.8, through@~2.3, through@~2.3.4: resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= -tiny-glob@^0.2.9: - version "0.2.9" - resolved "https://registry.yarnpkg.com/tiny-glob/-/tiny-glob-0.2.9.tgz#2212d441ac17928033b110f8b3640683129d31e2" - integrity sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg== - dependencies: - globalyzer "0.1.0" - globrex "^0.1.2" - to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -4413,7 +4340,7 @@ tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.1, tslib@^2.3.1: +tslib@^2.0.1: version "2.3.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== From 7a8d487729d5c74575503138bbc6e91818a9657a Mon Sep 17 00:00:00 2001 From: Devin Buhl Date: Tue, 10 May 2022 17:11:06 -0400 Subject: [PATCH 48/55] chore: push code-server image to GHCR (#5187) --- .github/workflows/docker.yaml | 7 +++++++ ci/release-image/docker-bake.hcl | 2 ++ 2 files changed, 9 insertions(+) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 3d05e7543..e97815ca4 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -35,6 +35,13 @@ jobs: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} + - name: Login to GHCR + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Get version id: version run: echo "::set-output name=version::$(jq -r .version package.json)" diff --git a/ci/release-image/docker-bake.hcl b/ci/release-image/docker-bake.hcl index cb55da69c..27bf2194f 100644 --- a/ci/release-image/docker-bake.hcl +++ b/ci/release-image/docker-bake.hcl @@ -15,6 +15,8 @@ target "code-server" { tags = [ "docker.io/codercom/code-server:latest", notequal("latest",VERSION) ? "docker.io/codercom/code-server:${VERSION}" : "", + "ghcr.io/coder/code-server:latest", + notequal("latest",VERSION) ? "ghcr.io/coder/code-server:${VERSION}" : "", ] platforms = ["linux/amd64", "linux/arm64"] } From b13849ded0796c8a0a8be8f371fa3b0b16a1d768 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Tue, 10 May 2022 15:44:54 -0700 Subject: [PATCH 49/55] refactor: remove dead code (#5188) * refactor: delete unused code * refactor: move onLine to test helpers * Revert "refactor: move onLine to test helpers" This reverts commit 32cc27b21361f88ac7d0457f9e2b3906f2f94fe1. * fixup! refactor: delete unused code --- src/common/util.ts | 30 -------------------- src/node/app.ts | 23 ---------------- src/node/constants.ts | 3 -- src/node/util.ts | 9 ------ test/unit/common/util.test.ts | 47 -------------------------------- test/unit/node/app.test.ts | 34 +---------------------- test/unit/node/constants.test.ts | 4 --- 7 files changed, 1 insertion(+), 149 deletions(-) diff --git a/src/common/util.ts b/src/common/util.ts index 191c907ab..6639beca4 100644 --- a/src/common/util.ts +++ b/src/common/util.ts @@ -1,12 +1,3 @@ -/** - * Split a string up to the delimiter. If the delimiter doesn't exist the first - * item will have all the text and the second item will be an empty string. - */ -export const split = (str: string, delimiter: string): [string, string] => { - const index = str.indexOf(delimiter) - return index !== -1 ? [str.substring(0, index).trim(), str.substring(index + 1)] : [str, ""] -} - /** * Appends an 's' to the provided string if count is greater than one; * otherwise the string is returned @@ -34,27 +25,6 @@ export const normalize = (url: string, keepTrailing = false): string => { return url.replace(/\/\/+/g, "/").replace(/\/+$/, keepTrailing ? "/" : "") } -/** - * Remove leading and trailing slashes. - */ -export const trimSlashes = (url: string): string => { - return url.replace(/^\/+|\/+$/g, "") -} - -/** - * Wrap the value in an array if it's not already an array. If the value is - * undefined return an empty array. - */ -export const arrayify = (value?: T | T[]): T[] => { - if (Array.isArray(value)) { - return value - } - if (typeof value === "undefined") { - return [] - } - return [value] -} - // TODO: Might make sense to add Error handling to the logger itself. export function logError(logger: { error: (msg: string) => void }, prefix: string, err: unknown): void { if (err instanceof Error) { diff --git a/src/node/app.ts b/src/node/app.ts index aece0432c..3e6e4bfa0 100644 --- a/src/node/app.ts +++ b/src/node/app.ts @@ -102,29 +102,6 @@ export const ensureAddress = (server: http.Server, protocol: string): URL | stri return addr } -/** - * Handles error events from the server. - * - * If the outlying Promise didn't resolve - * then we reject with the error. - * - * Otherwise, we log the error. - * - * We extracted into a function so that we could - * test this logic more easily. - */ -export const handleServerError = (resolved: boolean, err: Error, reject: (err: Error) => void) => { - // Promise didn't resolve earlier so this means it's an error - // that occurs before the server can successfully listen. - // Possibly triggered by listening on an invalid port or socket. - if (!resolved) { - reject(err) - } else { - // Promise resolved earlier so this is an unrelated error. - util.logError(logger, "http server error", err) - } -} - /** * Handles the error that occurs in the catch block * after we try fs.unlink(args.socket). diff --git a/src/node/constants.ts b/src/node/constants.ts index c85e0a7b0..bb6873dfa 100644 --- a/src/node/constants.ts +++ b/src/node/constants.ts @@ -3,8 +3,6 @@ import type { JSONSchemaForNPMPackageJsonFiles } from "@schemastore/package" import * as os from "os" import * as path from "path" -export const WORKBENCH_WEB_CONFIG_ID = "vscode-workbench-web-configuration" - export function getPackageJson(relativePath: string): JSONSchemaForNPMPackageJsonFiles { let pkg = {} try { @@ -21,7 +19,6 @@ export const vsRootPath = path.join(rootPath, "lib/vscode") const PACKAGE_JSON = "package.json" const pkg = getPackageJson(`${rootPath}/${PACKAGE_JSON}`) const codePkg = getPackageJson(`${vsRootPath}/${PACKAGE_JSON}`) || { version: "0.0.0" } -export const pkgName = pkg.name || "code-server" export const version = pkg.version || "development" export const commit = pkg.commit || "development" export const codeVersion = codePkg.version || "development" diff --git a/src/node/util.ts b/src/node/util.ts index e33ad95bf..1bf43cd89 100644 --- a/src/node/util.ts +++ b/src/node/util.ts @@ -426,15 +426,6 @@ export const enumToArray = (t: any): string[] => { return values } -/** - * For displaying all allowed options in an enum. - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export const buildAllowedMessage = (t: any): string => { - const values = enumToArray(t) - return `Allowed value${values.length === 1 ? " is" : "s are"} ${values.map((t) => `'${t}'`).join(", ")}` -} - /** * Return a promise that resolves with whether the socket path is active. */ diff --git a/test/unit/common/util.test.ts b/test/unit/common/util.test.ts index eef219210..9e17b5734 100644 --- a/test/unit/common/util.test.ts +++ b/test/unit/common/util.test.ts @@ -24,16 +24,6 @@ describe("util", () => { }) }) - describe("split", () => { - it("should split at a comma", () => { - expect(util.split("Hello,world", ",")).toStrictEqual(["Hello", "world"]) - }) - - it("shouldn't split if the delimiter doesn't exist", () => { - expect(util.split("Hello world", ",")).toStrictEqual(["Hello world", ""]) - }) - }) - describe("plural", () => { it("should add an s if count is greater than 1", () => { expect(util.plural(2, "dog")).toBe("dogs") @@ -57,43 +47,6 @@ describe("util", () => { }) }) - describe("trimSlashes", () => { - it("should remove leading slashes", () => { - expect(util.trimSlashes("/hello-world")).toBe("hello-world") - }) - - it("should remove trailing slashes", () => { - expect(util.trimSlashes("hello-world/")).toBe("hello-world") - }) - - it("should remove both leading and trailing slashes", () => { - expect(util.trimSlashes("/hello-world/")).toBe("hello-world") - }) - - it("should remove multiple leading and trailing slashes", () => { - expect(util.trimSlashes("///hello-world////")).toBe("hello-world") - }) - }) - - describe("arrayify", () => { - it("should return value it's already an array", () => { - expect(util.arrayify(["hello", "world"])).toStrictEqual(["hello", "world"]) - }) - - it("should wrap the value in an array if not an array", () => { - expect( - util.arrayify({ - name: "Coder", - version: "3.8", - }), - ).toStrictEqual([{ name: "Coder", version: "3.8" }]) - }) - - it("should return an empty array if the value is undefined", () => { - expect(util.arrayify(undefined)).toStrictEqual([]) - }) - }) - describe("logError", () => { beforeAll(() => { mockLogger() diff --git a/test/unit/node/app.test.ts b/test/unit/node/app.test.ts index 56c0e70dd..b2c169a2e 100644 --- a/test/unit/node/app.test.ts +++ b/test/unit/node/app.test.ts @@ -3,7 +3,7 @@ import { promises } from "fs" import * as http from "http" import * as https from "https" import * as path from "path" -import { createApp, ensureAddress, handleArgsSocketCatchError, handleServerError, listen } from "../../../src/node/app" +import { createApp, ensureAddress, handleArgsSocketCatchError, listen } from "../../../src/node/app" import { OptionalString, setDefaults } from "../../../src/node/cli" import { generateCertificate } from "../../../src/node/util" import { clean, mockLogger, getAvailablePort, tmpdir } from "../../utils/helpers" @@ -169,38 +169,6 @@ describe("ensureAddress", () => { }) }) -describe("handleServerError", () => { - beforeAll(() => { - mockLogger() - }) - - afterEach(() => { - jest.clearAllMocks() - }) - - it("should call reject if resolved is false", async () => { - const resolved = false - const reject = jest.fn((err: Error) => undefined) - const error = new Error("handleServerError Error") - - handleServerError(resolved, error, reject) - - expect(reject).toHaveBeenCalledTimes(1) - expect(reject).toHaveBeenCalledWith(error) - }) - - it("should log an error if resolved is true", async () => { - const resolved = true - const reject = jest.fn((err: Error) => undefined) - const error = new Error("handleServerError Error") - - handleServerError(resolved, error, reject) - - expect(logger.error).toHaveBeenCalledTimes(1) - expect(logger.error).toHaveBeenCalledWith(`http server error: ${error.message} ${error.stack}`) - }) -}) - describe("handleArgsSocketCatchError", () => { beforeAll(() => { mockLogger() diff --git a/test/unit/node/constants.test.ts b/test/unit/node/constants.test.ts index 38affbb87..2ed963f87 100644 --- a/test/unit/node/constants.test.ts +++ b/test/unit/node/constants.test.ts @@ -34,10 +34,6 @@ describe("constants", () => { jest.resetModules() }) - it("should provide the package name", () => { - expect(constants.pkgName).toBe(mockPackageJson.name) - }) - it("should provide the commit", () => { expect(constants.commit).toBe(mockPackageJson.commit) }) From a02f47714e7c2b460fb26829464aa23d30002bc0 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Tue, 10 May 2022 23:26:04 +0000 Subject: [PATCH 50/55] refactor: remove unused code enumToArray --- src/node/util.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/node/util.ts b/src/node/util.ts index 1bf43cd89..e33ed4585 100644 --- a/src/node/util.ts +++ b/src/node/util.ts @@ -414,18 +414,6 @@ export const open = async (address: URL | string): Promise => { }) } -/** - * For iterating over an enum's values. - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export const enumToArray = (t: any): string[] => { - const values = [] as string[] - for (const k in t) { - values.push(t[k]) - } - return values -} - /** * Return a promise that resolves with whether the socket path is active. */ From dedd770a787fba3411c2a3976b3a8fa87cb7a6e5 Mon Sep 17 00:00:00 2001 From: Feng Yu Date: Thu, 12 May 2022 05:39:57 +0800 Subject: [PATCH 51/55] docs: rename master to main in all github doc links (#5190) * docs: correct link master -> main * fix missing ] --- .tours/contributing.tour | 10 +++++----- .tours/start-development.tour | 6 +++--- ci/build/npm-postinstall.sh | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.tours/contributing.tour b/.tours/contributing.tour index 970543343..aaff2b500 100644 --- a/.tours/contributing.tour +++ b/.tours/contributing.tour @@ -50,7 +50,7 @@ { "file": "src/node/heart.ts", "line": 7, - "description": "code-server's heart beats to indicate recent activity.\n\nAlso documented here: [https://github.com/coder/code-server/blob/master/docs/FAQ.md#heartbeat-file](https://github.com/coder/code-server/blob/master/docs/FAQ.md#heartbeat-file)" + "description": "code-server's heart beats to indicate recent activity.\n\nAlso documented here: [https://github.com/coder/code-server/blob/main/docs/FAQ.md#heartbeat-file](https://github.com/coder/code-server/blob/main/docs/FAQ.md#heartbeat-file)" }, { "file": "src/node/socket.ts", @@ -80,12 +80,12 @@ { "file": "src/node/routes/domainProxy.ts", "line": 18, - "description": "code-server provides a built-in proxy to help in developing web-based applications. This is the code for the domain-based proxy.\n\nAlso documented here: [https://github.com/coder/code-server/blob/master/docs/FAQ.md#how-do-i-securely-access-web-services](https://github.com/coder/code-server/blob/master/docs/FAQ.md#how-do-i-securely-access-web-services)" + "description": "code-server provides a built-in proxy to help in developing web-based applications. This is the code for the domain-based proxy.\n\nAlso documented here: [https://github.com/coder/code-server/blob/main/docs/FAQ.md#how-do-i-securely-access-web-services](https://github.com/coder/code-server/blob/main/docs/FAQ.md#how-do-i-securely-access-web-services)" }, { "file": "src/node/routes/pathProxy.ts", "line": 19, - "description": "Here is the path-based version of the proxy.\n\nAlso documented here: [https://github.com/coder/code-server/blob/master/docs/FAQ.md#how-do-i-securely-access-web-services](https://github.com/coder/code-server/blob/master/docs/FAQ.md#how-do-i-securely-access-web-services)" + "description": "Here is the path-based version of the proxy.\n\nAlso documented here: [https://github.com/coder/code-server/blob/main/docs/FAQ.md#how-do-i-securely-access-web-services](https://github.com/coder/code-server/blob/main/docs/FAQ.md#how-do-i-securely-access-web-services)" }, { "file": "src/node/proxy.ts", @@ -95,7 +95,7 @@ { "file": "src/node/routes/health.ts", "line": 5, - "description": "A simple endpoint that lets you see if code-server is up.\n\nAlso documented here: [https://github.com/coder/code-server/blob/master/docs/FAQ.md#healthz-endpoint](https://github.com/coder/code-server/blob/master/docs/FAQ.md#healthz-endpoint)" + "description": "A simple endpoint that lets you see if code-server is up.\n\nAlso documented here: [https://github.com/coder/code-server/blob/main/docs/FAQ.md#healthz-endpoint](https://github.com/coder/code-server/blob/main/docs/FAQ.md#healthz-endpoint)" }, { "file": "src/node/routes/login.ts", @@ -145,7 +145,7 @@ { "directory": "lib/vscode", "line": 1, - "description": "code-server makes use of VS Code's frontend web/remote support. Most of the modifications implement the remote server since that portion of the code is closed source and not released with VS Code.\n\nWe also have a few bug fixes and have added some features (like client-side extensions). See [https://github.com/coder/code-server/blob/master/docs/CONTRIBUTING.md#modifications-to-vs-code](https://github.com/coder/code-server/blob/master/docs/CONTRIBUTING.md#modifications-to-vs-code) for a list.\n\nWe make an effort to keep the modifications as few as possible." + "description": "code-server makes use of VS Code's frontend web/remote support. Most of the modifications implement the remote server since that portion of the code is closed source and not released with VS Code.\n\nWe also have a few bug fixes and have added some features (like client-side extensions). See [https://github.com/coder/code-server/blob/main/docs/CONTRIBUTING.md#modifications-to-vs-code](https://github.com/coder/code-server/blob/main/docs/CONTRIBUTING.md#modifications-to-vs-code) for a list.\n\nWe make an effort to keep the modifications as few as possible." } ] } diff --git a/.tours/start-development.tour b/.tours/start-development.tour index 168dce241..8ce815c5a 100644 --- a/.tours/start-development.tour +++ b/.tours/start-development.tour @@ -5,7 +5,7 @@ { "file": "package.json", "line": 31, - "description": "## Commands\n\nTo start developing, make sure you have Node 14+ and the [required dependencies](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#prerequisites) installed. Then, run the following commands:\n\n1. Install dependencies:\n>> yarn\n\n3. Start development mode (and watch for changes):\n>> yarn watch" + "description": "## Commands\n\nTo start developing, make sure you have Node 16+ and the [required dependencies](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#prerequisites) installed. Then, run the following commands:\n\n1. Install dependencies:\n>> yarn\n\n3. Start development mode (and watch for changes):\n>> yarn watch" }, { "file": "src/node/app.ts", @@ -20,7 +20,7 @@ { "file": "src/node/app.ts", "line": 62, - "description": "## That's it!\n\n\nThat's all there is to it! When this tour ends, your terminal session may stop, but just use `yarn watch` to start developing from here on out!\n\n\nIf you haven't already, be sure to check out these resources:\n- [Tour: Contributing](command:codetour.startTourByTitle?[\"Contributing\")\n- [Docs: FAQ.md](https://github.com/coder/code-server/blob/master/docs/FAQ.md)\n- [Docs: CONTRIBUTING.md](https://github.com/coder/code-server/blob/master/docs/CONTRIBUTING.md)\n- [Community: GitHub Discussions](https://github.com/coder/code-server/discussions)\n- [Community: Slack](https://community.coder.com)" + "description": "## That's it!\n\n\nThat's all there is to it! When this tour ends, your terminal session may stop, but just use `yarn watch` to start developing from here on out!\n\n\nIf you haven't already, be sure to check out these resources:\n- [Tour: Contributing](command:codetour.startTourByTitle?[\"Contributing\"])\n- [Docs: FAQ.md](https://github.com/coder/code-server/blob/main/docs/FAQ.md)\n- [Docs: CONTRIBUTING.md](https://github.com/coder/code-server/blob/main/docs/CONTRIBUTING.md)\n- [Community: GitHub Discussions](https://github.com/coder/code-server/discussions)\n- [Community: Slack](https://community.coder.com)" } ] -} +} \ No newline at end of file diff --git a/ci/build/npm-postinstall.sh b/ci/build/npm-postinstall.sh index d98bd992d..cc40fd291 100755 --- a/ci/build/npm-postinstall.sh +++ b/ci/build/npm-postinstall.sh @@ -68,7 +68,7 @@ main() { if ! vscode_yarn; then echo "You may not have the required dependencies to build the native modules." - echo "Please see https://github.com/coder/code-server/blob/master/docs/npm.md" + echo "Please see https://github.com/coder/code-server/blob/main/docs/npm.md" exit 1 fi From 5276e41606c89c3e9d55e87c2995d4c7be02f74d Mon Sep 17 00:00:00 2001 From: djarbz <30350993+djarbz@users.noreply.github.com> Date: Wed, 11 May 2022 17:10:04 -0500 Subject: [PATCH 52/55] Allow user Entrypoint scripts (#5194) * Allow user Entrypoint scripts * Variable encapsulation Co-authored-by: Asher * Check if Entrypoint Dir exists & run all executable * Don't create entrypoint.d by default * yarn fmt * yarn fmt * Fix for SC2044 * Revert "yarn fmt" This reverts commit 5ca347f36155ec731587c1ed8437bca332c76693. Co-authored-by: Asher --- ci/release-image/Dockerfile | 4 ++++ ci/release-image/entrypoint.sh | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/ci/release-image/Dockerfile b/ci/release-image/Dockerfile index f665a1588..c0eaa3de1 100644 --- a/ci/release-image/Dockerfile +++ b/ci/release-image/Dockerfile @@ -42,6 +42,10 @@ RUN ARCH="$(dpkg --print-architecture)" && \ COPY ci/release-image/entrypoint.sh /usr/bin/entrypoint.sh RUN --mount=from=packages,src=/tmp,dst=/tmp/packages dpkg -i /tmp/packages/code-server*$(dpkg --print-architecture).deb +# Allow users to have scripts run on container startup to prepare workspace. +# https://github.com/coder/code-server/issues/5177 +ENV ENTRYPOINTD=${HOME}/entrypoint.d + EXPOSE 8080 # This way, if someone sets $DOCKER_USER, docker-exec will still work as # the uid will remain the same. note: only relevant if -u isn't passed to diff --git a/ci/release-image/entrypoint.sh b/ci/release-image/entrypoint.sh index 9af98fbc3..460b559ba 100755 --- a/ci/release-image/entrypoint.sh +++ b/ci/release-image/entrypoint.sh @@ -18,4 +18,10 @@ if [ "${DOCKER_USER-}" ]; then fi fi +# Allow users to have scripts run on container startup to prepare workspace. +# https://github.com/coder/code-server/issues/5177 +if [ -d "${ENTRYPOINTD}" ]; then + find "${ENTRYPOINTD}" -type f -executable -print -exec {} \; +fi + exec dumb-init /usr/bin/code-server "$@" From 1e304b1e7d3b5cd0edb1aa35edbbe74cd79254c2 Mon Sep 17 00:00:00 2001 From: Feng Yu Date: Sat, 14 May 2022 00:57:50 +0800 Subject: [PATCH 53/55] chore(deps): upgrade typescript to v4.6 (#5202) --- package.json | 6 +-- yarn.lock | 112 ++++++++++++++++++++++++++++----------------------- 2 files changed, 64 insertions(+), 54 deletions(-) diff --git a/package.json b/package.json index 2cc17000a..420c71d53 100644 --- a/package.json +++ b/package.json @@ -50,8 +50,8 @@ "@types/split2": "^3.2.0", "@types/trusted-types": "^2.0.2", "@types/ws": "^8.0.0", - "@typescript-eslint/eslint-plugin": "^5.0.0", - "@typescript-eslint/parser": "^5.0.0", + "@typescript-eslint/eslint-plugin": "^5.23.0", + "@typescript-eslint/parser": "^5.23.0", "audit-ci": "^6.0.0", "codecov": "^3.8.3", "doctoc": "^2.0.0", @@ -68,7 +68,7 @@ "stylelint-config-recommended": "^5.0.0", "synp": "^1.9.10", "ts-node": "^10.0.0", - "typescript": "^4.4.0-dev.20210528" + "typescript": "^4.6.2" }, "resolutions": { "ansi-regex": "^5.0.1", diff --git a/yarn.lock b/yarn.lock index 6512f404d..904676f8e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -507,13 +507,14 @@ dependencies: "@types/node" "*" -"@typescript-eslint/eslint-plugin@^5.0.0": - version "5.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.2.0.tgz#2bdb247cc2e2afce7efbce09afb9a6f0a8a08434" - integrity sha512-qQwg7sqYkBF4CIQSyRQyqsYvP+g/J0To9ZPVNJpfxfekl5RmdvQnFFTVVwpRtaUDFNvjfe/34TgY/dpc3MgNTw== +"@typescript-eslint/eslint-plugin@^5.23.0": + version "5.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.23.0.tgz#bc4cbcf91fbbcc2e47e534774781b82ae25cc3d8" + integrity sha512-hEcSmG4XodSLiAp1uxv/OQSGsDY6QN3TcRU32gANp+19wGE1QQZLRS8/GV58VRUoXhnkuJ3ZxNQ3T6Z6zM59DA== dependencies: - "@typescript-eslint/experimental-utils" "5.2.0" - "@typescript-eslint/scope-manager" "5.2.0" + "@typescript-eslint/scope-manager" "5.23.0" + "@typescript-eslint/type-utils" "5.23.0" + "@typescript-eslint/utils" "5.23.0" debug "^4.3.2" functional-red-black-tree "^1.0.1" ignore "^5.1.8" @@ -521,60 +522,69 @@ semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@5.2.0": - version "5.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.2.0.tgz#e3b2cb9cd0aff9b50f68d9a414c299fd26b067e6" - integrity sha512-fWyT3Agf7n7HuZZRpvUYdFYbPk3iDCq6fgu3ulia4c7yxmPnwVBovdSOX7RL+k8u6hLbrXcdAehlWUVpGh6IEw== +"@typescript-eslint/parser@^5.23.0": + version "5.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.23.0.tgz#443778e1afc9a8ff180f91b5e260ac3bec5e2de1" + integrity sha512-V06cYUkqcGqpFjb8ttVgzNF53tgbB/KoQT/iB++DOIExKmzI9vBJKjZKt/6FuV9c+zrDsvJKbJ2DOCYwX91cbw== dependencies: - "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.2.0" - "@typescript-eslint/types" "5.2.0" - "@typescript-eslint/typescript-estree" "5.2.0" - eslint-scope "^5.1.1" - eslint-utils "^3.0.0" - -"@typescript-eslint/parser@^5.0.0": - version "5.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.2.0.tgz#dc081aa89de16b5676b10215519af3aa7b58fb72" - integrity sha512-Uyy4TjJBlh3NuA8/4yIQptyJb95Qz5PX//6p8n7zG0QnN4o3NF9Je3JHbVU7fxf5ncSXTmnvMtd/LDQWDk0YqA== - dependencies: - "@typescript-eslint/scope-manager" "5.2.0" - "@typescript-eslint/types" "5.2.0" - "@typescript-eslint/typescript-estree" "5.2.0" + "@typescript-eslint/scope-manager" "5.23.0" + "@typescript-eslint/types" "5.23.0" + "@typescript-eslint/typescript-estree" "5.23.0" debug "^4.3.2" -"@typescript-eslint/scope-manager@5.2.0": - version "5.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.2.0.tgz#7ce8e4ab2baaa0ad5282913ea8e13ce03ec6a12a" - integrity sha512-RW+wowZqPzQw8MUFltfKYZfKXqA2qgyi6oi/31J1zfXJRpOn6tCaZtd9b5u9ubnDG2n/EMvQLeZrsLNPpaUiFQ== +"@typescript-eslint/scope-manager@5.23.0": + version "5.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.23.0.tgz#4305e61c2c8e3cfa3787d30f54e79430cc17ce1b" + integrity sha512-EhjaFELQHCRb5wTwlGsNMvzK9b8Oco4aYNleeDlNuL6qXWDF47ch4EhVNPh8Rdhf9tmqbN4sWDk/8g+Z/J8JVw== dependencies: - "@typescript-eslint/types" "5.2.0" - "@typescript-eslint/visitor-keys" "5.2.0" + "@typescript-eslint/types" "5.23.0" + "@typescript-eslint/visitor-keys" "5.23.0" -"@typescript-eslint/types@5.2.0": - version "5.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.2.0.tgz#7ad32d15abddb0ee968a330f0ea182ea544ef7cf" - integrity sha512-cTk6x08qqosps6sPyP2j7NxyFPlCNsJwSDasqPNjEQ8JMD5xxj2NHxcLin5AJQ8pAVwpQ8BMI3bTxR0zxmK9qQ== - -"@typescript-eslint/typescript-estree@5.2.0": - version "5.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.2.0.tgz#c22e0ff6f8a4a3f78504a80ebd686fe2870a68ae" - integrity sha512-RsdXq2XmVgKbm9nLsE3mjNUM7BTr/K4DYR9WfFVMUuozHWtH5gMpiNZmtrMG8GR385EOSQ3kC9HiEMJWimxd/g== +"@typescript-eslint/type-utils@5.23.0": + version "5.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.23.0.tgz#f852252f2fc27620d5bb279d8fed2a13d2e3685e" + integrity sha512-iuI05JsJl/SUnOTXA9f4oI+/4qS/Zcgk+s2ir+lRmXI+80D8GaGwoUqs4p+X+4AxDolPpEpVUdlEH4ADxFy4gw== dependencies: - "@typescript-eslint/types" "5.2.0" - "@typescript-eslint/visitor-keys" "5.2.0" + "@typescript-eslint/utils" "5.23.0" + debug "^4.3.2" + tsutils "^3.21.0" + +"@typescript-eslint/types@5.23.0": + version "5.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.23.0.tgz#8733de0f58ae0ed318dbdd8f09868cdbf9f9ad09" + integrity sha512-NfBsV/h4dir/8mJwdZz7JFibaKC3E/QdeMEDJhiAE3/eMkoniZ7MjbEMCGXw6MZnZDMN3G9S0mH/6WUIj91dmw== + +"@typescript-eslint/typescript-estree@5.23.0": + version "5.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.23.0.tgz#dca5f10a0a85226db0796e8ad86addc9aee52065" + integrity sha512-xE9e0lrHhI647SlGMl+m+3E3CKPF1wzvvOEWnuE3CCjjT7UiRnDGJxmAcVKJIlFgK6DY9RB98eLr1OPigPEOGg== + dependencies: + "@typescript-eslint/types" "5.23.0" + "@typescript-eslint/visitor-keys" "5.23.0" debug "^4.3.2" globby "^11.0.4" is-glob "^4.0.3" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@5.2.0": - version "5.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.2.0.tgz#03522d35df98474f08e0357171a7d1b259a88f55" - integrity sha512-Nk7HizaXWWCUBfLA/rPNKMzXzWS8Wg9qHMuGtT+v2/YpPij4nVXrVJc24N/r5WrrmqK31jCrZxeHqIgqRzs0Xg== +"@typescript-eslint/utils@5.23.0": + version "5.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.23.0.tgz#4691c3d1b414da2c53d8943310df36ab1c50648a" + integrity sha512-dbgaKN21drqpkbbedGMNPCtRPZo1IOUr5EI9Jrrh99r5UW5Q0dz46RKXeSBoPV+56R6dFKpbrdhgUNSJsDDRZA== dependencies: - "@typescript-eslint/types" "5.2.0" + "@types/json-schema" "^7.0.9" + "@typescript-eslint/scope-manager" "5.23.0" + "@typescript-eslint/types" "5.23.0" + "@typescript-eslint/typescript-estree" "5.23.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/visitor-keys@5.23.0": + version "5.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.23.0.tgz#057c60a7ca64667a39f991473059377a8067c87b" + integrity sha512-Vd4mFNchU62sJB8pX19ZSPog05B0Y0CE2UxAZPT5k4iqhRYjPnqyY3woMxCd0++t9OTqkgjST+1ydLBi7e2Fvg== + dependencies: + "@typescript-eslint/types" "5.23.0" eslint-visitor-keys "^3.0.0" "@yarnpkg/lockfile@^1.1.0": @@ -4401,10 +4411,10 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@^4.4.0-dev.20210528: - version "4.4.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.2.tgz#6d618640d430e3569a1dfb44f7d7e600ced3ee86" - integrity sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ== +typescript@^4.6.2: + version "4.6.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.4.tgz#caa78bbc3a59e6a5c510d35703f6a09877ce45e9" + integrity sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg== unbox-primitive@^1.0.0: version "1.0.1" From d3f58f9b7d645b2e5ece9f6ce5bff0e4bde033a9 Mon Sep 17 00:00:00 2001 From: Petar Petrov Date: Fri, 20 May 2022 00:36:06 +0200 Subject: [PATCH 54/55] Fix caddy installation docs (#5209) Applies Caddy installations documentation fixes and also resolves the following issue when trying to install Caddy: W: GPG error: https://dl.cloudsmith.io/public/caddy/stable/deb/debian any-version InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY ABA1F9B8875A6661 See: - https://github.com/caddyserver/website/commit/930109ec3399035c4870a6c6a673537ca4813960 - https://github.com/caddyserver/website/commit/2e255b1ee39c36919e913466489c205e47a7a8f2 - https://github.com/caddyserver/website/commit/0f4885e59214a2d08a775051b587bb3363c7453c --- docs/guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guide.md b/docs/guide.md index b08a3ed17..f3a8a4f04 100644 --- a/docs/guide.md +++ b/docs/guide.md @@ -126,8 +126,8 @@ access code-server on an iPad or do not want to use SSH port forwarding. ```console sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https -curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/cfg/gpg/gpg.155B6D79CA56EA34.key' | sudo apt-key add - -curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/cfg/setup/config.deb.txt?distro=debian&version=any-version' | sudo tee -a /etc/apt/sources.list.d/caddy-stable.list +curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo apt-key add - +curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list sudo apt update sudo apt install caddy ``` From 5d47282ea55e0487440a7eb8112d414343476095 Mon Sep 17 00:00:00 2001 From: Asher Date: Fri, 20 May 2022 14:39:54 -0500 Subject: [PATCH 55/55] fix: install nfpm straight from GitHub (#5214) * fix: install nfpm straight from GitHub install.goreleaser.com appears to no longer be available. * Add -f to curl commands This might have made it so we got the right error rather than erroring on the envsubst step. --- .github/workflows/ci.yaml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c7f7f6033..0793a0aff 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -265,8 +265,9 @@ jobs: - name: Install nfpm and envsubst run: | - curl -sfL https://install.goreleaser.com/github.com/goreleaser/nfpm.sh | sh -s -- -b ~/.local/bin v2.3.1 - curl -L https://github.com/a8m/envsubst/releases/download/v1.1.0/envsubst-`uname -s`-`uname -m` -o envsubst + mkdir -p ~/.local/bin + curl -sSfL https://github.com/goreleaser/nfpm/releases/download/v2.3.1/nfpm_2.3.1_`uname -s`_`uname -m`.tar.gz | tar -C ~/.local/bin -zxv nfpm + curl -sSfL https://github.com/a8m/envsubst/releases/download/v1.1.0/envsubst-`uname -s`-`uname -m` -o envsubst chmod +x envsubst mv envsubst ~/.local/bin echo "$HOME/.local/bin" >> $GITHUB_PATH @@ -352,7 +353,8 @@ jobs: - name: Install nfpm run: | - curl -sfL https://install.goreleaser.com/github.com/goreleaser/nfpm.sh | sh -s -- -b ~/.local/bin v2.3.1 + mkdir -p ~/.local/bin + curl -sSfL https://github.com/goreleaser/nfpm/releases/download/v2.3.1/nfpm_2.3.1_`uname -s`_`uname -m`.tar.gz | tar -C ~/.local/bin -zxv nfpm echo "$HOME/.local/bin" >> $GITHUB_PATH - name: Install cross-compiler @@ -404,7 +406,8 @@ jobs: - name: Install nfpm run: | - curl -sfL https://install.goreleaser.com/github.com/goreleaser/nfpm.sh | sh -s -- -b ~/.local/bin v2.3.1 + mkdir -p ~/.local/bin + curl -sSfL https://github.com/goreleaser/nfpm/releases/download/v2.3.1/nfpm_2.3.1_`uname -s`_`uname -m`.tar.gz | tar -C ~/.local/bin -zxv nfpm echo "$HOME/.local/bin" >> $GITHUB_PATH - name: Download npm package