Compare commits

..

9 Commits

Author SHA1 Message Date
Joe Previte
fa2f887c6e chore: bump version 4.8.2 2022-11-02 14:10:08 -07:00
Joe Previte
3736cffdca refactor: warn plugin range incompatibble 2022-11-01 11:08:35 -07:00
Joe Previte
26c46beab8 Merge branch 'main' into release/v4.8.2 2022-11-01 10:50:14 -07:00
Joe Previte
428e21dfdf docs: add release candidate notes 2022-11-01 10:42:02 -07:00
Joe Previte
c37d9c5cbe fixup: use 4.8.2-rc.1 2022-11-01 10:41:52 -07:00
Joe Previte
7db7c81a58 Revert "chore: bump version to 4.8.2"
This reverts commit 5d70994f22.
2022-11-01 10:35:18 -07:00
Joe Previte
2988146593 docs: add back line in publishing release
See https://github.com/coder/code-server/pull/5732#discussion_r1010685933
2022-11-01 10:17:48 -07:00
Joe Previte
3949927d5c chore: update CHANGELOG 2022-11-01 10:17:19 -07:00
Joe Previte
5d70994f22 chore: bump version to 4.8.2 2022-11-01 10:17:19 -07:00
86 changed files with 1058 additions and 1183 deletions

2
.github/CODEOWNERS vendored
View File

@@ -3,5 +3,3 @@
ci/helm-chart/ @Matthew-Beckett @alexgorbatchev
docs/install.md @GNUxeava
src/node/i18n/locales/zh-cn.json @zhaozhiming

View File

@@ -1,31 +0,0 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
time: "06:00"
timezone: "America/Chicago"
labels: []
commit-message:
prefix: "chore"
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "monthly"
time: "06:00"
timezone: "America/Chicago"
commit-message:
prefix: "chore"
labels: []
ignore:
# Ignore patch updates for all dependencies
- dependency-name: "*"
update-types:
- version-update:semver-patch
# Ignore major updates to Node.js types, because they need to
# correspond to the Node.js engine version
- dependency-name: "@types/node"
update-types:
- version-update:semver-major

View File

@@ -24,7 +24,7 @@ concurrency:
jobs:
prettier:
name: Format with Prettier
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout repo
@@ -37,7 +37,7 @@ jobs:
doctoc:
name: Doctoc markdown files
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout repo
@@ -66,7 +66,7 @@ jobs:
lint-helm:
name: Lint Helm chart
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout repo
@@ -83,7 +83,7 @@ jobs:
- name: Install helm
if: steps.changed-files.outputs.any_changed == 'true'
uses: azure/setup-helm@v3.5
uses: azure/setup-helm@v3.4
with:
token: ${{ secrets.GITHUB_TOKEN }}
@@ -97,7 +97,7 @@ jobs:
lint-ts:
name: Lint TypeScript files
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout repo
@@ -139,70 +139,9 @@ jobs:
if: steps.changed-files.outputs.any_changed == 'true'
run: yarn lint:ts
lint-actions:
name: Lint GitHub Actions
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Check workflow files
run: |
bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/7fdc9630cc360ea1a469eed64ac6d78caeda1234/scripts/download-actionlint.bash)
./actionlint -color -shellcheck= -ignore "set-output"
shell: bash
test-unit:
name: Run unit tests
runs-on: ubuntu-20.04
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
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: Run unit tests
if: steps.changed-files.outputs.any_changed == 'true'
run: yarn test:unit
- name: Upload coverage report to Codecov
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
if: success()
build:
name: Build code-server
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
timeout-minutes: 30
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
@@ -231,17 +170,15 @@ jobs:
uses: actions/cache@v3
with:
path: "**/node_modules"
key: yarn-build-code-server-${{ hashFiles('**/yarn.lock') }}
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
yarn-build-code-server-
yarn-build-
- name: Install dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: yarn --frozen-lockfile
- name: Build code-server
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: yarn build
# Get Code's git hash. When this changes it means the content is
@@ -250,6 +187,10 @@ jobs:
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
@@ -259,14 +200,25 @@ jobs:
uses: actions/cache@v3
with:
path: lib/vscode-reh-web-*
key: vscode-reh-package-${{ secrets.VSCODE_CACHE_VERSION }}-${{ steps.vscode-rev.outputs.rev }}-${{ hashFiles('patches/*.diff', 'ci/build/build-vscode.sh') }}
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
env:
VERSION: "0.0.0"
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
@@ -283,11 +235,64 @@ jobs:
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-20.04
timeout-minutes: 25
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout repo
uses: actions/checkout@v3
@@ -315,7 +320,7 @@ jobs:
run: tar -xzf package.tar.gz
- name: Install release package dependencies
run: cd release && npm install --unsafe-perm --omit=dev
run: cd release && yarn install
- name: Install dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
@@ -327,7 +332,7 @@ jobs:
./test/node_modules/.bin/playwright install
- name: Run end-to-end tests
run: CODE_SERVER_TEST_ENTRY=./release yarn test:e2e
run: CODE_SERVER_TEST_ENTRY=./release yarn test:e2e --global-timeout 840000
- name: Upload test artifacts
if: always()
@@ -342,7 +347,7 @@ jobs:
test-e2e-proxy:
name: Run e2e tests behind proxy
needs: build
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- name: Checkout repo
@@ -371,7 +376,7 @@ jobs:
run: tar -xzf package.tar.gz
- name: Install release package dependencies
run: cd release && npm install --unsafe-perm --omit=dev
run: cd release && yarn install
- name: Install dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
@@ -383,7 +388,7 @@ jobs:
./test/node_modules/.bin/playwright install
- name: Cache Caddy
uses: actions/cache@v3
uses: actions/cache@v2
id: caddy-cache
with:
path: |
@@ -396,7 +401,7 @@ jobs:
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
mkdir -p ~/.cache/caddy
tar -xzf caddy_2.5.2_linux_amd64.tar.gz --directory ~/.cache/caddy
- name: Start Caddy

46
.github/workflows/docs-preview.yaml vendored Normal file
View File

@@ -0,0 +1,46 @@
name: Docs preview
on:
pull_request:
branches:
- main
paths:
- "docs/**"
permissions:
actions: none
checks: none
contents: read
deployments: none
issues: none
packages: none
pull-requests: write
repository-projects: none
security-events: none
statuses: none
jobs:
preview:
name: Docs preview
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- name: Set outputs
id: vars
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
- name: Comment Credentials
uses: marocchino/sticky-pull-request-comment@v2
# Only run if PR comes from base repo
# Reason: forks cannot access secrets and this will always fail
if: github.event.pull_request.head.repo.full_name == github.repository
with:
GITHUB_TOKEN: ${{ github.token }}
header: codercom-preview-docs
message: |
✨ code-server docs for PR #${{ github.event.number }} is ready! It will be updated on every commit.
* _Host_: https://coder.com/docs/code-server/${{ steps.vars.outputs.sha_short }}
* _Last deploy status_: success
* _Commit_: ${{ github.event.pull_request.head.sha }}
* _Workflow status_: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}

View File

@@ -41,7 +41,7 @@ jobs:
alpine:
name: Test installer on Alpine
runs-on: ubuntu-latest
container: "alpine:3.17"
container: "alpine:3.16"
steps:
- name: Checkout repo
uses: actions/checkout@v3

View File

@@ -4,11 +4,6 @@ on:
# Shows the manual trigger in GitHub UI
# helpful as a back-up in case the GitHub Actions Workflow fails
workflow_dispatch:
inputs:
version:
description: The version to publish (include "v", i.e. "v4.9.1").
type: string
required: true
release:
types: [released]
@@ -29,25 +24,21 @@ jobs:
- 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.7
uses: robinraju/release-downloader@v1.5
with:
repository: "coder/code-server"
tag: ${{ github.event.inputs.version || github.ref_name }}
tag: v${{ steps.version.outputs.version }}
fileName: "package.tar.gz"
out-file-path: "release-npm-package"
# NOTE@jsjoeio - we do this so we can strip out the v
# i.e. v4.9.1 -> 4.9.1
- name: Get and set VERSION
run: |
TAG="${{ github.event.inputs.version || github.ref_name }}"
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- name: Publish npm package and tag with "latest"
run: yarn publish:npm
env:
VERSION: ${{ env.VERSION }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_ENVIRONMENT: "production"
@@ -71,18 +62,9 @@ jobs:
git config --global user.name cdrci
git config --global user.email opensource@coder.com
# NOTE@jsjoeio - we do this so we can strip out the v
# i.e. v4.9.1 -> 4.9.1
- name: Get and set VERSION
run: |
TAG="${{ github.event.inputs.version || github.ref_name }}"
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- name: Bump code-server homebrew version
env:
VERSION: ${{ env.VERSION }}
HOMEBREW_GITHUB_API_TOKEN: ${{secrets.HOMEBREW_GITHUB_API_TOKEN}}
run: ./ci/steps/brew-bump.sh
aur:
@@ -91,7 +73,6 @@ jobs:
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
@@ -100,6 +81,13 @@ jobs:
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:
@@ -118,33 +106,22 @@ jobs:
git config --global user.name cdrci
git config --global user.email opensource@coder.com
# NOTE@jsjoeio - we do this so we can strip out the v
# i.e. v4.9.1 -> 4.9.1
- name: Get and set VERSION
run: |
TAG="${{ github.event.inputs.version || github.ref_name }}"
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- name: Validate package
uses: hapakaien/archlinux-package-action@v2
env:
VERSION: ${{ env.VERSION }}
with:
pkgver: ${{ env.VERSION }}
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.
env:
VERSION: ${{ env.VERSION }}
run: |
git checkout -b update-version-${{ env.VERSION }}
git checkout -b update-version-${{ steps.version.outputs.version }}
git add .
git commit -m "chore: updating version to ${{ env.VERSION }}"
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 ${{ env.VERSION }}" --body "PR opened by @$GITHUB_ACTOR" --assignee $GITHUB_ACTOR
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:
@@ -170,23 +147,19 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# NOTE@jsjoeio - we do this so we can strip out the v
# i.e. v4.9.1 -> 4.9.1
- name: Get and set VERSION
run: |
TAG="${{ github.event.inputs.version || github.ref_name }}"
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- 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.7
uses: robinraju/release-downloader@v1.5
with:
repository: "coder/code-server"
tag: v${{ env.VERSION }}
tag: v${{ steps.version.outputs.version }}
fileName: "*.deb"
out-file-path: "release-packages"
- name: Publish to Docker
run: yarn publish:docker
env:
VERSION: ${{ env.VERSION }}
GITHUB_TOKEN: ${{ github.token }}

View File

@@ -2,11 +2,6 @@ name: Draft release
on:
workflow_dispatch:
inputs:
version:
description: The version to publish (include "v", i.e. "v4.9.1").
type: string
required: true
permissions:
contents: write # For creating releases.
@@ -26,7 +21,6 @@ jobs:
name: x86-64 Linux build
runs-on: ubuntu-latest
timeout-minutes: 15
needs: npm-version
container: "centos:7"
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
@@ -44,13 +38,11 @@ jobs:
run: |
yum install -y epel-release centos-release-scl make
yum install -y devtoolset-9-{make,gcc,gcc-c++} jq rsync python3
# for keytar
yum install -y libsecret-devel
- name: Install nfpm and envsubst
run: |
mkdir -p ~/.local/bin
curl -sSfL https://github.com/goreleaser/nfpm/releases/download/v2.22.2/nfpm_2.22.2_`uname -s`_`uname -m`.tar.gz | tar -C ~/.local/bin -zxv nfpm
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
@@ -59,10 +51,15 @@ jobs:
- name: Install yarn
run: npm install -g yarn
- name: Download npm package
uses: actions/download-artifact@v3
- name: Download artifacts
uses: dawidd6/action-download-artifact@v2
id: download
with:
name: npm-release-package
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
@@ -70,9 +67,19 @@ jobs:
# 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 && npm run release:standalone
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
@@ -84,16 +91,7 @@ jobs:
token: ${{ secrets.CODECOV_TOKEN }}
if: success()
# NOTE@jsjoeio - we do this so we can strip out the v
# i.e. v4.9.1 -> 4.9.1
- name: Get and set VERSION
run: |
TAG="${{ inputs.version || github.ref_name }}"
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- name: Build packages with nfpm
env:
VERSION: ${{ env.VERSION }}
run: yarn package
- uses: softprops/action-gh-release@v1
@@ -119,13 +117,12 @@ jobs:
# but this means we don't need to maintain a self-hosted runner!
# NOTE@jsjoeio:
# We used to use 18.04 until GitHub browned it out on December 15, 2022
# See here: https://github.com/actions/runner-images/issues/6002
# 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-20.04
runs-on: ubuntu-18.04
timeout-minutes: 15
needs: npm-version
strategy:
matrix:
include:
@@ -162,16 +159,19 @@ jobs:
env:
PACKAGE: ${{ format('g++-{0}', matrix.prefix) }}
- name: Download npm package
uses: actions/download-artifact@v3
- name: Download artifacts
uses: dawidd6/action-download-artifact@v2
id: download
with:
name: npm-release-package
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@jsjoeio - npm fails here
# so use yarn
- name: Build standalone release
run: yarn release:standalone
@@ -181,16 +181,7 @@ jobs:
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
# NOTE@jsjoeio - we do this so we can strip out the v
# i.e. v4.9.1 -> 4.9.1
- name: Get and set VERSION
run: |
TAG="${{ inputs.version || github.ref_name }}"
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- name: Build packages with nfpm
env:
VERSION: ${{ env.VERSION }}
run: yarn package ${NPM_CONFIG_ARCH}
- uses: softprops/action-gh-release@v1
@@ -203,7 +194,6 @@ jobs:
name: x86-64 macOS build
runs-on: macos-latest
timeout-minutes: 15
needs: npm-version
steps:
- name: Checkout repo
uses: actions/checkout@v3
@@ -219,33 +209,39 @@ jobs:
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
- name: Download artifacts
uses: dawidd6/action-download-artifact@v2
id: download
with:
name: npm-release-package
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: npm run release:standalone
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
# NOTE@jsjoeio - we do this so we can strip out the v
# i.e. v4.9.1 -> 4.9.1
- name: Get and set VERSION
run: |
TAG="${{ inputs.version || github.ref_name }}"
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- name: Build packages with nfpm
env:
VERSION: ${{ env.VERSION }}
run: yarn package
- uses: softprops/action-gh-release@v1
@@ -258,23 +254,6 @@ jobs:
name: Upload npm package
runs-on: ubuntu-latest
timeout-minutes: 15
needs: npm-version
steps:
- name: Download npm package
uses: actions/download-artifact@v3
with:
name: npm-release-package
- uses: softprops/action-gh-release@v1
with:
draft: true
discussion_category_name: "📣 Announcements"
files: ./package.tar.gz
npm-version:
name: Modify package.json version
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Download artifacts
uses: dawidd6/action-download-artifact@v2
@@ -283,38 +262,11 @@ jobs:
branch: ${{ github.ref }}
workflow: build.yaml
workflow_conclusion: completed
check_artifacts: true
name: npm-package
check_artifacts: false
if_no_artifact_found: fail
- name: Decompress npm package
run: tar -xzf package.tar.gz
# NOTE@jsjoeio - we do this so we can strip out the v
# i.e. v4.9.1 -> 4.9.1
- name: Get and set VERSION
run: |
TAG="${{ inputs.version || github.ref_name }}"
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- name: Modify version
env:
VERSION: ${{ env.VERSION }}
run: |
echo "Updating version in root package.json"
npm version --prefix release "$VERSION"
echo "Updating version in lib/vscode/product.json"
tmp=$(mktemp)
jq ".codeServerVersion = \"$VERSION\"" release/lib/vscode/product.json > "$tmp" && mv "$tmp" release/lib/vscode/product.json
# Ensure it has the same permissions as before
chmod 644 release/lib/vscode/product.json
- name: Compress release package
run: tar -czf package.tar.gz release
- name: Upload npm package artifact
uses: actions/upload-artifact@v3
- uses: softprops/action-gh-release@v1
with:
name: npm-release-package
path: ./package.tar.gz
draft: true
discussion_category_name: "📣 Announcements"
files: ./package.tar.gz

View File

@@ -38,7 +38,7 @@ jobs:
name: Run script unit tests
runs-on: ubuntu-latest
# This runs on Alpine to make sure we're testing with actual sh.
container: "alpine:3.17"
container: "alpine:3.16"
steps:
- name: Checkout repo
uses: actions/checkout@v3

View File

@@ -65,7 +65,7 @@ jobs:
fetch-depth: 0
- name: Run Trivy vulnerability scanner in repo mode
uses: aquasecurity/trivy-action@cff3e9a7f62c41dd51975266d0ae235709e39c41
uses: aquasecurity/trivy-action@e55de85beea5fcec743de6bb6bc56943a0af3c33
with:
scan-type: "fs"
scan-ref: "."

View File

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

View File

@@ -1,7 +1,6 @@
lib/vscode
lib/vscode-reh-web-linux-x64
release-standalone
release-packages
release
helm-chart
test/scripts

View File

@@ -20,67 +20,6 @@ Code v99.99.999
-->
## [4.10.0](https://github.com/coder/code-server/releases/tag/v4.10.0) - TBD
Code v1.75.1
### Changed
- Updated to Code 1.75.1
### Removed
- Removed `--link` (was deprecated in 4.0.1).
## [4.9.1](https://github.com/coder/code-server/releases/tag/v4.9.1) - 2022-12-15
Code v1.73.1
### Changed
- Updated a couple steps in the build and release process to ensure we're using
`npm` and `yarn` consistently depending on the step.
### Fixed
- Fixed an issue with code-server version not displaying in the Help > About window.
- Fixed terminal not loading on macOS clients.
## [4.9.0](https://github.com/coder/code-server/releases/tag/v4.9.0) - 2022-12-06
Code v1.73.1
### Changed
- Upgraded to Code 1.73.1
### Added
- `/security.txt` added as a route with info on our security policy information thanks to @ghuntley
### Fixed
- Installing on majaro images should now work thanks to @MrPeacockNLB for
adding the `--noconfirm` flag in `install.sh`
### Known Issues
- `--cert` on Ubuntu 22.04: OpenSSL v3 is used which breaks `pem` meaning the
`--cert` feature will not work. [Reference](https://github.com/adobe/fetch/pull/318#issuecomment-1306070259)
## [4.8.3](https://github.com/coder/code-server/releases/tag/v4.8.3) - 2022-11-07
Code v1.72.1
### Added
- install script now supports arch-like (i.e. manjaro, endeavourous, etc.)
architectures
### Changed
- Updated text in the Getting Started page.
## [4.8.2](https://github.com/coder/code-server/releases/tag/v4.8.2) - 2022-11-02
Code v1.72.1

View File

@@ -14,6 +14,22 @@ main() {
sed -i.bak "1s;^;#!/usr/bin/env node\n;" out/node/entry.js && rm out/node/entry.js.bak
chmod +x out/node/entry.js
fi
# for arch; we do not use OS from lib.sh and get our own.
# lib.sh normalizes macos to darwin - but cloud-agent's binaries do not
source ./ci/lib.sh
OS="$(uname | tr '[:upper:]' '[:lower:]')"
mkdir -p ./lib
if ! [ -f ./lib/coder-cloud-agent ]; then
echo "Downloading the cloud agent..."
set +e
curl -fsSL "https://github.com/coder/cloud-agent/releases/latest/download/cloud-agent-$OS-$ARCH" -o ./lib/coder-cloud-agent
chmod +x ./lib/coder-cloud-agent
set -e
fi
}
main "$@"

View File

@@ -63,6 +63,8 @@ EOF
if [ "$KEEP_MODULES" = 1 ]; then
rsync node_modules/ "$RELEASE_PATH/node_modules"
mkdir -p "$RELEASE_PATH/lib"
rsync ./lib/coder-cloud-agent "$RELEASE_PATH/lib"
fi
}

View File

@@ -42,12 +42,6 @@ main() {
pushd lib/vscode
if [[ ! ${VERSION-} ]]; then
echo "VERSION not set. Please set before running this script:"
echo "VERSION='0.0.0' yarn build:vscode"
exit 1
fi
# Set the commit Code will embed into the product.json. We need to do this
# since Code tries to get the commit from the `.git` directory which will fail
# as it is a submodule.

View File

@@ -4,7 +4,7 @@ platform: "linux"
version: "v${VERSION}"
section: "devel"
priority: "optional"
maintainer: "Joe Previte <joe@coder.com>"
maintainer: "Anmol Sethi <hi@nhooyr.io>"
description: |
Run VS Code in the browser.
vendor: "Coder"
@@ -22,4 +22,4 @@ contents:
dst: /usr/lib/systemd/user/code-server.service
- src: ./release-standalone/*
dst: /usr/lib/code-server
dst: /usr/lib/code-server/

View File

@@ -1,8 +1,18 @@
#!/usr/bin/env sh
set -eu
# Copied from ../lib.sh except we do not rename Darwin and we do not need to
# detect Alpine.
# Copied from ../lib.sh.
arch() {
cpu="$(uname -m)"
case "$cpu" in
aarch64) cpu=arm64 ;;
x86_64) cpu=amd64 ;;
esac
echo "$cpu"
}
# Copied from ../lib.sh except we do not rename Darwin since the cloud agent
# uses "darwin" in the release names and we do not need to detect Alpine.
os() {
osname=$(uname | tr '[:upper:]' '[:lower:]')
case $osname in
@@ -51,6 +61,7 @@ symlink_bin_script() {
cd "$oldpwd"
}
ARCH="${NPM_CONFIG_ARCH:-$(arch)}"
OS="$(os)"
# This is due to an upstream issue with RHEL7/CentOS 7 comptability with node-argon2
@@ -91,6 +102,14 @@ main() {
;;
esac
mkdir -p ./lib
if curl -fsSL "https://github.com/coder/cloud-agent/releases/latest/download/cloud-agent-$OS-$ARCH" -o ./lib/coder-cloud-agent; then
chmod +x ./lib/coder-cloud-agent
else
echo "Failed to download cloud agent; --link will not work"
fi
if ! vscode_install; 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"
@@ -105,18 +124,27 @@ main() {
}
install_with_yarn_or_npm() {
echo "User agent: ${npm_config_user_agent-none}"
# 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
npm*)
# 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
;;
yarn*)
yarn --production --frozen-lockfile --no-default-rc
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"

103
ci/build/release-prep.sh Executable file
View File

@@ -0,0 +1,103 @@
#!/usr/bin/env bash
# Description: This is a script to make the release process easier
# Run it with `yarn release:prep` and it will do the following:
# 1. Check that you have gh installed and that you're signed in
# 2. Update the version of code-server (package.json, docs, etc.)
# 3. Update the code coverage badge in the README
# 4. Open a draft PR using the release_template.md and view in browser
# If you want to perform a dry run of this script run DRY_RUN=1 yarn release:prep
set -euo pipefail
CHECKMARK="\xE2\x9C\x94"
DASH="-"
main() {
if [ "${DRY_RUN-}" = 1 ]; then
echo "Performing a dry run..."
CMD="echo"
else
CMD=''
fi
cd "$(dirname "$0")/../.."
# Check that gh is installed
if ! command -v gh &> /dev/null; then
echo "gh could not be found."
echo "We use this with the release-github-draft.sh and release-github-assets.sh scripts."
echo -e "See docs here: https://github.com/cli/cli#installation"
exit
fi
# Check that they have jq installed
if ! command -v jq &> /dev/null; then
echo "jq could not be found."
echo "We use this to parse the package.json and grab the current version of code-server."
echo -e "See docs here: https://stedolan.github.io/jq/download/"
exit
fi
# Check that they have rg installed
if ! command -v rg &> /dev/null; then
echo "rg could not be found."
echo "We use this when updating files across the codebase."
echo -e "See docs here: https://github.com/BurntSushi/ripgrep#installation"
exit
fi
# Check that they have node installed
if ! command -v node &> /dev/null; then
echo "node could not be found."
echo "That's surprising..."
echo "We use it in this script for getting the package.json version"
echo -e "See docs here: https://nodejs.org/en/download/"
exit
fi
# Check that gh is authenticated
if ! gh auth status -h github.com &> /dev/null; then
echo "gh isn't authenticated to github.com."
echo "This is needed for our scripts that use gh."
echo -e "See docs regarding authentication: https://cli.github.com/manual/gh_auth_login"
exit
fi
# Note: we need to set upstream as well or the gh pr create step will fail
# See: https://github.com/cli/cli/issues/575
CURRENT_BRANCH=$(git branch | grep '\*' | cut -d' ' -f2-)
if [[ -z $(git config "branch.${CURRENT_BRANCH}.remote") ]]; then
echo "Doesn't look like you've pushed this branch to remote"
# Note: we need to set upstream as well or the gh pr create step will fail
# See: https://github.com/cli/cli/issues/575
echo "Please set the upstream and then run the script"
exit 1
fi
# credit to jakwuh for this solution
# https://gist.github.com/DarrenN/8c6a5b969481725a4413#gistcomment-1971123
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}"
# 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"
$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"
# This runs from the root so that's why we use this path vs. ../../
RELEASE_TEMPLATE_STRING=$(cat ./.github/PULL_REQUEST_TEMPLATE/release_template.md)
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"
# Open PR in browser
$CMD gh pr view --web
}
main "$@"

View File

@@ -11,6 +11,22 @@ main() {
make -s out/index.js
popd
# Our code imports from `out` in order to work during development but if you
# have only built for production you will have not have this directory. In
# that case symlink `out` to a production build directory.
if [[ ! -e lib/vscode/out ]]; then
pushd lib
local out=(vscode-reh-web-*)
if [[ -d "${out[0]}" ]]; then
ln -s "../${out[0]}/out" ./vscode/out
else
echo "Could not find lib/vscode/out or lib/vscode-reh-web-*"
echo "Code must be built before running unit tests"
exit 1
fi
popd
fi
# We must keep jest in a sub-directory. See ../../test/package.json for more
# information. We must also run it from the root otherwise coverage will not
# include our source files.

View File

@@ -1,4 +1,4 @@
import { spawn, ChildProcess } from "child_process"
import { spawn, fork, ChildProcess } from "child_process"
import * as path from "path"
import { onLine, OnLineCallback } from "../../src/node/util"
@@ -30,13 +30,12 @@ class Watcher {
// Pass CLI args, save for `node` and the initial script name.
const args = process.argv.slice(2)
this.webServer = spawn("node", [path.join(this.rootPath, "out/node/entry.js"), ...args])
onLine(this.webServer, (line) => console.log("[code-server]", line))
this.webServer = fork(path.join(this.rootPath, "out/node/entry.js"), args)
const { pid } = this.webServer
this.webServer.on("exit", () => console.log("[code-server]", `Web process ${pid} exited`))
this.webServer.on("exit", () => console.log("[Code Server]", `Web process ${pid} exited`))
console.log("\n[code-server]", `Spawned web server process ${pid}`)
console.log("\n[Code Server]", `Spawned web server process ${pid}`)
}
//#endregion
@@ -83,10 +82,10 @@ class Watcher {
private parseVSCodeLine: OnLineCallback = (strippedLine, originalLine) => {
if (!strippedLine.length) return
console.log("[Code OSS]", originalLine)
console.log("[VS Code]", originalLine)
if (strippedLine.includes("Finished compilation with")) {
console.log("[Code OSS] ✨ Finished compiling! ✨", "(Refresh your web browser ♻️)")
console.log("[VS Code] ✨ Finished compiling! ✨", "(Refresh your web browser ♻️)")
this.reloadWebServer()
}
}
@@ -94,10 +93,10 @@ class Watcher {
private parseCodeServerLine: OnLineCallback = (strippedLine, originalLine) => {
if (!strippedLine.length) return
console.log("[Compiler][code-server]", originalLine)
console.log("[Compiler][Code Server]", originalLine)
if (strippedLine.includes("Watching for file changes")) {
console.log("[Compiler][code-server]", "Finished compiling!", "(Refresh your web browser ♻️)")
console.log("[Compiler][Code Server]", "Finished compiling!", "(Refresh your web browser ♻️)")
this.reloadWebServer()
}
}

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.5.1
version: 3.3.2
# 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.9.1
appVersion: 4.8.2

View File

@@ -102,7 +102,6 @@ spec:
{{- range .Values.extraSecretMounts }}
- name: {{ .name }}
mountPath: {{ .mountPath }}
subPath: {{ .subPath | default "" }}
readOnly: {{ .readOnly }}
{{- end }}
{{- range .Values.extraVolumeMounts }}
@@ -115,11 +114,6 @@ spec:
- name: http
containerPort: 8080
protocol: TCP
{{- range .Values.extraPorts }}
- name: {{ .name }}
containerPort: {{ .port }}
protocol: {{ .protocol }}
{{- end }}
livenessProbe:
httpGet:
path: /

View File

@@ -14,12 +14,6 @@ spec:
targetPort: http
protocol: TCP
name: http
{{- range .Values.extraPorts }}
- port: {{ .port }}
targetPort: {{ .port }}
protocol: {{ .protocol }}
name: {{ .name }}
{{- end }}
selector:
app.kubernetes.io/name: {{ include "code-server.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}

View File

@@ -6,7 +6,7 @@ replicaCount: 1
image:
repository: codercom/code-server
tag: '4.9.1'
tag: '4.8.2'
pullPolicy: Always
# Specifies one or more secrets to be used when pulling images from a
@@ -179,7 +179,6 @@ extraInitContainers: |
extraSecretMounts: []
# - name: secret-files
# mountPath: /etc/secrets
# subPath: private.key # (optional)
# secretName: code-server-secret-files
# readOnly: true
@@ -197,8 +196,3 @@ extraConfigmapMounts: []
# subPath: certificates.crt # (optional)
# configMap: certs-configmap
# readOnly: true
extraPorts: []
# - name: minecraft
# port: 25565
# protocol: tcp

View File

@@ -9,6 +9,10 @@ popd() {
builtin popd > /dev/null
}
pkg_json_version() {
jq -r .version package.json
}
vscode_version() {
jq -r .version lib/vscode/package.json
}
@@ -44,6 +48,8 @@ rsync() {
command rsync -a --del "$@"
}
VERSION="$(pkg_json_version)"
export VERSION
ARCH="$(arch)"
export ARCH
OS=$(os)

View File

@@ -3,8 +3,9 @@ set -euo pipefail
main() {
cd "$(dirname "$0")/../.."
# NOTE@jsjoeio - this script assumes VERSION exists as an
# environment variable.
# ci/lib.sh sets VERSION so it's available to ci/release-image/docker-bake.hcl
# to push the VERSION tag.
source ./ci/lib.sh
# NOTE@jsjoeio - this script assumes that you've downloaded
# the release-packages artifact to ./release-packages before

View File

@@ -19,6 +19,12 @@ main() {
# This is because npm won't publish your package unless it's a new version.
# i.e. for development, we bump the version to <current version>-<pr number>-<commit sha>
# example: "version": "4.0.1-4769-ad7b23cfe6ffd72914e34781ef7721b129a23040"
# We need the current package.json VERSION
if ! is_env_var_set "VERSION"; then
echo "VERSION is not set. Cannot publish to npm without VERSION."
exit 1
fi
# We use this to grab the PR_NUMBER
if ! is_env_var_set "GITHUB_REF"; then
echo "GITHUB_REF is not set. Are you running this locally? We rely on values provided by GitHub."
@@ -96,7 +102,6 @@ main() {
# This means the npm version will be tagged with "beta"
# and installed when a user runs `yarn install code-server@beta`
NPM_TAG="beta"
PACKAGE_NAME="@coder/code-server-pr"
fi
if [[ "$NPM_ENVIRONMENT" == "development" ]]; then

View File

@@ -11,10 +11,9 @@
- [Version updates to Code](#version-updates-to-code)
- [Patching Code](#patching-code)
- [Build](#build)
- [Creating a Standalone Release](#creating-a-standalone-release)
- [Troubleshooting](#troubleshooting)
- [I see "Forbidden access" when I load code-server in the browser](#i-see-forbidden-access-when-i-load-code-server-in-the-browser)
- ["Can only have one anonymous define call per script"](#can-only-have-one-anonymous-define-call-per-script)
- ["Can only have one anonymous define call per script"](#can-only-have-one-anonymous-define-call-per-script)
- [Help](#help)
- [Test](#test)
- [Unit tests](#unit-tests)
@@ -171,22 +170,6 @@ yarn package
> If you need your builds to support older distros, run the build commands
> inside a Docker container with all the build requirements installed.
#### Creating a Standalone Release
Part of the build process involves creating standalone releases. At the time of
writing, we do this for the following platforms/architectures:
- Linux amd64 (.tar.gz, .deb, and .rpm)
- Linux arm64 (.tar.gz, .deb, and .rpm)
- Linux arm7l (.tar.gz)
- Linux armhf.deb
- Linux armhf.rpm
- macOS amd64 (Intel-based)
Currently, these are compiled in CI using the `yarn release-standalone` command
in the `release.yaml` workflow. We then upload them to the draft release and
distribute via GitHub Releases.
### Troubleshooting
#### I see "Forbidden access" when I load code-server in the browser
@@ -195,7 +178,7 @@ This means your patches didn't apply correctly. We have a patch to remove the au
Try popping off the patches with `quilt pop -a` and reapplying with `quilt push -a`.
#### "Can only have one anonymous define call per script"
### "Can only have one anonymous define call per script"
Code might be trying to use a dev or prod HTML in the wrong context. You can try re-running code-server and setting `VSCODE_DEV=1`.

View File

@@ -26,7 +26,6 @@
- [Is multi-tenancy possible?](#is-multi-tenancy-possible)
- [Can I use Docker in a code-server container?](#can-i-use-docker-in-a-code-server-container)
- [How do I disable telemetry?](#how-do-i-disable-telemetry)
- [What's the difference between code-server and Coder?](#whats-the-difference-between-code-server-and-coder)
- [What's the difference between code-server and Theia?](#whats-the-difference-between-code-server-and-theia)
- [What's the difference between code-server and OpenVSCode-Server?](#whats-the-difference-between-code-server-and-openvscode-server)
- [What's the difference between code-server and GitHub Codespaces?](#whats-the-difference-between-code-server-and-github-codespaces)
@@ -34,7 +33,6 @@
- [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)
- [How do I disable file download?](#how-do-i-disable-file-download)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- prettier-ignore-end -->
@@ -364,15 +362,6 @@ Use the `--disable-telemetry` flag to disable telemetry.
> We use the data collected only to improve code-server.
## What's the difference between code-server and Coder?
code-server and Coder are both applications that can be installed on any
machine. The main difference is who they serve. Out of the box, code-server is
simply VS Code in the browser while Coder is a tool for provisioning remote
development environments via Terraform.
code-server was built for individuals while Coder was built for teams. In Coder, you create Workspaces which can have applications like code-server. If you're looking for a team solution, you should reach for [Coder](https://github.com/coder/coder).
## What's the difference between code-server and Theia?
At a high level, code-server is a patched fork of VS Code that runs in the
@@ -436,7 +425,3 @@ There are two ways to change the port on which code-server runs:
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`.
## How do I disable file download?
You can pass the flag `--disable-file-downloads` to `code-server`

View File

@@ -142,28 +142,24 @@ changelog](https://github.com/emacs-mirror/emacs/blob/master/etc/NEWS).
### Publishing a release
1. Go to GitHub Actions > Draft release > Run workflow on the commit you want to
release. Make sure CI has finished the build workflow on that commit or this
will fail.
2. CI will automatically grab the build artifact on that commit, inject the
version into the `package.json`, put together platform-specific packages, and
upload those packages to a draft release.
3. Summarize the major changes in the `CHANGELOG.md`.
4. Copy the relevant changelog section to the release then publish it.
5. CI will automatically publish the NPM package, Docker image, and update
Homebrew using the published release assets.
6. Bump the chart version in `Chart.yaml` and merge in the changelog updates.
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. 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
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:
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. Add a `-rc.<number>` suffix to the version.
2. When you publish the release select "pre-release". CI will not automatically
publish pre-releases.
3. Do not update the chart version or merge in the changelog until the final
release.
1. Only bump version in `package.json`
1. use `0.0.0-rc.0`
1. When you publish the release, select "pre-release"
#### AUR

View File

@@ -16,7 +16,7 @@ access it in the browser.
## Requirements
See [requirements](https://coder.com/docs/code-server/latest/requirements) for minimum specs, as well as instructions
See [requirements](requirements.md) for minimum specs, as well as instructions
on how to set up a Google VM on which you can install code-server.
**TL;DR:** Linux machine with WebSockets enabled, 1 GB RAM, and 2 vCPUs

View File

@@ -1,37 +0,0 @@
# Coder
To install and run code-server in a Coder workspace, we suggest using the `install.sh`
script in your template like so:
```terraform
resource "coder_agent" "dev" {
arch = "amd64"
os = "linux"
startup_script = <<EOF
#!/bin/sh
set -x
# install and start code-server
curl -fsSL https://code-server.dev/install.sh | sh -s -- --version 4.8.3
code-server --auth none --port 13337 &
EOF
}
resource "coder_app" "code-server" {
agent_id = coder_agent.dev.id
slug = "code-server"
display_name = "code-server"
url = "http://localhost:13337/"
icon = "/icon/code.svg"
subdomain = false
share = "owner"
healthcheck {
url = "http://localhost:13337/healthz"
interval = 3
threshold = 10
}
}
```
If you run into issues, ask for help on the `coder/coder` [Discussions
here](https://github.com/coder/coder/discussions).

View File

@@ -14,7 +14,6 @@
- [Accessing web services](#accessing-web-services)
- [Using a subdomain](#using-a-subdomain)
- [Using a subpath](#using-a-subpath)
- [Using your own proxy](#using-your-own-proxy)
- [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)
@@ -317,32 +316,12 @@ To set your domain, start code-server with the `--proxy-domain` flag:
code-server --proxy-domain <domain>
```
For instance, if you have code-server exposed on `domain.tld` and a Python
server running on port 8080 of the same machine code-server is running on, you
could run code-server with `--proxy-domain domain.tld` and access the Python
server via `8080.domain.tld`.
Note that this uses the host header, so ensure your reverse proxy (if you're
using one) forwards that information.
Now you can browse to `<port>.<domain>`. Note that this uses the host header, so
ensure your reverse proxy (if you're using one) forwards that information.
### Using a subpath
Simply browse to `/proxy/<port>/`. For instance, if you have code-server
exposed on `domain.tld` and a Python server running on port 8080 of the same
machine code-server is running on, you could access the Python server via
`domain.tld/proxy/8000`.
### Using your own proxy
You can make extensions and the ports panel use your own proxy by setting
`VSCODE_PROXY_URI`. For example if you set
`VSCODE_PROXY_URI=https://{{port}}.kyle.dev` when an application is detected
running on port 3000 of the same machine code-server is running on the ports
panel will create a link to https://3000.kyle.dev instead of pointing to the
built-in subpath-based proxy.
Note: relative paths are also supported i.e.
`VSCODE_PROXY_URI=./proxy/{{port}}`
Simply browse to `/proxy/<port>/`.
### Stripping `/proxy/<port>` from the request path

View File

@@ -59,7 +59,6 @@ following flags:
- `--prefix=/usr/local`: install a standalone release archive system-wide.
- `--version=X.X.X`: install version `X.X.X` instead of latest version.
- `--help`: see usage docs.
- `--edge`: install the latest edge version (i.e. pre-release)
When done, the install script prints out instructions for running and starting
code-server.
@@ -297,9 +296,9 @@ 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 [`npm`](#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

11
docs/link.md Normal file
View File

@@ -0,0 +1,11 @@
# code-server --link
> Note: This feature is no longer recommended due to instability. Stay tuned for a revised version.
Run code-server with the flag `--link` and you'll get TLS, authentication, and a dedicated URL
for accessing your IDE out of the box.
```console
$ code-server --link
Proxying code-server, you can access your IDE at https://example.coder.co
```

View File

@@ -38,9 +38,9 @@
"path": "./guide.md",
"children": [
{
"title": "Coder",
"description": "How to run code-server in Coder",
"path": "./coder.md"
"title": "--link",
"description": "How to run code-server --link",
"path": "./link.md"
},
{
"title": "iPad",

View File

@@ -12,6 +12,7 @@
- [Create a new user](#create-a-new-user)
- [Install Go](#install-go)
- [Install Python](#install-python)
- [Working with PRoot](#working-with-proot)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- prettier-ignore-end -->
@@ -19,9 +20,53 @@
## Install
1. Get [Termux](https://f-droid.org/en/packages/com.termux/) from **F-Droid**.
2. Run `pkg install tur-repo`
3. Run `pkg install code-server`
4. You can now start code server by simply running `code-server`.
2. Install Debian by running the following:
- Run `termux-setup-storage` to allow storage access, or else code-server won't be able to read from `/sdcard`.\
> The following command is from [proot-distro](https://github.com/termux/proot-distro), but you can also use [Andronix](https://andronix.app/).
> After Debian is installed the `~ $` will change to `root@localhost`.
```bash
pkg update -y && pkg install proot-distro -y && proot-distro install debian && proot-distro login debian
```
3. Run the following commands to setup Debian:
```bash
apt update && apt upgrade -y && apt-get install sudo vim git -y
```
4. Install [NVM](https://github.com/nvm-sh/nvm#install--update-script) by following the install guide in the README, just a curl/wget command.
5. Set up NVM for multi-user. After installing NVM it automatically adds the necessary commands for it to work, but it will only work if you are logged in as root:
- Copy the lines NVM asks you to run after running the install script.
- Run `nano /root/.bashrc` and comment out those lines by adding a `#` at the start.
- Run `nano /etc/profile` and paste those lines at the end of the file. Make sure to replace `$HOME` with `/root` on the first line.
- Now run `exit`
- Start Debian again `proot-distro login debian`
6. After following the instructions and setting up NVM you can now install the [required node version](https://coder.com/docs/code-server/latest/npm#nodejs-version) by running:
```bash
nvm install v<major_version_here>
```
7. To install `code-server` run the following:
> To check the install process (Will not actually install code-server)
> If it all looks good, you can install code-server by running the second command
```bash
curl -fsSL https://code-server.dev/install.sh | sh -s -- --dry-run
```
```bash
curl -fsSL https://code-server.dev/install.sh | sh
```
8. You can now start code server by simply running `code-server`.
> 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
@@ -157,3 +202,35 @@ eval "$(pyenv virtualenv-init -)"
7. Run `touch /root/.pyenv/version && echo "your_version_here" > /root/.pyenv/version`
8. (You may have to start Debian again) Run `python3 -V` to verify if PATH works or not.
> If `python3` doesn't work but pyenv says that the install was successful in step 6 then try running `$PYENV_ROOT/versions/your_version/bin/python3`.
### Working with PRoot
Debian PRoot Distro Dev Environment
- Since Node and code-server are installed in the Debian PRoot distro, your `~/.ssh/` configuration, `~/.bashrc`, git, npm packages, etc. should be setup in PRoot as well.
- The terminal accessible in code-server will bring up the filesystem and `~/.bashrc` in the Debian PRoot distro.
Accessing files in the Debian PRoot Distro
- The `/data/data/com.termux/files/home` directory in PRoot accesses the termux home directory (`~`)
- The `/sdcard` directory in PRoot accesses the Android storage directory, though there are [known issues with git and files in the `/sdcard` path](#git-wont-work-in-sdcard)
Accessing the Debian PRoot distro/Starting code-server
- Run the following command to access the Debian PRoot distro, from the termux shell:
```bash
proot-distro login debian
```
- Run the following command to start code-server directly in the Debian PRoot distro, from the termux shell:
```bash
proot-distro login debian -- code-server
```
- If you [created a new user](#create-a-new-user), you'll need to insert the `--user <username>` option between `login` and `debian` in the commands above to run as the user instead of root in PRoot.
Additional information on PRoot and Termux
- Additional information on using your Debian PRoot Distro can be [found here](https://github.com/termux/proot-distro#functionality-overview).

View File

@@ -12,13 +12,13 @@
in {
devShells.default = pkgs.mkShell {
nativeBuildInputs = with pkgs; [
nodejs yarn' python pkg-config git rsync jq moreutils quilt bats
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 (with pkgs.darwin.apple_sdk.frameworks; [
AppKit Cocoa CoreServices Security xcbuild
]));
++ lib.optionals stdenv.isDarwin [
AppKit Cocoa CoreServices Security cctools xcbuild
]);
};
}
);

View File

@@ -131,11 +131,6 @@ Or, if you don't want/need a background service you can run:
EOF
}
echo_coder_postinstall() {
echoh
echoh "Deploy code-server for your team with Coder: https://github.com/coder/coder"
}
main() {
if [ "${TRACE-}" ]; then
set -x
@@ -248,7 +243,6 @@ main() {
if [ "$METHOD" = standalone ]; then
if has_standalone; then
install_standalone
echo_coder_postinstall
exit 0
else
echoerr "There are no standalone releases for $ARCH"
@@ -292,8 +286,6 @@ main() {
npm_fallback install_standalone
;;
esac
echo_coder_postinstall
}
parse_arg() {
@@ -387,7 +379,7 @@ install_aur() {
if [ ! "${DRY_RUN-}" ]; then
cd "$CACHE_DIR/code-server-aur"
fi
sh_c makepkg -si --noconfirm
sh_c makepkg -si
echo_systemd_postinstall AUR
}
@@ -490,7 +482,7 @@ os() {
# - amzn, centos, rhel, fedora, ... -> fedora
# - opensuse-{leap,tumbleweed} -> opensuse
# - alpine -> alpine
# - arch, manjaro, endeavouros, ... -> arch
# - arch -> arch
#
# Inspired by https://github.com/docker/docker-install/blob/26ff363bcf3b3f5a00498ac43694bf1c7d9ce16c/install.sh#L111-L120.
distro() {
@@ -504,7 +496,7 @@ distro() {
. /etc/os-release
if [ "${ID_LIKE-}" ]; then
for id_like in $ID_LIKE; do
case "$id_like" in debian | fedora | opensuse | arch)
case "$id_like" in debian | fedora | opensuse)
echo "$id_like"
return
;;

View File

@@ -1,7 +1,7 @@
{
"name": "code-server",
"license": "MIT",
"version": "0.0.0",
"version": "4.8.2",
"description": "Run VS Code on a remote server.",
"homepage": "https://github.com/coder/code-server",
"bugs": {
@@ -61,7 +61,7 @@
"eslint-import-resolver-typescript": "^3.5.2",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-prettier": "^4.2.1",
"prettier": "2.8.0",
"prettier": "2.7.1",
"prettier-plugin-sh": "^0.12.8",
"ts-node": "^10.0.0",
"typescript": "^4.6.2"
@@ -83,21 +83,19 @@
"nanoid": "^3.1.31",
"minimist": "npm:minimist-lite@2.2.1",
"glob-parent": "^6.0.1",
"@types/node": "^16.0.0",
"qs": "^6.7.3"
"@types/node": "^16.0.0"
},
"dependencies": {
"@coder/logger": "^3.0.0",
"argon2": "0.30.3",
"argon2": "0.29.0",
"compression": "^1.7.4",
"cookie-parser": "^1.4.5",
"env-paths": "^2.2.0",
"express": "5.0.0-alpha.8",
"http-proxy": "^1.18.0",
"httpolyglot": "^0.1.2",
"i18next": "^22.4.6",
"js-yaml": "^4.0.0",
"limiter": "^2.1.0",
"limiter": "^1.1.5",
"pem": "^1.14.2",
"proxy-agent": "^5.0.0",
"qs": "6.11.0",
@@ -118,8 +116,7 @@
"ide",
"coder",
"vscode-remote",
"browser-ide",
"remote-development"
"browser-ide"
],
"engines": {
"node": "16"

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
@@ -166,7 +166,9 @@ class RemoteAuthoritiesImpl {
@@ -162,7 +162,9 @@ class RemoteAuthoritiesImpl {
return URI.from({
scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource,
authority: `${host}:${port}`,
@@ -119,7 +119,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
@@ -267,12 +267,11 @@ export class WebClientServer {
return void res.end();
return res.end();
}
- const getFirstHeader = (headerName: string) => {
@@ -176,7 +176,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
`frame-src 'self' https://*.vscode-cdn.net data:;`,
'worker-src \'self\' data:;',
@@ -417,3 +421,70 @@ export class WebClientServer {
return void res.end(data);
return res.end(data);
}
}
+
@@ -279,10 +279,10 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
// Create workbench
create(document.body, {
Index: code-server/lib/vscode/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts
Index: code-server/lib/vscode/src/vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts
+++ code-server/lib/vscode/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts
--- code-server.orig/lib/vscode/src/vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader.ts
+++ code-server/lib/vscode/src/vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader.ts
@@ -16,7 +16,6 @@ import { getServiceMachineId } from 'vs/
import { IStorageService } from 'vs/platform/storage/common/storage';
import { TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';

View File

@@ -8,7 +8,7 @@ To test:
2. Open code-server
3. Open terminal
4. Open another code-server window
5. Run node ./out/node/entry.js with a file or directory argument
5. Run code-server with a file or directory argument
The file or directory should only open from the instance attached to that
terminal.

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
@@ -243,6 +243,10 @@ export class Extension implements IExten
@@ -237,6 +237,10 @@ export class Extension implements IExten
if (this.type === ExtensionType.System && this.productService.quality === 'stable') {
return false;
}
@@ -18,3 +18,14 @@ 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
// Skip if check updates only for builtin extensions and current extension is not builtin.
continue;
}
+ if (installed.type !== ExtensionType.User) {
+ // Never update builtin extensions.
+ continue;
+ }
if (installed.isBuiltin && (!installed.local?.identifier.uuid || (!isWeb && this.productService.quality === 'stable'))) {
// Skip checking updates for a builtin extension if it does not has Marketplace identifier or the current product is VS Code Desktop stable.
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
@@ -266,6 +266,11 @@ export interface IWorkbenchConstructionO
@@ -271,6 +271,11 @@ export interface IWorkbenchConstructionO
*/
readonly userDataPath?: string
@@ -23,12 +23,12 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
+
//#endregion
//#region Profile options
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
@@ -32,6 +32,11 @@ export interface IBrowserWorkbenchEnviro
@@ -31,6 +31,11 @@ export interface IBrowserWorkbenchEnviro
* Options used to configure the workbench.
*/
readonly options?: IWorkbenchConstructionOptions;
@@ -40,7 +40,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi
}
export class BrowserWorkbenchEnvironmentService implements IBrowserWorkbenchEnvironmentService {
@@ -104,6 +109,13 @@ export class BrowserWorkbenchEnvironment
@@ -62,6 +67,13 @@ export class BrowserWorkbenchEnvironment
return this.options.userDataPath;
}
@@ -135,16 +135,16 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts
@@ -20,7 +20,7 @@ import { CLOSE_SAVED_EDITORS_COMMAND_ID,
@@ -22,7 +22,7 @@ import { CLOSE_SAVED_EDITORS_COMMAND_ID,
import { AutoSaveAfterShortDelayContext } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import { WorkbenchListDoubleSelection } from 'vs/platform/list/browser/listService';
import { Schemas } from 'vs/base/common/network';
-import { DirtyWorkingCopiesContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, WorkbenchStateContext, WorkspaceFolderCountContext, SidebarFocusContext, ActiveEditorCanRevertContext, ActiveEditorContext, ResourceContextKey, ActiveEditorAvailableEditorIdsContext } from 'vs/workbench/common/contextkeys';
+import { DirtyWorkingCopiesContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, WorkbenchStateContext, WorkspaceFolderCountContext, SidebarFocusContext, ActiveEditorCanRevertContext, ActiveEditorContext, ResourceContextKey, ActiveEditorAvailableEditorIdsContext, IsEnabledFileDownloads } from 'vs/workbench/common/contextkeys';
-import { DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, WorkbenchStateContext, WorkspaceFolderCountContext, SidebarFocusContext, ActiveEditorCanRevertContext, ActiveEditorContext, ResourceContextKey } from 'vs/workbench/common/contextkeys';
+import { DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, WorkbenchStateContext, WorkspaceFolderCountContext, SidebarFocusContext, ActiveEditorCanRevertContext, ActiveEditorContext, ResourceContextKey, IsEnabledFileDownloads } from 'vs/workbench/common/contextkeys';
import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { ThemeIcon } from 'vs/base/common/themables';
@@ -484,13 +484,16 @@ MenuRegistry.appendMenuItem(MenuId.Explo
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
@@ -477,13 +477,16 @@ MenuRegistry.appendMenuItem(MenuId.Explo
id: DOWNLOAD_COMMAND_ID,
title: DOWNLOAD_LABEL
},

View File

@@ -19,7 +19,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/serverServices.ts
+++ code-server/lib/vscode/src/vs/server/node/serverServices.ts
@@ -220,6 +220,9 @@ export async function setupServerService
@@ -209,6 +209,9 @@ export async function setupServerService
const channel = new ExtensionManagementChannel(extensionManagementService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority));
socketServer.registerChannel('extensions', channel);
@@ -42,7 +42,7 @@ Index: code-server/lib/vscode/src/vs/base/common/platform.ts
export const LANGUAGE_DEFAULT = 'en';
let _isWindows = false;
@@ -86,17 +84,19 @@ if (typeof navigator === 'object' && !is
@@ -83,17 +81,19 @@ if (typeof navigator === 'object' && !is
_isMobile = _userAgent?.indexOf('Mobi') >= 0;
_isWeb = true;
@@ -125,7 +125,7 @@ Index: code-server/lib/vscode/src/vs/platform/environment/common/environmentServ
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/environment/common/environmentService.ts
+++ code-server/lib/vscode/src/vs/platform/environment/common/environmentService.ts
@@ -107,7 +107,7 @@ export abstract class AbstractNativeEnvi
@@ -105,7 +105,7 @@ export abstract class AbstractNativeEnvi
return URI.file(join(vscodePortable, 'argv.json'));
}
@@ -248,7 +248,7 @@ Index: code-server/lib/vscode/src/vs/workbench/workbench.web.main.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/workbench.web.main.ts
+++ code-server/lib/vscode/src/vs/workbench/workbench.web.main.ts
@@ -119,8 +119,9 @@ import 'vs/workbench/contrib/logs/browse
@@ -123,8 +123,9 @@ import 'vs/workbench/contrib/logs/browse
// Explorer
import 'vs/workbench/contrib/files/browser/files.web.contribution';
@@ -264,35 +264,27 @@ Index: code-server/lib/vscode/src/vs/platform/languagePacks/browser/languagePack
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/languagePacks/browser/languagePacks.ts
+++ code-server/lib/vscode/src/vs/platform/languagePacks/browser/languagePacks.ts
@@ -6,18 +6,24 @@
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { Language } from 'vs/base/common/platform';
import { URI } from 'vs/base/common/uri';
@@ -4,10 +4,23 @@
*--------------------------------------------------------------------------------------------*/
import { ILanguagePackItem, LanguagePackBaseService } from 'vs/platform/languagePacks/common/languagePacks';
+import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc';
import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionResourceLoaderService } from 'vs/platform/extensionResourceLoader/common/extensionResourceLoader';
-import { ILanguagePackItem, LanguagePackBaseService } from 'vs/platform/languagePacks/common/languagePacks';
+import { ILanguagePackItem, ILanguagePackService, LanguagePackBaseService } from 'vs/platform/languagePacks/common/languagePacks';
import { ILogService } from 'vs/platform/log/common/log';
+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;
+
constructor(
+ constructor(
+ @IRemoteAgentService remoteAgentService: IRemoteAgentService,
@IExtensionResourceLoaderService private readonly extensionResourceLoaderService: IExtensionResourceLoaderService,
@IExtensionGalleryService extensionGalleryService: IExtensionGalleryService,
@ILogService private readonly logService: ILogService
) {
super(extensionGalleryService);
+ this.languagePackService = ProxyChannel.toService<ILanguagePackService>(remoteAgentService.getConnection()!.getChannel('languagePacks'))
}
async getBuiltInExtensionTranslationsUri(id: string): Promise<URI | undefined> {
@@ -73,6 +79,6 @@ export class WebLanguagePacksService ext
// Web doesn't have a concept of language packs, so we just return an empty array
+ @IExtensionGalleryService extensionGalleryService: IExtensionGalleryService
+ ) {
+ super(extensionGalleryService)
+ this.languagePackService = ProxyChannel.toService<ILanguagePackService>(remoteAgentService.getConnection()!.getChannel('languagePacks'));
+ }
+
getInstalledLanguages(): Promise<ILanguagePackItem[]> {
- return Promise.resolve([]);
+ return this.languagePackService.getInstalledLanguages()

24
patches/exec-argv.diff Normal file
View File

@@ -0,0 +1,24 @@
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

@@ -10,7 +10,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
===================================================================
--- 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
@@ -60,7 +60,7 @@ import { GettingStartedIndexList } from
@@ -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';
@@ -19,106 +19,32 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
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';
@@ -759,6 +759,72 @@ export class GettingStartedPage extends
@@ -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"))
);
+ let gettingStartedCoder: HTMLElement = $('.header', {});
+ if (this.contextService.contextMatchesRules(IsEnabledCoderGettingStarted)) {
+ gettingStartedCoder = $('.gettingStartedCategory', {},
+ $('h2', {
+ style: 'margin-bottom: 12px',
+ }, 'Next Up'),
+ $('a', {
+ href: 'https://cdr.co/code-server-to-coder',
+ target: '_blank',
+ },
+ $('button', {
+ style: [
+ 'padding: 10px 16px ',
+ 'border-radius: 4px',
+ 'background: linear-gradient(94.04deg, #7934DA 0%, #4D52E0 101.2%)',
+ 'color: white',
+ 'overflow: hidden',
+ 'margin-right: 14px',
+ ].join(';'),
+ },
+ $('h3', {
+ style: [
+ 'margin: 0px 0px 6px',
+ 'font-weight: 500',
+ ].join(';'),
+ }, 'Deploy code-server for your team'),
+ $('p', {
+ style: [
+ 'margin: 0',
+ 'font-size: 13px',
+ 'color: #dcdee2',
+ ].join(';'),
+ }, 'Provision software development environments on your infrastructure with Coder.'),
+ $('p', {
+ style: [
+ 'margin-top: 8px',
+ 'font-size: 13px',
+ 'color: #dcdee2',
+ ].join(';'),
+ }, 'Coder is a self-service portal which provisions via Terraform—Linux, macOS, Windows, x86, ARM, and, of course, Kubernetes based infrastructure.'),
+ $('p', {
+ style: [
+ 'margin: 0',
+ 'margin-top: 8px',
+ 'font-size: 13px',
+ 'display: flex',
+ 'align-items: center',
+ ].join(';'),
+ }, 'Get started ', $('span', {
+ class: ThemeIcon.asClassName(Codicon.arrowRight),
+ style: [
+ 'color: white',
+ 'margin-left: 8px',
+ ].join(';'),
+ })),
+ $('img', {
+ src: './_static/src/browser/media/templates.png',
+ style: [
+ 'margin-bottom: -65px',
+ ].join(';'),
+ }),
+ ),
+ ),
+ );
+ 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', {},);
@@ -776,13 +842,23 @@ export class GettingStartedPage extends
const layoutLists = () => {
if (gettingStartedList.itemCount) {
this.container.classList.remove('noWalkthroughs');
- reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
- reset(rightColumn, gettingStartedList.getDomElement());
+ if (this.contextService.contextMatchesRules(IsEnabledCoderGettingStarted)) {
+ reset(leftColumn, startList.getDomElement(), recentList.getDomElement(), gettingStartedList.getDomElement());
+ reset(rightColumn, gettingStartedCoder);
+ } else {
+ reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
+ reset(rightColumn, gettingStartedList.getDomElement());
+ }
+
recentList.setLimit(5);
}
else {
this.container.classList.add('noWalkthroughs');
- reset(leftColumn, startList.getDomElement());
+ if (this.contextService.contextMatchesRules(IsEnabledCoderGettingStarted)) {
+ reset(leftColumn, startList.getDomElement(), gettingStartedCoder);
+ } else {
+ reset(leftColumn, startList.getDomElement());
+ }
reset(rightColumn, recentList.getDomElement());
recentList.setLimit(10);
}
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
@@ -143,7 +69,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
@@ -276,6 +276,11 @@ export interface IWorkbenchConstructionO
*/
readonly isEnabledFileDownloads?: boolean
@@ -154,12 +80,12 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
+
//#endregion
//#region Profile options
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
@@ -37,6 +37,11 @@ export interface IBrowserWorkbenchEnviro
@@ -36,6 +36,11 @@ export interface IBrowserWorkbenchEnviro
* Enable downloading files via menu actions.
*/
readonly isEnabledFileDownloads?: boolean;
@@ -171,7 +97,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi
}
export class BrowserWorkbenchEnvironmentService implements IBrowserWorkbenchEnvironmentService {
@@ -116,6 +121,13 @@ export class BrowserWorkbenchEnvironment
@@ -74,6 +79,13 @@ export class BrowserWorkbenchEnvironment
return this.options.isEnabledFileDownloads;
}

View File

@@ -38,7 +38,7 @@ Index: code-server/lib/vscode/src/vs/server/node/server.main.ts
-const LOCAL_HISTORY_HOME = join(APP_SETTINGS_HOME, 'History');
-const MACHINE_SETTINGS_HOME = join(USER_DATA_PATH, 'Machine');
-args['user-data-dir'] = USER_DATA_PATH;
-const APP_ROOT = dirname(FileAccess.asFileUri('').fsPath);
-const APP_ROOT = dirname(FileAccess.asFileUri('', require).fsPath);
-const BUILTIN_EXTENSIONS_FOLDER_PATH = join(APP_ROOT, 'extensions');
-args['builtin-extensions-dir'] = BUILTIN_EXTENSIONS_FOLDER_PATH;
-args['extensions-dir'] = args['extensions-dir'] || join(REMOTE_DATA_FOLDER, 'extensions');
@@ -58,7 +58,7 @@ Index: code-server/lib/vscode/src/vs/server/node/server.main.ts
+ const LOCAL_HISTORY_HOME = join(APP_SETTINGS_HOME, 'History');
+ const MACHINE_SETTINGS_HOME = join(USER_DATA_PATH, 'Machine');
+ args['user-data-dir'] = USER_DATA_PATH;
+ const APP_ROOT = dirname(FileAccess.asFileUri('').fsPath);
+ const APP_ROOT = dirname(FileAccess.asFileUri('', require).fsPath);
+ const BUILTIN_EXTENSIONS_FOLDER_PATH = args['builtin-extensions-dir'] || join(APP_ROOT, 'extensions');
+ args['builtin-extensions-dir'] = BUILTIN_EXTENSIONS_FOLDER_PATH;
+ args['extensions-dir'] = args['extensions-dir'] || join(REMOTE_DATA_FOLDER, 'extensions');
@@ -95,7 +95,7 @@ Index: code-server/lib/vscode/src/vs/base/common/processes.ts
--- code-server.orig/lib/vscode/src/vs/base/common/processes.ts
+++ code-server/lib/vscode/src/vs/base/common/processes.ts
@@ -111,6 +111,8 @@ export function sanitizeProcessEnvironme
/^VSCODE_(?!(PORTABLE|SHELL_LOGIN)).+$/,
/^VSCODE_(?!SHELL_LOGIN).+$/,
/^SNAP(|_.*)$/,
/^GDK_PIXBUF_.+$/,
+ /^CODE_SERVER_.+$/,
@@ -107,7 +107,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandl
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts
@@ -145,8 +145,11 @@ export class BrowserDialogHandler implem
@@ -143,8 +143,11 @@ export class BrowserDialogHandler implem
async about(): Promise<void> {
const detailString = (useAgo: boolean): string => {
@@ -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';
@@ -119,6 +120,9 @@ export class BrowserMain extends Disposa
@@ -116,6 +117,9 @@ export class BrowserMain extends Disposa
// Startup
const instantiationService = workbench.startup();

View File

@@ -32,7 +32,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
@@ -261,6 +261,11 @@ export interface IWorkbenchConstructionO
@@ -266,6 +266,11 @@ export interface IWorkbenchConstructionO
*/
readonly configurationDefaults?: Record<string, any>;
@@ -43,13 +43,13 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
+
//#endregion
//#region Profile options
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
@@ -95,7 +95,14 @@ export class BrowserWorkbenchEnvironment
get logFile(): URI { return joinPath(this.windowLogsPath, 'window.log'); }
@@ -53,7 +53,14 @@ export class BrowserWorkbenchEnvironment
get logFile(): URI { return joinPath(this.logsHome, 'window.log'); }
@memoize
- get userRoamingDataHome(): URI { return URI.file('/User').with({ scheme: Schemas.vscodeUserData }); }

View File

@@ -21,7 +21,7 @@ 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
@@ -13,6 +13,7 @@ import { IEnvironmentService, INativeEnv
export const serverOptions: OptionDescriptions<Required<ServerParsedArgs>> = {
export const serverOptions: OptionDescriptions<ServerParsedArgs> = {
/* ----- code-server ----- */
'disable-update-check': { type: 'boolean' },
+ 'auth': { type: 'string' },

View File

@@ -19,7 +19,7 @@ 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
@@ -47,6 +47,16 @@ else if (globalThis._VSCODE_PRODUCT_JSON
@@ -53,6 +53,16 @@ else if (typeof require?.__$__nodeRequir
version: pkg.version
});
}
@@ -65,10 +65,10 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
},
callbackRoute: this._callbackRoute
};
Index: code-server/lib/vscode/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts
Index: code-server/lib/vscode/src/vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts
+++ code-server/lib/vscode/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts
--- code-server.orig/lib/vscode/src/vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader.ts
+++ code-server/lib/vscode/src/vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader.ts
@@ -16,7 +16,6 @@ import { getServiceMachineId } from 'vs/
import { IStorageService } from 'vs/platform/storage/common/storage';
import { TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';

View File

@@ -1,7 +1,6 @@
Unconditionally enable the proposed API
To test run an extension that uses the proposed API (i.e.
https://github.com/microsoft/vscode-extension-samples/tree/ddae6c0c9ff203b4ed6f6b43bfacdd0834215f83/proposed-api-sample)
To test run an extension that uses the proposed API.
We also override isProposedApiEnabled in case an extension does not declare the
APIs it needs correctly (the Jupyter extension had this issue).
@@ -10,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
@@ -1486,7 +1486,7 @@ class ProposedApiController {
@@ -1462,7 +1462,7 @@ class ProposedApiController {
this._envEnabledExtensions = new Set((_environmentService.extensionEnabledProposedApi ?? []).map(id => ExtensionIdentifier.toKey(id)));
@@ -23,7 +22,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/extensions/common/extens
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/extensions/common/extensions.ts
+++ code-server/lib/vscode/src/vs/workbench/services/extensions/common/extensions.ts
@@ -364,10 +364,7 @@ function extensionDescriptionArrayToMap(
@@ -359,10 +359,7 @@ function extensionDescriptionArrayToMap(
}
export function isProposedApiEnabled(extension: IExtensionDescription, proposal: ApiProposalName): boolean {

View File

@@ -42,31 +42,31 @@ Index: code-server/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityReso
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts
+++ code-server/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts
@@ -11,7 +11,7 @@ import { StopWatch } from 'vs/base/commo
@@ -8,7 +8,7 @@ import { Disposable } from 'vs/base/comm
import { RemoteAuthorities } from 'vs/base/common/network';
import { URI } from 'vs/base/common/uri';
import { ILogService } from 'vs/platform/log/common/log';
import { IProductService } from 'vs/platform/product/common/productService';
-import { IRemoteAuthorityResolverService, IRemoteConnectionData, ResolvedAuthority, ResolverResult, getRemoteAuthorityPrefix } from 'vs/platform/remote/common/remoteAuthorityResolver';
+import { IRemoteAuthorityResolverService, IRemoteConnectionData, ResolvedAuthority, ResolvedOptions, ResolverResult, getRemoteAuthorityPrefix } from 'vs/platform/remote/common/remoteAuthorityResolver';
-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';
export class RemoteAuthorityResolverService extends Disposable implements IRemoteAuthorityResolverService {
@@ -29,7 +29,7 @@ export class RemoteAuthorityResolverServ
constructor(
connectionToken: Promise<string> | string | undefined,
resourceUriProvider: ((uri: URI) => URI) | undefined,
- @IProductService productService: IProductService,
+ @IProductService private readonly productService: IProductService,
@ILogService private readonly _logService: ILogService,
) {
@@ -23,7 +23,7 @@ export class RemoteAuthorityResolverServ
private readonly _connectionToken: Promise<string> | 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) {
super();
@@ -75,9 +75,14 @@ export class RemoteAuthorityResolverServ
this._connectionToken = connectionToken;
this._connectionTokens = new Map<string, string>();
@@ -61,9 +61,14 @@ export class RemoteAuthorityResolverServ
private async _doResolveAuthority(authority: string): Promise<ResolverResult> {
const connectionToken = await Promise.resolve(this._connectionTokens.get(authority) || this._connectionToken);
performance.mark(`code/didResolveConnectionToken/${authorityPrefix}`);
this._logService.info(`Resolved connection token (${authorityPrefix}) after ${sw.elapsed()} ms`);
+ let options: ResolvedOptions | undefined;
+ if (this.productService.proxyEndpointTemplate) {
+ const proxyUrl = new URL(this.productService.proxyEndpointTemplate, window.location.href);
+ 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);
@@ -88,11 +88,24 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery,
},
Index: code-server/lib/vscode/src/vs/workbench/browser/web.main.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/web.main.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/web.main.ts
@@ -247,7 +247,7 @@ export class BrowserMain extends Disposa
// Remote
const connectionToken = environmentService.options.connectionToken || getCookieValue(connectionTokenCookieName);
- const remoteAuthorityResolverService = new RemoteAuthorityResolverService(productService, connectionToken, this.configuration.resourceUriProvider);
+ const remoteAuthorityResolverService = new RemoteAuthorityResolverService(productService, connectionToken, this.configuration.resourceUriProvider, this.configuration.productConfiguration?.proxyEndpointTemplate);
serviceCollection.set(IRemoteAuthorityResolverService, remoteAuthorityResolverService);
// Signing
Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts
===================================================================
--- 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
@@ -383,7 +383,7 @@ export async function createTerminalEnvi
@@ -392,7 +392,7 @@ export async function createTerminalEnvi
// Sanitize the environment, removing any undesirable VS Code and Electron environment
// variables
@@ -157,7 +170,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/remote/browser/remoteExpl
===================================================================
--- 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
@@ -73,7 +73,7 @@ export class ForwardedPortsView extends
this.contextKeyListener = undefined;
}

View File

@@ -18,4 +18,5 @@ disable-downloads.diff
telemetry.diff
display-language.diff
cli-window-open.diff
exec-argv.diff
getting-started.diff

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
@@ -192,8 +192,7 @@ function packageTask(type, platform, arc
@@ -191,8 +191,7 @@ function packageTask(type, platform, arc
const src = gulp.src(sourceFolderName + '/**', { base: '.' })
.pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + sourceFolderName), 'out'); }))
@@ -20,7 +20,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js
const workspaceExtensionPoints = ['debuggers', 'jsonValidation'];
const isUIExtension = (manifest) => {
@@ -232,9 +231,9 @@ function packageTask(type, platform, arc
@@ -231,9 +230,9 @@ function packageTask(type, platform, arc
.map(name => `.build/extensions/${name}/**`);
const extensions = gulp.src(extensionPaths, { base: '.build', dot: true });
@@ -32,7 +32,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js
let version = packageJson.version;
const quality = product.quality;
@@ -389,7 +388,7 @@ function tweakProductForServerWeb(produc
@@ -387,7 +386,7 @@ function tweakProductForServerWeb(produc
const minifyTask = task.define(`minify-vscode-${type}`, task.series(
optimizeTask,
util.rimraf(`out-vscode-${type}-min`),

View File

@@ -1,10 +1,9 @@
Add support for telemetry endpoint
To test:
1. Create a mock API using [RequestBin](https://requestbin.io/) or [Beeceptor](https://beeceptor.com/)
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`
NOTE: it has to be a production build.
3. Load code-server in browser an do things (i.e. open a file)
4. Refresh RequestBin and you should see logs
@@ -12,15 +11,15 @@ 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
@@ -70,6 +70,7 @@ import { IExtensionsScannerService } fro
@@ -71,6 +71,7 @@ import { IExtensionsScannerService } fro
import { ExtensionsScannerService } from 'vs/server/node/extensionsScannerService';
import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService';
import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
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';
import { LoggerService } from 'vs/platform/log/node/loggerService';
@@ -142,10 +143,13 @@ export async function setupServerService
@@ -133,10 +134,13 @@ export async function setupServerService
const machineId = await getMachineId();
const isInternal = isInternalTelemetry(productService, configurationService);
if (supportsTelemetry(productService, environmentService)) {

View File

@@ -120,7 +120,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
@@ -11,6 +11,8 @@ import { refineServiceDecorator } from '
import { IEnvironmentService, INativeEnvironmentService } from 'vs/platform/environment/common/environment';
export const serverOptions: OptionDescriptions<Required<ServerParsedArgs>> = {
export const serverOptions: OptionDescriptions<ServerParsedArgs> = {
+ /* ----- code-server ----- */
+ 'disable-update-check': { type: 'boolean' },

View File

@@ -41,7 +41,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
@@ -224,7 +224,7 @@ export class BrowserWorkbenchEnvironment
@@ -177,7 +177,7 @@ export class BrowserWorkbenchEnvironment
@memoize
get webviewExternalEndpoint(): string {
@@ -62,15 +62,6 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
_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,
@@ -344,7 +345,7 @@ export class WebClientServer {
`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:;',
+ 'worker-src \'self\' data: blob:;',
'style-src \'self\' \'unsafe-inline\';',
'connect-src \'self\' ws: wss: https:;',
'font-src \'self\' blob:;',
Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index.html
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index.html
@@ -79,12 +70,12 @@ 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-RaCvj6SRgHm+2C3LKzSAamDwa3Bp4u4iQ1Y2Sm+97tE=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
+ content="default-src 'none'; script-src 'sha256-mi72idjvdhsPSBMKFqU82FG/kZVJjKR0TfHLE13gB+w=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
- 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';">
<!-- Disable pinch zooming -->
<meta name="viewport"
@@ -325,6 +325,12 @@
@@ -331,6 +331,12 @@
const hostname = location.hostname;
@@ -101,7 +92,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html
+++ code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html
@@ -324,6 +324,12 @@
@@ -330,6 +330,12 @@
const hostname = location.hostname;

View File

@@ -6,16 +6,10 @@
"matchUpdateTypes": ["minor", "patch", "digest"],
"automerge": true,
"groupName": "Minor dependency updates"
},
{
"matchDepTypes": ["peerDependencies"],
"matchUpdateTypes": ["minor", "patch", "digest"],
"automerge": true,
"groupName": "Peer dependency updates"
}
],
"vulnerabilityAlerts": {
"enabled": "true"
},
"ignoreDeps": ["express", "ansi-regex", "env-paths", "limiter", "node", "prettier"]
"ignoreDeps": ["express"]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

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>{{I18N_LOGIN_TITLE}}</title>
<title>{{APP_NAME}} 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" />
@@ -25,7 +25,7 @@
<div class="card-box">
<div class="header">
<h1 class="main">{{WELCOME_TEXT}}</h1>
<div class="sub">{{I18N_LOGIN_BELOW}} {{PASSWORD_MSG}}</div>
<div class="sub">Please log in below. {{PASSWORD_MSG}}</div>
</div>
<div class="content">
<form class="login-form" method="post">
@@ -38,11 +38,11 @@
autofocus
class="password"
type="password"
placeholder="{{I18N_PASSWORD_PLACEHOLDER}}"
placeholder="PASSWORD"
name="password"
autocomplete="current-password"
/>
<input class="submit -button" value="{{I18N_SUBMIT}}" type="submit" />
<input class="submit -button" value="SUBMIT" type="submit" />
</div>
{{ERROR}}
</form>

View File

@@ -1,6 +0,0 @@
Contact: mailto:security@coder.com
Acknowledgments: https://coder.com/security/thanks
Preferred-Languages: en-US
Canonical: https://coder.com/.well-known/security.txt
Policy: https://coder.com/security/policy
Hiring: https://coder.com/careers

View File

@@ -84,6 +84,7 @@ export interface UserProvidedArgs extends UserProvidedCodeArgs {
"reuse-window"?: boolean
"new-window"?: boolean
"ignore-last-opened"?: boolean
link?: OptionalString
verbose?: boolean
"app-name"?: string
"welcome-text"?: string
@@ -179,14 +180,7 @@ export const options: Options<Required<UserProvidedArgs>> = {
enable: { type: "string[]" },
help: { type: "boolean", short: "h", description: "Show this output." },
json: { type: "boolean" },
locale: {
// The preferred way to set the locale is via the UI.
type: "string",
description: `
Set vscode display language and language to show on the login page, more info see
https://en.wikipedia.org/wiki/IETF_language_tag
`,
},
locale: { type: "string" }, // The preferred way to set the locale is via the UI.
open: { type: "boolean", description: "Open in browser on startup. Does not work remotely." },
"bind-addr": {
@@ -261,6 +255,15 @@ export const options: Options<Required<UserProvidedArgs>> = {
short: "w",
description: "Text to show on login page",
},
link: {
type: OptionalString,
description: `
Securely bind code-server via our cloud service with the passed name. You'll get a URL like
https://hostname-username.coder.co at which you can easily access your code-server instance.
Authorization is done via GitHub.
`,
deprecated: true,
},
}
export const optionDescriptions = (opts: Partial<Options<Required<UserProvidedArgs>>> = options): string[] => {
@@ -537,6 +540,17 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
args.host = addr.host
args.port = addr.port
// If we're being exposed to the cloud, we listen on a random address and
// disable auth.
if (args.link) {
args.host = "localhost"
args.port = 0
args.socket = undefined
args["socket-mode"] = undefined
args.cert = undefined
args.auth = AuthType.None
}
if (args.cert && !args.cert.value) {
const { cert, certKey } = await generateCertificate(args["cert-host"] || "localhost")
args.cert = {
@@ -800,7 +814,6 @@ export interface CodeArgs extends UserProvidedCodeArgs {
"without-connection-token"?: boolean
"without-browser-env-var"?: boolean
compatibility: string
log: string[] | undefined
}
/**
@@ -822,6 +835,5 @@ export const toCodeArgs = async (args: DefaultedArgs): Promise<CodeArgs> => {
help: !!args.help,
version: !!args.version,
port: args.port?.toString(),
log: args.log ? [args.log] : undefined,
}
}

43
src/node/coder_cloud.ts Normal file
View File

@@ -0,0 +1,43 @@
import { logger } from "@coder/logger"
import { spawn } from "child_process"
import path from "path"
import split2 from "split2"
// https://github.com/coder/coder-cloud
const coderCloudAgent = path.resolve(__dirname, "../../lib/coder-cloud-agent")
function runAgent(...args: string[]): Promise<void> {
logger.debug(`running agent with ${args}`)
const agent = spawn(coderCloudAgent, args, {
stdio: ["inherit", "inherit", "pipe"],
})
agent.stderr.pipe(split2()).on("data", (line) => {
line = line.replace(/^[0-9-]+ [0-9:]+ [^ ]+\t/, "")
logger.info(line)
})
return new Promise((res, rej) => {
agent.on("error", rej)
agent.on("close", (code) => {
if (code !== 0) {
rej({
message: `--link agent exited with ${code}`,
})
return
}
res()
})
})
}
export function coderCloudBind(address: URL | string, serverName = ""): Promise<void> {
if (typeof address === "string") {
throw new Error("Cannot link socket paths")
}
// Address needs to be in hostname:port format without the protocol.
return runAgent("bind", `--code-server-addr=${address.host}`, serverName)
}

View File

@@ -1,21 +0,0 @@
import i18next, { init } from "i18next"
import * as en from "./locales/en.json"
import * as zhCn from "./locales/zh-cn.json"
init({
lng: "en",
fallbackLng: "en", // language to use if translations in user language are not available.
returnNull: false,
lowerCaseLng: true,
debug: process.env.NODE_ENV === "development",
resources: {
en: {
translation: en,
},
"zh-cn": {
translation: zhCn,
},
},
})
export default i18next

View File

@@ -1,13 +0,0 @@
{
"LOGIN_TITLE": "{{app}} login",
"LOGIN_BELOW": "Please log in below.",
"WELCOME": "Welcome to {{app}}",
"LOGIN_PASSWORD": "Check the config file at {{configFile}} for the password.",
"LOGIN_USING_ENV_PASSWORD": "Password was set from $PASSWORD.",
"LOGIN_USING_HASHED_PASSWORD": "Password was set from $HASHED_PASSWORD.",
"SUBMIT": "SUBMIT",
"PASSWORD_PLACEHOLDER": "PASSWORD",
"LOGIN_RATE_LIMIT": "Login rate limited!",
"MISS_PASSWORD": "Missing password",
"INCORRECT_PASSWORD": "Incorrect password"
}

View File

@@ -1,13 +0,0 @@
{
"LOGIN_TITLE": "{{app}} 登录",
"LOGIN_BELOW": "请在下面登录。",
"WELCOME": "欢迎来到 {{app}}",
"LOGIN_PASSWORD": "查看配置文件 {{configFile}} 中的密码。",
"LOGIN_USING_ENV_PASSWORD": "密码在 $PASSWORD 中设置。",
"LOGIN_USING_HASHED_PASSWORD": "密码在 $HASHED_PASSWORD 中设置。",
"SUBMIT": "提交",
"PASSWORD_PLACEHOLDER": "密码",
"LOGIN_RATE_LIMIT": "登录速率限制!",
"MISS_PASSWORD": "缺少密码",
"INCORRECT_PASSWORD": "密码不正确"
}

View File

@@ -6,6 +6,7 @@ import { Disposable } from "../common/emitter"
import { plural } from "../common/util"
import { createApp, ensureAddress } from "./app"
import { AuthType, DefaultedArgs, Feature, SpawnCodeCli, toCodeArgs, UserProvidedArgs } from "./cli"
import { coderCloudBind } from "./coder_cloud"
import { commit, version } from "./constants"
import { register } from "./routes"
import { humanPath, isDirectory, loadAMDModule, open } from "./util"
@@ -126,7 +127,11 @@ export const runCodeServer = async (
const disposeRoutes = await register(app, args)
logger.info(`Using config file ${humanPath(os.homedir(), args.config)}`)
logger.info(`${protocol.toUpperCase()} server listening on ${serverAddress.toString()}`)
logger.info(
`${protocol.toUpperCase()} server listening on ${serverAddress.toString()} ${
args.link ? "(randomized by --link)" : ""
}`,
)
if (args.auth === AuthType.Password) {
logger.info(" - Authentication is enabled")
@@ -138,13 +143,13 @@ export const runCodeServer = async (
logger.info(` - Using password from ${humanPath(os.homedir(), args.config)}`)
}
} else {
logger.info(" - Authentication is disabled")
logger.info(` - Authentication is disabled ${args.link ? "(disabled by --link)" : ""}`)
}
if (args.cert) {
logger.info(` - Using certificate for HTTPS: ${humanPath(os.homedir(), args.cert.value)}`)
} else {
logger.info(" - Not serving HTTPS")
logger.info(` - Not serving HTTPS ${args.link ? "(disabled by --link)" : ""}`)
}
if (args["proxy-domain"].length > 0) {
@@ -152,6 +157,11 @@ export const runCodeServer = async (
args["proxy-domain"].forEach((domain) => logger.info(` - *.${domain}`))
}
if (args.link) {
await coderCloudBind(serverAddress, args.link.value)
logger.info(" - Connected to cloud agent")
}
if (args.enable && args.enable.length > 0) {
logger.info("Enabling the following experimental features:")
args.enable.forEach((feature) => {

View File

@@ -33,15 +33,7 @@ import { CodeServerRouteWrapper } from "./vscode"
export const register = async (app: App, args: DefaultedArgs): Promise<Disposable["dispose"]> => {
const heart = new Heart(path.join(paths.data, "heartbeat"), async () => {
return new Promise((resolve, reject) => {
// getConnections appears to not call the callback when there are no more
// connections. Feels like it must be a bug? For now add a timer to make
// sure we eventually resolve.
const timer = setTimeout(() => {
logger.debug("Node failed to respond with connections; assuming zero")
resolve(false)
}, 5000)
app.server.getConnections((error, count) => {
clearTimeout(timer)
if (error) {
return reject(error)
}
@@ -89,13 +81,6 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
return res.redirect(`https://${req.headers.host}${req.originalUrl}`)
}
// Return security.txt.
if (req.originalUrl === "/security.txt" || req.originalUrl === "/.well-known/security.txt") {
const resourcePath = path.resolve(rootPath, "src/browser/security.txt")
res.set("Content-Type", getMediaMime(resourcePath))
return res.send(await fs.readFile(resourcePath))
}
// Return robots.txt.
if (req.originalUrl === "/robots.txt") {
const resourcePath = path.resolve(rootPath, "src/browser/robots.txt")

View File

@@ -7,13 +7,12 @@ import { CookieKeys } from "../../common/http"
import { rootPath } from "../constants"
import { authenticated, getCookieOptions, redirect, replaceTemplates } from "../http"
import { getPasswordMethod, handlePasswordValidation, humanPath, sanitizeString, escapeHtml } from "../util"
import i18n from "../i18n"
// RateLimiter wraps around the limiter library for logins.
// It allows 2 logins every minute plus 12 logins every hour.
export class RateLimiter {
private readonly minuteLimiter = new Limiter({ tokensPerInterval: 2, interval: "minute" })
private readonly hourLimiter = new Limiter({ tokensPerInterval: 12, interval: "hour" })
private readonly minuteLimiter = new Limiter(2, "minute")
private readonly hourLimiter = new Limiter(12, "hour")
public canTry(): boolean {
// Note: we must check using >= 1 because technically when there are no tokens left
@@ -29,26 +28,21 @@ 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 locale = req.args["locale"] || "en"
i18n.changeLanguage(locale)
const appName = req.args["app-name"] || "code-server"
const welcomeText = req.args["welcome-text"] || (i18n.t("WELCOME", { app: appName }) as string)
let passwordMsg = i18n.t("LOGIN_PASSWORD", { configFile: humanPath(os.homedir(), req.args.config) })
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 = i18n.t("LOGIN_USING_ENV_PASSWORD")
passwordMsg = "Password was set from $PASSWORD."
} else if (req.args.usingEnvHashedPassword) {
passwordMsg = i18n.t("LOGIN_USING_HASHED_PASSWORD")
passwordMsg = "Password was set from $HASHED_PASSWORD."
}
return replaceTemplates(
req,
content
.replace(/{{I18N_LOGIN_TITLE}}/g, i18n.t("LOGIN_TITLE", { app: appName }))
.replace(/{{APP_NAME}}/g, appName)
.replace(/{{WELCOME_TEXT}}/g, welcomeText)
.replace(/{{PASSWORD_MSG}}/g, passwordMsg)
.replace(/{{I18N_LOGIN_BELOW}}/g, i18n.t("LOGIN_BELOW"))
.replace(/{{I18N_PASSWORD_PLACEHOLDER}}/g, i18n.t("PASSWORD_PLACEHOLDER"))
.replace(/{{I18N_SUBMIT}}/g, i18n.t("SUBMIT"))
.replace(/{{ERROR}}/, error ? `<div class="error">${escapeHtml(error.message)}</div>` : ""),
)
}
@@ -76,11 +70,11 @@ router.post<{}, string, { password: string; base?: string }, { to?: string }>("/
try {
// Check to see if they exceeded their login attempts
if (!limiter.canTry()) {
throw new Error(i18n.t("LOGIN_RATE_LIMIT") as string)
throw new Error("Login rate limited!")
}
if (!password) {
throw new Error(i18n.t("MISS_PASSWORD") as string)
throw new Error("Missing password")
}
const passwordMethod = getPasswordMethod(hashedPasswordFromArgs)
@@ -114,7 +108,7 @@ router.post<{}, string, { password: string; base?: string }, { to?: string }>("/
}),
)
throw new Error(i18n.t("INCORRECT_PASSWORD") as string)
throw new Error("Incorrect password")
} catch (error: any) {
const renderedHtml = await getRoot(req, error)
res.send(renderedHtml)

View File

@@ -147,7 +147,7 @@ abstract class Process {
* Child process that will clean up after itself if the parent goes away and can
* perform a handshake with the parent and ask it to relaunch.
*/
export class ChildProcess extends Process {
class ChildProcess extends Process {
public logger = logger.named(`child:${process.pid}`)
public constructor(private readonly parentPid: number) {

View File

@@ -128,8 +128,6 @@ export class CodeServer {
path.join(dir, "extensions"),
"--auth",
"none",
// The workspace to open.
...(this.args.includes("--ignore-last-opened") ? [] : [dir]),
...this.args,
// Using port zero will spawn on a random port.
"--bind-addr",
@@ -141,6 +139,8 @@ export class CodeServer {
path.join(dir, "config.yaml"),
"--user-data-dir",
dir,
// The last argument is the workspace to open.
dir,
]
this.logger.debug("spawning `node " + args.join(" ") + "`")
const proc = cp.spawn("node", args, {

View File

@@ -1,111 +0,0 @@
import { describe, test, expect } from "./baseFixture"
import { clean, getMaybeProxiedPathname } from "../utils/helpers"
const routes = ["/", "/vscode", "/vscode/"]
describe("VS Code Routes", ["--disable-workspace-trust"], {}, async () => {
const testName = "vscode-routes-default"
test.beforeAll(async () => {
await clean(testName)
})
test("should load all route variations", async ({ codeServerPage }) => {
for (const route of routes) {
await codeServerPage.navigate(route)
// Check there were no redirections
const url = new URL(codeServerPage.page.url())
const pathname = getMaybeProxiedPathname(url)
expect(pathname).toBe(route)
// TODO@jsjoeio
// now that we are in a proper browser instead of scraping the HTML we
// could possibly intercept requests to make sure assets are loading from
// the right spot.
//
// Check that page loaded from correct route
const html = await codeServerPage.page.innerHTML("html")
switch (route) {
case "/":
case "/vscode/":
expect(html).toMatch(/src="\.\/[a-z]+-[0-9a-z]+\/static\//)
break
case "/vscode":
expect(html).toMatch(/src="\.\/vscode\/[a-z]+-[0-9a-z]+\/static\//)
break
}
}
})
})
const CODE_WORKSPACE_DIR = process.env.CODE_WORKSPACE_DIR || ""
describe("VS Code Routes with code-workspace", ["--disable-workspace-trust", CODE_WORKSPACE_DIR], {}, async () => {
test("should redirect to the passed in workspace using human-readable query", async ({ codeServerPage }) => {
const url = new URL(codeServerPage.page.url())
const pathname = getMaybeProxiedPathname(url)
expect(pathname).toBe("/")
expect(url.search).toBe(`?workspace=${CODE_WORKSPACE_DIR}`)
})
})
const CODE_FOLDER_DIR = process.env.CODE_FOLDER_DIR || ""
describe("VS Code Routes with code-workspace", ["--disable-workspace-trust", CODE_FOLDER_DIR], {}, async () => {
test("should redirect to the passed in folder using human-readable query", async ({ codeServerPage }) => {
const url = new URL(codeServerPage.page.url())
const pathname = getMaybeProxiedPathname(url)
expect(pathname).toBe("/")
expect(url.search).toBe(`?folder=${CODE_FOLDER_DIR}`)
})
})
describe(
"VS Code Routes with ignore-last-opened",
["--disable-workspace-trust", "--ignore-last-opened"],
{},
async () => {
test("should not redirect", async ({ codeServerPage }) => {
const folder = process.env.CODE_FOLDER_DIR
await codeServerPage.navigate(`/?folder=${folder}`)
await codeServerPage.navigate(`/`)
const url = new URL(codeServerPage.page.url())
const pathname = getMaybeProxiedPathname(url)
expect(pathname).toBe("/")
expect(url.search).toBe("")
})
},
)
describe("VS Code Routes with no workspace or folder", ["--disable-workspace-trust"], {}, async () => {
test("should redirect to last query folder/workspace", async ({ codeServerPage }) => {
const folder = process.env.CODE_FOLDER_DIR
const workspace = process.env.CODE_WORKSPACE_DIR
await codeServerPage.navigate(`/?folder=${folder}&workspace=${workspace}`)
// If you visit again without query parameters it will re-attach them by
// redirecting. It should always redirect to the same route.
for (const route of routes) {
await codeServerPage.navigate(route)
const url = new URL(codeServerPage.page.url())
const pathname = getMaybeProxiedPathname(url)
expect(pathname).toBe(route)
expect(url.search).toBe(`?folder=${folder}&workspace=${workspace}`)
}
})
})
describe("VS Code Routes with no workspace or folder", ["--disable-workspace-trust"], {}, async () => {
test("should not redirect if ew passed in", async ({ codeServerPage }) => {
const folder = process.env.CODE_FOLDER_DIR
const workspace = process.env.CODE_WORKSPACE_DIR
await codeServerPage.navigate(`/?folder=${folder}&workspace=${workspace}`)
// Closing the folder should stop the redirecting.
await codeServerPage.navigate("/?ew=true")
let url = new URL(codeServerPage.page.url())
const pathname = getMaybeProxiedPathname(url)
expect(pathname).toBe("/")
expect(url.search).toBe("?ew=true")
})
})

13
test/e2e/trust.test.ts Normal file
View File

@@ -0,0 +1,13 @@
import { describe, test, expect } from "./baseFixture"
describe("Workspace trust (enabled)", [], {}, async () => {
test("should see the 'I Trust...' option", async ({ codeServerPage }) => {
expect(await codeServerPage.page.isVisible("text=Yes, I trust")).toBe(true)
})
})
describe("Workspace trust (disabled)", ["--disable-workspace-trust"], {}, async () => {
test("should not see the 'I Trust...' option", async ({ codeServerPage }) => {
expect(await codeServerPage.page.isVisible("text=Yes, I trust")).toBe(false)
})
})

View File

@@ -1,28 +0,0 @@
import { promises as fs } from "fs"
import * as path from "path"
import { describe, test, expect } from "./baseFixture"
describe("Webviews", ["--disable-workspace-trust"], {}, () => {
test("should preview a Markdown file", async ({ codeServerPage }) => {
// Create Markdown file
const heading = "Hello world"
const dir = await codeServerPage.workspaceDir
const file = path.join(dir, "text.md")
await fs.writeFile(file, `# ${heading}`)
await codeServerPage.openFile(file)
// Open Preview
await codeServerPage.executeCommandViaMenus("Markdown: Open Preview to the Side")
// Wait for the iframe to open and load
await codeServerPage.waitForTab(`Preview ${file}`)
// It's an iframe within an iframe
// so we have to do .frameLocator twice
const renderedText = await codeServerPage.page
.frameLocator("iframe.webview.ready")
.frameLocator("#active-frame")
.locator("text=Hello world")
expect(renderedText).toBeVisible
})
})

View File

@@ -11,14 +11,14 @@ function should-use-deb() {
DISTRO=$1 ARCH=$2 OS=linux run "$SCRIPT" --dry-run
[ "$status" -eq 0 ]
[ "${lines[1]}" = "Installing v$VERSION of the $2 deb package from GitHub." ]
[ "${lines[-6]}" = "deb package has been installed." ]
[ "${lines[-5]}" = "deb package has been installed." ]
}
function should-use-rpm() {
DISTRO=$1 ARCH=$2 OS=linux run "$SCRIPT" --dry-run
[ "$status" -eq 0 ]
[ "${lines[1]}" = "Installing v$VERSION of the $2 rpm package from GitHub." ]
[ "${lines[-6]}" = "rpm package has been installed." ]
[ "${lines[-5]}" = "rpm package has been installed." ]
}
function should-fallback-npm() {
@@ -27,21 +27,21 @@ function should-fallback-npm() {
[ "${lines[1]}" = "No standalone releases for $2." ]
[ "${lines[2]}" = "Falling back to installation from npm." ]
[ "${lines[3]}" = "Installing latest from npm." ]
[ "${lines[-6]}" = "npm package has been installed." ]
[ "${lines[-5]}" = "npm package has been installed." ]
}
function should-use-npm() {
YARN_PATH=true DISTRO=$1 ARCH=$2 OS=linux run "$SCRIPT" --dry-run
[ "$status" -eq 0 ]
[ "${lines[1]}" = "Installing latest from npm." ]
[ "${lines[-6]}" = "npm package has been installed." ]
[ "${lines[-5]}" = "npm package has been installed." ]
}
function should-use-aur() {
DISTRO=$1 ARCH=$2 OS=linux run "$SCRIPT" --dry-run
[ "$status" -eq 0 ]
[ "${lines[1]}" = "Installing latest from the AUR." ]
[ "${lines[-6]}" = "AUR package has been installed." ]
[ "${lines[-5]}" = "AUR package has been installed." ]
}
function should-fallback-npm-brew() {
@@ -52,21 +52,21 @@ function should-fallback-npm-brew() {
[ "${lines[3]}" = "No standalone releases for $1." ]
[ "${lines[4]}" = "Falling back to installation from npm." ]
[ "${lines[5]}" = "Installing latest from npm." ]
[ "${lines[-6]}" = "npm package has been installed." ]
[ "${lines[-5]}" = "npm package has been installed." ]
}
function should-use-brew() {
BREW_PATH=true OS=macos ARCH=$1 run "$SCRIPT" --dry-run
[ "$status" -eq 0 ]
[ "${lines[1]}" = "Installing latest from Homebrew." ]
[ "${lines[-4]}" = "Brew release has been installed." ]
[ "${lines[-3]}" = "Brew release has been installed." ]
}
function should-use-standalone() {
DISTRO=$1 ARCH=$2 OS=$3 run "$SCRIPT" --method standalone --dry-run
[ "$status" -eq 0 ]
[ "${lines[1]}" = "Installing v$VERSION of the $2 release from GitHub." ]
[[ "${lines[-6]}" = "Standalone release has been installed"* ]]
[[ "${lines[-5]}" = "Standalone release has been installed"* ]]
}
@test "$SCRIPT_NAME: usage with --help" {
@@ -141,7 +141,7 @@ function should-use-standalone() {
[ "${lines[1]}" = "Homebrew not installed." ]
[ "${lines[2]}" = "Falling back to standalone installation." ]
[ "${lines[3]}" = "Installing v$VERSION of the amd64 release from GitHub." ]
[[ "${lines[-6]}" = "Standalone release has been installed"* ]]
[[ "${lines[-5]}" = "Standalone release has been installed"* ]]
}
@test "$SCRIPT_NAME: macos i386 (no brew)" {
should-fallback-npm-brew "i386"

View File

@@ -1,6 +1,5 @@
import { promises as fs } from "fs"
import { clean, getAvailablePort, getMaybeProxiedPathname, tmpdir, useEnv } from "../../test/utils/helpers"
import { REVERSE_PROXY_BASE_PATH } from "../utils/constants"
import { clean, getAvailablePort, tmpdir, useEnv } from "../../test/utils/helpers"
/**
* This file is for testing test helpers (not core code).
@@ -57,22 +56,3 @@ describe("getAvailablePort", () => {
expect(portOne).not.toEqual(portTwo)
})
})
describe("getMaybeProxiedPathname", () => {
it("should return the route", () => {
const route = "/vscode"
const url = new URL(`http://localhost:3000${route}`)
const actual = getMaybeProxiedPathname(url)
expect(actual).toBe(route)
})
it("should strip proxy if env var set", () => {
const envKey = "USE_PROXY"
const [setValue, resetValue] = useEnv(envKey)
setValue("1")
const route = "/vscode"
const url = new URL(`http://localhost:3000/8000/${REVERSE_PROXY_BASE_PATH}${route}`)
const actual = getMaybeProxiedPathname(url)
expect(actual).toBe(route)
resetValue()
})
})

View File

@@ -297,6 +297,26 @@ describe("parser", () => {
})
})
it("should override with --link", async () => {
const args = parse(
"--cert test --cert-key test --socket test --socket-mode 777 --host 0.0.0.0 --port 8888 --link test".split(" "),
)
const defaultArgs = await setDefaults(args)
expect(defaultArgs).toEqual({
...defaults,
auth: "none",
host: "localhost",
link: {
value: "test",
},
port: 0,
cert: undefined,
"cert-key": path.resolve("test"),
socket: undefined,
"socket-mode": undefined,
})
})
it("should use env var password", async () => {
process.env.PASSWORD = "test"
const args = parse([])
@@ -775,7 +795,6 @@ describe("toCodeArgs", () => {
help: false,
port: "8080",
version: false,
log: undefined,
}
const testName = "vscode-args"
@@ -861,13 +880,21 @@ describe("optionDescriptions", () => {
it("should show if an option is deprecated", () => {
const opts: Partial<Options<Required<UserProvidedArgs>>> = {
cert: {
link: {
type: OptionalString,
description: "foo",
description: `
Securely bind code-server via our cloud service with the passed name. You'll get a URL like
https://hostname-username.coder.co at which you can easily access your code-server instance.
Authorization is done via GitHub.
`,
deprecated: true,
},
}
expect(optionDescriptions(opts)).toStrictEqual([" --cert (deprecated) foo"])
expect(optionDescriptions(opts)).toStrictEqual([
` --link (deprecated) Securely bind code-server via our cloud service with the passed name. You'll get a URL like
https://hostname-username.coder.co at which you can easily access your code-server instance.
Authorization is done via GitHub.`,
])
})
it("should show newlines in description", () => {

View File

@@ -138,16 +138,5 @@ describe("login", () => {
expect(resp.status).toBe(200)
expect(htmlContent).toContain(`Welcome to ${appName}`)
})
it("should return correct welcome text when locale is set to non-English", async () => {
process.env.PASSWORD = previousEnvPassword
const locale = "zh-cn"
const codeServer = await integration.setup([`--locale=${locale}`], "")
const resp = await codeServer.fetch("/login", { method: "GET" })
const htmlContent = await resp.text()
expect(resp.status).toBe(200)
expect(htmlContent).toContain(`欢迎来到 code-server`)
})
})
})

View File

@@ -0,0 +1,137 @@
import { promises as fs } from "fs"
import * as path from "path"
import { clean, tmpdir } from "../../../utils/helpers"
import * as httpserver from "../../../utils/httpserver"
import * as integration from "../../../utils/integration"
// TODO@jsjoeio - move these to integration tests since they rely on Code
// to be built
describe("vscode", () => {
let codeServer: httpserver.HttpServer | undefined
const testName = "vscode"
beforeAll(async () => {
await clean(testName)
})
afterEach(async () => {
if (codeServer) {
await codeServer.dispose()
codeServer = undefined
}
})
const routes = ["/", "/vscode", "/vscode/"]
it("should load all route variations", async () => {
codeServer = await integration.setup(["--auth=none"], "")
for (const route of routes) {
const resp = await codeServer.fetch(route)
expect(resp.status).toBe(200)
const html = await resp.text()
const url = new URL(resp.url) // Check there were no redirections.
expect(url.pathname + url.search).toBe(route)
switch (route) {
case "/":
case "/vscode/":
expect(html).toMatch(/src="\.\/[a-z]+-[0-9a-z]+\/static\//)
break
case "/vscode":
expect(html).toMatch(/src="\.\/vscode\/[a-z]+-[0-9a-z]+\/static\//)
break
}
}
})
it("should redirect to the passed in workspace using human-readable query", async () => {
const workspace = path.join(await tmpdir(testName), "test.code-workspace")
await fs.writeFile(workspace, "")
codeServer = await integration.setup(["--auth=none", workspace], "")
const resp = await codeServer.fetch("/")
const url = new URL(resp.url)
expect(url.pathname).toBe("/")
expect(url.search).toBe(`?workspace=${workspace}`)
})
it("should redirect to the passed in folder using human-readable query", async () => {
const folder = await tmpdir(testName)
codeServer = await integration.setup(["--auth=none", folder], "")
const resp = await codeServer.fetch("/")
const url = new URL(resp.url)
expect(url.pathname).toBe("/")
expect(url.search).toBe(`?folder=${folder}`)
})
it("should redirect to last query folder/workspace", async () => {
codeServer = await integration.setup(["--auth=none"], "")
const folder = await tmpdir(testName)
const workspace = path.join(await tmpdir(testName), "test.code-workspace")
await fs.writeFile(workspace, "")
let resp = await codeServer.fetch("/", undefined, {
folder,
workspace,
})
expect(resp.status).toBe(200)
await resp.text()
// If you visit again without query parameters it will re-attach them by
// redirecting. It should always redirect to the same route.
for (const route of routes) {
resp = await codeServer.fetch(route)
const url = new URL(resp.url)
expect(url.pathname).toBe(route)
expect(url.search).toBe(`?folder=${folder}&workspace=${workspace}`)
await resp.text()
}
// Closing the folder should stop the redirecting.
resp = await codeServer.fetch("/", undefined, { ew: "true" })
let url = new URL(resp.url)
expect(url.pathname).toBe("/")
expect(url.search).toBe("?ew=true")
await resp.text()
resp = await codeServer.fetch("/")
url = new URL(resp.url)
expect(url.pathname).toBe("/")
expect(url.search).toBe("")
await resp.text()
})
it("should do nothing when nothing is passed in", async () => {
codeServer = await integration.setup(["--auth=none"], "")
const resp = await codeServer.fetch("/", undefined)
expect(resp.status).toBe(200)
const url = new URL(resp.url)
expect(url.search).toBe("")
await resp.text()
})
it("should not redirect when last opened is ignored", async () => {
codeServer = await integration.setup(["--auth=none", "--ignore-last-opened"], "")
const folder = await tmpdir(testName)
const workspace = path.join(await tmpdir(testName), "test.code-workspace")
await fs.writeFile(workspace, "")
let resp = await codeServer.fetch("/", undefined, {
folder,
workspace,
})
expect(resp.status).toBe(200)
await resp.text()
// No redirections.
resp = await codeServer.fetch("/")
const url = new URL(resp.url)
expect(url.pathname).toBe("/")
expect(url.search).toBe("")
await resp.text()
})
})

View File

@@ -1,14 +0,0 @@
import { ChildProcess, ParentProcess, isChild } from "../../../src/node/wrapper"
describe("wrapper", () => {
describe("isChild", () => {
it("should return false for parent process", () => {
const p = new ParentProcess("1")
expect(isChild(p)).toBe(false)
})
})
it("should return false for parent process", () => {
const childProc = new ChildProcess(1)
expect(isChild(childProc)).toBe(true)
})
})

View File

@@ -1,8 +1,6 @@
import { workspaceDir } from "./constants"
import { clean, tmpdir } from "./helpers"
import { clean } from "./helpers"
import * as wtfnode from "./wtfnode"
import * as path from "path"
import { promises as fs } from "fs"
/**
* Perform workspace cleanup and authenticate. This should be ran before e2e
@@ -19,14 +17,5 @@ export default async function () {
wtfnode.setup()
}
// Create dummy code-workspace for routes.test.ts
const codeWorkspace = path.join(await tmpdir(workspaceDir), "test.code-workspace")
await fs.writeFile(codeWorkspace, "")
process.env.CODE_WORKSPACE_DIR = codeWorkspace
// Create dummy folder for routes.test.ts
const folder = await tmpdir(workspaceDir)
process.env.CODE_FOLDER_DIR = folder
console.log("✅ Global Setup for Playwright End-to-End Tests is now complete.")
}

View File

@@ -136,17 +136,3 @@ export async function getMaybeProxiedCodeServer(codeServer: CodeServerPage | Cod
return address
}
/**
* Stripes proxy base from url.pathname
* i.e. /<port>/ide + route returns just route
*/
export function getMaybeProxiedPathname(url: URL): string {
if (process.env.USE_PROXY === "1") {
// Behind proxy, path will be /<port>/ide + route
const pathWithoutProxy = url.pathname.split(`/${REVERSE_PROXY_BASE_PATH}`)[1]
return pathWithoutProxy
}
return url.pathname
}

View File

@@ -22,8 +22,7 @@
"./test/node_modules/@types",
"./lib/vscode/src/vs/server/@types"
],
"downlevelIteration": true,
"resolveJsonModule": true
"downlevelIteration": true
},
"include": ["./src/**/*"],
"exclude": ["/test", "/lib", "/ci", "/doc"]

176
yarn.lock
View File

@@ -2,13 +2,6 @@
# yarn lockfile v1
"@babel/runtime@^7.20.6":
version "7.20.7"
resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.20.7.tgz#fcb41a5a70550e04a7b708037c7c32f7f356d8fd"
integrity sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==
dependencies:
regenerator-runtime "^0.13.11"
"@coder/logger@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@coder/logger/-/logger-3.0.0.tgz#fd4d2332ca375412c75cb5ba7767d3290b106dec"
@@ -48,7 +41,7 @@
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
"@mapbox/node-pre-gyp@^1.0.10":
"@mapbox/node-pre-gyp@^1.0.9":
version "1.0.10"
resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz#8e6735ccebbb1581e5a7e652244cadc8a844d03c"
integrity sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==
@@ -336,17 +329,15 @@
"@types/node" "*"
"@typescript-eslint/eslint-plugin@^5.41.0":
version "5.51.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.51.0.tgz#da3f2819633061ced84bb82c53bba45a6fe9963a"
integrity sha512-wcAwhEWm1RgNd7dxD/o+nnLW8oH+6RK1OGnmbmkj/GGoDPV1WWMVP0FXYQBivKHdwM1pwii3bt//RC62EriIUQ==
version "5.41.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.41.0.tgz#f8eeb1c6bb2549f795f3ba71aec3b38d1ab6b1e1"
integrity sha512-DXUS22Y57/LAFSg3x7Vi6RNAuLpTXwxB9S2nIA7msBb/Zt8p7XqMwdpdc1IU7CkOQUPgAqR5fWvxuKCbneKGmA==
dependencies:
"@typescript-eslint/scope-manager" "5.51.0"
"@typescript-eslint/type-utils" "5.51.0"
"@typescript-eslint/utils" "5.51.0"
"@typescript-eslint/scope-manager" "5.41.0"
"@typescript-eslint/type-utils" "5.41.0"
"@typescript-eslint/utils" "5.41.0"
debug "^4.3.4"
grapheme-splitter "^1.0.4"
ignore "^5.2.0"
natural-compare-lite "^1.4.0"
regexpp "^3.2.0"
semver "^7.3.7"
tsutils "^3.21.0"
@@ -369,21 +360,13 @@
"@typescript-eslint/types" "5.41.0"
"@typescript-eslint/visitor-keys" "5.41.0"
"@typescript-eslint/scope-manager@5.51.0":
version "5.51.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.51.0.tgz#ad3e3c2ecf762d9a4196c0fbfe19b142ac498990"
integrity sha512-gNpxRdlx5qw3yaHA0SFuTjW4rxeYhpHxt491PEcKF8Z6zpq0kMhe0Tolxt0qjlojS+/wArSDlj/LtE69xUJphQ==
"@typescript-eslint/type-utils@5.41.0":
version "5.41.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.41.0.tgz#2371601171e9f26a4e6da918a7913f7266890cdf"
integrity sha512-L30HNvIG6A1Q0R58e4hu4h+fZqaO909UcnnPbwKiN6Rc3BUEx6ez2wgN7aC0cBfcAjZfwkzE+E2PQQ9nEuoqfA==
dependencies:
"@typescript-eslint/types" "5.51.0"
"@typescript-eslint/visitor-keys" "5.51.0"
"@typescript-eslint/type-utils@5.51.0":
version "5.51.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.51.0.tgz#7af48005531700b62a20963501d47dfb27095988"
integrity sha512-QHC5KKyfV8sNSyHqfNa0UbTbJ6caB8uhcx2hYcWVvJAZYJRBo5HyyZfzMdRx8nvS+GyMg56fugMzzWnojREuQQ==
dependencies:
"@typescript-eslint/typescript-estree" "5.51.0"
"@typescript-eslint/utils" "5.51.0"
"@typescript-eslint/typescript-estree" "5.41.0"
"@typescript-eslint/utils" "5.41.0"
debug "^4.3.4"
tsutils "^3.21.0"
@@ -392,11 +375,6 @@
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.41.0.tgz#6800abebc4e6abaf24cdf220fb4ce28f4ab09a85"
integrity sha512-5BejraMXMC+2UjefDvrH0Fo/eLwZRV6859SXRg+FgbhA0R0l6lDqDGAQYhKbXhPN2ofk2kY5sgGyLNL907UXpA==
"@typescript-eslint/types@5.51.0":
version "5.51.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.51.0.tgz#e7c1622f46c7eea7e12bbf1edfb496d4dec37c90"
integrity sha512-SqOn0ANn/v6hFn0kjvLwiDi4AzR++CBZz0NV5AnusT2/3y32jdc0G4woXPWHCumWtUXZKPAS27/9vziSsC9jnw==
"@typescript-eslint/typescript-estree@5.41.0":
version "5.41.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.41.0.tgz#bf5c6b3138adbdc73ba4871d060ae12c59366c61"
@@ -410,29 +388,16 @@
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/typescript-estree@5.51.0":
version "5.51.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.51.0.tgz#0ec8170d7247a892c2b21845b06c11eb0718f8de"
integrity sha512-TSkNupHvNRkoH9FMA3w7TazVFcBPveAAmb7Sz+kArY6sLT86PA5Vx80cKlYmd8m3Ha2SwofM1KwraF24lM9FvA==
dependencies:
"@typescript-eslint/types" "5.51.0"
"@typescript-eslint/visitor-keys" "5.51.0"
debug "^4.3.4"
globby "^11.1.0"
is-glob "^4.0.3"
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/utils@5.51.0":
version "5.51.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.51.0.tgz#074f4fabd5b12afe9c8aa6fdee881c050f8b4d47"
integrity sha512-76qs+5KWcaatmwtwsDJvBk4H76RJQBFe+Gext0EfJdC3Vd2kpY2Pf//OHHzHp84Ciw0/rYoGTDnIAr3uWhhJYw==
"@typescript-eslint/utils@5.41.0":
version "5.41.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.41.0.tgz#f41ae5883994a249d00b2ce69f4188f3a23fa0f9"
integrity sha512-QlvfwaN9jaMga9EBazQ+5DDx/4sAdqDkcs05AsQHMaopluVCUyu1bTRUVKzXbgjDlrRAQrYVoi/sXJ9fmG+KLQ==
dependencies:
"@types/json-schema" "^7.0.9"
"@types/semver" "^7.3.12"
"@typescript-eslint/scope-manager" "5.51.0"
"@typescript-eslint/types" "5.51.0"
"@typescript-eslint/typescript-estree" "5.51.0"
"@typescript-eslint/scope-manager" "5.41.0"
"@typescript-eslint/types" "5.41.0"
"@typescript-eslint/typescript-estree" "5.41.0"
eslint-scope "^5.1.1"
eslint-utils "^3.0.0"
semver "^7.3.7"
@@ -445,14 +410,6 @@
"@typescript-eslint/types" "5.41.0"
eslint-visitor-keys "^3.3.0"
"@typescript-eslint/visitor-keys@5.51.0":
version "5.51.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.51.0.tgz#c0147dd9a36c0de758aaebd5b48cae1ec59eba87"
integrity sha512-Oh2+eTdjHjOFjKA27sxESlA87YPSOJafGCR0md5oeMdh1ZcCfAGCIOL216uTBAkAIptvLIfKQhl7lHxMJet4GQ==
dependencies:
"@typescript-eslint/types" "5.51.0"
eslint-visitor-keys "^3.3.0"
JSONStream@^1.3.5:
version "1.3.5"
resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0"
@@ -548,12 +505,12 @@ arg@^4.1.0:
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
argon2@0.30.3:
version "0.30.3"
resolved "https://registry.yarnpkg.com/argon2/-/argon2-0.30.3.tgz#795ca57acad76fc67dd5695732662a03018b84ed"
integrity sha512-DoH/kv8c9127ueJSBxAVJXinW9+EuPA3EMUxoV2sAY1qDE5H9BjTyVF/aD2XyHqbqUWabgBkIfcP3ZZuGhbJdg==
argon2@0.29.0:
version "0.29.0"
resolved "https://registry.yarnpkg.com/argon2/-/argon2-0.29.0.tgz#94b6ef96cbdbe9f3562523c7130552af4c8d25bb"
integrity sha512-J8XxGYjq90qohrN5ySXTIXJ2HyDjMOw3uXMOsWrHzKe9daT6TtFCCtrADz1wPFuDH2bOxumPwbgBhKa5AknIhw==
dependencies:
"@mapbox/node-pre-gyp" "^1.0.10"
"@mapbox/node-pre-gyp" "^1.0.9"
"@phc/format" "^1.0.0"
node-addon-api "^5.0.0"
@@ -894,10 +851,10 @@ debug@3.1.0:
dependencies:
ms "2.0.0"
debug@4, debug@^4.0.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
debug@4, debug@^4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
dependencies:
ms "2.1.2"
@@ -908,6 +865,13 @@ debug@^3.2.7:
dependencies:
ms "^2.1.1"
debug@^4.0.0, debug@^4.1.1, debug@^4.3.4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
dependencies:
ms "2.1.2"
deep-is@^0.1.3, deep-is@~0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
@@ -1170,9 +1134,9 @@ escodegen@^1.8.1:
source-map "~0.6.1"
eslint-config-prettier@^8.5.0:
version "8.6.0"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.6.0.tgz#dec1d29ab728f4fa63061774e1672ac4e363d207"
integrity sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA==
version "8.5.0"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1"
integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==
eslint-import-resolver-node@^0.3.6:
version "0.3.6"
@@ -1850,13 +1814,6 @@ https-proxy-agent@5, https-proxy-agent@^5.0.0:
agent-base "6"
debug "4"
i18next@^22.4.6:
version "22.4.6"
resolved "https://registry.npmmirror.com/i18next/-/i18next-22.4.6.tgz#876352c3ba81bdfedc38eeda124e2bbd05f46988"
integrity sha512-9Tm1ezxWyzV+306CIDMBbYBitC1jedQyYuuLtIv7oxjp2ohh8eyxP9xytIf+2bbQfhH784IQKPSYp+Zq9+YSbw==
dependencies:
"@babel/runtime" "^7.20.6"
iconv-lite@0.4.24:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
@@ -2133,9 +2090,9 @@ json-stable-stringify-without-jsonify@^1.0.1:
integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
json5@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593"
integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==
version "1.0.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==
dependencies:
minimist "^1.2.0"
@@ -2151,11 +2108,6 @@ jsonparse@^1.2.0:
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=
just-performance@4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/just-performance/-/just-performance-4.3.0.tgz#cc2bc8c9227f09e97b6b1df4cd0de2df7ae16db1"
integrity sha512-L7RjvtJsL0QO8xFs5wEoDDzzJwoiowRw6Rn/GnvldlchS2JQr9wFYPiwZcDfrbbujEKqKN0tvENdbjXdYhDp5Q==
levn@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
@@ -2172,12 +2124,10 @@ levn@~0.3.0:
prelude-ls "~1.1.2"
type-check "~0.3.2"
limiter@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/limiter/-/limiter-2.1.0.tgz#d38d7c5b63729bb84fb0c4d8594b7e955a5182a2"
integrity sha512-361TYz6iay6n+9KvUUImqdLuFigK+K79qrUtBsXhJTLdH4rIt/r1y8r1iozwh8KbZNpujbFTSh74mJ7bwbAMOw==
dependencies:
just-performance "4.3.0"
limiter@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/limiter/-/limiter-1.1.5.tgz#8f92a25b3b16c6131293a0cc834b4a838a2aa7c2"
integrity sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==
locate-path@^6.0.0:
version "6.0.0"
@@ -2516,11 +2466,6 @@ nanoid@^3.1.23, nanoid@^3.1.31:
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c"
integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==
natural-compare-lite@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4"
integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==
natural-compare@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
@@ -2830,10 +2775,10 @@ prettier-plugin-sh@^0.12.8:
sh-syntax "^0.3.6"
synckit "^0.8.1"
prettier@2.8.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.0.tgz#c7df58393c9ba77d6fba3921ae01faf994fb9dc9"
integrity sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA==
prettier@2.7.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64"
integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==
proxy-addr@~2.0.5:
version "2.0.6"
@@ -2867,13 +2812,18 @@ punycode@^2.1.0:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
qs@6.11.0, qs@6.7.0, qs@^6.7.3:
qs@6.11.0:
version "6.11.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==
dependencies:
side-channel "^1.0.4"
qs@6.7.0:
version "6.7.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==
queue-microtask@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.2.tgz#abf64491e6ecf0f38a6502403d4cda04f372dfd3"
@@ -2928,11 +2878,6 @@ readline-transform@1.0.0:
resolved "https://registry.yarnpkg.com/readline-transform/-/readline-transform-1.0.0.tgz#3157f97428acaec0f05a5c1ff2c3120f4e6d904b"
integrity sha512-7KA6+N9IGat52d83dvxnApAWN+MtVb1MiVuMR/cf1O4kYsJG+g/Aav0AHcHKsb6StinayfPLne0+fMX2sOzAKg==
regenerator-runtime@^0.13.11:
version "0.13.11"
resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
regexp.prototype.flags@^1.4.3:
version "1.4.3"
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac"
@@ -3083,7 +3028,14 @@ semver@^6.0.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
semver@^7.0.0, semver@^7.1.3, semver@^7.3.5, semver@^7.3.7:
semver@^7.0.0, semver@^7.1.3, semver@^7.3.5:
version "7.3.5"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
dependencies:
lru-cache "^6.0.0"
semver@^7.3.7:
version "7.3.8"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798"
integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==