Compare commits

..

5 Commits

Author SHA1 Message Date
Asher
1321bd41c6 Fix changelog typo 2022-08-15 15:08:30 -05:00
Asher
abef6b23c1 Add missing period 2022-08-15 13:23:50 -05:00
Asher
d39f5c32bf Fill out 4.5.2 changelog 2022-08-15 13:15:39 -05:00
Asher
4c7242ccee 4.5.2 2022-08-15 13:00:57 -05:00
Asher
be6cce23f0 release: 4.5.2-rc.1 2022-08-11 11:16:28 -05:00
110 changed files with 3743 additions and 3397 deletions

2
.github/CODEOWNERS vendored
View File

@@ -1,4 +1,4 @@
* @coder/code-server
* @coder/code-server-reviewers
ci/helm-chart/ @Matthew-Beckett @alexgorbatchev

View File

@@ -12,6 +12,5 @@ Follow "Publishing a release" steps in `ci/README.md`
<!-- Note some of these steps below are redundant since they're listed in the "Publishing a release" docs -->
- [ ] update `CHANGELOG.md`
- [ ] manually run "Draft release" workflow after merging this PR
- [ ] merge PR opened in [code-server-aur](https://github.com/coder/code-server-aur)
- [ ] publish release and merge PR
- [ ] update the AUR package

View File

@@ -1,425 +0,0 @@
name: Build
on:
push:
branches:
- main
pull_request:
branches:
- main
# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
# Note: if: success() is used in several jobs -
# this ensures that it only executes if all previous jobs succeeded.
# if: steps.cache-node-modules.outputs.cache-hit != 'true'
# will skip running `yarn install` if it successfully fetched from cache
jobs:
prettier:
name: Format with Prettier
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Run prettier with actionsx/prettier
uses: actionsx/prettier@v2
with:
args: --check --loglevel=warn .
doctoc:
name: Doctoc markdown files
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v26.1
with:
files: |
docs/**
- name: Install Node.js v16
if: steps.changed-files.outputs.any_changed == 'true'
uses: actions/setup-node@v3
with:
node-version: "16"
cache: "yarn"
- name: Install doctoc
run: yarn global add doctoc@2.2.1
- name: Run doctoc
if: steps.changed-files.outputs.any_changed == 'true'
run: yarn doctoc
lint-helm:
name: Lint Helm chart
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 2
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v26.1
with:
files: |
ci/helm-chart/**
- name: Install helm
if: steps.changed-files.outputs.any_changed == 'true'
uses: azure/setup-helm@v3.4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Install helm kubeval plugin
if: steps.changed-files.outputs.any_changed == 'true'
run: helm plugin install https://github.com/instrumenta/helm-kubeval
- name: Lint Helm chart
if: steps.changed-files.outputs.any_changed == 'true'
run: helm kubeval ci/helm-chart
lint-ts:
name: Lint TypeScript files
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 2
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v26.1
with:
files: |
**/*.ts
**/*.js
files_ignore: |
lib/vscode/**
- name: Install Node.js v16
if: steps.changed-files.outputs.any_changed == 'true'
uses: actions/setup-node@v3
with:
node-version: "16"
- name: Fetch dependencies from cache
if: steps.changed-files.outputs.any_changed == 'true'
id: cache-node-modules
uses: actions/cache@v3
with:
path: "**/node_modules"
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
yarn-build-
- name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true' && steps.cache-node-modules.outputs.cache-hit != 'true'
run: SKIP_SUBMODULE_DEPS=1 yarn --frozen-lockfile
- name: Lint TypeScript files
if: steps.changed-files.outputs.any_changed == 'true'
run: yarn lint:ts
build:
name: Build code-server
runs-on: ubuntu-latest
timeout-minutes: 30
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
submodules: true
- name: Install quilt
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: quilt
version: 1.0
- name: Patch Code
run: quilt push -a
- name: Install Node.js v16
uses: actions/setup-node@v3
with:
node-version: "16"
- name: Fetch dependencies from cache
id: cache-node-modules
uses: actions/cache@v3
with:
path: "**/node_modules"
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
yarn-build-
- name: Install dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: yarn --frozen-lockfile
- name: Build code-server
run: yarn build
# Get Code's git hash. When this changes it means the content is
# different and we need to rebuild.
- name: Get latest lib/vscode rev
id: vscode-rev
run: echo "::set-output name=rev::$(git rev-parse HEAD:./lib/vscode)"
- name: Get version
id: version
run: echo "::set-output name=version::$(jq -r .version package.json)"
# We need to rebuild when we have a new version of Code, when any of
# the patches changed, or when the code-server version changes (since
# it gets embedded into the code). Use VSCODE_CACHE_VERSION to
# force a rebuild.
- name: Fetch prebuilt Code package from cache
id: cache-vscode
uses: actions/cache@v3
with:
path: lib/vscode-reh-web-*
key: vscode-reh-package-${{ secrets.VSCODE_CACHE_VERSION }}-${{ steps.vscode-rev.outputs.rev }}-${{ steps.version.outputs.version }}-${{ hashFiles('patches/*.diff', 'ci/build/build-vscode.sh') }}
- name: Build vscode
if: steps.cache-vscode.outputs.cache-hit != 'true'
run: yarn build:vscode
# Our code imports code from VS Code's `out` directory meaning VS Code
# must be built before running these tests.
# TODO: Move to its own step?
- name: Run code-server unit tests
run: yarn test:unit
if: success()
- name: Upload coverage report to Codecov
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
if: success()
# The release package does not contain any native modules
# and is neutral to architecture/os/libc version.
- name: Create release package
run: yarn release
if: success()
# https://github.com/actions/upload-artifact/issues/38
- name: Compress release package
run: tar -czf package.tar.gz release
- name: Upload npm package artifact
uses: actions/upload-artifact@v3
with:
name: npm-package
path: ./package.tar.gz
npm:
name: Publish npm package
# the npm-package gets uploaded as an artifact in Build
# so we need that to complete before this runs
needs: build
# This environment "npm" requires someone from
# coder/code-server-reviewers to approve the PR before this job runs.
environment: npm
# Only run if PR comes from base repo or event is not a PR
# Reason: forks cannot access secrets and this will always fail
if: github.event.pull_request.head.repo.full_name == github.repository || github.event_name != 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Download artifact
uses: actions/download-artifact@v3
id: download
with:
name: "npm-package"
path: release-npm-package
- name: Run ./ci/steps/publish-npm.sh
run: yarn publish:npm
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
# NOTE@jsjoeio
# NPM_ENVIRONMENT intentionally not set here.
# 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 }}
```
test-e2e:
name: Run e2e tests
needs: build
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Install Node.js v16
uses: actions/setup-node@v3
with:
node-version: "16"
- name: Fetch dependencies from cache
id: cache-node-modules
uses: actions/cache@v3
with:
path: "**/node_modules"
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
yarn-build-
- name: Download npm package
uses: actions/download-artifact@v3
with:
name: npm-package
- name: Decompress npm package
run: tar -xzf package.tar.gz
- name: Install release package dependencies
run: cd release && yarn install
- name: Install dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: SKIP_SUBMODULE_DEPS=1 yarn --frozen-lockfile
- name: Install Playwright OS dependencies
run: |
./test/node_modules/.bin/playwright install-deps
./test/node_modules/.bin/playwright install
- name: Run end-to-end tests
run: CODE_SERVER_TEST_ENTRY=./release yarn test:e2e --global-timeout 840000
- name: Upload test artifacts
if: always()
uses: actions/upload-artifact@v3
with:
name: failed-test-videos
path: ./test/test-results
- name: Remove release packages and test artifacts
run: rm -rf ./release ./test/test-results
test-e2e-proxy:
name: Run e2e tests behind proxy
needs: build
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Install Node.js v16
uses: actions/setup-node@v3
with:
node-version: "16"
- name: Fetch dependencies from cache
id: cache-node-modules
uses: actions/cache@v3
with:
path: "**/node_modules"
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
yarn-build-
- name: Download npm package
uses: actions/download-artifact@v3
with:
name: npm-package
- name: Decompress npm package
run: tar -xzf package.tar.gz
- name: Install release package dependencies
run: cd release && yarn install
- name: Install dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: SKIP_SUBMODULE_DEPS=1 yarn --frozen-lockfile
- name: Install Playwright OS dependencies
run: |
./test/node_modules/.bin/playwright install-deps
./test/node_modules/.bin/playwright install
- name: Cache Caddy
uses: actions/cache@v2
id: caddy-cache
with:
path: |
~/.cache/caddy
key: cache-caddy-2.5.2
- name: Install Caddy
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
if: steps.caddy-cache.outputs.cache-hit != 'true'
run: |
gh release download v2.5.2 --repo caddyserver/caddy --pattern "caddy_2.5.2_linux_amd64.tar.gz"
mkdir -p ~/.cache/caddy
tar -xzf caddy_2.5.2_linux_amd64.tar.gz --directory ~/.cache/caddy
- name: Start Caddy
run: sudo ~/.cache/caddy/caddy start --config ./ci/Caddyfile
- name: Run end-to-end tests
run: CODE_SERVER_TEST_ENTRY=./release yarn test:e2e:proxy --global-timeout 840000
- name: Stop Caddy
if: always()
run: sudo ~/.cache/caddy/caddy stop --config ./ci/Caddyfile
- name: Upload test artifacts
if: always()
uses: actions/upload-artifact@v3
with:
name: failed-test-videos-proxy
path: ./test/test-results
- name: Remove release packages and test artifacts
run: rm -rf ./release ./test/test-results

625
.github/workflows/ci.yaml vendored Normal file
View File

@@ -0,0 +1,625 @@
name: Build
on:
push:
branches:
- main
pull_request:
branches:
- main
# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
# Note: if: success() is used in several jobs -
# this ensures that it only executes if all previous jobs succeeded.
# if: steps.cache-yarn.outputs.cache-hit != 'true'
# will skip running `yarn install` if it successfully fetched from cache
jobs:
prebuild:
name: Pre-build checks
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 0
submodules: true
- name: Install Node.js v16
uses: actions/setup-node@v3
with:
node-version: "16"
- name: Install helm
uses: azure/setup-helm@v3.3
- name: Fetch dependencies from cache
id: cache-yarn
uses: actions/cache@v3
with:
path: "**/node_modules"
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
yarn-build-
- name: Install dependencies
if: steps.cache-yarn.outputs.cache-hit != 'true'
run: yarn --frozen-lockfile
- name: Run yarn fmt
run: yarn fmt
if: success()
- name: Run yarn lint
run: yarn lint
if: success()
audit-ci:
name: Run audit-ci
needs: prebuild
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 0
submodules: true
- name: Install Node.js v16
uses: actions/setup-node@v3
with:
node-version: "16"
- name: Fetch dependencies from cache
id: cache-yarn
uses: actions/cache@v3
with:
path: "**/node_modules"
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
yarn-build-
- name: Install dependencies
if: steps.cache-yarn.outputs.cache-hit != 'true'
run: yarn --frozen-lockfile
- name: Audit for vulnerabilities
run: yarn _audit
if: success()
build:
name: Build
needs: prebuild
runs-on: ubuntu-latest
timeout-minutes: 30
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 0
submodules: true
- name: Install quilt
run: sudo apt update && sudo apt install quilt
- name: Patch Code
run: quilt push -a
- name: Install Node.js v16
uses: actions/setup-node@v3
with:
node-version: "16"
- name: Fetch dependencies from cache
id: cache-yarn
uses: actions/cache@v3
with:
path: "**/node_modules"
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
yarn-build-
- name: Install dependencies
if: steps.cache-yarn.outputs.cache-hit != 'true'
run: yarn --frozen-lockfile
- name: Build code-server
run: yarn build
# Get Code's git hash. When this changes it means the content is
# different and we need to rebuild.
- name: Get latest lib/vscode rev
id: vscode-rev
run: echo "::set-output name=rev::$(git rev-parse HEAD:./lib/vscode)"
- name: Get version
id: version
run: echo "::set-output name=version::$(jq -r .version package.json)"
# We need to rebuild when we have a new version of Code, when any of
# the patches changed, or when the code-server version changes (since
# it gets embedded into the code). Use VSCODE_CACHE_VERSION to
# force a rebuild.
- name: Fetch prebuilt Code package from cache
id: cache-vscode
uses: actions/cache@v3
with:
path: lib/vscode-reh-web-*
key: vscode-reh-package-${{ secrets.VSCODE_CACHE_VERSION }}-${{ steps.vscode-rev.outputs.rev }}-${{ steps.version.outputs.version }}-${{ hashFiles('patches/*.diff', 'ci/build/build-vscode.sh') }}
- name: Build vscode
if: steps.cache-vscode.outputs.cache-hit != 'true'
run: yarn build:vscode
# Our code imports code from VS Code's `out` directory meaning VS Code
# must be built before running these tests.
# TODO: Move to its own step?
- name: Run code-server unit tests
run: yarn test:unit
if: success()
- name: Upload coverage report to Codecov
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
if: success()
# The release package does not contain any native modules
# and is neutral to architecture/os/libc version.
- name: Create release package
run: yarn release
if: success()
# https://github.com/actions/upload-artifact/issues/38
- name: Compress release package
run: tar -czf package.tar.gz release
- name: Upload npm package artifact
uses: actions/upload-artifact@v3
with:
name: npm-package
path: ./package.tar.gz
npm:
# the npm-package gets uploaded as an artifact in Build
# so we need that to complete before this runs
needs: build
# This environment "npm" requires someone from
# coder/code-server-reviewers to approve the PR before this job runs.
environment: npm
# Only run if PR comes from base repo or event is not a PR
# Reason: forks cannot access secrets and this will always fail
if: github.event.pull_request.head.repo.full_name == github.repository || github.event_name != 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Download artifact
uses: actions/download-artifact@v3
id: download
with:
name: "npm-package"
path: release-npm-package
- name: Run ./ci/steps/publish-npm.sh
run: yarn publish:npm
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
# NOTE@jsjoeio
# NPM_ENVIRONMENT intentionally not set here.
# 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
package-linux-amd64:
name: x86-64 Linux build
needs: build
runs-on: ubuntu-latest
timeout-minutes: 15
container: "centos:7"
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install Node.js v16
uses: actions/setup-node@v3
with:
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 python3
- name: Install nfpm and envsubst
run: |
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
- name: Install yarn
run: npm install -g yarn
- name: Download npm package
uses: actions/download-artifact@v3
with:
name: npm-package
- name: Decompress npm package
run: tar -xzf package.tar.gz
# NOTE: && here is deliberate - GitHub puts each line in its own `.sh`
# file when running inside a docker container.
- name: Build standalone release
run: source scl_source enable devtoolset-9 && yarn release:standalone
- name: Install test dependencies
run: SKIP_SUBMODULE_DEPS=1 yarn install
- name: Run integration tests on standalone release
run: yarn test:integration
- name: Build packages with nfpm
run: yarn package
- name: Upload release artifacts
uses: actions/upload-artifact@v3
with:
name: release-packages
path: ./release-packages
# NOTE@oxy:
# We use Ubuntu 16.04 here, so that our build is more compatible
# with older libc versions. We used to (Q1'20) use CentOS 7 here,
# but it has a full update EOL of Q4'20 and a 'critical security'
# update EOL of 2024. We're dropping full support a few years before
# the final EOL, but I don't believe CentOS 7 has a large arm64 userbase.
# It is not feasible to cross-compile with CentOS.
# Cross-compile notes: To compile native dependencies for arm64,
# we install the aarch64/armv7l cross toolchain and then set it as the default
# compiler/linker/etc. with the AR/CC/CXX/LINK environment variables.
# qemu-user-static on ubuntu-16.04 currently doesn't run Node correctly,
# so we just build with "native"/x86_64 node, then download arm64/armv7l node
# and then put it in our release. We can't smoke test the cross build this way,
# but this means we don't need to maintain a self-hosted runner!
# NOTE@jsjoeio:
# We used to use 16.04 until GitHub deprecated it on September 20, 2021
# See here: https://github.com/actions/virtual-environments/pull/3862/files
package-linux-cross:
name: Linux cross-compile builds
needs: build
runs-on: ubuntu-18.04
timeout-minutes: 15
strategy:
matrix:
include:
- prefix: aarch64-linux-gnu
arch: arm64
- prefix: arm-linux-gnueabihf
arch: armv7l
env:
AR: ${{ format('{0}-ar', matrix.prefix) }}
CC: ${{ format('{0}-gcc', matrix.prefix) }}
CXX: ${{ format('{0}-g++', matrix.prefix) }}
LINK: ${{ format('{0}-g++', matrix.prefix) }}
NPM_CONFIG_ARCH: ${{ matrix.arch }}
NODE_VERSION: v16.13.0
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install Node.js v16
uses: actions/setup-node@v3
with:
node-version: "16"
- name: Install nfpm
run: |
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
run: sudo apt update && sudo apt install $PACKAGE
env:
PACKAGE: ${{ format('g++-{0}', matrix.prefix) }}
- name: Download npm package
uses: actions/download-artifact@v3
with:
name: npm-package
- name: Decompress npm package
run: tar -xzf package.tar.gz
- name: Build standalone release
run: yarn release:standalone
- name: Replace node with cross-compile equivalent
run: |
wget https://nodejs.org/dist/${NODE_VERSION}/node-${NODE_VERSION}-linux-${NPM_CONFIG_ARCH}.tar.xz
tar -xf node-${NODE_VERSION}-linux-${NPM_CONFIG_ARCH}.tar.xz node-${NODE_VERSION}-linux-${NPM_CONFIG_ARCH}/bin/node --strip-components=2
mv ./node ./release-standalone/lib/node
- name: Build packages with nfpm
run: yarn package ${NPM_CONFIG_ARCH}
- name: Upload release artifacts
uses: actions/upload-artifact@v3
with:
name: release-packages
path: ./release-packages
package-macos-amd64:
name: x86-64 macOS build
needs: build
runs-on: macos-latest
timeout-minutes: 15
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install Node.js v16
uses: actions/setup-node@v3
with:
node-version: "16"
- name: Install nfpm
run: |
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
uses: actions/download-artifact@v3
with:
name: npm-package
- name: Decompress npm package
run: tar -xzf package.tar.gz
- name: Build standalone release
run: yarn release:standalone
- name: Install test dependencies
run: SKIP_SUBMODULE_DEPS=1 yarn install
- name: Run integration tests on standalone release
run: yarn test:integration
- name: Build packages with nfpm
run: yarn package
- name: Upload release artifacts
uses: actions/upload-artifact@v3
with:
name: release-packages
path: ./release-packages
test-e2e:
name: End-to-end tests
needs: package-linux-amd64
runs-on: ubuntu-latest
timeout-minutes: 15
env:
# Since we build code-server we might as well run tests from the release
# since VS Code will load faster due to the bundling.
CODE_SERVER_TEST_ENTRY: "./release-packages/code-server-linux-amd64"
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install Node.js v16
uses: actions/setup-node@v3
with:
node-version: "16"
- name: Fetch dependencies from cache
id: cache-yarn
uses: actions/cache@v3
with:
path: "**/node_modules"
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
yarn-build-
- name: Download release packages
uses: actions/download-artifact@v3
with:
name: release-packages
path: ./release-packages
- name: Untar code-server release
run: |
cd release-packages
tar -xzf code-server*-linux-amd64.tar.gz
mv code-server*-linux-amd64 code-server-linux-amd64
- name: Install dependencies
if: steps.cache-yarn.outputs.cache-hit != 'true'
run: SKIP_SUBMODULE_DEPS=1 yarn --frozen-lockfile
- name: Install Playwright OS dependencies
run: |
./test/node_modules/.bin/playwright install-deps
./test/node_modules/.bin/playwright install
- name: Run end-to-end tests
run: yarn test:e2e --global-timeout 840000
- name: Upload test artifacts
if: always()
uses: actions/upload-artifact@v3
with:
name: failed-test-videos
path: ./test/test-results
- name: Remove release packages and test artifacts
run: rm -rf ./release-packages ./test/test-results
test-e2e-proxy:
name: End-to-end tests behind proxy
needs: package-linux-amd64
runs-on: ubuntu-latest
timeout-minutes: 25
env:
# Since we build code-server we might as well run tests from the release
# since VS Code will load faster due to the bundling.
CODE_SERVER_TEST_ENTRY: "./release-packages/code-server-linux-amd64"
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install Node.js v16
uses: actions/setup-node@v3
with:
node-version: "16"
- name: Fetch dependencies from cache
id: cache-yarn
uses: actions/cache@v3
with:
path: "**/node_modules"
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
yarn-build-
- name: Download release packages
uses: actions/download-artifact@v3
with:
name: release-packages
path: ./release-packages
- name: Untar code-server release
run: |
cd release-packages
tar -xzf code-server*-linux-amd64.tar.gz
mv code-server*-linux-amd64 code-server-linux-amd64
- name: Install dependencies
if: steps.cache-yarn.outputs.cache-hit != 'true'
run: SKIP_SUBMODULE_DEPS=1 yarn --frozen-lockfile
- name: Install Playwright OS dependencies
run: |
./test/node_modules/.bin/playwright install-deps
./test/node_modules/.bin/playwright install
- name: Cache Caddy
uses: actions/cache@v2
id: caddy-cache
with:
path: |
~/.cache/caddy
key: cache-caddy-2.5.2
- name: Install Caddy
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
if: steps.caddy-cache.outputs.cache-hit != 'true'
run: |
gh release download v2.5.2 --repo caddyserver/caddy --pattern "caddy_2.5.2_linux_amd64.tar.gz"
mkdir -p ~/.cache/caddy
tar -xzf caddy_2.5.2_linux_amd64.tar.gz --directory ~/.cache/caddy
- name: Start Caddy
run: sudo ~/.cache/caddy/caddy start --config ./ci/Caddyfile
- name: Run end-to-end tests
run: yarn test:e2e:proxy
- name: Stop Caddy
if: always()
run: sudo ~/.cache/caddy/caddy stop --config ./ci/Caddyfile
- name: Upload test artifacts
if: always()
uses: actions/upload-artifact@v3
with:
name: failed-test-videos-proxy
path: ./test/test-results
- name: Remove release packages and test artifacts
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
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Run Trivy vulnerability scanner in repo mode
uses: aquasecurity/trivy-action@cb606dfdb0d2b3698ace62192088ef4f5360b24f
with:
scan-type: "fs"
scan-ref: "."
ignore-unfixed: true
format: "template"
template: "@/contrib/sarif.tpl"
output: "trivy-repo-results.sarif"
severity: "HIGH,CRITICAL"
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: "trivy-repo-results.sarif"

47
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,47 @@
name: "Code Scanning"
on:
push:
branches: [main]
pull_request:
# The branches below must be a subset of the branches above
branches: [main]
schedule:
# Runs every Monday morning PST
- cron: "17 15 * * 1"
# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
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
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
config-file: ./.github/codeql-config.yml
languages: javascript
- name: Autobuild
uses: github/codeql-action/autobuild@v2
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

60
.github/workflows/docker.yaml vendored Normal file
View File

@@ -0,0 +1,60 @@
name: Publish on Docker
on:
# Shows the manual trigger in GitHub UI
# helpful as a back-up in case the GitHub Actions Workflow fails
workflow_dispatch:
release:
types:
- released
# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
docker-images:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
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)"
- name: Download release artifacts
uses: robinraju/release-downloader@v1.4
with:
repository: "coder/code-server"
tag: v${{ steps.version.outputs.version }}
fileName: "*.deb"
out-file-path: "release-packages"
- name: Publish to Docker
run: yarn publish:docker
env:
GITHUB_TOKEN: ${{ github.token }}

View File

@@ -6,13 +6,11 @@ on:
- main
paths:
- "install.sh"
- ".github/workflows/installer.yaml"
pull_request:
branches:
- main
paths:
- "install.sh"
- ".github/workflows/installer.yaml"
# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
@@ -35,8 +33,8 @@ jobs:
- name: Install code-server
run: ./install.sh
- name: Test code-server was installed globally
run: code-server --help
- name: Test code-server
run: CODE_SERVER_PATH="code-server" yarn test:integration
alpine:
name: Test installer on Alpine
@@ -56,11 +54,6 @@ jobs:
- name: Test standalone to a non-existent prefix
run: su coder -c "./install.sh --method standalone --prefix /tmp/does/not/yet/exist"
# We do not actually have Alpine standalone builds so running code-server
# will not work.
- name: Test code-server was installed to prefix
run: test -f /tmp/does/not/yet/exist/bin/code-server
macos:
name: Test installer on macOS
runs-on: macos-latest
@@ -72,5 +65,5 @@ jobs:
- name: Install code-server
run: ./install.sh
- name: Test code-server was installed globally
run: code-server --help
- name: Test code-server
run: CODE_SERVER_PATH="code-server" yarn test:integration

69
.github/workflows/npm-brew.yaml vendored Normal file
View File

@@ -0,0 +1,69 @@
name: Publish on npm and brew
on:
# Shows the manual trigger in GitHub UI
# helpful as a back-up in case the GitHub Actions Workflow fails
workflow_dispatch:
release:
types: [released]
# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
# NOTE: this job requires curl, jq and yarn
# All of them are included in ubuntu-latest.
npm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Get version
id: version
run: echo "::set-output name=version::$(jq -r .version package.json)"
- name: Download artifact
uses: dawidd6/action-download-artifact@v2
id: download
with:
branch: release/v${{ steps.version.outputs.version }}
workflow: ci.yaml
workflow_conclusion: completed
name: "npm-package"
path: release-npm-package
- name: Publish npm package and tag with "latest"
run: yarn publish:npm
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_ENVIRONMENT: "production"
homebrew:
needs: npm
runs-on: ubuntu-latest
steps:
# Ensure things are up to date
# Suggested by homebrew maintainers
# https://github.com/Homebrew/discussions/discussions/1532#discussioncomment-782633
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@master
- name: Checkout code-server
uses: actions/checkout@v3
- name: Configure git
run: |
git config --global user.name cdrci
git config --global user.email opensource@coder.com
- name: Bump code-server homebrew version
env:
HOMEBREW_GITHUB_API_TOKEN: ${{secrets.HOMEBREW_GITHUB_API_TOKEN}}
run: ./ci/steps/brew-bump.sh

View File

@@ -1,165 +0,0 @@
name: Publish code-server
on:
# Shows the manual trigger in GitHub UI
# helpful as a back-up in case the GitHub Actions Workflow fails
workflow_dispatch:
release:
types: [released]
# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
# NOTE: this job requires curl, jq and yarn
# All of them are included in ubuntu-latest.
npm:
runs-on: ubuntu-latest
steps:
- name: Checkout code-server
uses: actions/checkout@v3
- name: Get version
id: version
run: echo "::set-output name=version::$(jq -r .version package.json)"
- name: Download npm package from release artifacts
uses: robinraju/release-downloader@v1.5
with:
repository: "coder/code-server"
tag: v${{ steps.version.outputs.version }}
fileName: "package.tar.gz"
out-file-path: "release-npm-package"
- name: Publish npm package and tag with "latest"
run: yarn publish:npm
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_ENVIRONMENT: "production"
homebrew:
needs: npm
runs-on: ubuntu-latest
steps:
# Ensure things are up to date
# Suggested by homebrew maintainers
# https://github.com/Homebrew/discussions/discussions/1532#discussioncomment-782633
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@master
- name: Checkout code-server
uses: actions/checkout@v3
- name: Configure git
run: |
git config --global user.name cdrci
git config --global user.email opensource@coder.com
- name: Bump code-server homebrew version
env:
HOMEBREW_GITHUB_API_TOKEN: ${{secrets.HOMEBREW_GITHUB_API_TOKEN}}
run: ./ci/steps/brew-bump.sh
aur:
needs: npm
runs-on: ubuntu-latest
timeout-minutes: 10
env:
GH_TOKEN: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }}
steps:
# We need to checkout code-server so we can get the version
- name: Checkout code-server
uses: actions/checkout@v3
with:
fetch-depth: 0
path: "./code-server"
- name: Get code-server version
id: version
run: |
pushd code-server
echo "::set-output name=version::$(jq -r .version package.json)"
popd
- name: Checkout code-server-aur repo
uses: actions/checkout@v3
with:
repository: "cdrci/code-server-aur"
token: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }}
ref: "master"
- name: Merge in master
run: |
git remote add upstream https://github.com/coder/code-server-aur.git
git fetch upstream
git merge upstream/master
- name: Configure git
run: |
git config --global user.name cdrci
git config --global user.email opensource@coder.com
- name: Validate package
uses: hapakaien/archlinux-package-action@v2
with:
pkgver: ${{ steps.version.outputs.version }}
updpkgsums: true
srcinfo: true
- name: Open PR
# We need to git push -u otherwise gh will prompt
# asking where to push the branch.
run: |
git checkout -b update-version-${{ steps.version.outputs.version }}
git add .
git commit -m "chore: updating version to ${{ steps.version.outputs.version }}"
git push -u origin $(git branch --show)
gh pr create --repo coder/code-server-aur --title "chore: bump version to ${{ steps.version.outputs.version }}" --body "PR opened by @$GITHUB_ACTOR" --assignee $GITHUB_ACTOR
docker:
runs-on: ubuntu-20.04
steps:
- name: Checkout code-server
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
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)"
- name: Download release artifacts
uses: robinraju/release-downloader@v1.5
with:
repository: "coder/code-server"
tag: v${{ steps.version.outputs.version }}
fileName: "*.deb"
out-file-path: "release-packages"
- name: Publish to Docker
run: yarn publish:docker
env:
GITHUB_TOKEN: ${{ github.token }}

View File

@@ -1,272 +0,0 @@
name: Draft release
on:
workflow_dispatch:
permissions:
contents: write # For creating releases.
discussions: write # For creating a discussion.
# Cancel in-progress runs for pull requests when developers push
# additional changes
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
# TODO: cache building yarn --production
# possibly 2m30s of savings(?)
# this requires refactoring our release scripts
package-linux-amd64:
name: x86-64 Linux build
runs-on: ubuntu-latest
timeout-minutes: 15
container: "centos:7"
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Install Node.js v16
uses: actions/setup-node@v3
with:
node-version: "16"
- name: Install development tools
run: |
yum install -y epel-release centos-release-scl make
yum install -y devtoolset-9-{make,gcc,gcc-c++} jq rsync python3
- name: Install nfpm and envsubst
run: |
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
- name: Install yarn
run: npm install -g yarn
- name: Download artifacts
uses: dawidd6/action-download-artifact@v2
id: download
with:
branch: ${{ github.ref }}
workflow: build.yaml
workflow_conclusion: completed
check_artifacts: true
name: npm-package
- name: Decompress npm package
run: tar -xzf package.tar.gz
# NOTE: && here is deliberate - GitHub puts each line in its own `.sh`
# file when running inside a docker container.
- name: Build standalone release
run: source scl_source enable devtoolset-9 && yarn release:standalone
- name: Fetch dependencies from cache
id: cache-node-modules
uses: actions/cache@v3
with:
path: "**/node_modules"
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
yarn-build-
- name: Install test dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: SKIP_SUBMODULE_DEPS=1 yarn --frozen-lockfile
- name: Run integration tests on standalone release
run: yarn test:integration
- name: Upload coverage report to Codecov
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
if: success()
- name: Build packages with nfpm
run: yarn package
- uses: softprops/action-gh-release@v1
with:
draft: true
discussion_category_name: "📣 Announcements"
files: ./release-packages/*
# NOTE@oxy:
# We use Ubuntu 16.04 here, so that our build is more compatible
# with older libc versions. We used to (Q1'20) use CentOS 7 here,
# but it has a full update EOL of Q4'20 and a 'critical security'
# update EOL of 2024. We're dropping full support a few years before
# the final EOL, but I don't believe CentOS 7 has a large arm64 userbase.
# It is not feasible to cross-compile with CentOS.
# Cross-compile notes: To compile native dependencies for arm64,
# we install the aarch64/armv7l cross toolchain and then set it as the default
# compiler/linker/etc. with the AR/CC/CXX/LINK environment variables.
# qemu-user-static on ubuntu-16.04 currently doesn't run Node correctly,
# so we just build with "native"/x86_64 node, then download arm64/armv7l node
# and then put it in our release. We can't smoke test the cross build this way,
# but this means we don't need to maintain a self-hosted runner!
# NOTE@jsjoeio:
# We used to use 16.04 until GitHub deprecated it on September 20, 2021
# See here: https://github.com/actions/virtual-environments/pull/3862/files
package-linux-cross:
name: Linux cross-compile builds
runs-on: ubuntu-18.04
timeout-minutes: 15
strategy:
matrix:
include:
- prefix: aarch64-linux-gnu
arch: arm64
- prefix: arm-linux-gnueabihf
arch: armv7l
env:
AR: ${{ format('{0}-ar', matrix.prefix) }}
CC: ${{ format('{0}-gcc', matrix.prefix) }}
CXX: ${{ format('{0}-g++', matrix.prefix) }}
LINK: ${{ format('{0}-g++', matrix.prefix) }}
NPM_CONFIG_ARCH: ${{ matrix.arch }}
NODE_VERSION: v16.13.0
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Install Node.js v16
uses: actions/setup-node@v3
with:
node-version: "16"
- name: Install nfpm
run: |
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
run: sudo apt update && sudo apt install $PACKAGE
env:
PACKAGE: ${{ format('g++-{0}', matrix.prefix) }}
- name: Download artifacts
uses: dawidd6/action-download-artifact@v2
id: download
with:
branch: ${{ github.ref }}
workflow: build.yaml
workflow_conclusion: completed
check_artifacts: true
name: npm-package
- name: Decompress npm package
run: tar -xzf package.tar.gz
- name: Build standalone release
run: yarn release:standalone
- name: Replace node with cross-compile equivalent
run: |
wget https://nodejs.org/dist/${NODE_VERSION}/node-${NODE_VERSION}-linux-${NPM_CONFIG_ARCH}.tar.xz
tar -xf node-${NODE_VERSION}-linux-${NPM_CONFIG_ARCH}.tar.xz node-${NODE_VERSION}-linux-${NPM_CONFIG_ARCH}/bin/node --strip-components=2
mv ./node ./release-standalone/lib/node
- name: Build packages with nfpm
run: yarn package ${NPM_CONFIG_ARCH}
- uses: softprops/action-gh-release@v1
with:
draft: true
discussion_category_name: "📣 Announcements"
files: ./release-packages/*
package-macos-amd64:
name: x86-64 macOS build
runs-on: macos-latest
timeout-minutes: 15
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Install Node.js v16
uses: actions/setup-node@v3
with:
node-version: "16"
- name: Install nfpm
run: |
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 artifacts
uses: dawidd6/action-download-artifact@v2
id: download
with:
branch: ${{ github.ref }}
workflow: build.yaml
workflow_conclusion: completed
check_artifacts: true
name: npm-package
- name: Decompress npm package
run: tar -xzf package.tar.gz
- name: Build standalone release
run: yarn release:standalone
- name: Fetch dependencies from cache
id: cache-node-modules
uses: actions/cache@v3
with:
path: "**/node_modules"
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
yarn-build-
- name: Install test dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: SKIP_SUBMODULE_DEPS=1 yarn install
- name: Run native module tests on standalone release
run: yarn test:native
- name: Build packages with nfpm
run: yarn package
- uses: softprops/action-gh-release@v1
with:
draft: true
discussion_category_name: "📣 Announcements"
files: ./release-packages/*
npm-package:
name: Upload npm package
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Download artifacts
uses: dawidd6/action-download-artifact@v2
id: download
with:
branch: ${{ github.ref }}
workflow: build.yaml
workflow_conclusion: completed
check_artifacts: true
name: npm-package
- uses: softprops/action-gh-release@v1
with:
draft: true
discussion_category_name: "📣 Announcements"
files: ./package.tar.gz

View File

@@ -51,17 +51,3 @@ jobs:
- name: Run script unit tests
run: ./ci/dev/test-scripts.sh
lint:
name: Lint shell files
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Install lint utilities
run: sudo apt install shellcheck
- name: Lint shell files
run: ./ci/dev/lint-scripts.sh

View File

@@ -1,106 +0,0 @@
name: Security
on:
push:
branches: [main]
paths:
- "package.json"
pull_request:
paths:
- "package.json"
schedule:
# Runs every Monday morning PST
- cron: "17 15 * * 1"
# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
audit-ci:
name: Audit node modules
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install Node.js v16
uses: actions/setup-node@v3
with:
node-version: "16"
- name: Fetch dependencies from cache
id: cache-yarn
uses: actions/cache@v3
with:
path: "**/node_modules"
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
yarn-build-
- name: Install dependencies
if: steps.cache-yarn.outputs.cache-hit != 'true'
run: SKIP_SUBMODULE_DEPS=1 yarn --frozen-lockfile
- name: Audit for vulnerabilities
run: yarn _audit
if: success()
trivy-scan-repo:
name: Scan repo with Trivy
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
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Run Trivy vulnerability scanner in repo mode
uses: aquasecurity/trivy-action@e55de85beea5fcec743de6bb6bc56943a0af3c33
with:
scan-type: "fs"
scan-ref: "."
ignore-unfixed: true
format: "template"
template: "@/contrib/sarif.tpl"
output: "trivy-repo-results.sarif"
severity: "HIGH,CRITICAL"
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: "trivy-repo-results.sarif"
codeql-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 with CodeQL
runs-on: ubuntu-20.04
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
config-file: ./.github/codeql-config.yml
languages: javascript
- name: Autobuild
uses: github/codeql-action/autobuild@v2
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

View File

@@ -51,7 +51,7 @@ jobs:
uses: actions/checkout@v3
- name: Run Trivy vulnerability scanner in image mode
uses: aquasecurity/trivy-action@e55de85beea5fcec743de6bb6bc56943a0af3c33
uses: aquasecurity/trivy-action@cb606dfdb0d2b3698ace62192088ef4f5360b24f
with:
image-ref: "docker.io/codercom/code-server:latest"
ignore-unfixed: true

View File

@@ -1,8 +1 @@
lib/vscode
lib/vscode-reh-web-linux-x64
release-standalone
release
helm-chart
test/scripts
test/e2e/extensions/test-extension
.pc
lib/vscode

2
.stylelintrc.yaml Normal file
View File

@@ -0,0 +1,2 @@
extends:
- stylelint-config-recommended

View File

@@ -20,116 +20,6 @@ Code v99.99.999
-->
## [4.8.2](https://github.com/coder/code-server/releases/tag/v4.8.2) - 2022-11-02
Code v1.72.1
### Added
- New text in the Getting Started page with info about
`coder/coder`. This is enabled by default but can be disabled by passing the CLI
flag `--disable-getting-started-override` or setting
`CS_DISABLE_GETTING_STARTED_OVERRIDE=1` or
`CS_DISABLE_GETTING_STARTED_OVERRIDE=true`.
## [4.8.1](https://github.com/coder/code-server/releases/tag/v4.8.1) - 2022-10-28
Code v1.72.1
### Fixed
- Fixed CSP error introduced in 4.8.0 that caused issues with webviews and most
extensions.
## [4.8.0](https://github.com/coder/code-server/releases/tag/v4.8.0) - 2022-10-24
Code v1.72.1
### Added
- Support for the Ports panel which leverages code-server's built-in proxy. It
also uses `VSCODE_PROXY_URI` where `{{port}}` is replace when forwarding a port.
Example: `VSCODE_PROXY_URI=https://{{port}}.kyle.dev` would forward an
application running on localhost:3000 to https://3000.kyle.dev
- Support for `--disable-workspace-trust` CLI flag
- Support for `--goto` flag to open file @ line:column
- Added Ubuntu-based images for Docker releases. If you run into issues with
`PATH` being overwritten in Docker please try the Ubuntu image as this is a
problem in the Debian base image.
### Changed
- Updated Code to 1.72.1
### Fixed
- Enabled `BROWSER` environment variable
- Patched `asExternalUri` to work so now extensions run inside code-server can use it
## [4.7.1](https://github.com/coder/code-server/releases/tag/v4.7.1) - 2022-09-30
Code v1.71.2
### Changed
- Updated Code to 1.71.2
### Fixed
- Fixed install script not upgrading code-server when already installed on RPM-based machines
- Fixed install script failing to gain root permissions on FreeBSD
## [4.7.0](https://github.com/coder/code-server/releases/tag/v4.7.0) - 2022-09-09
Code v1.71.0
### Changed
- Updated Code to 1.71.0
### Removed
- Dropped heartbeat patch because it was implemented upstream
### Fixed
- Add flags --unsafe-perm --legacy-peer-deps in `npm-postinstsall.sh` which ensures installing with npm works correctly
## [4.6.1](https://github.com/coder/code-server/releases/tag/v4.6.1) - 2022-09-31
Code v1.70.2
### Changed
- Updated Code to 1.70.2
- Updated `argon2` to 0.29.0 which should fix issues on FreeBSD
- Updated docs to suggest using `npm` instead of `yarn`
### Removed
- Dropped database migration patch affected to 4.0.2 versions and earlier.
### Fixed
- Fixed preservation of `process.execArgv` which means you can pass `--prof` to profile code-server
## [4.6.0](https://github.com/coder/code-server/releases/tag/v4.6.0) - 2022-08-17
Code v1.70.1
### Changed
- Updated Code to 1.70.1.
### Added
- Added a heartbeat to sockets. This should prevent them from getting closed by
reverse proxy timeouts when idle like NGINX's default 60-second timeout.
### Fixed
- Fixed logout option appearing even when authentication is disabled.
## [4.5.2](https://github.com/coder/code-server/releases/tag/v4.5.2) - 2022-08-15
Code v1.68.1

View File

@@ -18,8 +18,6 @@ main() {
VSCODE_SRC_PATH="lib/vscode"
VSCODE_OUT_PATH="$RELEASE_PATH/lib/vscode"
create_shrinkwraps
mkdir -p "$RELEASE_PATH"
bundle_code_server
@@ -57,6 +55,15 @@ bundle_code_server() {
EOF
) > "$RELEASE_PATH/package.json"
rsync yarn.lock "$RELEASE_PATH"
# To ensure deterministic dependency versions (even when code-server is installed with NPM), we seed
# an npm-shrinkwrap file from our yarn lockfile and the current node-modules installed.
synp --source-file yarn.lock
npm shrinkwrap
# HACK@edvincent: The shrinkwrap file will contain the devDependencies, which by default
# are installed if present in a lockfile. To avoid every user having to specify --production
# to skip them, we carefully remove them from the shrinkwrap file.
json -f npm-shrinkwrap.json -I -e "Object.keys(this.dependencies).forEach(dependency => { if (this.dependencies[dependency].dev) { delete this.dependencies[dependency] } } )"
mv npm-shrinkwrap.json "$RELEASE_PATH"
rsync ci/build/npm-postinstall.sh "$RELEASE_PATH/postinstall.sh"
@@ -98,44 +105,11 @@ bundle_vscode() {
"$VSCODE_SRC_PATH/package.json" > "$VSCODE_OUT_PATH/package.json"
rsync "$VSCODE_SRC_PATH/remote/yarn.lock" "$VSCODE_OUT_PATH/yarn.lock"
mv "$VSCODE_SRC_PATH/remote/npm-shrinkwrap.json" "$VSCODE_OUT_PATH/npm-shrinkwrap.json"
# 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"
mv "$VSCODE_SRC_PATH/extensions/npm-shrinkwrap.json" "$VSCODE_OUT_PATH/extensions/npm-shrinkwrap.json"
rsync "$VSCODE_SRC_PATH/extensions/postinstall.mjs" "$VSCODE_OUT_PATH/extensions/postinstall.mjs"
}
create_shrinkwraps() {
# yarn.lock or package-lock.json files (used to ensure deterministic versions of dependencies) are
# not packaged when publishing to the NPM registry.
# To ensure deterministic dependency versions (even when code-server is installed with NPM), we create
# an npm-shrinkwrap.json file from the currently installed node_modules. This ensures the versions used
# from development (that the yarn.lock guarantees) are also the ones installed by end-users.
# These will include devDependencies, but those will be ignored when installing globally (for code-server), and
# because we use --omit=dev when installing vscode.
# We first generate the shrinkwrap file for code-server itself - which is the current directory
create_shrinkwrap_keeping_yarn_lock
# Then the shrinkwrap files for the bundled VSCode
pushd "$VSCODE_SRC_PATH/remote/"
create_shrinkwrap_keeping_yarn_lock
popd
pushd "$VSCODE_SRC_PATH/extensions/"
create_shrinkwrap_keeping_yarn_lock
popd
}
create_shrinkwrap_keeping_yarn_lock() {
# HACK@edvincent: Generating a shrinkwrap alters the yarn.lock which we don't want (with NPM URLs rather than the Yarn URLs)
# But to generate a valid shrinkwrap, it has to exist... So we copy it to then restore it
cp yarn.lock yarn.lock.temp
npm shrinkwrap
cp yarn.lock.temp yarn.lock
rm yarn.lock.temp
}
main "$@"

View File

@@ -24,8 +24,11 @@ main() {
rsync ./ci/build/code-server.sh "$RELEASE_PATH/bin/code-server"
rsync "$node_path" "$RELEASE_PATH/lib/node"
ln -s "./bin/code-server" "$RELEASE_PATH/code-server"
ln -s "./lib/node" "$RELEASE_PATH/node"
pushd "$RELEASE_PATH"
npm install --unsafe-perm --omit=dev
yarn --production --frozen-lockfile
popd
}

View File

@@ -23,9 +23,6 @@ copy-bin-script() {
# shellcheck disable=SC2016
sed -i.bak 's/^ROOT=\(.*\)$/VSROOT=\1\nROOT="$(dirname "$(dirname "$VSROOT")")"/g' "$dest"
sed -i.bak 's/ROOT\/out/VSROOT\/out/g' "$dest"
# We do not want expansion here; this text should make it to the file as-is.
# shellcheck disable=SC2016
sed -i.bak 's/$ROOT\/node/${NODE_EXEC_PATH:-$ROOT\/lib\/node}/g' "$dest"
# Fix Node path on Windows.
sed -i.bak 's/^set ROOT_DIR=\(.*\)$/set ROOT_DIR=%~dp0..\\..\\..\\..\r\nset VSROOT_DIR=\1/g' "$dest"
@@ -82,10 +79,7 @@ main() {
"newsletterSignupUrl": "https://www.research.net/r/vsc-newsletter",
"linkProtectionTrustedDomains": [
"https://open-vsx.org"
],
"aiConfig": {
"ariaKey": "code-server"
}
]
}
EOF
) > product.json

View File

@@ -11,6 +11,14 @@ _realpath() {
cd "$(dirname "$script")"
while [ -L "$(basename "$script")" ]; do
if [ -L "./node" ] && [ -L "./code-server" ] \
&& [ -f "package.json" ] \
&& cat package.json | grep -q '^ "name": "code-server",$'; then
echo "***** Please use the script in bin/code-server instead!" >&2
echo "***** This script will soon be removed!" >&2
echo "***** See the release notes at https://github.com/coder/code-server/releases/tag/v3.4.0" >&2
fi
script="$(readlink "$(basename "$script")")"
cd "$(dirname "$script")"
done

View File

@@ -110,7 +110,7 @@ main() {
echo "Failed to download cloud agent; --link will not work"
fi
if ! vscode_install; then
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/main/docs/npm.md"
exit 1
@@ -123,47 +123,17 @@ main() {
fi
}
install_with_yarn_or_npm() {
# NOTE@edvincent: We want to keep using the package manager that the end-user was using to install the package.
# This also ensures that when *we* run `yarn` in the development process, the yarn.lock file is used.
case "${npm_config_user_agent-}" in
yarn*)
if [ -f "yarn.lock" ]; then
yarn --production --frozen-lockfile --no-default-rc
else
echo "yarn.lock file not present, not running in development mode. use npm to install code-server!"
exit 1
fi
;;
npm*)
if [ -f "yarn.lock" ]; then
echo "yarn.lock file present, running in development mode. use yarn to install code-server!"
exit 1
else
# HACK: NPM's use of semver doesn't like resolving some peerDependencies that vscode (upstream) brings in the form of pre-releases.
# The legacy behavior doesn't complain about pre-releases being used, falling back to that for now.
# See https://github.com//pull/5071
npm install --unsafe-perm --legacy-peer-deps --omit=dev
fi
;;
*)
echo "Could not determine which package manager is being used to install code-server"
exit 1
;;
esac
}
vscode_install() {
vscode_yarn() {
echo 'Installing Code dependencies...'
cd lib/vscode
install_with_yarn_or_npm
yarn --production --frozen-lockfile --no-default-rc
symlink_asar
symlink_bin_script remote-cli code code-server
symlink_bin_script helpers browser browser .sh
cd extensions
install_with_yarn_or_npm
yarn --production --frozen-lockfile
}
main "$@"

View File

@@ -0,0 +1,28 @@
#!/usr/bin/env bash
set -euo pipefail
# Downloads the release artifacts from CI for the current
# commit and then uploads them to the release with the version
# in package.json.
# You will need $GITHUB_TOKEN set.
main() {
cd "$(dirname "$0")/../.."
source ./ci/lib.sh
source ./ci/steps/steps-lib.sh
# NOTE@jsjoeio - only needed if we use the download_artifact
# because we talk to the GitHub API.
# Needed to use GitHub API
if ! is_env_var_set "GITHUB_TOKEN"; then
echo "GITHUB_TOKEN is not set. Cannot download npm release-packages without GitHub credentials."
exit 1
fi
download_artifact release-packages ./release-packages
local assets=(./release-packages/code-server*"$VERSION"*{.tar.gz,.deb,.rpm})
EDITOR=true gh release upload "v$VERSION" "${assets[@]}" --clobber
}
main "$@"

View File

@@ -0,0 +1,50 @@
#!/usr/bin/env bash
set -euo pipefail
# Creates a draft release with the template for the version in package.json
main() {
cd "$(dirname "$0")/../.."
source ./ci/lib.sh
gh release create "v$VERSION" \
--notes-file - \
--target "$(git rev-parse HEAD)" \
--draft << EOF
v$VERSION
VS Code v$(vscode_version)
Upgrading is as easy as installing the new version over the old one. code-server
maintains all user data in \`~/.local/share/code-server\` so that it is preserved in between
installations.
## New Features
⭐ Summarize new features here with references to issues
- item
## Bug Fixes
⭐ Summarize bug fixes here with references to issues
- item
## Documentation
⭐ Summarize doc changes here with references to issues
- item
## Development
⭐ Summarize development/testing changes here with references to issues
- item
Cheers! 🍻
EOF
}
main "$@"

View File

@@ -9,9 +9,6 @@
set -euo pipefail
CHECKMARK="\xE2\x9C\x94"
DASH="-"
main() {
if [ "${DRY_RUN-}" = 1 ]; then
echo "Performing a dry run..."
@@ -79,12 +76,11 @@ main() {
CODE_SERVER_CURRENT_VERSION=$(node -pe "require('./package.json').version")
# Ask which version we should update to
# In the future, we'll automate this and determine the latest version automatically
echo -e "$DASH Current version: ${CODE_SERVER_CURRENT_VERSION}"
echo "Current version: ${CODE_SERVER_CURRENT_VERSION}"
# The $'\n' adds a line break. See: https://stackoverflow.com/a/39581815/3015595
CODE_SERVER_VERSION_TO_UPDATE=$(git rev-parse --abbrev-ref HEAD | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/')
echo -e "$CHECKMARK Version in branch name"
echo -e "$CHECKMARK Updating to: $CODE_SERVER_VERSION_TO_UPDATE"
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' -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"
@@ -94,7 +90,7 @@ main() {
echo -e "\nOpening a draft PR on GitHub"
# To read about these flags, visit the docs: https://cli.github.com/manual/gh_pr_create
$CMD gh pr create --base main --title "release: $CODE_SERVER_VERSION_TO_UPDATE" --body "$RELEASE_TEMPLATE_STRING" --reviewer @coder/code-server --repo coder/code-server --draft --assignee "@me"
$CMD gh pr create --base main --title "release: $CODE_SERVER_VERSION_TO_UPDATE" --body "$RELEASE_TEMPLATE_STRING" --reviewer @coder/code-server-reviewers --repo coder/code-server --draft --assignee "@me"
# Open PR in browser
$CMD gh pr view --web

View File

@@ -4,6 +4,24 @@ set -euo pipefail
main() {
cd "$(dirname "$0")/../.."
local prettierExts
prettierExts=(
"*.js"
"*.ts"
"*.tsx"
"*.html"
"*.json"
"*.css"
"*.md"
"*.toml"
"*.yaml"
"*.yml"
"*.sh"
)
prettier --write --loglevel=warn $(
git ls-files "${prettierExts[@]}" | grep -v "lib/vscode" | grep -v 'helm-chart'
)
doctoc --title '# FAQ' docs/FAQ.md > /dev/null
doctoc --title '# Setup Guide' docs/guide.md > /dev/null
doctoc --title '# Install' docs/install.md > /dev/null
@@ -14,11 +32,12 @@ main() {
doctoc --title '# iPad' docs/ipad.md > /dev/null
doctoc --title '# Termux' docs/termux.md > /dev/null
# TODO: replace with a method that generates fewer false positives.
if [[ ${CI-} && $(git ls-files --other --modified --exclude-standard) ]]; then
echo "Files need generation or are formatted incorrectly:"
git -c color.ui=always status | grep --color=no '\[31m'
echo "Please run the following locally:"
echo " yarn doctoc"
echo " yarn fmt"
exit 1
fi
}

View File

@@ -1,9 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
main() {
cd "$(dirname "$0")/../.."
shellcheck -e SC2046,SC2164,SC2154,SC1091,SC1090,SC2002 $(git ls-files '*.sh' | grep -v 'lib/vscode')
}
main "$@"

18
ci/dev/lint.sh Executable file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env bash
set -euo pipefail
main() {
cd "$(dirname "$0")/../.."
eslint --max-warnings=0 --fix $(git ls-files "*.ts" "*.tsx" "*.js" | grep -v "lib/vscode")
stylelint $(git ls-files "*.css" | grep -v "lib/vscode")
tsc --noEmit --skipLibCheck
shellcheck -e SC2046,SC2164,SC2154,SC1091,SC1090,SC2002 $(git ls-files "*.sh" | grep -v "lib/vscode")
if command -v helm && helm kubeval --help > /dev/null; then
helm kubeval ci/helm-chart
fi
cd "$OLDPWD"
}
main "$@"

View File

@@ -1,39 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
help() {
echo >&2 " You can build the standalone release with 'yarn release:standalone'"
echo >&2 " Or you can pass in a custom path."
echo >&2 " CODE_SERVER_PATH='/var/tmp/coder/code-server/bin/code-server' yarn test:integration"
}
# Make sure a code-server release works. You can pass in the path otherwise it
# will look for release-standalone in the current directory.
#
# This is to make sure we don't have Node version errors or any other
# compilation-related errors.
main() {
cd "$(dirname "$0")/../.."
source ./ci/lib.sh
local path="$RELEASE_PATH-standalone/bin/code-server"
if [[ ! ${CODE_SERVER_PATH-} ]]; then
echo "Set CODE_SERVER_PATH to test another build of code-server"
else
path="$CODE_SERVER_PATH"
fi
echo "Running tests with code-server binary: '$path'"
if [[ ! -f $path ]]; then
echo >&2 "No code-server build detected"
echo >&2 "Looked in $path"
help
exit 1
fi
CODE_SERVER_PATH="$path" ./test/node_modules/.bin/jest "$@" --coverage=false --testRegex "./test/integration/help.test.ts"
}
main "$@"

View File

@@ -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: 3.3.2
version: 3.1.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.8.2
appVersion: 4.5.2

View File

@@ -6,7 +6,7 @@ replicaCount: 1
image:
repository: codercom/code-server
tag: '4.8.2'
tag: '4.5.2'
pullPolicy: Always
# Specifies one or more secrets to be used when pulling images from a

View File

@@ -44,6 +44,47 @@ arch() {
echo "$cpu"
}
# Grabs the most recent ci.yaml github workflow run that was triggered from the
# pull request of the release branch for this version (regardless of whether
# that run succeeded or failed). The release branch name must be in semver
# format with a v prepended.
# This will contain the artifacts we want.
# https://developer.github.com/v3/actions/workflow-runs/#list-workflow-runs
get_artifacts_url() {
local artifacts_url
local version_branch="release/v$VERSION"
local workflow_runs_url="repos/:owner/:repo/actions/workflows/ci.yaml/runs?event=pull_request&branch=$version_branch"
artifacts_url=$(gh api "$workflow_runs_url" | jq -r ".workflow_runs[] | select(.head_branch == \"$version_branch\") | .artifacts_url" | head -n 1)
if [[ -z "$artifacts_url" ]]; then
echo >&2 "ERROR: artifacts_url came back empty"
echo >&2 "We looked for a successful run triggered by a pull_request with for code-server version: $VERSION and a branch named $version_branch"
echo >&2 "URL used for gh API call: $workflow_runs_url"
exit 1
fi
echo "$artifacts_url"
}
# Grabs the artifact's download url.
# https://developer.github.com/v3/actions/artifacts/#list-workflow-run-artifacts
get_artifact_url() {
local artifact_name="$1"
gh api "$(get_artifacts_url)" | jq -r ".artifacts[] | select(.name == \"$artifact_name\") | .archive_download_url" | head -n 1
}
# Uses the above two functions to download a artifact into a directory.
download_artifact() {
local artifact_name="$1"
local dst="$2"
local tmp_file
tmp_file="$(mktemp)"
gh api "$(get_artifact_url "$artifact_name")" > "$tmp_file"
unzip -q -o "$tmp_file" -d "$dst"
rm "$tmp_file"
}
rsync() {
command rsync -a --del "$@"
}

View File

@@ -1,13 +1,12 @@
# syntax=docker/dockerfile:experimental
ARG BASE=debian:11
FROM scratch AS packages
COPY release-packages/code-server*.deb /tmp/
FROM $BASE
FROM debian:11
RUN apt-get update \
&& apt-get install -y \
&& apt-get install -y \
curl \
dumb-init \
zsh \
@@ -30,15 +29,15 @@ RUN sed -i "s/# en_US.UTF-8/en_US.UTF-8/" /etc/locale.gen \
&& locale-gen
ENV LANG=en_US.UTF-8
RUN adduser --gecos '' --disabled-password coder \
&& echo "coder ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/nopasswd
RUN adduser --gecos '' --disabled-password coder && \
echo "coder ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/nopasswd
RUN ARCH="$(dpkg --print-architecture)" \
&& curl -fsSL "https://github.com/boxboat/fixuid/releases/download/v0.5/fixuid-0.5-linux-$ARCH.tar.gz" | tar -C /usr/local/bin -xzf - \
&& chown root:root /usr/local/bin/fixuid \
&& chmod 4755 /usr/local/bin/fixuid \
&& mkdir -p /etc/fixuid \
&& printf "user: coder\ngroup: coder\n" > /etc/fixuid/config.yml
RUN ARCH="$(dpkg --print-architecture)" && \
curl -fsSL "https://github.com/boxboat/fixuid/releases/download/v0.5/fixuid-0.5-linux-$ARCH.tar.gz" | tar -C /usr/local/bin -xzf - && \
chown root:root /usr/local/bin/fixuid && \
chmod 4755 /usr/local/bin/fixuid && \
mkdir -p /etc/fixuid && \
printf "user: coder\ngroup: coder\n" > /etc/fixuid/config.yml
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

View File

@@ -6,63 +6,17 @@ variable "VERSION" {
default = "latest"
}
variable "DOCKER_REGISTRY" {
default = "docker.io/codercom/code-server"
}
variable "GITHUB_REGISTRY" {
default = "ghcr.io/coder/code-server"
}
group "default" {
targets = [
"code-server-debian-11",
"code-server-ubuntu-focal",
targets = ["code-server"]
}
target "code-server" {
dockerfile = "ci/release-image/Dockerfile"
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}" : "",
]
}
function "prepend_hyphen_if_not_null" {
params = [tag]
result = notequal("","${tag}") ? "-${tag}" : "${tag}"
}
# use empty tag (tag="") to generate default tags
function "gen_tags" {
params = [registry, tag]
result = notequal("","${registry}") ? [
notequal("", "${tag}") ? "${registry}:${tag}" : "${registry}:latest",
notequal("latest",VERSION) ? "${registry}:${VERSION}${prepend_hyphen_if_not_null(tag)}" : "",
] : []
}
# helper function to generate tags for docker registry and github registry.
# set (DOCKER|GITHUB)_REGISTRY="" to disable corresponding registry
function "gen_tags_for_docker_and_ghcr" {
params = [tag]
result = concat(
gen_tags("${DOCKER_REGISTRY}", "${tag}"),
gen_tags("${GITHUB_REGISTRY}", "${tag}"),
)
}
target "code-server-debian-11" {
dockerfile = "ci/release-image/Dockerfile"
tags = concat(
gen_tags_for_docker_and_ghcr(""),
gen_tags_for_docker_and_ghcr("debian"),
gen_tags_for_docker_and_ghcr("bullseye"),
)
platforms = ["linux/amd64", "linux/arm64"]
}
target "code-server-ubuntu-focal" {
dockerfile = "ci/release-image/Dockerfile"
tags = concat(
gen_tags_for_docker_and_ghcr("ubuntu"),
gen_tags_for_docker_and_ghcr("focal"),
)
args = {
BASE = "ubuntu:focal"
}
platforms = ["linux/amd64", "linux/arm64"]
}

View File

@@ -65,8 +65,7 @@ main() {
# "production" - this means we tag with `latest` (default), allowing
# 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."
echo "Determining in script based on GITHUB environment variables."
echo "NPM_ENVIRONMENT is not set. Determining in script based on GITHUB environment variables."
if [[ "$GITHUB_EVENT_NAME" == 'push' && "$GITHUB_REF" == 'refs/heads/main' ]]; then
NPM_ENVIRONMENT="staging"
@@ -74,6 +73,7 @@ main() {
NPM_ENVIRONMENT="development"
fi
echo "Using npm environment: $NPM_ENVIRONMENT"
fi
# NOTE@jsjoeio - this script assumes we have the artifact downloaded on disk
@@ -96,6 +96,9 @@ main() {
NPM_TAG="latest"
else
COMMIT_SHA="$GITHUB_SHA"
echo "Not a production environment"
echo "Found environment: $NPM_ENVIRONMENT"
echo "Manually bumping npm version..."
if [[ "$NPM_ENVIRONMENT" == "staging" ]]; then
NPM_VERSION="$VERSION-beta-$COMMIT_SHA"
@@ -114,10 +117,8 @@ main() {
NPM_TAG="$PR_NUMBER"
fi
echo "- tag: $NPM_TAG"
echo "- version: $NPM_VERSION"
echo "- package name: $PACKAGE_NAME"
echo "- npm environment: $NPM_ENVIRONMENT"
echo "using tag: $NPM_TAG"
echo "using package name: $PACKAGE_NAME"
# We modify the version in the package.json
# to be the current version + the PR number + commit SHA
@@ -139,13 +140,13 @@ main() {
popd
fi
# NOTE@jsjoeio
# We need to make sure we haven't already published the version.
# If we get error, continue with script because we want to publish
# If version is valid, we check if we're publishing the same one
# This is because npm view won't exit with non-zero so we have
# to check the output.
local hasVersion
if hasVersion=$(npm view "$PACKAGE_NAME@$NPM_VERSION" version 2> /dev/null) && [[ $hasVersion == "$NPM_VERSION" ]]; then
echo "$NPM_VERSION is already published under $PACKAGE_NAME"
hasVersion=$(npm view "code-server@$NPM_VERSION" version)
if [[ $hasVersion == "$NPM_VERSION" ]]; then
echo "$NPM_VERSION is already published"
return
fi

View File

@@ -1,18 +1,5 @@
<!-- prettier-ignore-start -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
# Contributor Covenant Code of Conduct
- [Contributor Covenant Code of Conduct](#contributor-covenant-code-of-conduct)
- [Our Pledge](#our-pledge)
- [Our Standards](#our-standards)
- [Our Responsibilities](#our-responsibilities)
- [Scope](#scope)
- [Enforcement](#enforcement)
- [Attribution](#attribution)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- prettier-ignore-end -->
# Contributor Covenant Code of Conduct

View File

@@ -1,4 +1,3 @@
<!-- prettier-ignore-start -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
# Contributing
@@ -25,7 +24,6 @@
- [Currently Known Issues](#currently-known-issues)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- prettier-ignore-end -->
- [Detailed CI and build process docs](../ci)
@@ -113,15 +111,6 @@ re-apply the patches.
6. Commit the updated submodule and patches to `code-server`.
7. Open a PR.
Tip: if you're certain all patches are applied correctly and you simply need to
refresh, you can use this trick:
```shell
while quilt push; do quilt refresh; done
```
[Source](https://raphaelhertzog.com/2012/08/08/how-to-use-quilt-to-manage-patches-in-debian-packages/)
### Patching Code
0. You can go through the patch stack with `quilt push` and `quilt pop`.
@@ -152,7 +141,7 @@ Run your build:
```shell
cd release
npm install --omit=dev # Skip if you used KEEP_MODULES=1
yarn --production # Skip if you used KEEP_MODULES=1
# Runs the built JavaScript with Node.
node .
```

View File

@@ -1,4 +1,3 @@
<!-- prettier-ignore-start -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
# FAQ
@@ -32,10 +31,8 @@
- [Does code-server have any security login validation?](#does-code-server-have-any-security-login-validation)
- [Are there community projects involving code-server?](#are-there-community-projects-involving-code-server)
- [How do I change the port?](#how-do-i-change-the-port)
- [How do I hide the coder/coder promotion in Help: Getting Started?](#how-do-i-hide-the-codercoder-promotion-in-help-getting-started)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- prettier-ignore-end -->
## Questions?
@@ -419,9 +416,3 @@ There are two ways to change the port on which code-server runs:
1. with an environment variable e.g. `PORT=3000 code-server`
2. using the flag `--bind-addr` e.g. `code-server --bind-addr localhost:3000`
## How do I hide the coder/coder promotion in Help: Getting Started?
You can pass the flag `--disable-getting-started-override` to `code-server` or
you can set the environment variable `CS_DISABLE_GETTING_STARTED_OVERRIDE=1` or
`CS_DISABLE_GETTING_STARTED_OVERRIDE=true`.

View File

@@ -1,4 +1,3 @@
<!-- prettier-ignore-start -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
# Maintaining
@@ -9,13 +8,13 @@
- [Workflow](#workflow)
- [Milestones](#milestones)
- [Triage](#triage)
- [Project boards](#project-boards)
- [Versioning](#versioning)
- [Pull requests](#pull-requests)
- [Merge strategies](#merge-strategies)
- [Changelog](#changelog)
- [Releases](#releases)
- [Publishing a release](#publishing-a-release)
- [Release Candidates](#release-candidates)
- [AUR](#aur)
- [Docker](#docker)
- [Homebrew](#homebrew)
@@ -26,7 +25,6 @@
- [Troubleshooting](#troubleshooting)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- prettier-ignore-end -->
This document is meant to serve current and future maintainers of code-server,
as well as share our workflow for maintaining the project.
@@ -44,7 +42,7 @@ Occasionally, other Coder employees may step in time to time to assist with code
To onboard a new maintainer to the project, please make sure to do the following:
- [ ] Add to [coder/code-server](https://github.com/orgs/coder/teams/code-server)
- [ ] Add to [coder/code-server-reviewers](https://github.com/orgs/coder/teams/code-server-reviewers)
- [ ] Add as Admin under [Repository Settings > Access](https://github.com/coder/code-server/settings/access)
- [ ] Add to [npm Coder org](https://www.npmjs.com/org/coder)
- [ ] Add as [AUR maintainer](https://aur.archlinux.org/packages/code-server/) (talk to Colin)
@@ -74,7 +72,7 @@ Here are the milestones we use and how we use them:
- "On Deck" -> Work under consideration for upcoming milestones.
- "Backlog Candidates" -> Work that is not yet accepted for the backlog. We wait
for the community to weigh in.
- "<Month>" -> Work to be done for said month.
- "<0.0.0>" -> Work to be done for a specific version.
With this flow, any un-assigned issues are essentially in triage state. Once
triaged, issues are either "Backlog" or "Backlog Candidates". They will
@@ -93,6 +91,19 @@ We use the following process for triaging GitHub issues:
2. If not urgent, add to "Backlog"
3. Otherwise, add to "Backlog Candidate" for future consideration
### Project boards
We use project boards for projects or goals that span multiple milestones.
Think of this as a place to put miscellaneous things (like testing, clean up
stuff, etc). As a maintainer, random tasks may come up here and there. The
project boards give you places to add temporary notes before opening a new
issue. Given that our release milestones function off of issues, we believe
tasks should have dedicated issues.
Project boards also give us a way to separate the issue triage from
bigger-picture, long-term work.
## Versioning
`<major.minor.patch>`
@@ -140,26 +151,43 @@ changelog](https://github.com/emacs-mirror/emacs/blob/master/etc/NEWS).
## Releases
With each release, we rotate the role of release manager to ensure every
maintainer goes through the process. This helps us keep documentation up-to-date
and encourages us to continually review and improve the flow.
If you're the current release manager, follow these steps:
1. Create a [release issue](../.github/ISSUE_TEMPLATE/release.md)
1. Fill out checklist
1. Publish the release
1. After release is published, close release milestone
### Publishing a release
1. Create a new branch called `release/v0.0.0` (replace 0s with actual version aka v4.5.0)
1. Run `yarn release:prep`
1. If you don't do this, the `npm-brew` GitHub workflow will fail. It looks for the release artifacts under the branch pattern.
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
before proceeding.
1. Run `yarn release:github-draft` to create a GitHub draft release from the
template with the updated version. Make sure to update the `CHANGELOG.md`.
1. Bump chart version in `Chart.yaml`.
1. Summarize the major changes in the `CHANGELOG.md`
1. Download CI artifacts and make sure code-server works locally.
1. Merge PR and wait for CI build on `main` to finish.
1. Go to GitHub Actions > Draft release > Run workflow off `main`. CI will automatically upload the artifacts to the release.
1. Add the release notes from the `CHANGELOG.md` and publish release. CI will automatically grab the
1. Summarize the major changes in the release notes and link to the relevant
issues.
1. Change the @ to target the version branch. Example: `v3.9.0 @ Target: release/v3.9.0`
1. Wait for the `npm-package`, `release-packages` and `release-images` artifacts
to build.
1. Run `yarn release:github-assets` to download the `release-packages` artifact.
They will upload them to the draft release.
1. Run some basic sanity tests on one of the released packages (pay special
attention to making sure the terminal works).
1. Publish the release and merge the PR. CI will automatically grab the
artifacts, publish the NPM package from `npm-package`, and publish the Docker
Hub image from `release-images`.
#### Release Candidates
We prefer to do release candidates so the community can test things before a full-blown release. To do this follow the same steps as above but:
1. Only bump version in `package.json`
1. use `0.0.0-rc.0`
1. When you publish the release, select "pre-release"
1. Update the AUR package. Instructions for updating the AUR package are at
[coder/code-server-aur](https://github.com/coder/code-server-aur).
1. Wait for the npm package to be published.
#### AUR

View File

@@ -16,10 +16,10 @@ We use the following tools to help us stay on top of vulnerability mitigation.
- [trivy](https://github.com/aquasecurity/trivy)
- Comprehensive vulnerability scanner that runs on PRs into the default
branch and scans both our container image and repository code (see
`trivy-scan-repo` and `trivy-scan-image` jobs in `build.yaml`)
`trivy-scan-repo` and `trivy-scan-image` jobs in `ci.yaml`)
- [`audit-ci`](https://github.com/IBM/audit-ci)
- Audits npm and Yarn dependencies in CI (see `Audit for vulnerabilities` step
in `build.yaml`) on PRs into the default branch and fails CI if moderate or
in `ci.yaml`) on PRs into the default branch and fails CI if moderate or
higher vulnerabilities (see the `audit.sh` script) are present.
## Supported Versions

View File

@@ -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 and `curl` 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
@@ -18,6 +18,6 @@ nvm install 16
nvm use 16
```
8. Install code-server globally on device with: `npm install --global code-server --unsafe-perm`
8. Install code-server globally on device with: `npm i -g code-server`
9. Run code-server with `code-server`
10. Access on localhost:8080 in your browser

View File

@@ -1,3 +1 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.8 3.6H0V16.2C0 17.19 0.81 18 1.8 18H14.4V16.2H1.8V3.6ZM16.2 0H5.4C4.41 0 3.6 0.81 3.6 1.8V12.6C3.6 13.59 4.41 14.4 5.4 14.4H16.2C17.19 14.4 18 13.59 18 12.6V1.8C18 0.81 17.19 0 16.2 0ZM16.2 9L13.95 7.65L11.7 9V1.8H16.2V9Z" fill="black"/>
</svg>
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 10l-2.5-1.5L15 12V4h5v8z"></path></svg>

Before

Width:  |  Height:  |  Size: 352 B

After

Width:  |  Height:  |  Size: 221 B

View File

@@ -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/latest/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.5.2/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.

View File

@@ -1,4 +1,3 @@
<!-- prettier-ignore-start -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
# Setup Guide
@@ -17,13 +16,11 @@
- [Stripping `/proxy/<port>` from the request path](#stripping-proxyport-from-the-request-path)
- [Proxying to create a React app](#proxying-to-create-a-react-app)
- [Proxying to a Vue app](#proxying-to-a-vue-app)
- [Proxying to an Angular app](#proxying-to-an-angular-app)
- [SSH into code-server on VS Code](#ssh-into-code-server-on-vs-code)
- [Option 1: cloudflared tunnel](#option-1-cloudflared-tunnel)
- [Option 2: ngrok tunnel](#option-2-ngrok-tunnel)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- prettier-ignore-end -->
This article will walk you through exposing code-server securely once you've
completed the [installation process](install.md).
@@ -91,10 +88,11 @@ we recommend using another method, such as [Let's Encrypt](#let-encrypt) instead
using [mutagen](https://mutagen.io/documentation/introduction/installation)
to do so. Once you've installed mutagen, you can port forward as follows:
```shell
```console
# This is the same as the above SSH command, but it runs in the background
# continuously. Be sure to add `mutagen daemon start` to your ~/.bashrc to
# start the mutagen daemon when you open a shell.
mutagen forward create --name=code-server tcp:127.0.0.1:8080 < instance-ip > :tcp:127.0.0.1:8080
```
@@ -384,15 +382,6 @@ module.exports = {
Read more about `publicPath` in the [Vue.js docs](https://cli.vuejs.org/config/#publicpath)
### Proxying to an Angular app
In order to use code-server's built-in proxy with Angular, you need to make the following changes in your app:
1. use `<base href="./.">` in `src/index.html`
2. add `--serve-path /absproxy/4200` to `ng serve` in your `package.json`
For additional context, see [this GitHub Discussion](https://github.com/coder/code-server/discussions/5439#discussioncomment-3371983).
## SSH into code-server on VS Code
[![SSH](https://img.shields.io/badge/SSH-363636?style=for-the-badge&logo=GNU+Bash&logoColor=ffffff)](https://ohmyz.sh/) [![Terminal](https://img.shields.io/badge/Terminal-2E2E2E?style=for-the-badge&logo=Windows+Terminal&logoColor=ffffff)](https://img.shields.io/badge/Terminal-2E2E2E?style=for-the-badge&logo=Windows+Terminal&logoColor=ffffff) [![Visual Studio Code](https://img.shields.io/badge/Visual_Studio_Code-007ACC?style=for-the-badge&logo=Visual+Studio+Code&logoColor=ffffff)](vscode:extension/ms-vscode-remote.remote-ssh)
@@ -418,20 +407,20 @@ sudo passwd {user} # replace user with your code-server user
[![Cloudflared](https://img.shields.io/badge/Cloudflared-E4863B?style=for-the-badge&logo=cloudflare&logoColor=ffffff)](https://github.com/cloudflare/cloudflared)
1. Install [cloudflared](https://github.com/cloudflare/cloudflared#installing-cloudflared) on your local computer and remote server
2. Then go to `~/.ssh/config` and add the following on your local computer:
1. Install [cloudflared](https://github.com/cloudflare/cloudflared#installing-cloudflared) on your local computer
2. Then go to `~/.ssh/config` and add the following:
```shell
Host *.trycloudflare.com
HostName %h
User user
User root
Port 22
ProxyCommand "cloudflared location" access ssh --hostname %h
```
3. Run `cloudflared tunnel --url ssh://localhost:22` on the remote server
4. Finally on VS Code or any IDE that supports SSH, run `ssh user@https://your-link.trycloudflare.com` or `ssh user@your-link.trycloudflare.com`
4. Finally on VS Code or any IDE that supports SSH, run `ssh coder@https://your-link.trycloudflare.com` or `ssh coder@your-link.trycloudflare.com`
### Option 2: ngrok tunnel

View File

@@ -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.8.0](https://img.shields.io/badge/AppVersion-4.8.0-informational?style=flat-square)](https://img.shields.io/badge/AppVersion-4.8.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.5.2](https://img.shields.io/badge/AppVersion-4.5.2-informational?style=flat-square)](https://img.shields.io/badge/AppVersion-4.5.2-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.8.0"` |
| image.tag | string | `"4.5.2"` |
| imagePullSecrets | list | `[]` |
| ingress.enabled | bool | `false` |
| nameOverride | string | `""` |

View File

@@ -1,11 +1,10 @@
<!-- prettier-ignore-start -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
# Install
- [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)
@@ -21,11 +20,10 @@
- [Uninstall](#uninstall)
- [install.sh](#installsh-1)
- [Homebrew](#homebrew)
- [npm](#npm-1)
- [yarn, npm](#yarn-npm-1)
- [Debian, Ubuntu](#debian-ubuntu-1)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- prettier-ignore-end -->
This document demonstrates how to install `code-server` on various distros and
operating systems.
@@ -90,16 +88,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
@@ -109,9 +108,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) 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
@@ -119,7 +118,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
@@ -153,11 +152,11 @@ 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
sudo dpkg -i code-server_${VERSION}_amd64.deb
curl -fOL https://github.com/coder/code-server/releases/download/v$VERSION/code-server_$VERSION_amd64.deb
sudo dpkg -i code-server_$VERSION_amd64.deb
sudo systemctl enable --now code-server@$USER
# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml
```
@@ -165,7 +164,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
@@ -296,13 +295,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).
If you see an error related to `node-gyp` during installation, See [#5174](https://github.com/coder/code-server/issues/5174) for more information.
@@ -346,12 +346,18 @@ brew remove code-server
brew uninstall code-server
```
### npm
### yarn, npm
To remove the code-server global module, run:
```shell
npm uninstall --global code-server
yarn global remove code-server
```
or
```shell
npm uninstall -g code-server
```
### Debian, Ubuntu

View File

@@ -1,4 +1,3 @@
<!-- prettier-ignore-start -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
# iPad
@@ -14,7 +13,6 @@
- [Sharing a self-signed certificate with an iPad](#sharing-a-self-signed-certificate-with-an-ipad)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- prettier-ignore-end -->
Once you've installed code-server, you can access it from an iPad.

View File

@@ -1,5 +1,5 @@
{
"versions": ["v4.8.0"],
"versions": ["v4.5.2"],
"routes": [
{
"title": "Home",
@@ -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"
},
{

View File

@@ -1,4 +1,3 @@
<!-- prettier-ignore-start -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
# npm Install Requirements
@@ -16,17 +15,11 @@
- [Debugging install issues with npm](#debugging-install-issues-with-npm)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- prettier-ignore-end -->
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 Code's remote, which is
@@ -79,7 +72,7 @@ Proceed to [installing](#installing)
## FreeBSD
```sh
pkg install -y git python npm-node16 pkgconf
pkg install -y git python npm-node16 yarn-node16 pkgconf
pkg install -y libinotify
```
@@ -92,7 +85,8 @@ Installing code-server requires all of the [prerequisites for VS Code developmen
Next, install code-server with:
```bash
npm install --global code-server --unsafe-perm
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
```
@@ -102,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).
@@ -112,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 --global code-server --unsafe-perm
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
```
@@ -126,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.
@@ -140,12 +136,12 @@ A step-by-step example of how you might do this is:
### Debugging install issues with npm
To debug installation issues, install with `npm`:
`yarn` suppresses logs when running `yarn global add`, so to debug installation issues, install with `npm` instead:
```shell
# Uninstall
npm uninstall --global --unsafe-perm code-server > /dev/null 2>&1
npm uninstall -g --unsafe-perm code-server > /dev/null 2>&1
# Install with logging
npm install --loglevel verbose --global --unsafe-perm code-server
npm install --loglevel verbose -g --unsafe-perm code-server
```

View File

@@ -1,10 +1,9 @@
<!-- prettier-ignore-start -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
# Termux
- [Install](#install)
- [NPM Installation](#npm-installation)
- [Yarn Installation](#yarn-installation)
- [Upgrade](#upgrade)
- [Known Issues](#known-issues)
- [Git won't work in `/sdcard`](#git-wont-work-in-sdcard)
@@ -15,7 +14,6 @@
- [Working with PRoot](#working-with-proot)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- prettier-ignore-end -->
## Install
@@ -68,7 +66,7 @@ curl -fsSL https://code-server.dev/install.sh | sh
> Consider using a new user instead of root, read [here](https://www.howtogeek.com/124950/htg-explains-why-you-shouldnt-log-into-your-linux-system-as-root/) why using root is not recommended.\
> Learn how to add a user [here](#create-a-new-user).
## NPM Installation
## Yarn Installation
1. Get [Termux](https://f-droid.org/en/packages/com.termux/) from **F-Droid**.
@@ -95,6 +93,7 @@ pkg install -y \
binutils \
pkg-config \
python3 \
yarn \
nodejs-lts
npm config set python python3
node -v
@@ -102,7 +101,11 @@ node -v
you will get node version `v16.15.0`
5. Now install code-server following our guide on [installing with npm](./npm.md)
5. Now install code-server
```sh
yarn global add code-server
```
6. Congratulation code-server is installed on your device using the following command.
@@ -113,7 +116,7 @@ code-server --auth none
7. If already installed then use the following command for upgradation.
```
npm update --global code-server --unsafe-perm
yarn upgrade code-server
```
## Upgrade

41
flake.lock generated
View File

@@ -1,41 +0,0 @@
{
"nodes": {
"flake-utils": {
"locked": {
"lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1660639432,
"narHash": "sha256-2WDiboOCfB0LhvnDVMXOAr8ZLDfm3WdO54CkoDPwN1A=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "6c6409e965a6c883677be7b9d87a95fab6c3472e",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

View File

@@ -1,25 +0,0 @@
{
description = "code-server";
inputs.flake-utils.url = "github:numtide/flake-utils";
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem
(system:
let pkgs = nixpkgs.legacyPackages.${system};
nodejs = pkgs.nodejs-16_x;
yarn' = pkgs.yarn.override { inherit nodejs; };
in {
devShells.default = pkgs.mkShell {
nativeBuildInputs = with pkgs; [
nodejs yarn' python pkg-config git rsync jq moreutils
];
buildInputs = with pkgs; (lib.optionals (!stdenv.isDarwin) [ libsecret ]
++ (with xorg; [ libX11 libxkbfile ])
++ lib.optionals stdenv.isDarwin [
AppKit Cocoa CoreServices Security cctools xcbuild
]);
};
}
);
}

View File

@@ -364,7 +364,7 @@ install_rpm() {
fetch "https://github.com/coder/code-server/releases/download/v$VERSION/code-server-$VERSION-$ARCH.rpm" \
"$CACHE_DIR/code-server-$VERSION-$ARCH.rpm"
sudo_sh_c rpm -U "$CACHE_DIR/code-server-$VERSION-$ARCH.rpm"
sudo_sh_c rpm -i "$CACHE_DIR/code-server-$VERSION-$ARCH.rpm"
echo_systemd_postinstall rpm
}
@@ -553,17 +553,15 @@ sh_c() {
sudo_sh_c() {
if [ "$(id -u)" = 0 ]; then
sh_c "$@"
elif command_exists doas; then
sh_c "doas $*"
elif command_exists sudo; then
sh_c "sudo $*"
elif command_exists su; then
sh_c "su root -c '$*'"
sh_c "su - -c '$*'"
else
echoh
echoerr "This script needs to run the following command as root."
echoerr " $*"
echoerr "Please install doas, sudo, or su."
echoerr "Please install sudo or su."
exit 1
fi
}

View File

@@ -1,7 +1,7 @@
{
"name": "code-server",
"license": "MIT",
"version": "4.8.2",
"version": "4.5.2",
"description": "Run VS Code on a remote server.",
"homepage": "https://github.com/coder/code-server",
"bugs": {
@@ -12,25 +12,23 @@
"clean": "./ci/build/clean.sh",
"build": "./ci/build/build-code-server.sh",
"build:vscode": "./ci/build/build-vscode.sh",
"doctoc": "./ci/dev/doctoc.sh",
"release": "./ci/build/build-release.sh",
"release:standalone": "./ci/build/build-standalone-release.sh",
"release:github-draft": "./ci/build/release-github-draft.sh",
"release:github-assets": "./ci/build/release-github-assets.sh",
"release:prep": "./ci/build/release-prep.sh",
"test:e2e": "VSCODE_IPC_HOOK_CLI= ./ci/dev/test-e2e.sh",
"test:e2e:proxy": "USE_PROXY=1 ./ci/dev/test-e2e.sh",
"test:unit": "./ci/dev/test-unit.sh --forceExit --detectOpenHandles",
"test:integration": "./ci/dev/test-integration.sh",
"test:native": "./ci/dev/test-native.sh",
"test:scripts": "./ci/dev/test-scripts.sh",
"package": "./ci/build/build-packages.sh",
"prettier": "prettier --write --loglevel=warn --cache .",
"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": "yarn prettier && ./ci/dev/doctoc.sh",
"lint:scripts": "./ci/dev/lint-scripts.sh",
"lint:ts": "eslint --max-warnings=0 --fix $(git ls-files '*.ts' '*.js' | grep -v 'lib/vscode')",
"fmt": "./ci/dev/fmt.sh",
"lint": "./ci/dev/lint.sh",
"test": "echo 'Run yarn test:unit or yarn test:e2e' && exit 1",
"ci": "./ci/dev/ci.sh",
"watch": "VSCODE_DEV=1 VSCODE_IPC_HOOK_CLI= NODE_OPTIONS='--max_old_space_size=32384 --trace-warnings' ts-node ./ci/dev/watch.ts",
@@ -52,23 +50,28 @@
"@types/split2": "^3.2.0",
"@types/trusted-types": "^2.0.2",
"@types/ws": "^8.5.3",
"@typescript-eslint/eslint-plugin": "^5.41.0",
"@typescript-eslint/parser": "^5.41.0",
"@typescript-eslint/eslint-plugin": "^5.23.0",
"@typescript-eslint/parser": "^5.23.0",
"audit-ci": "^6.0.0",
"doctoc": "2.2.1",
"eslint": "^8.26.0",
"eslint-config-prettier": "^8.5.0",
"eslint-import-resolver-typescript": "^3.5.2",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-prettier": "^4.2.1",
"prettier": "2.7.1",
"prettier-plugin-sh": "^0.12.8",
"doctoc": "^2.0.0",
"eslint": "^7.7.0",
"eslint-config-prettier": "^8.1.0",
"eslint-import-resolver-typescript": "^2.5.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-prettier": "^4.0.0",
"json": "^11.0.0",
"prettier": "^2.2.1",
"prettier-plugin-sh": "^0.12.0",
"shellcheck": "^1.0.0",
"stylelint": "^13.0.0",
"stylelint-config-recommended": "^5.0.0",
"synp": "^1.9.10",
"ts-node": "^10.0.0",
"typescript": "^4.6.2"
},
"resolutions": {
"ansi-regex": "^5.0.1",
"normalize-package-data": "^5.0.0",
"normalize-package-data": "^4.0.0",
"doctoc/underscore": "^1.13.1",
"doctoc/**/trim": "^1.0.0",
"postcss": "^8.2.1",
@@ -77,7 +80,7 @@
"vfile-message": "^2.0.2",
"tar": "^6.1.9",
"path-parse": "^1.0.7",
"vm2": "^3.9.11",
"vm2": "^3.9.6",
"follow-redirects": "^1.14.8",
"node-fetch": "^2.6.7",
"nanoid": "^3.1.31",
@@ -86,8 +89,8 @@
"@types/node": "^16.0.0"
},
"dependencies": {
"@coder/logger": "^3.0.0",
"argon2": "0.29.0",
"@coder/logger": "1.1.16",
"argon2": "^0.28.0",
"compression": "^1.7.4",
"cookie-parser": "^1.4.5",
"env-paths": "^2.2.0",
@@ -105,7 +108,8 @@
"semver": "^7.1.3",
"split2": "^4.0.0",
"ws": "^8.0.0",
"xdg-basedir": "^4.0.0"
"xdg-basedir": "^4.0.0",
"yarn": "^1.22.4"
},
"bin": {
"code-server": "out/node/entry.js"

View File

@@ -10,7 +10,7 @@ Index: code-server/lib/vscode/src/vs/base/common/network.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/base/common/network.ts
+++ code-server/lib/vscode/src/vs/base/common/network.ts
@@ -162,7 +162,9 @@ class RemoteAuthoritiesImpl {
@@ -157,7 +157,9 @@ class RemoteAuthoritiesImpl {
return URI.from({
scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource,
authority: `${host}:${port}`,
@@ -104,7 +104,7 @@ Index: code-server/lib/vscode/src/vs/platform/remote/browser/browserSocketFactor
connect(host: string, port: number, path: string, query: string, debugLabel: string, callback: IConnectCallback): void {
const webSocketSchema = (/^https:/.test(window.location.href) ? 'wss' : 'ws');
+ path = (window.location.pathname + "/" + path).replace(/\/\/+/g, "/")
const socket = this._webSocketFactory.create(`${webSocketSchema}://${(/:/.test(host) && !/\[/.test(host)) ? `[${host}]` : host}:${port}${path}?${query}&skipWebSocketFrames=false`, debugLabel);
const socket = this._webSocketFactory.create(`${webSocketSchema}://${/:/.test(host) ? `[${host}]` : host}:${port}${path}?${query}&skipWebSocketFrames=false`, debugLabel);
const errorListener = socket.onError((err) => callback(err, undefined));
socket.onOpen(() => {
@@ -282,6 +283,3 @@ export class BrowserSocketFactory implem
@@ -118,25 +118,26 @@ 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
@@ -267,12 +267,11 @@ export class WebClientServer {
@@ -267,14 +267,10 @@ export class WebClientServer {
return res.end();
}
- const getFirstHeader = (headerName: string) => {
- const val = req.headers[headerName];
- return Array.isArray(val) ? val[0] : val;
- };
-
- const remoteAuthority = getFirstHeader('x-original-host') || getFirstHeader('x-forwarded-host') || req.headers.host;
+ // For now we are getting the remote authority from the client to avoid
+ // needing specific configuration for reverse proxies to work. Set this to
+ // something invalid to make sure we catch code that is using this value
+ // from the backend when it should not.
- let originalHost = req.headers['x-original-host'];
- if (Array.isArray(originalHost)) {
- originalHost = originalHost[0];
- }
- const remoteAuthority = originalHost || req.headers.host;
- if (!remoteAuthority) {
- return serveError(req, res, 400, `Bad request.`);
- }
+ // It is not possible to reliably detect the remote authority on the server
+ // in all cases. Set this to something invalid to make sure we catch code
+ // that is using this when it should not.
+ const remoteAuthority = 'remote';
if (!remoteAuthority) {
return serveError(req, res, 400, `Bad request.`);
}
@@ -298,6 +297,8 @@ export class WebClientServer {
function asJSON(value: unknown): string {
return JSON.stringify(value).replace(/"/g, '&quot;');
@@ -297,6 +293,8 @@ export class WebClientServer {
scopes: [['user:email'], ['repo']]
} : undefined;
@@ -145,7 +146,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
const workbenchWebConfiguration = {
remoteAuthority,
@@ -309,6 +310,7 @@ export class WebClientServer {
@@ -308,6 +306,7 @@ export class WebClientServer {
workspaceUri: resolveWorkspaceURI(this._environmentService.args['default-workspace']),
productConfiguration: <Partial<IProductConfiguration>>{
codeServerVersion: this._productService.codeServerVersion,
@@ -153,29 +154,20 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
embedderIdentifier: 'server-distro',
extensionsGallery: this._webExtensionResourceUrlTemplate ? {
...this._productService.extensionsGallery,
@@ -326,8 +328,10 @@ export class WebClientServer {
@@ -328,8 +327,10 @@ export class WebClientServer {
const values: { [key: string]: string } = {
WORKBENCH_WEB_CONFIGURATION: asJSON(workbenchWebConfiguration),
WORKBENCH_AUTH_SESSION: authSessionInfo ? asJSON(authSessionInfo) : '',
- WORKBENCH_WEB_BASE_URL: this._staticRoute,
- WORKBENCH_NLS_BASE_URL: nlsBaseUrl ? `${nlsBaseUrl}${!nlsBaseUrl.endsWith('/') ? '/' : ''}${this._productService.commit}/${this._productService.version}/` : '',
- WORKBENCH_NLS_BASE_URL: nlsBaseUrl ? `${nlsBaseUrl}${this._productService.commit}/${this._productService.version}/` : '',
+ WORKBENCH_WEB_BASE_URL: vscodeBase + this._staticRoute,
+ WORKBENCH_NLS_BASE_URL: vscodeBase + (nlsBaseUrl ? `${nlsBaseUrl}${!nlsBaseUrl.endsWith('/') ? '/' : ''}${this._productService.commit}/${this._productService.version}/` : ''),
+ WORKBENCH_NLS_BASE_URL: vscodeBase + (nlsBaseUrl ? `${nlsBaseUrl}${this._productService.commit}/${this._productService.version}/` : ''),
+ BASE: base,
+ VS_BASE: vscodeBase,
};
@@ -344,7 +348,7 @@ export class WebClientServer {
'default-src \'self\';',
'img-src \'self\' https: data: blob:;',
'media-src \'self\';',
- `script-src 'self' 'unsafe-eval' ${this._getScriptCspHashes(data).join(' ')} 'sha256-fh3TwPMflhsEIpR8g1OYTIMVWhXTLcjQ9kh2tIpmv54=' http://${remoteAuthority};`, // the sha is the same as in src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
+ `script-src 'self' 'unsafe-eval' ${this._getScriptCspHashes(data).join(' ')} 'sha256-fh3TwPMflhsEIpR8g1OYTIMVWhXTLcjQ9kh2tIpmv54=';`, // the sha is the same as in src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
'child-src \'self\';',
`frame-src 'self' https://*.vscode-cdn.net data:;`,
'worker-src \'self\' data:;',
@@ -417,3 +421,70 @@ export class WebClientServer {
@@ -419,3 +420,70 @@ export class WebClientServer {
return res.end(data);
}
}
@@ -262,7 +254,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
@@ -489,6 +489,7 @@ function doCreateUri(path: string, query
@@ -485,6 +485,7 @@ function doCreateUri(path: string, query
});
}
@@ -270,7 +262,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
return URI.parse(window.location.href).with({ path, query });
}
@@ -500,7 +501,7 @@ function doCreateUri(path: string, query
@@ -496,7 +497,7 @@ function doCreateUri(path: string, query
if (!configElement || !configElementAttribute) {
throw new Error('Missing web configuration element');
}

View File

@@ -13,15 +13,62 @@ To test:
The file or directory should only open from the instance attached to that
terminal.
Index: code-server/lib/vscode/src/vs/server/node/remoteTerminalChannel.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/remoteTerminalChannel.ts
+++ code-server/lib/vscode/src/vs/server/node/remoteTerminalChannel.ts
@@ -89,7 +89,7 @@ export class RemoteTerminalChannel exten
uriTransformer: IURITransformer;
}>();
- private readonly _onExecuteCommand = this._register(new Emitter<{ reqId: number; commandId: string; commandArgs: any[] }>());
+ private readonly _onExecuteCommand = this._register(new Emitter<{ reqId: number; terminalId: number; commandId: string; commandArgs: any[] }>());
readonly onExecuteCommand = this._onExecuteCommand.event;
constructor(
@@ -240,20 +240,20 @@ export class RemoteTerminalChannel exten
const ipcHandlePath = createRandomIPCHandle();
env.VSCODE_IPC_HOOK_CLI = ipcHandlePath;
const commandsExecuter: ICommandsExecuter = {
- executeCommand: <T>(id: string, ...args: any[]): Promise<T> => this._executeCommand(id, args, uriTransformer)
+ executeCommand: <T>(commandId: string, ...args: any[]): Promise<T> => this._executeCommand(terminalId, commandId, args, uriTransformer)
};
const cliServer = new CLIServerBase(commandsExecuter, this._logService, ipcHandlePath);
- const id = await this._ptyService.createProcess(shellLaunchConfig, initialCwd, args.cols, args.rows, args.unicodeVersion, env, baseEnv, args.options, args.shouldPersistTerminal, args.workspaceId, args.workspaceName);
- this._ptyService.onProcessExit(e => e.id === id && cliServer.dispose());
+ const terminalId = await this._ptyService.createProcess(shellLaunchConfig, initialCwd, args.cols, args.rows, args.unicodeVersion, env, baseEnv, args.options, args.shouldPersistTerminal, args.workspaceId, args.workspaceName);
+ this._ptyService.onProcessExit(e => e.id === terminalId && cliServer.dispose());
return {
- persistentTerminalId: id,
+ persistentTerminalId: terminalId,
resolvedShellLaunchConfig: shellLaunchConfig
};
}
- private _executeCommand<T>(commandId: string, commandArgs: any[], uriTransformer: IURITransformer): Promise<T> {
+ private _executeCommand<T>(terminalId: number, commandId: string, commandArgs: any[], uriTransformer: IURITransformer): Promise<T> {
let resolve!: (data: any) => void;
let reject!: (err: any) => void;
const result = new Promise<T>((_resolve, _reject) => {
@@ -276,6 +276,7 @@ export class RemoteTerminalChannel exten
});
this._onExecuteCommand.fire({
reqId,
+ terminalId,
commandId,
commandArgs: serializedCommandArgs
});
Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
@@ -100,10 +100,14 @@ class RemoteTerminalBackend extends Base
}
@@ -94,10 +94,14 @@ class RemoteTerminalBackend extends Base
this._remoteTerminalChannel.onExecuteCommand(async e => {
const reqId = e.reqId;
const commandId = e.commandId;
+ const terminalId = e.persistentProcessId;
+ const terminalId = e.terminalId;
if (!allowedCommands.includes(commandId)) {
this._remoteTerminalChannel.sendCommandResult(reqId, true, 'Invalid remote cli command: ' + commandId);
return;
@@ -32,3 +79,18 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTe
const commandArgs = e.commandArgs.map(arg => revive(arg));
try {
const result = await this._commandService.executeCommand(e.commandId, ...commandArgs);
Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts
@@ -88,8 +88,8 @@ export class RemoteTerminalChannelClient
get onProcessOrphanQuestion(): Event<{ id: number }> {
return this._channel.listen<{ id: number }>('$onProcessOrphanQuestion');
}
- get onExecuteCommand(): Event<{ reqId: number; commandId: string; commandArgs: any[] }> {
- return this._channel.listen<{ reqId: number; commandId: string; commandArgs: any[] }>('$onExecuteCommand');
+ get onExecuteCommand(): Event<{ reqId: number; terminalId: number; commandId: string; commandArgs: any[] }> {
+ return this._channel.listen<{ reqId: number; terminalId: number; commandId: string; commandArgs: any[] }>('$onExecuteCommand');
}
get onDidRequestDetach(): Event<{ requestId: number; workspaceId: string; instanceId: number }> {
return this._channel.listen<{ requestId: number; workspaceId: string; instanceId: number }>('$onDidRequestDetach');

View File

@@ -0,0 +1,26 @@
Add connection type to web sockets
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=<connection-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
@@ -233,7 +233,8 @@ async function connectToRemoteExtensionH
let socket: ISocket;
try {
- socket = await createSocket(options.logService, options.socketFactory, options.host, options.port, getRemoteServerRootPath(options), `reconnectionToken=${options.reconnectionToken}&reconnection=${options.reconnectionProtocol ? 'true' : 'false'}`, `renderer-${connectionTypeToString(connectionType)}-${options.reconnectionToken}`, timeoutCancellationToken);
+
+ socket = await createSocket(options.logService, options.socketFactory, options.host, options.port, getRemoteServerRootPath(options), `type=${connectionTypeToString(connectionType)}&reconnectionToken=${options.reconnectionToken}&reconnection=${options.reconnectionProtocol ? 'true' : 'false'}`, `renderer-${connectionTypeToString(connectionType)}-${options.reconnectionToken}`, timeoutCancellationToken);
} catch (error) {
options.logService.error(`${logPrefix} socketFactory.connect() failed or timed out. Error:`);
options.logService.error(error);

View File

@@ -7,7 +7,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
===================================================================
--- 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
@@ -237,6 +237,10 @@ export class Extension implements IExten
@@ -234,6 +234,10 @@ export class Extension implements IExten
if (this.type === ExtensionType.System && this.productService.quality === 'stable') {
return false;
}
@@ -18,7 +18,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
if (!this.local.preRelease && this.gallery.properties.isPreReleaseVersion) {
return false;
}
@@ -1234,6 +1238,10 @@ export class ExtensionsWorkbenchService
@@ -1088,6 +1092,10 @@ export class ExtensionsWorkbenchService
// Skip if check updates only for builtin extensions and current extension is not builtin.
continue;
}

View File

@@ -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
@@ -271,6 +271,11 @@ export interface IWorkbenchConstructionO
@@ -250,6 +250,11 @@ export interface IWorkbenchConstructionO
*/
readonly userDataPath?: string
@@ -52,7 +52,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi
+ }
+
@memoize
get argvResource(): URI { return joinPath(this.userRoamingDataHome, 'argv.json'); }
get settingsResource(): URI { return joinPath(this.userRoamingDataHome, 'settings.json'); }
Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
===================================================================
@@ -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
@@ -304,6 +304,7 @@ export class WebClientServer {
@@ -300,6 +300,7 @@ export class WebClientServer {
remoteAuthority,
webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
userDataPath: this._environmentService.userDataPath,
+ isEnabledFileDownloads: !this._environmentService.args['disable-file-downloads'],
_wrapWebWorkerExtHostInIframe,
developmentOptions: { enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined, logLevel: this._logService.getLevel() },
settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined,
developmentOptions: {
enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined,
Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/contextkeys.ts
@@ -93,35 +93,35 @@ Index: 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, ProductQualityContext, IsMobileContext } 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, TemporaryWorkspaceContext } 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, TemporaryWorkspaceContext, IsEnabledFileDownloads } from 'vs/workbench/common/contextkeys';
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, isTemporaryWorkspace } from 'vs/platform/workspace/common/workspace';
import { WorkbenchState, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IWorkbenchLayoutService, Parts, positionToString } from 'vs/workbench/services/layout/browser/layoutService';
@@ -25,6 +24,7 @@ import { IPaneCompositePartService } fro
@@ -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 { IProductService } from 'vs/platform/product/common/productService';
+import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
+import { IBrowserWorkbenchEnvironmentService } from '../services/environment/browser/environmentService';
export class WorkbenchContextKeysHandler extends Disposable {
private inputFocusedContext: IContextKey<boolean>;
@@ -77,7 +77,7 @@ export class WorkbenchContextKeysHandler
@@ -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,
@IProductService private readonly productService: IProductService,
@IEditorService private readonly editorService: IEditorService,
@IEditorResolverService private readonly editorResolverService: IEditorResolverService,
@@ -202,6 +202,9 @@ export class WorkbenchContextKeysHandler
@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));
@@ -172,7 +172,7 @@ 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
@@ -32,6 +32,8 @@ export const IsFullscreenContext = new R
@@ -30,6 +30,8 @@ export const IsFullscreenContext = new R
export const HasWebFileSystemAccess = new RawContextKey<boolean>('hasWebFileSystemAccess', false, true); // Support for FileSystemAccess web APIs (https://wicg.github.io/file-system-access)

View File

@@ -5,21 +5,19 @@ We can remove this once upstream supports all language packs.
1. Proxies language packs to the service on the backend.
2. NLS configuration is embedded into the HTML for the browser to pick up. This
code to generate this configuration is copied from the native portion.
3. Remove configuredLocale since we have our own thing.
3. Remove navigator.language default since that will prevent the argv file from
being created if you are changing the language to whatever your browser
default happens to be.
4. Move the argv.json file to the server instead of in-browser storage. This is
where the current locale is stored and currently the server needs to be able
to read it.
5. Add the locale flag.
6. Remove the redundant locale verification. It does the same as the existing
one but is worse because it does not handle non-existent or empty files.
7. Replace some caching and Node requires because code-server does not restart
when changing the language unlike native Code.
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
@@ -209,6 +209,9 @@ export async function setupServerService
@@ -202,6 +202,9 @@ export async function setupServerService
const channel = new ExtensionManagementChannel(extensionManagementService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority));
socketServer.registerChannel('extensions', channel);
@@ -33,31 +31,14 @@ 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
@@ -2,8 +2,6 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import * as nls from 'vs/nls';
-
export const LANGUAGE_DEFAULT = 'en';
let _isWindows = false;
@@ -83,17 +81,19 @@ if (typeof navigator === 'object' && !is
_isMobile = _userAgent?.indexOf('Mobi') >= 0;
@@ -80,8 +80,19 @@ if (typeof navigator === 'object' && !is
_isIOS = (_userAgent.indexOf('Macintosh') >= 0 || _userAgent.indexOf('iPad') >= 0 || _userAgent.indexOf('iPhone') >= 0) && !!navigator.maxTouchPoints && navigator.maxTouchPoints > 0;
_isLinux = _userAgent.indexOf('Linux') >= 0;
_isWeb = true;
- const configuredLocale = nls.getConfiguredDefaultLocale(
- // This call _must_ be done in the file that calls `nls.getConfiguredDefaultLocale`
- // to ensure that the NLS AMD Loader plugin has been loaded and configured.
- // This is because the loader plugin decides what the default locale is based on
- // how it's able to resolve the strings.
- nls.localize({ key: 'ensureLoaderPluginIsLoaded', comment: ['{Locked}'] }, '_')
- );
-
- _locale = configuredLocale || LANGUAGE_DEFAULT;
- _locale = navigator.language;
+ _locale = LANGUAGE_DEFAULT;
_language = _locale;
+
+ const el = typeof document !== 'undefined' && document.getElementById('vscode-remote-nls-configuration');
+ const rawNlsConfig = el && el.getAttribute('data-settings');
+ if (rawNlsConfig) {
@@ -85,19 +66,21 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html
<!-- Workbench Icon/Manifest/CSS -->
<link rel="icon" href="{{BASE}}/_static/src/browser/media/favicon-dark-support.svg" />
<link rel="alternate icon" href="{{BASE}}/_static/src/browser/media/favicon.ico" type="image/x-icon" />
@@ -46,15 +49,26 @@
// Set up nls if the user is not using the default language (English)
@@ -43,17 +46,27 @@
self.webPackagePaths[key] = `${baseUrl}/node_modules/${key}/${self.webPackagePaths[key]}`;
});
- // Set up nls if the user is not using the default language (English)
const nlsConfig = {};
const locale = window.localStorage.getItem('vscode.nls.locale') || navigator.language;
- const locale = navigator.language;
- if (!locale.startsWith('en')) {
- nlsConfig['vs/nls'] = {
- availableLanguages: {
- '*': locale
- },
- translationServiceUrl: '{{WORKBENCH_NLS_BASE_URL}}'
- baseUrl: '{{WORKBENCH_NLS_BASE_URL}}'
- };
- }
-
+ try {
+ nlsConfig['vs/nls'] = JSON.parse(document.getElementById("vscode-remote-nls-configuration").getAttribute("data-settings"))
+ if (nlsConfig['vs/nls']._resolvedLanguagePackCoreLocation) {
@@ -118,14 +101,14 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html
+ }
+ }
+ } catch (error) { /* Probably fine. */ }
require.config({
baseUrl: `${baseUrl}/out`,
recordStats: true,
Index: code-server/lib/vscode/src/vs/platform/environment/common/environmentService.ts
===================================================================
--- 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'));
}
@@ -207,7 +190,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
import { CharCode } from 'vs/base/common/charCode';
import { getRemoteServerRootPath } from 'vs/platform/remote/common/remoteHosts';
@@ -299,6 +300,8 @@ export class WebClientServer {
@@ -295,6 +296,8 @@ export class WebClientServer {
const base = relativeRoot(getOriginalUrl(req))
const vscodeBase = relativePath(getOriginalUrl(req))
@@ -216,8 +199,8 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
const workbenchWebConfiguration = {
remoteAuthority,
@@ -336,6 +339,7 @@ export class WebClientServer {
WORKBENCH_NLS_BASE_URL: vscodeBase + (nlsBaseUrl ? `${nlsBaseUrl}${!nlsBaseUrl.endsWith('/') ? '/' : ''}${this._productService.commit}/${this._productService.version}/` : ''),
@@ -338,6 +341,7 @@ export class WebClientServer {
WORKBENCH_NLS_BASE_URL: vscodeBase + (nlsBaseUrl ? `${nlsBaseUrl}${this._productService.commit}/${this._productService.version}/` : ''),
BASE: base,
VS_BASE: vscodeBase,
+ NLS_CONFIGURATION: asJSON(nlsConfiguration),
@@ -248,69 +231,39 @@ 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
@@ -123,8 +123,9 @@ import 'vs/workbench/contrib/logs/browse
// Explorer
import 'vs/workbench/contrib/files/browser/files.web.contribution';
@@ -109,6 +109,12 @@ registerSingleton(IDiagnosticsService, N
-// Localization
-import 'vs/workbench/contrib/localization/browser/localization.contribution';
+// Localization. This does not actually import anything specific to Electron so
+// it should be safe.
//#region --- workbench contributions
+// Localization. These do not actually import anything specific to Electron so
+// they should be safe.
+import 'vs/workbench/services/localization/electron-sandbox/localeService';
+import 'vs/workbench/contrib/localization/electron-sandbox/localization.contribution';
+import 'vs/platform/languagePacks/browser/languagePacks';
+
// Output
import 'vs/workbench/contrib/output/common/outputChannelModelService';
// Performance
import 'vs/workbench/contrib/performance/browser/performance.web.contribution';
Index: code-server/lib/vscode/src/vs/platform/languagePacks/browser/languagePacks.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/languagePacks/browser/languagePacks.ts
--- /dev/null
+++ code-server/lib/vscode/src/vs/platform/languagePacks/browser/languagePacks.ts
@@ -4,10 +4,23 @@
*--------------------------------------------------------------------------------------------*/
import { ILanguagePackItem, LanguagePackBaseService } from 'vs/platform/languagePacks/common/languagePacks';
@@ -0,0 +1,18 @@
+import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc';
+import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
+import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks';
+import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
+import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement';
export class WebLanguagePacksService extends LanguagePackBaseService {
- // Web doesn't have a concept of language packs, so we just return an empty array
+ private readonly languagePackService: ILanguagePackService;
+
+// @ts-ignore: interface is implemented via proxy
+export class LanguagePackService implements ILanguagePackService {
+
+ declare readonly _serviceBrand: undefined;
+
+ constructor(
+ @IRemoteAgentService remoteAgentService: IRemoteAgentService,
+ @IExtensionGalleryService extensionGalleryService: IExtensionGalleryService
+ ) {
+ super(extensionGalleryService)
+ this.languagePackService = ProxyChannel.toService<ILanguagePackService>(remoteAgentService.getConnection()!.getChannel('languagePacks'));
+ return ProxyChannel.toService<ILanguagePackService>(remoteAgentService.getConnection()!.getChannel('languagePacks'));
+ }
+}
+
getInstalledLanguages(): Promise<ILanguagePackItem[]> {
- return Promise.resolve([]);
+ return this.languagePackService.getInstalledLanguages()
}
}
Index: code-server/lib/vscode/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts
@@ -41,7 +41,8 @@ export class NativeLocaleService impleme
@IProductService private readonly productService: IProductService
) { }
- private async validateLocaleFile(): Promise<boolean> {
+ // Make public just so we do not have to patch all the unused code out.
+ public async validateLocaleFile(): Promise<boolean> {
try {
const content = await this.textFileService.read(this.environmentService.argvResource, { encoding: 'utf8' });
@@ -68,9 +69,6 @@ export class NativeLocaleService impleme
}
private async writeLocaleValue(locale: string | undefined): Promise<boolean> {
- if (!(await this.validateLocaleFile())) {
- return false;
- }
await this.jsonEditingService.write(this.environmentService.argvResource, [{ path: ['locale'], value: locale }], true);
return true;
}
+registerSingleton(ILanguagePackService, LanguagePackService, true);

View File

@@ -1,24 +0,0 @@
Preserve process.execArgv
This ensures flags like `--prof` are passed down to the code-server process so
we can profile everything.
To test this:
1. run `./lib/node --prof .`
2. in another terminal, run `ps -ejww`
You should see `--prof` next to every code-server process.
Index: code-server/lib/vscode/src/vs/server/node/extensionHostConnection.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/extensionHostConnection.ts
+++ code-server/lib/vscode/src/vs/server/node/extensionHostConnection.ts
@@ -228,7 +228,7 @@ export class ExtensionHostConnection {
public async start(startParams: IRemoteExtensionHostStartParams): Promise<void> {
try {
- let execArgv: string[] = [];
+ let execArgv: string[] = process.execArgv ? process.execArgv.filter(a => !/^--inspect(-brk)?=/.test(a)) : [];
if (startParams.port && !(<any>process).pkg) {
execArgv = [`--inspect${startParams.break ? '-brk' : ''}=${startParams.port}`];
}

View File

@@ -1,178 +0,0 @@
Modify Help: Getting Started
This modifies some text on the Getting Started page and adds text about using
code-server on a team.
It is enabled by default but can be overriden using the cli flag
`--disable-getting-started-override`.
Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts
@@ -62,7 +62,7 @@ import { GettingStartedIndexList } from
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { getTelemetryLevel } from 'vs/platform/telemetry/common/telemetryUtils';
-import { WorkbenchStateContext } from 'vs/workbench/common/contextkeys';
+import { IsEnabledCoderGettingStarted, WorkbenchStateContext } from 'vs/workbench/common/contextkeys';
import { OpenFolderViaWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions';
import { OpenRecentAction } from 'vs/workbench/browser/actions/windowActions';
import { Toggle } from 'vs/base/browser/ui/toggle/toggle';
@@ -753,11 +753,24 @@ export class GettingStartedPage extends
onShowOnStartupChanged();
}));
- const header = $('.header', {},
+ let header = $('.header', {},
$('h1.product-name.caption', {}, this.productService.nameLong),
$('p.subtitle.description', {}, localize({ key: 'gettingStarted.editingEvolved', comment: ['Shown as subtitle on the Welcome page.'] }, "Editing evolved"))
);
+ if (this.contextService.contextMatchesRules(IsEnabledCoderGettingStarted)) {
+ header = $('.header', {},
+ $('h1.product-name.caption', {}, this.productService.nameLong),
+ $('p.subtitle.description.coder', {},
+ "Using code-server on a team?",
+ ),
+ $('p.subtitle.description.coder-coder', {},
+ "Check out: ",
+ $('a', { href: "https://github.com/coder/coder" }, "coder/coder")
+ ),
+ );
+ }
+
const leftColumn = $('.categories-column.categories-column-left', {},);
const rightColumn = $('.categories-column.categories-column-right', {},);
Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css
+++ code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css
@@ -60,6 +60,15 @@
display: block;
}
+.monaco-workbench .part.editor > .content .gettingStartedContainer .coder {
+ margin-bottom: 0.2em;
+}
+
+.monaco-workbench .part.editor>.content .gettingStartedContainer .coder-coder {
+ font-size: 1em;
+ margin-top: 0.2em;
+}
+
.monaco-workbench.hc-black .part.editor>.content .gettingStartedContainer .subtitle,
.monaco-workbench.hc-light .part.editor>.content .gettingStartedContainer .subtitle {
font-weight: 200;
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
@@ -276,6 +276,11 @@ export interface IWorkbenchConstructionO
*/
readonly isEnabledFileDownloads?: boolean
+ /**
+ * Whether to use Coder's custom Getting Started text.
+ */
+ readonly isEnabledCoderGettingStarted?: 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
@@ -36,6 +36,11 @@ export interface IBrowserWorkbenchEnviro
* Enable downloading files via menu actions.
*/
readonly isEnabledFileDownloads?: boolean;
+
+ /**
+ * Enable Coder's custom getting started text.
+ */
+ readonly isEnabledCoderGettingStarted?: boolean;
}
export class BrowserWorkbenchEnvironmentService implements IBrowserWorkbenchEnvironmentService {
@@ -74,6 +79,13 @@ export class BrowserWorkbenchEnvironment
return this.options.isEnabledFileDownloads;
}
+ get isEnabledCoderGettingStarted(): boolean {
+ if (typeof this.options.isEnabledCoderGettingStarted === "undefined") {
+ throw new Error('isEnabledCoderGettingStarted was not provided to the browser');
+ }
+ return this.options.isEnabledCoderGettingStarted;
+ }
+
@memoize
get argvResource(): URI { return joinPath(this.userRoamingDataHome, 'argv.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
@@ -16,6 +16,7 @@ export const serverOptions: OptionDescri
'auth': { type: 'string' },
'disable-file-downloads': { type: 'boolean' },
'locale': { type: 'string' },
+ 'disable-getting-started-override': { type: 'boolean' },
/* ----- server setup ----- */
@@ -98,6 +99,7 @@ export interface ServerParsedArgs {
'auth'?: string
'disable-file-downloads'?: boolean;
'locale'?: string
+ 'disable-getting-started-override'?: 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
@@ -308,6 +308,7 @@ export class WebClientServer {
webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
userDataPath: this._environmentService.userDataPath,
isEnabledFileDownloads: !this._environmentService.args['disable-file-downloads'],
+ isEnabledCoderGettingStarted: !this._environmentService.args['disable-getting-started-override'],
_wrapWebWorkerExtHostInIframe,
developmentOptions: { enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined, logLevel: this._logService.getLevel() },
settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined,
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,7 +7,7 @@ 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, ProductQualityContext, IsMobileContext } 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, TemporaryWorkspaceContext, IsEnabledFileDownloads } 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, TemporaryWorkspaceContext, IsEnabledFileDownloads, IsEnabledCoderGettingStarted } 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';
@@ -204,6 +204,7 @@ export class WorkbenchContextKeysHandler
// code-server
IsEnabledFileDownloads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileDownloads ?? true)
+ IsEnabledCoderGettingStarted.bindTo(this.contextKeyService).set(this.environmentService.isEnabledCoderGettingStarted ?? true)
this.registerListeners();
}
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
@@ -33,6 +33,7 @@ export const IsFullscreenContext = new R
export const HasWebFileSystemAccess = new RawContextKey<boolean>('hasWebFileSystemAccess', false, true); // Support for FileSystemAccess web APIs (https://wicg.github.io/file-system-access)
export const IsEnabledFileDownloads = new RawContextKey<boolean>('isEnabledFileDownloads', true, true);
+export const IsEnabledCoderGettingStarted = new RawContextKey<boolean>('isEnabledCoderGettingStarted', true, true);
//#endregion

View File

@@ -20,14 +20,14 @@ 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,
) {
super();
}
@@ -42,5 +45,31 @@ export class CodeServerClient extends Di
@@ -42,5 +45,32 @@ export class CodeServerClient extends Di
}
});
}
@@ -49,6 +49,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
+ class: undefined,
+ enabled: true,
+ checked: true,
+ dispose: () => undefined,
+ run: () => {
+ return Promise.resolve();
+ },

View File

@@ -184,7 +184,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.main.ts
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IProgressService } from 'vs/platform/progress/common/progress';
import { DelayedLogChannel } from 'vs/workbench/services/output/common/delayedLogChannel';
@@ -116,6 +117,9 @@ export class BrowserMain extends Disposa
@@ -109,6 +110,9 @@ export class BrowserMain extends Disposa
// Startup
const instantiationService = workbench.startup();
@@ -221,13 +221,12 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench-dev.html
<!-- Disable pinch zooming -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
@@ -26,9 +27,9 @@
@@ -26,8 +27,9 @@
<meta id="vscode-workbench-builtin-extensions" data-settings="{{WORKBENCH_BUILTIN_EXTENSIONS}}">
<!-- Workbench Icon/Manifest/CSS -->
- <link rel="icon" href="{{WORKBENCH_WEB_BASE_URL}}/resources/server/favicon.ico" type="image/x-icon" />
- <link rel="manifest" href="{{WORKBENCH_WEB_BASE_URL}}/resources/server/manifest.json" crossorigin="use-credentials" />
-
+ <link rel="icon" href="/_static/src/browser/media/favicon-dark-support.svg" />
+ <link rel="alternate icon" href="/_static/src/browser/media/favicon.ico" type="image/x-icon" />
+ <link rel="manifest" href="/manifest.json" crossorigin="use-credentials" />
@@ -264,7 +263,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
@@ -308,6 +308,7 @@ export class WebClientServer {
@@ -307,6 +307,7 @@ export class WebClientServer {
folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']),
workspaceUri: resolveWorkspaceURI(this._environmentService.args['default-workspace']),
productConfiguration: <Partial<IProductConfiguration>>{

View File

@@ -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
@@ -303,6 +303,7 @@ export class WebClientServer {
@@ -299,6 +299,7 @@ export class WebClientServer {
const workbenchWebConfiguration = {
remoteAuthority,
webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
+ userDataPath: this._environmentService.userDataPath,
_wrapWebWorkerExtHostInIframe,
developmentOptions: { enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined, logLevel: this._logService.getLevel() },
settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined,
developmentOptions: {
enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined,
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
@@ -266,6 +266,11 @@ export interface IWorkbenchConstructionO
@@ -245,6 +245,11 @@ export interface IWorkbenchConstructionO
*/
readonly configurationDefaults?: Record<string, any>;
@@ -63,4 +63,4 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi
+ }
@memoize
get argvResource(): URI { return joinPath(this.userRoamingDataHome, 'argv.json'); }
get settingsResource(): URI { return joinPath(this.userRoamingDataHome, 'settings.json'); }

21
patches/log-level.diff Normal file
View File

@@ -0,0 +1,21 @@
Propagate the log level to the client
This can be tested by using `--log trace`. You should see plenty of debug and
trace logs in the console.
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
@@ -300,7 +300,10 @@ export class WebClientServer {
remoteAuthority,
webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
_wrapWebWorkerExtHostInIframe,
- developmentOptions: { enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined },
+ developmentOptions: {
+ enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined,
+ logLevel: this._logService.getLevel(),
+ },
settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined,
enableWorkspaceTrust: !this._environmentService.args['disable-workspace-trust'],
folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']),

View File

@@ -40,11 +40,11 @@ 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
@@ -313,6 +313,7 @@ export class WebClientServer {
@@ -309,6 +309,7 @@ export class WebClientServer {
codeServerVersion: this._productService.codeServerVersion,
rootEndpoint: base,
updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
+ logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined,
+ logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined,
embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery,
},
@@ -68,7 +68,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
constructor (
@ILogService private logService: ILogService,
@INotificationService private notificationService: INotificationService,
@@ -81,6 +85,10 @@ export class CodeServerClient extends Di
@@ -82,6 +86,10 @@ export class CodeServerClient extends Di
if (this.productService.updateEndpoint) {
this.checkUpdates(this.productService.updateEndpoint)
}
@@ -79,7 +79,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
}
private checkUpdates(updateEndpoint: string) {
@@ -132,4 +140,25 @@ export class CodeServerClient extends Di
@@ -133,4 +141,25 @@ export class CodeServerClient extends Di
updateLoop();
}

View File

@@ -19,23 +19,22 @@ Index: code-server/lib/vscode/src/vs/platform/product/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/product/common/product.ts
+++ code-server/lib/vscode/src/vs/platform/product/common/product.ts
@@ -53,6 +53,16 @@ else if (typeof require?.__$__nodeRequir
version: pkg.version
});
@@ -45,7 +45,14 @@ else if (typeof require?.__$__nodeRequir
}
+
+ Object.assign(product, {
Object.assign(product, {
- version: pkg.version
+ version: pkg.version,
+ extensionsGallery: env.EXTENSIONS_GALLERY ? JSON.parse(env.EXTENSIONS_GALLERY) : (product.extensionsGallery || {
+ serviceUrl: "https://open-vsx.org/vscode/gallery",
+ itemUrl: "https://open-vsx.org/vscode/item",
+ resourceUrlTemplate: "https://open-vsx.org/vscode/asset/{publisher}/{name}/{version}/Microsoft.VisualStudio.Code.WebResources/{path}",
+ controlUrl: "",
+ recommendationsUrl: "",
+ })
+ });
+ }),
});
}
// Web environment or unknown
Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -49,7 +48,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
}
/**
@@ -312,14 +312,7 @@ export class WebClientServer {
@@ -308,14 +308,7 @@ export class WebClientServer {
codeServerVersion: this._productService.codeServerVersion,
rootEndpoint: base,
embedderIdentifier: 'server-distro',

View File

@@ -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

View File

@@ -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
@@ -1462,7 +1462,7 @@ class ProposedApiController {
@@ -1451,7 +1451,7 @@ class ProposedApiController {
this._envEnabledExtensions = new Set((_environmentService.extensionEnabledProposedApi ?? []).map(id => ExtensionIdentifier.toKey(id)));

View File

@@ -10,22 +10,6 @@ extensions, use --extensions-dir, or symlink it).
This has e2e tests.
For the `asExternalUri` changes, you'll need to test manually by:
1. running code-server with the test extension
2. Command Palette > code-server: asExternalUri test
3. input a url like http://localhost:3000
4. it should show a notification and show output as <code-server>/proxy/3000
Do the same thing but set `VSCODE_PROXY_URI: "https://{{port}}-main-workspace-name-user-name.coder.com"`
and the output should replace `{{port}}` with port used in input url.
This also enables the forwared ports view panel by default.
Lastly, it adds a tunnelProvider so that ports are forwarded using code-server's
built-in proxy. You can test this by starting a server i.e. `python3 -m
http.server` and it should show a notification and show up in the ports panel
using the /proxy/port.
Index: code-server/lib/vscode/src/vs/base/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
@@ -48,43 +32,47 @@ Index: code-server/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityReso
import { IProductService } from 'vs/platform/product/common/productService';
-import { IRemoteAuthorityResolverService, IRemoteConnectionData, ResolvedAuthority, ResolverResult } from 'vs/platform/remote/common/remoteAuthorityResolver';
+import { IRemoteAuthorityResolverService, IRemoteConnectionData, ResolvedAuthority, ResolvedOptions, ResolverResult } from 'vs/platform/remote/common/remoteAuthorityResolver';
import { getRemoteServerRootPath, parseAuthorityWithOptionalPort } from 'vs/platform/remote/common/remoteHosts';
import { getRemoteServerRootPath } from 'vs/platform/remote/common/remoteHosts';
export class RemoteAuthorityResolverService extends Disposable implements IRemoteAuthorityResolverService {
@@ -23,7 +23,7 @@ export class RemoteAuthorityResolverServ
private readonly _connectionToken: Promise<string> | string | undefined;
@@ -22,7 +22,7 @@ export class RemoteAuthorityResolverServ
private readonly _connectionToken: string | undefined;
private readonly _connectionTokens: Map<string, string>;
- constructor(@IProductService productService: IProductService, connectionToken: Promise<string> | string | undefined, resourceUriProvider: ((uri: URI) => URI) | undefined) {
+ constructor(@IProductService productService: IProductService, connectionToken: Promise<string> | string | undefined, resourceUriProvider: ((uri: URI) => URI) | undefined, private readonly proxyEndpointTemplate?: string) {
- constructor(@IProductService productService: IProductService, connectionToken: string | undefined, resourceUriProvider: ((uri: URI) => URI) | undefined) {
+ constructor(@IProductService productService: IProductService, connectionToken: string | undefined, resourceUriProvider: ((uri: URI) => URI) | undefined, private readonly proxyEndpointTemplate?: string) {
super();
this._cache = new Map<string, ResolverResult>();
this._connectionToken = connectionToken;
this._connectionTokens = new Map<string, string>();
@@ -61,9 +61,14 @@ export class RemoteAuthorityResolverServ
@@ -62,12 +62,17 @@ export class RemoteAuthorityResolverServ
private async _doResolveAuthority(authority: string): Promise<ResolverResult> {
const connectionToken = await Promise.resolve(this._connectionTokens.get(authority) || this._connectionToken);
+ let options: ResolvedOptions | undefined;
private _doResolveAuthority(authority: string): ResolverResult {
const connectionToken = this._connectionTokens.get(authority) || this._connectionToken;
+ let options: ResolvedOptions | undefined
+ if (this.proxyEndpointTemplate) {
+ const proxyUrl = new URL(this.proxyEndpointTemplate, window.location.href);
+ options = { extensionHostEnv: { VSCODE_PROXY_URI: decodeURIComponent(proxyUrl.toString()) }}
+ }
const defaultPort = (/^https:/.test(window.location.href) ? 443 : 80);
const { host, port } = parseAuthorityWithOptionalPort(authority, defaultPort);
- const result: ResolverResult = { authority: { authority, host: host, port: port, connectionToken } };
+ const result: ResolverResult = { authority: { authority, host: host, port: port, connectionToken }, options };
RemoteAuthorities.set(authority, result.authority.host, result.authority.port);
this._cache.set(authority, result);
this._onDidChangeConnectionData.fire();
if (authority.indexOf(':') >= 0) {
const pieces = authority.split(':');
- return { authority: { authority, host: pieces[0], port: parseInt(pieces[1], 10), connectionToken } };
+ return { authority: { authority, host: pieces[0], port: parseInt(pieces[1], 10), connectionToken }, options };
}
const port = (/^https:/.test(window.location.href) ? 443 : 80);
- return { authority: { authority, host: authority, port: port, connectionToken } };
+ return { authority: { authority, host: authority, port: port, connectionToken }, options };
}
_clearResolvedAuthority(authority: string): void {
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
@@ -314,6 +314,7 @@ export class WebClientServer {
@@ -310,6 +310,7 @@ export class WebClientServer {
rootEndpoint: base,
updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined,
+ proxyEndpointTemplate: process.env.VSCODE_PROXY_URI ?? base + '/proxy/{{port}}/',
logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined,
+ proxyEndpointTemplate: base + '/proxy/{{port}}',
embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery,
},
@@ -92,7 +80,7 @@ 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
@@ -247,7 +247,7 @@ export class BrowserMain extends Disposa
@@ -209,7 +209,7 @@ export class BrowserMain extends Disposa
// Remote
const connectionToken = environmentService.options.connectionToken || getCookieValue(connectionTokenCookieName);
@@ -105,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
@@ -392,7 +392,7 @@ export async function createTerminalEnvi
@@ -388,7 +388,7 @@ export async function createTerminalEnvi
// Sanitize the environment, removing any undesirable VS Code and Electron environment
// variables
@@ -114,68 +102,3 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalE
// Merge config (settings) and ShellLaunchConfig environments
mergeEnvironments(env, allowedEnvFromConfig);
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
@@ -21,6 +21,7 @@ import type { ICredentialsProvider } fro
import type { IURLCallbackProvider } from 'vs/workbench/services/url/browser/urlService';
import type { IWorkbenchConstructionOptions } from 'vs/workbench/browser/web.api';
import type { IWorkspace, IWorkspaceProvider } from 'vs/workbench/services/host/browser/browserHostService';
+import { extractLocalHostUriMetaDataForPortMapping, TunnelOptions, TunnelCreationOptions } from 'vs/platform/tunnel/common/tunnel';
interface ICredential {
service: string;
@@ -511,6 +512,38 @@ function doCreateUri(path: string, query
} : undefined,
workspaceProvider: WorkspaceProvider.create(config),
urlCallbackProvider: new LocalStorageURLCallbackProvider(config.callbackRoute),
- credentialsProvider: config.remoteAuthority ? undefined : new LocalStorageCredentialsProvider() // with a remote, we don't use a local credentials provider
+ credentialsProvider: config.remoteAuthority ? undefined : new LocalStorageCredentialsProvider(), // with a remote, we don't use a local credentials provider
+ resolveExternalUri: (uri: URI): Promise<URI> => {
+ let resolvedUri = uri
+ const localhostMatch = extractLocalHostUriMetaDataForPortMapping(resolvedUri)
+
+ if (localhostMatch && resolvedUri.authority !== location.host) {
+ if (config.productConfiguration && config.productConfiguration.proxyEndpointTemplate) {
+ resolvedUri = URI.parse(new URL(config.productConfiguration.proxyEndpointTemplate.replace('{{port}}', localhostMatch.port.toString()), window.location.href).toString())
+ } else {
+ throw new Error(`Failed to resolve external URI: ${uri.toString()}. Could not determine base url because productConfiguration missing.`)
+ }
+ }
+
+ // If not localhost, return unmodified
+ return Promise.resolve(resolvedUri)
+ },
+ tunnelProvider: {
+ tunnelFactory: (tunnelOptions: TunnelOptions, tunnelCreationOptions: TunnelCreationOptions) => {
+ const onDidDispose: Emitter<void> = new Emitter();
+ let isDisposed = false;
+ return Promise.resolve({
+ remoteAddress: tunnelOptions.remoteAddress,
+ localAddress: `localhost:${tunnelOptions.remoteAddress.port}`,
+ onDidDispose: onDidDispose.event,
+ dispose: () => {
+ if (!isDisposed) {
+ isDisposed = true;
+ onDidDispose.fire();
+ }
+ }
+ })
+ }
+ }
});
})();
Index: code-server/lib/vscode/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts
@@ -73,7 +73,7 @@ export class ForwardedPortsView extends
this.contextKeyListener = undefined;
}
- const viewEnabled: boolean = !!forwardedPortsViewEnabled.getValue(this.contextKeyService);
+ const viewEnabled: boolean = true;
if (this.environmentService.remoteAuthority && viewEnabled) {
const viewContainer = await this.getViewContainer();

View File

@@ -11,12 +11,12 @@ store-socket.diff
proxy-uri.diff
github-auth.diff
unique-db.diff
log-level.diff
local-storage.diff
service-worker.diff
connection-type.diff
sourcemaps.diff
disable-downloads.diff
telemetry.diff
display-language.diff
cli-window-open.diff
exec-argv.diff
getting-started.diff

View File

@@ -17,11 +17,26 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
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
@@ -315,6 +315,10 @@ export class WebClientServer {
updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined,
proxyEndpointTemplate: base + '/proxy/{{port}}',
+ serviceWorker: {
+ scope: vscodeBase + '/',
+ path: base + '/_static/out/browser/serviceWorker.js',
+ },
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
+++ code-server/lib/vscode/src/vs/workbench/browser/client.ts
@@ -89,6 +89,10 @@ export class CodeServerClient extends Di
@@ -90,6 +90,10 @@ export class CodeServerClient extends Di
if (this.productService.logoutEndpoint) {
this.addLogoutCommand(this.productService.logoutEndpoint);
}
@@ -32,7 +47,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
}
private checkUpdates(updateEndpoint: string) {
@@ -161,4 +165,17 @@ export class CodeServerClient extends Di
@@ -162,4 +166,17 @@ export class CodeServerClient extends Di
});
}
}
@@ -50,18 +65,3 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
+ }
+ }
}
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
@@ -316,6 +316,10 @@ export class WebClientServer {
updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined,
proxyEndpointTemplate: process.env.VSCODE_PROXY_URI ?? base + '/proxy/{{port}}/',
+ serviceWorker: {
+ scope: vscodeBase + '/',
+ path: base + '/_static/out/browser/serviceWorker.js',
+ },
embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery,
},

View File

@@ -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
@@ -191,8 +191,7 @@ function packageTask(type, platform, arc
@@ -194,8 +194,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) => {
@@ -231,9 +230,9 @@ function packageTask(type, platform, arc
@@ -234,9 +233,9 @@ function packageTask(type, platform, arc
.map(name => `.build/extensions/${name}/**`);
const extensions = gulp.src(extensionPaths, { base: '.build', dot: true });
@@ -32,12 +32,12 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js
let version = packageJson.version;
const quality = product.quality;
@@ -387,7 +386,7 @@ function tweakProductForServerWeb(produc
@@ -371,7 +370,7 @@ function tweakProductForServerWeb(produc
const minifyTask = task.define(`minify-vscode-${type}`, task.series(
optimizeTask,
util.rimraf(`out-vscode-${type}-min`),
- optimize.minifyTask(`out-vscode-${type}`, `https://ticino.blob.core.windows.net/sourcemaps/${commit}/core`)
+ optimize.minifyTask(`out-vscode-${type}`, ``)
- common.minifyTask(`out-vscode-${type}`, `https://ticino.blob.core.windows.net/sourcemaps/${commit}/core`)
+ common.minifyTask(`out-vscode-${type}`, '')
));
gulp.task(minifyTask);

View File

@@ -24,7 +24,7 @@ Index: code-server/lib/vscode/src/vs/workbench/api/node/extHostExtensionService.
import * as performance from 'vs/base/common/performance';
import { createApiFactoryAndRegisterActors } from 'vs/workbench/api/common/extHost.api.impl';
import { RequireInterceptor } from 'vs/workbench/api/common/extHostRequireInterceptor';
@@ -72,6 +74,10 @@ export class ExtHostExtensionService ext
@@ -69,6 +71,10 @@ export class ExtHostExtensionService ext
if (this._initData.remote.isRemote && this._initData.remote.authority) {
const cliServer = this._instaService.createInstance(CLIServer);
process.env['VSCODE_IPC_HOOK_CLI'] = cliServer.ipcHandlePath;

View File

@@ -1,57 +1,127 @@
Add support for telemetry endpoint
To test:
1. Create a RequestBin - https://requestbin.io/
2. Run code-server with `CS_TELEMETRY_URL` set:
i.e. `CS_TELEMETRY_URL="https://requestbin.io/1ebub9z1" ./code-server-<version>-macos-amd64/bin/code-server`
3. Load code-server in browser an do things (i.e. open a file)
4. Refresh RequestBin and you should see logs
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
@@ -71,6 +71,7 @@ import { IExtensionsScannerService } fro
@@ -70,6 +70,7 @@ import { REMOTE_FILE_SYSTEM_CHANNEL_NAME
import { ExtensionHostStatusService, IExtensionHostStatusService } from 'vs/server/node/extensionHostStatusService';
import { IExtensionsScannerService } from 'vs/platform/extensionManagement/common/extensionsScannerService';
import { ExtensionsScannerService } from 'vs/server/node/extensionsScannerService';
import { ExtensionsProfileScannerService, IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService';
import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
+import { TelemetryClient } from "vs/server/node/telemetryClient";
import { NullPolicyService } from 'vs/platform/policy/common/policy';
import { OneDataSystemAppender } from 'vs/platform/telemetry/node/1dsAppender';
@@ -133,10 +134,13 @@ export async function setupServerService
const eventPrefix = 'monacoworkbench';
@@ -123,7 +124,11 @@ export async function setupServerService
let appInsightsAppender: ITelemetryAppender = NullAppender;
const machineId = await getMachineId();
const isInternal = isInternalTelemetry(productService, configurationService);
if (supportsTelemetry(productService, environmentService)) {
- if (productService.aiConfig && productService.aiConfig.ariaKey) {
- if (productService.aiConfig && productService.aiConfig.asimovKey) {
+ const telemetryEndpoint = process.env.CS_TELEMETRY_URL || "https://v1.telemetry.coder.com/track";
+ if (telemetryEndpoint) {
+ oneDsAppender = new OneDataSystemAppender(false, eventPrefix, null, () => new TelemetryClient(telemetryEndpoint));
+ } else if (productService.aiConfig && productService.aiConfig.ariaKey) {
oneDsAppender = new OneDataSystemAppender(isInternal, eventPrefix, null, productService.aiConfig.ariaKey);
- disposables.add(toDisposable(() => oneDsAppender?.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
+ 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
}
+ disposables.add(toDisposable(() => oneDsAppender?.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
const config: ITelemetryServiceConfig = {
appenders: [oneDsAppender],
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,49 @@
+import { AppInsightsCore, IExtendedTelemetryItem, ITelemetryItem } from '@microsoft/1ds-core-js';
@@ -0,0 +1,135 @@
+import * as appInsights from 'applicationinsights';
+import * as https from 'https';
+import * as http from 'http';
+import * as os from 'os';
+
+export class TelemetryClient extends AppInsightsCore {
+ public constructor(private readonly endpoint: string) {
+ super();
+class Channel {
+ public get _sender() {
+ throw new Error('unimplemented');
+ }
+ public get _buffer() {
+ throw new Error('unimplemented');
+ }
+
+ public override track(item: IExtendedTelemetryItem | ITelemetryItem): void {
+ const options = item.baseData || {}
+ 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 = {};
+ }
@@ -88,12 +158,51 @@ Index: code-server/lib/vscode/src/vs/server/node/telemetryClient.ts
+ request.end();
+ } catch (error) {}
+ }
+
+ public flush(options: { callback: (v: string) => void }): void {
+ if (options.callback) {
+ options.callback('');
+ }
+ }
+}
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
@@ -120,16 +120,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;
}
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
@@ -321,6 +321,7 @@ export class WebClientServer {
@@ -320,6 +320,7 @@ export class WebClientServer {
scope: vscodeBase + '/',
path: base + '/_static/out/browser/serviceWorker.js',
},

View File

@@ -9,28 +9,55 @@ ensures that different browser paths will be unique (for example /workspace1 and
The easiest way to test is to open files in the same workspace using both / and
/vscode and make sure they are not interacting with each other.
Index: code-server/lib/vscode/src/vs/workbench/services/storage/browser/storageService.ts
It should also migrate old databases which can be tested by opening in an old
code-server.
This has e2e tests.
Index: code-server/lib/vscode/src/vs/platform/storage/browser/storageService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/storage/browser/storageService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/storage/browser/storageService.ts
@@ -17,6 +17,7 @@ import { AbstractStorageService, isProfi
import { isUserDataProfile, IUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile';
--- code-server.orig/lib/vscode/src/vs/platform/storage/browser/storageService.ts
+++ 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 { IAnyWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace';
import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile';
+import { hash } from 'vs/base/common/hash';
export class BrowserStorageService extends AbstractStorageService {
@@ -297,7 +298,11 @@ export class IndexedDBStorageDatabase ex
@@ -36,7 +37,11 @@ export class BrowserStorageService exten
}
static async createWorkspaceStorage(workspaceId: string, logService: ILogService): Promise<IIndexedDBStorageDatabase> {
- return IndexedDBStorageDatabase.create({ id: workspaceId }, logService);
private getId(scope: StorageScope): string {
- return scope === StorageScope.GLOBAL ? 'global' : this.payload.id;
+ // Add a unique ID based on the current path for per-workspace databases.
+ // This prevents workspaces on different machines that share the same domain
+ // and file path from colliding (since it does not appear IndexedDB can be
+ // scoped to a path) as long as they are hosted on different paths.
+ return IndexedDBStorageDatabase.create({ id: workspaceId + '-' + hash(location.pathname.toString().replace(/\/$/, "")).toString(16) }, logService);
+ return scope === StorageScope.GLOBAL ? 'global' : (this.payload.id + '-' + hash(location.pathname.toString().replace(/\/$/, "")).toString(16));
}
static async create(options: IndexedDBStorageDatabaseOptions, logService: ILogService): Promise<IIndexedDBStorageDatabase> {
protected async doInitialize(): Promise<void> {
@@ -75,6 +80,21 @@ export class BrowserStorageService exten
const firstWorkspaceOpen = this.workspaceStorage.getBoolean(IS_NEW_KEY);
if (firstWorkspaceOpen === undefined) {
this.workspaceStorage.set(IS_NEW_KEY, true);
+ // Migrate the old database.
+ let db: IIndexedDBStorageDatabase | undefined
+ try {
+ db = await IndexedDBStorageDatabase.create({ id: this.payload.id }, this.logService)
+ const items = await db.getItems()
+ for (const [key, value] of items) {
+ this.workspaceStorage.set(key, value);
+ }
+ } catch (error) {
+ this.logService.error(`[IndexedDB Storage ${this.payload.id}] migrate error: ${toErrorMessage(error)}`);
+ } finally {
+ if (db) {
+ db.close()
+ }
+ }
} else if (firstWorkspaceOpen) {
this.workspaceStorage.set(IS_NEW_KEY, false);
}

View File

@@ -29,7 +29,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
) {
super();
}
@@ -71,5 +77,59 @@ export class CodeServerClient extends Di
@@ -72,5 +78,59 @@ export class CodeServerClient extends Di
},
});
}
@@ -57,7 +57,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
+ return;
+ }
+
+ const lastNoti = this.storageService.getNumber('csLastUpdateNotification', StorageScope.APPLICATION);
+ const lastNoti = this.storageService.getNumber('csLastUpdateNotification', StorageScope.GLOBAL);
+ if (lastNoti) {
+ // Only remind them again after 1 week.
+ const timeout = 1000 * 60 * 60 * 24 * 7;
@@ -67,7 +67,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
+ }
+ }
+
+ this.storageService.store('csLastUpdateNotification', Date.now(), StorageScope.APPLICATION, StorageTarget.MACHINE);
+ this.storageService.store('csLastUpdateNotification', Date.now(), StorageScope.GLOBAL, StorageTarget.MACHINE);
+
+ this.notificationService.notify({
+ severity: Severity.Info,
@@ -105,7 +105,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
@@ -312,6 +312,7 @@ export class WebClientServer {
@@ -308,6 +308,7 @@ export class WebClientServer {
productConfiguration: <Partial<IProductConfiguration>>{
codeServerVersion: this._productService.codeServerVersion,
rootEndpoint: base,

View File

@@ -20,28 +20,11 @@ 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).
Make sure to update the hash. To do so:
1. run code-server
2. open any webview (i.e. preview Markdown)
3. see error in console and copy hash
That will test the hash change in pre/index.html
Double-check the console to make sure there are no console errors for the webWorkerExtensionHostIframe
which also requires a hash change.
parentOriginHash changes
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/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
@@ -177,7 +177,7 @@ export class BrowserWorkbenchEnvironment
@@ -183,7 +183,7 @@ export class BrowserWorkbenchEnvironment
@memoize
get webviewExternalEndpoint(): string {
@@ -54,13 +37,13 @@ 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
@@ -302,6 +302,7 @@ export class WebClientServer {
@@ -298,6 +298,7 @@ export class WebClientServer {
const workbenchWebConfiguration = {
remoteAuthority,
+ webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
_wrapWebWorkerExtHostInIframe,
developmentOptions: { enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined, logLevel: this._logService.getLevel() },
developmentOptions: { enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined },
settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined,
Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index.html
===================================================================
@@ -70,8 +53,8 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy"
- content="default-src 'none'; script-src 'sha256-wwaDxsm1+SKIUb5YJXiZlYMyV7QPB8+zd6HPcTjigZs=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
+ content="default-src 'none'; script-src 'sha256-IZkGO4jZeUn7pzM6pBZCZc9bUYm8oVNV3z8zEa8gxlk=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
- content="default-src 'none'; script-src 'sha256-xgIcbQmGjpT42GEj54VFSNh6MI15PZ2D1+DdVehfYBI=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
+ content="default-src 'none'; script-src 'sha256-aOCIU83V9nV+0ERJudbrKLqgIVOHqU71i4Lv5urjGTI=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
<!-- Disable pinch zooming -->
<meta name="viewport"
@@ -87,7 +70,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index
+
if (!crypto.subtle) {
// cannot validate, not running in a secure context
throw new Error(`'crypto.subtle' is not available so webviews will not work. This is likely because the editor is not running in a secure context (https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts).`);
throw new Error(`Cannot validate in current context!`);
Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html
@@ -104,7 +87,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index
+
if (!crypto.subtle) {
// cannot validate, not running in a secure context
throw new Error(`'crypto.subtle' is not available so webviews will not work. This is likely because the editor is not running in a secure context (https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts).`);
throw new Error(`Cannot validate in current context!`);
Index: code-server/lib/vscode/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
@@ -113,8 +96,8 @@ Index: code-server/lib/vscode/src/vs/workbench/services/extensions/worker/webWor
<meta http-equiv="Content-Security-Policy" content="
default-src 'none';
child-src 'self' data: blob:;
- script-src 'self' 'unsafe-eval' 'sha256-/r7rqQ+yrxt57sxLuQ6AMYcy/lUpvAIzHjIJt/OeLWU=' https:;
+ script-src 'self' 'unsafe-eval' 'sha256-TkIM/TmudlFEe0ZRp0ptvN54LClwk30Rql4ZPE0hm/I=' https:;
- script-src 'self' 'unsafe-eval' 'sha256-fh3TwPMflhsEIpR8g1OYTIMVWhXTLcjQ9kh2tIpmv54=' https:;
+ script-src 'self' 'unsafe-eval' 'sha256-yHVIAbzODFRINjoLGID5qWPP45HzMtwhyVRC+7yiuXg=' https:;
connect-src 'self' https: wss: http://localhost:* http://127.0.0.1:* ws://localhost:* ws://127.0.0.1:*;"/>
</head>
<body>

View File

@@ -10,7 +10,7 @@
http-equiv="Content-Security-Policy"
content="style-src 'self'; script-src 'self' 'unsafe-inline'; manifest-src 'self'; img-src 'self' data:; font-src 'self' data:;"
/>
<title>{{APP_NAME}} login</title>
<title>code-server login</title>
<link rel="icon" href="{{CS_STATIC_BASE}}/src/browser/media/favicon-dark-support.svg" />
<link rel="alternate icon" href="{{CS_STATIC_BASE}}/src/browser/media/favicon.ico" />
<link rel="manifest" href="{{BASE}}/manifest.json" crossorigin="use-credentials" />
@@ -24,7 +24,7 @@
<div class="center-container">
<div class="card-box">
<div class="header">
<h1 class="main">{{WELCOME_TEXT}}</h1>
<h1 class="main">Welcome to code-server</h1>
<div class="sub">Please log in below. {{PASSWORD_MSG}}</div>
</div>
<div class="content">

View File

@@ -1,6 +1,6 @@
import { field, Level, logger } from "@coder/logger"
import { promises as fs } from "fs"
import { load } from "js-yaml"
import yaml from "js-yaml"
import * as os from "os"
import * as path from "path"
import { canConnect, generateCertificate, generatePassword, humanPath, paths, isNodeJSErrnoException } from "./util"
@@ -50,8 +50,6 @@ export interface UserProvidedCodeArgs {
"github-auth"?: string
"disable-update-check"?: boolean
"disable-file-downloads"?: boolean
"disable-workspace-trust"?: boolean
"disable-getting-started-override"?: boolean
}
/**
@@ -86,8 +84,6 @@ export interface UserProvidedArgs extends UserProvidedCodeArgs {
"ignore-last-opened"?: boolean
link?: OptionalString
verbose?: boolean
"app-name"?: string
"welcome-text"?: string
/* Positional arguments. */
_?: string[]
}
@@ -167,14 +163,6 @@ export const options: Options<Required<UserProvidedArgs>> = {
description:
"Disable file downloads from Code. This can also be set with CS_DISABLE_FILE_DOWNLOADS set to 'true' or '1'.",
},
"disable-workspace-trust": {
type: "boolean",
description: "Disable Workspace Trust feature. This switch only affects the current session.",
},
"disable-getting-started-override": {
type: "boolean",
description: "Disable the coder/coder override in the Help: Getting Started page.",
},
// --enable can be used to enable experimental features. These features
// provide no guarantees.
enable: { type: "string[]" },
@@ -245,16 +233,7 @@ export const options: Options<Required<UserProvidedArgs>> = {
log: { type: LogLevel },
verbose: { type: "boolean", short: "vvv", description: "Enable verbose logging." },
"app-name": {
type: "string",
short: "an",
description: "The name to use in branding. Will be shown in titlebar and welcome message",
},
"welcome-text": {
type: "string",
short: "w",
description: "Text to show on login page",
},
link: {
type: OptionalString,
description: `
@@ -522,7 +501,7 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
args.verbose = false
break
case LogLevel.Warn:
logger.level = Level.Warn
logger.level = Level.Warning
args.verbose = false
break
case LogLevel.Error:
@@ -568,10 +547,6 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
args["disable-file-downloads"] = true
}
if (process.env.CS_DISABLE_GETTING_STARTED_OVERRIDE?.match(/^(1|true)$/)) {
args["disable-getting-started-override"] = true
}
const usingEnvHashedPassword = !!process.env.HASHED_PASSWORD
if (process.env.HASHED_PASSWORD) {
args["hashed-password"] = process.env.HASHED_PASSWORD
@@ -666,7 +641,7 @@ export function parseConfigFile(configFile: string, configPath: string): ConfigA
return { config: configPath }
}
const config = load(configFile, {
const config = yaml.load(configFile, {
filename: configPath,
})
if (!config || typeof config === "string") {

View File

@@ -9,7 +9,7 @@ import { AuthType, DefaultedArgs, Feature, SpawnCodeCli, toCodeArgs, UserProvide
import { coderCloudBind } from "./coder_cloud"
import { commit, version } from "./constants"
import { register } from "./routes"
import { humanPath, isDirectory, loadAMDModule, open } from "./util"
import { humanPath, isFile, loadAMDModule, open } from "./util"
/**
* Return true if the user passed an extension-related VS Code flag.
@@ -69,15 +69,14 @@ export const openInExistingInstance = async (args: DefaultedArgs, socketPath: st
fileURIs: [],
forceReuseWindow: args["reuse-window"],
forceNewWindow: args["new-window"],
gotoLineMode: true,
}
const paths = args._ || []
for (let i = 0; i < paths.length; i++) {
const fp = path.resolve(paths[i])
if (await isDirectory(fp)) {
pipeArgs.folderURIs.push(fp)
} else {
if (await isFile(fp)) {
pipeArgs.fileURIs.push(fp)
} else {
pipeArgs.folderURIs.push(fp)
}
}
if (pipeArgs.forceNewWindow && pipeArgs.fileURIs.length > 0) {

View File

@@ -227,7 +227,7 @@ export class PluginAPI {
`)
}
if (!semver.satisfies(version, packageJSON.engines["code-server"])) {
this.logger.warn(
throw new Error(
`plugin range ${q(packageJSON.engines["code-server"])} incompatible` + ` with code-server version ${version}`,
)
}

View File

@@ -28,8 +28,6 @@ export class RateLimiter {
const getRoot = async (req: Request, error?: Error): Promise<string> => {
const content = await fs.readFile(path.join(rootPath, "src/browser/pages/login.html"), "utf8")
const appName = req.args["app-name"] || "code-server"
const welcomeText = req.args["welcome-text"] || `Welcome to ${appName}`
let passwordMsg = `Check the config file at ${humanPath(os.homedir(), req.args.config)} for the password.`
if (req.args.usingEnvPassword) {
passwordMsg = "Password was set from $PASSWORD."
@@ -40,8 +38,6 @@ const getRoot = async (req: Request, error?: Error): Promise<string> => {
return replaceTemplates(
req,
content
.replace(/{{APP_NAME}}/g, appName)
.replace(/{{WELCOME_TEXT}}/g, welcomeText)
.replace(/{{PASSWORD_MSG}}/g, passwordMsg)
.replace(/{{ERROR}}/, error ? `<div class="error">${escapeHtml(error.message)}</div>` : ""),
)

View File

@@ -156,7 +156,9 @@ export class CodeServerRouteWrapper {
try {
this._codeServerMain = await createVSServer(null, {
...(await toCodeArgs(args)),
// TODO: Make the browser helper script work.
"without-connection-token": true,
"without-browser-env-var": true,
})
} catch (error) {
logError(logger, "CodeServerRouteWrapper", error)

View File

@@ -482,15 +482,6 @@ export const isFile = async (path: string): Promise<boolean> => {
}
}
export const isDirectory = async (path: string): Promise<boolean> => {
try {
const stat = await fs.stat(path)
return stat.isDirectory()
} catch (error) {
return false
}
}
/**
* Escapes any HTML string special characters, like &, <, >, ", and '.
*

View File

@@ -317,11 +317,11 @@ export class ParentProcess extends Process {
}
private spawn(): cp.ChildProcess {
return cp.fork(path.join(__dirname, "entry"), {
// Use spawn (instead of fork) to use the new binary in case it was updated.
return cp.spawn(process.argv[0], process.argv.slice(1), {
env: {
...process.env,
CODE_SERVER_PARENT_PID: process.pid.toString(),
NODE_EXEC_PATH: process.execPath,
},
stdio: ["pipe", "pipe", "pipe", "ipc"],
})

View File

@@ -1,10 +1,13 @@
import * as cp from "child_process"
import { promises as fs } from "fs"
import * as os from "os"
import * as path from "path"
import * as util from "util"
import { getMaybeProxiedCodeServer } from "../utils/helpers"
import { describe, test, expect } from "./baseFixture"
import { CodeServer } from "./models/CodeServer"
describe("code-server", ["--disable-workspace-trust"], {}, () => {
describe("code-server", [], {}, () => {
// TODO@asher: Generalize this? Could be nice if we were to ever need
// multiple migration tests in other suites.
const instances = new Map<string, CodeServer>()
@@ -14,6 +17,30 @@ describe("code-server", ["--disable-workspace-trust"], {}, () => {
await Promise.all(procs.map((cs) => cs.close()))
})
/**
* Spawn a specific version of code-server using the install script.
*/
const spawn = async (version: string, dir?: string): Promise<CodeServer> => {
let instance = instances.get(version)
if (!instance) {
await util.promisify(cp.exec)(`./install.sh --method standalone --version ${version}`, {
cwd: path.join(__dirname, "../.."),
})
instance = new CodeServer(
"code-server@" + version,
["--auth=none"],
{ VSCODE_DEV: "" },
dir,
`${os.homedir()}/.local/lib/code-server-${version}`,
)
instances.set(version, instance)
}
return instance
}
test("should navigate to home page", async ({ codeServerPage }) => {
// We navigate codeServer before each test
// and we start the test with a storage state
@@ -41,4 +68,54 @@ describe("code-server", ["--disable-workspace-trust"], {}, () => {
await fs.writeFile(file, "bar")
await codeServerPage.openFile(file)
})
test("should migrate state to avoid collisions", async ({ codeServerPage }) => {
// This can take a very long time in development because of how long pages
// take to load and we are doing a lot of that here.
if (process.env.VSCODE_DEV === "1") {
test.slow()
}
const dir = await codeServerPage.workspaceDir
const files = [path.join(dir, "foo"), path.join(dir, "bar")]
await Promise.all(
files.map((file) => {
return fs.writeFile(file, path.basename(file))
}),
)
// Open a file in the latest instance.
await codeServerPage.openFile(files[0])
await codeServerPage.stateFlush()
// Open a file in an older version of code-server. It should not see the
// file opened in the new instance since the database has a different
// name. This must be accessed through the proxy so it shares the same
// domain and can write to the same database.
const cs = await spawn("4.0.2", dir)
const address = new URL(await cs.address())
await codeServerPage.navigate("/proxy/" + address.port + "/")
await codeServerPage.openFile(files[1])
expect(await codeServerPage.tabIsVisible(files[0])).toBe(false)
await codeServerPage.stateFlush()
// Move back to latest code-server. We should see the file we previously
// opened with it but not the old code-server file because the new instance
// already created its own database on this path and will avoid migrating.
await codeServerPage.navigate()
await codeServerPage.waitForTab(files[0])
expect(await codeServerPage.tabIsVisible(files[1])).toBe(false)
// Open a new path in latest code-server. This one should migrate the
// database from old code-server but see nothing from the new database
// created on the root.
await codeServerPage.navigate("/vscode")
await codeServerPage.waitForTab(files[1])
expect(await codeServerPage.tabIsVisible(files[0])).toBe(false)
// Should still be open after a reload.
await codeServerPage.navigate("/vscode")
await codeServerPage.waitForTab(files[1])
expect(await codeServerPage.tabIsVisible(files[0])).toBe(false)
})
})

View File

@@ -1,19 +0,0 @@
import * as path from "path"
import { describe, test, expect } from "./baseFixture"
// Given a code-server environment with Spanish Language Pack extension installed
// and a languagepacks.json in the data-dir
describe(
"--locale es",
["--disable-workspace-trust", "--extensions-dir", path.join(__dirname, "./extensions"), "--locale", "es"],
{},
() => {
test("should load code-server in Spanish", async ({ codeServerPage }) => {
// When
const visible = await codeServerPage.page.isVisible("text=Explorador")
// Then
expect(visible).toBe(true)
})
},
)

View File

@@ -3,7 +3,7 @@ import * as path from "path"
import { clean } from "../utils/helpers"
import { describe, test, expect } from "./baseFixture"
describe("Downloads (enabled)", ["--disable-workspace-trust"], {}, async () => {
describe("Downloads (enabled)", [], {}, async () => {
const testName = "downloads-enabled"
test.beforeAll(async () => {
await clean(testName)
@@ -25,7 +25,7 @@ describe("Downloads (enabled)", ["--disable-workspace-trust"], {}, async () => {
})
})
describe("Downloads (disabled)", ["--disable-workspace-trust", "--disable-file-downloads"], {}, async () => {
describe("Downloads (disabled)", ["--disable-file-downloads"], {}, async () => {
const testName = "downloads-disabled"
test.beforeAll(async () => {
await clean(testName)

View File

@@ -1,25 +1,23 @@
import { test as base } from "@playwright/test"
import * as path from "path"
import { getMaybeProxiedCodeServer } from "../utils/helpers"
import { test as base } from "@playwright/test"
import { describe, test, expect } from "./baseFixture"
import { getMaybeProxiedCodeServer } from "../utils/helpers"
function runTestExtensionTests() {
// This will only work if the test extension is loaded into code-server.
test("should have access to VSCODE_PROXY_URI", async ({ codeServerPage }) => {
const address = await getMaybeProxiedCodeServer(codeServerPage)
await codeServerPage.waitForTestExtensionLoaded()
await codeServerPage.executeCommandViaMenus("code-server: Get proxy URI")
await codeServerPage.page.waitForSelector("text=proxyUri", { timeout: 3000 })
const text = await codeServerPage.page.locator("text=proxyUri").first().textContent()
const text = await codeServerPage.page.locator(".notification-list-item-message").textContent()
// Remove end slash in address
const normalizedAddress = address.replace(/\/+$/, "")
expect(text).toBe(`Info: proxyUri: ${normalizedAddress}/proxy/{{port}}/`)
expect(text).toBe(`${normalizedAddress}/proxy/{{port}}`)
})
}
const flags = ["--disable-workspace-trust", "--extensions-dir", path.join(__dirname, "./extensions")]
const flags = ["--extensions-dir", path.join(__dirname, "./extensions")]
describe("Extensions", flags, {}, () => {
runTestExtensionTests()

View File

@@ -1,38 +0,0 @@
{
"name": "vscode-language-pack-es",
"displayName": "Spanish Language Pack for Visual Studio Code",
"description": "Language pack extension for Spanish",
"version": "1.70.0",
"publisher": "MS-CEINTL",
"repository": {
"type": "git",
"url": "https://github.com/Microsoft/vscode-loc"
},
"engines": {
"vscode": "^1.70.0"
},
"categories": [
"Language Packs"
],
"contributes": {
"localizations": [
{
"languageId": "es",
"languageName": "Spanish",
"localizedLanguageName": "español",
"translations": [
{
"id": "vscode",
"path": "./translations/main.i18n.json"
}
]
}
]
},
"__metadata": {
"id": "47e020a1-33db-4cc0-a1b4-42f97781749a",
"publisherDisplayName": "MS-CEINTL",
"publisherId": "0b0882c3-aee3-4d7c-b5f9-872f9be0a115",
"isPreReleaseVersion": false
}
}

View File

@@ -1,15 +0,0 @@
{
"": [
"--------------------------------------------------------------------------------------------",
"Copyright (c) Microsoft Corporation. All rights reserved.",
"Licensed under the MIT License. See License.txt in the project root for license information.",
"--------------------------------------------------------------------------------------------",
"Do not edit this file. It is machine generated."
],
"version": "1.0.0",
"contents": {
"vs/workbench/contrib/files/browser/explorerViewlet": {
"explore": "Explorador"
}
}
}

View File

@@ -1,31 +1,13 @@
import * as vscode from "vscode"
export function activate(context: vscode.ExtensionContext) {
vscode.window.showInformationMessage("test extension loaded")
// Test extension
context.subscriptions.push(
vscode.commands.registerCommand("codeServerTest.proxyUri", () => {
if (process.env.VSCODE_PROXY_URI) {
vscode.window.showInformationMessage(`proxyUri: ${process.env.VSCODE_PROXY_URI}`)
vscode.window.showInformationMessage(process.env.VSCODE_PROXY_URI)
} else {
vscode.window.showErrorMessage("No proxy URI was set")
}
}),
)
// asExternalUri extension
context.subscriptions.push(
vscode.commands.registerCommand("codeServerTest.asExternalUri", async () => {
const input = await vscode.window.showInputBox({
prompt: "URL to pass through to asExternalUri",
})
if (input) {
const output = await vscode.env.asExternalUri(vscode.Uri.parse(input))
vscode.window.showInformationMessage(`input: ${input} output: ${output}`)
} else {
vscode.window.showErrorMessage(`Failed to run test case. No input provided.`)
}
}),
)
}

View File

@@ -3,9 +3,8 @@
"description": "code-server test extension",
"version": "0.0.1",
"publisher": "coder",
"license": "MIT",
"activationEvents": [
"onStartupFinished"
"onCommand:codeServerTest.proxyUri"
],
"engines": {
"vscode": "^1.56.0"
@@ -17,11 +16,6 @@
"command": "codeServerTest.proxyUri",
"title": "Get proxy URI",
"category": "code-server"
},
{
"command": "codeServerTest.asExternalUri",
"title": "asExternalUri test",
"category": "code-server"
}
]
},

View File

@@ -2,7 +2,7 @@ import { test as base } from "@playwright/test"
import { describe, expect, test } from "./baseFixture"
if (process.env.GITHUB_TOKEN) {
describe("GitHub token", ["--disable-workspace-trust"], {}, () => {
describe("GitHub token", [], {}, () => {
test("should be logged in to pull requests extension", async ({ codeServerPage }) => {
await codeServerPage.exec("git init")
await codeServerPage.exec("git remote add origin https://github.com/coder/code-server")
@@ -16,7 +16,7 @@ if (process.env.GITHUB_TOKEN) {
})
})
describe("No GitHub token", ["--disable-workspace-trust"], { GITHUB_TOKEN: "" }, () => {
describe("No GitHub token", [], { GITHUB_TOKEN: "" }, () => {
test("should not be logged in to pull requests extension", async ({ codeServerPage }) => {
await codeServerPage.exec("git init")
await codeServerPage.exec("git remote add origin https://github.com/coder/code-server")

View File

@@ -1,7 +1,7 @@
import { PASSWORD } from "../utils/constants"
import { describe, test, expect } from "./baseFixture"
describe("login", ["--disable-workspace-trust", "--auth", "password"], {}, () => {
describe("login", ["--auth", "password"], {}, () => {
test("should see the login page", async ({ codeServerPage }) => {
// It should send us to the login page
expect(await codeServerPage.page.title()).toBe("code-server login")

View File

@@ -1,7 +1,7 @@
// NOTE@jsjoeio commenting out until we can figure out what's wrong
// import { describe, test, expect } from "./baseFixture"
// describe("logout", true, ["--disable-workspace-trust"], {}, () => {
// describe("logout", true, [], {}, () => {
// test("should be able logout", async ({ codeServerPage }) => {
// // Recommended by Playwright for async navigation
// // https://github.com/microsoft/playwright/issues/1987#issuecomment-620182151

View File

@@ -82,33 +82,12 @@ 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",
)
const extensionsDir = path.join(__dirname, "../extensions")
const languagepacksContent = {
es: {
hash: "8d919a946475223861fa0c62665a4c50",
extensions: [
{
extensionIdentifier: {
id: "ms-ceintl.vscode-language-pack-es",
uuid: "47e020a1-33db-4cc0-a1b4-42f97781749a",
},
version: "1.70.0",
},
],
translations: {
vscode: `${extensionsDir}/ms-ceintl.vscode-language-pack-es-1.70.0/translations/main.i18n.json`,
},
label: "español",
},
}
// NOTE@jsjoeio - code-server should automatically generate the languagepacks.json for
// using different display languages. This is a temporary workaround until we fix that.
await fs.writeFile(path.join(dir, "languagepacks.json"), JSON.stringify(languagepacksContent))
return dir
}
@@ -317,16 +296,6 @@ export class CodeServerPage {
return visible
}
/**
* Checks if the test extension loaded
*/
async waitForTestExtensionLoaded(): Promise<void> {
const selector = "text=test extension loaded"
this.codeServer.logger.debug("Waiting for test extension to load...")
await this.page.waitForSelector(selector)
}
/**
* Focuses the integrated terminal by navigating through the command palette.
*

View File

@@ -1,7 +1,7 @@
import { version } from "../../src/node/constants"
import { describe, test, expect } from "./baseFixture"
describe("Open Help > About", ["--disable-workspace-trust"], {}, () => {
describe("Open Help > About", [], {}, () => {
test("should see code-server version in about dialog", async ({ codeServerPage }) => {
// Open using the menu.
await codeServerPage.navigateMenus(["Help", "About"])

Some files were not shown because too many files have changed in this diff Show More