Compare commits
72 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6809ded1da | ||
|
|
d31b934991 | ||
|
|
8bb8fb74cf | ||
|
|
bfd2231b4d | ||
|
|
0fcaff8740 | ||
|
|
9640bdd15a | ||
|
|
9c58360aac | ||
|
|
9f1ef13946 | ||
|
|
36f6149be1 | ||
|
|
a7777ffa42 | ||
|
|
5028169e63 | ||
|
|
3fb38414dd | ||
|
|
b486354d6e | ||
|
|
a1cf4b9ea5 | ||
|
|
64822d0f64 | ||
|
|
74017ecc65 | ||
|
|
da03a648c2 | ||
|
|
6742e945cc | ||
|
|
4e9ed56580 | ||
|
|
8a227d9fa1 | ||
|
|
f9bfd58cf4 | ||
|
|
ef3f4e82b2 | ||
|
|
6262c7a0bf | ||
|
|
101d4ee4ad | ||
|
|
d1acfad2a8 | ||
|
|
ccbf0bebb7 | ||
|
|
f5a1e3a3fa | ||
|
|
3db08fdf51 | ||
|
|
bc05a2f3b9 | ||
|
|
90f603549a | ||
|
|
8352a22e33 | ||
|
|
33ee184ed7 | ||
|
|
6a7c3220b0 | ||
|
|
9d8588b2ed | ||
|
|
61e2a9ac41 | ||
|
|
61673b5918 | ||
|
|
2bfe15b3e9 | ||
|
|
bef78e6a41 | ||
|
|
6037468e0f | ||
|
|
ba6b8da76b | ||
|
|
43b87edc72 | ||
|
|
b091b00406 | ||
|
|
17aaa8b347 | ||
|
|
2ec1e2de34 | ||
|
|
c69f2c69f6 | ||
|
|
91589fd106 | ||
|
|
3335d0a456 | ||
|
|
6d8f30d579 | ||
|
|
11b2ef9846 | ||
|
|
a51c94190f | ||
|
|
5c18e3556b | ||
|
|
6b9bb89f43 | ||
|
|
7bb35af04f | ||
|
|
f178f0400b | ||
|
|
efb5baec83 | ||
|
|
45e222b3c1 | ||
|
|
04ff8c355b | ||
|
|
ca8ed8e35b | ||
|
|
9087e0c091 | ||
|
|
0022473744 | ||
|
|
b2ed6b8461 | ||
|
|
da9e72cb69 | ||
|
|
3054f09838 | ||
|
|
de042173b2 | ||
|
|
f772d7bd13 | ||
|
|
23a84e156e | ||
|
|
cb09650d7c | ||
|
|
0e9ec02bef | ||
|
|
e79f6f3ad2 | ||
|
|
40b650b7c7 | ||
|
|
0659e565d0 | ||
|
|
f4fc2ebecf |
4
.github/CODEOWNERS
vendored
@@ -1,3 +1,5 @@
|
||||
* @coder/code-server-reviewers
|
||||
* @coder/code-server
|
||||
|
||||
ci/helm-chart/ @Matthew-Beckett @alexgorbatchev
|
||||
|
||||
docs/install.md @GNUxeava
|
||||
|
||||
114
.github/workflows/ci.yaml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
prebuild:
|
||||
name: Pre-build checks
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
node-version: "16"
|
||||
|
||||
- name: Install helm
|
||||
uses: azure/setup-helm@v3.0
|
||||
uses: azure/setup-helm@v3.3
|
||||
|
||||
- name: Fetch dependencies from cache
|
||||
id: cache-yarn
|
||||
@@ -143,14 +143,20 @@ jobs:
|
||||
id: vscode-rev
|
||||
run: echo "::set-output name=rev::$(git rev-parse HEAD:./lib/vscode)"
|
||||
|
||||
# We need to rebuild when we have a new version of Code or when any of
|
||||
# the patches changed. Use VSCODE_CACHE_VERSION to force a rebuild.
|
||||
- name: Get version
|
||||
id: version
|
||||
run: echo "::set-output name=version::$(jq -r .version package.json)"
|
||||
|
||||
# We need to rebuild when we have a new version of Code, when any of
|
||||
# the patches changed, or when the code-server version changes (since
|
||||
# it gets embedded into the code). Use VSCODE_CACHE_VERSION to
|
||||
# force a rebuild.
|
||||
- name: Fetch prebuilt Code package from cache
|
||||
id: cache-vscode
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: lib/vscode-reh-web-*
|
||||
key: vscode-reh-package-${{ secrets.VSCODE_CACHE_VERSION }}-${{ steps.vscode-rev.outputs.rev }}-${{ hashFiles('patches/*.diff') }}
|
||||
key: vscode-reh-package-${{ secrets.VSCODE_CACHE_VERSION }}-${{ steps.vscode-rev.outputs.rev }}-${{ steps.version.outputs.version }}-${{ hashFiles('patches/*.diff', 'ci/build/build-vscode.sh') }}
|
||||
|
||||
- name: Build vscode
|
||||
if: steps.cache-vscode.outputs.cache-hit != 'true'
|
||||
@@ -192,9 +198,9 @@ jobs:
|
||||
# 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
|
||||
# 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
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository || github.event_name != 'pull_request'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
@@ -455,7 +461,6 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
|
||||
- name: Install Node.js v16
|
||||
uses: actions/setup-node@v3
|
||||
@@ -485,7 +490,7 @@ jobs:
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.cache-yarn.outputs.cache-hit != 'true'
|
||||
run: yarn --frozen-lockfile
|
||||
run: SKIP_SUBMODULE_DEPS=1 yarn --frozen-lockfile
|
||||
|
||||
- name: Install Playwright OS dependencies
|
||||
run: |
|
||||
@@ -493,7 +498,7 @@ jobs:
|
||||
./test/node_modules/.bin/playwright install
|
||||
|
||||
- name: Run end-to-end tests
|
||||
run: yarn test:e2e
|
||||
run: yarn test:e2e --global-timeout 840000
|
||||
|
||||
- name: Upload test artifacts
|
||||
if: always()
|
||||
@@ -505,6 +510,93 @@ jobs:
|
||||
- name: Remove release packages and test artifacts
|
||||
run: rm -rf ./release-packages ./test/test-results
|
||||
|
||||
test-e2e-proxy:
|
||||
name: End-to-end tests behind proxy
|
||||
needs: package-linux-amd64
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 25
|
||||
env:
|
||||
# Since we build code-server we might as well run tests from the release
|
||||
# since VS Code will load faster due to the bundling.
|
||||
CODE_SERVER_TEST_ENTRY: "./release-packages/code-server-linux-amd64"
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install Node.js v16
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16"
|
||||
|
||||
- name: Fetch dependencies from cache
|
||||
id: cache-yarn
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: "**/node_modules"
|
||||
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
yarn-build-
|
||||
|
||||
- name: Download release packages
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: release-packages
|
||||
path: ./release-packages
|
||||
|
||||
- name: Untar code-server release
|
||||
run: |
|
||||
cd release-packages
|
||||
tar -xzf code-server*-linux-amd64.tar.gz
|
||||
mv code-server*-linux-amd64 code-server-linux-amd64
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.cache-yarn.outputs.cache-hit != 'true'
|
||||
run: SKIP_SUBMODULE_DEPS=1 yarn --frozen-lockfile
|
||||
|
||||
- name: Install Playwright OS dependencies
|
||||
run: |
|
||||
./test/node_modules/.bin/playwright install-deps
|
||||
./test/node_modules/.bin/playwright install
|
||||
|
||||
- name: Cache Caddy
|
||||
uses: actions/cache@v2
|
||||
id: caddy-cache
|
||||
with:
|
||||
path: |
|
||||
~/.cache/caddy
|
||||
key: cache-caddy-2.5.2
|
||||
|
||||
- name: Install Caddy
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
if: steps.caddy-cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
gh release download v2.5.2 --repo caddyserver/caddy --pattern "caddy_2.5.2_linux_amd64.tar.gz"
|
||||
mkdir -p ~/.cache/caddy
|
||||
tar -xzf caddy_2.5.2_linux_amd64.tar.gz --directory ~/.cache/caddy
|
||||
|
||||
- name: Start Caddy
|
||||
run: sudo ~/.cache/caddy/caddy start --config ./ci/Caddyfile
|
||||
|
||||
- name: Run end-to-end tests
|
||||
run: yarn test:e2e:proxy
|
||||
|
||||
- name: Stop Caddy
|
||||
if: always()
|
||||
run: sudo ~/.cache/caddy/caddy stop --config ./ci/Caddyfile
|
||||
|
||||
- name: Upload test artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: failed-test-videos-proxy
|
||||
path: ./test/test-results
|
||||
|
||||
- name: Remove release packages and test artifacts
|
||||
run: rm -rf ./release-packages ./test/test-results
|
||||
|
||||
trivy-scan-repo:
|
||||
permissions:
|
||||
contents: read # for actions/checkout to fetch code
|
||||
@@ -517,7 +609,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Run Trivy vulnerability scanner in repo mode
|
||||
uses: aquasecurity/trivy-action@0105373003c89c494a3f436bd5efc57f3ac1ca20
|
||||
uses: aquasecurity/trivy-action@d63413b0a4a4482237085319f7f4a1ce99a8f2ac
|
||||
with:
|
||||
scan-type: "fs"
|
||||
scan-ref: "."
|
||||
|
||||
60
.github/workflows/docker.yaml
vendored
@@ -1,60 +0,0 @@
|
||||
name: Publish on Docker
|
||||
|
||||
on:
|
||||
# Shows the manual trigger in GitHub UI
|
||||
# helpful as a back-up in case the GitHub Actions Workflow fails
|
||||
workflow_dispatch:
|
||||
|
||||
release:
|
||||
types:
|
||||
- released
|
||||
|
||||
# Cancel in-progress runs for pull requests when developers push
|
||||
# additional changes, and serialize builds in branches.
|
||||
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
jobs:
|
||||
docker-images:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Login to GHCR
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Get version
|
||||
id: version
|
||||
run: echo "::set-output name=version::$(jq -r .version package.json)"
|
||||
|
||||
- name: Download release artifacts
|
||||
uses: robinraju/release-downloader@v1.4
|
||||
with:
|
||||
repository: "coder/code-server"
|
||||
tag: v${{ steps.version.outputs.version }}
|
||||
fileName: "*.deb"
|
||||
out-file-path: "release-packages"
|
||||
|
||||
- name: Publish to Docker
|
||||
run: yarn publish:docker
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
2
.github/workflows/docs-preview.yaml
vendored
@@ -4,6 +4,8 @@ on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "docs/**"
|
||||
|
||||
permissions:
|
||||
actions: none
|
||||
|
||||
2
.github/workflows/installer.yml
vendored
@@ -39,7 +39,7 @@ jobs:
|
||||
alpine:
|
||||
name: Test installer on Alpine
|
||||
runs-on: ubuntu-latest
|
||||
container: "alpine:3.14"
|
||||
container: "alpine:3.16"
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
|
||||
69
.github/workflows/npm-brew.yaml
vendored
@@ -1,69 +0,0 @@
|
||||
name: Publish on npm and brew
|
||||
|
||||
on:
|
||||
# Shows the manual trigger in GitHub UI
|
||||
# helpful as a back-up in case the GitHub Actions Workflow fails
|
||||
workflow_dispatch:
|
||||
|
||||
release:
|
||||
types: [released]
|
||||
|
||||
# Cancel in-progress runs for pull requests when developers push
|
||||
# additional changes, and serialize builds in branches.
|
||||
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
jobs:
|
||||
# NOTE: this job requires curl, jq and yarn
|
||||
# All of them are included in ubuntu-latest.
|
||||
npm:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Get version
|
||||
id: version
|
||||
run: echo "::set-output name=version::$(jq -r .version package.json)"
|
||||
|
||||
- name: Download artifact
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
id: download
|
||||
with:
|
||||
branch: release/v${{ steps.version.outputs.version }}
|
||||
workflow: ci.yaml
|
||||
workflow_conclusion: completed
|
||||
name: "npm-package"
|
||||
path: release-npm-package
|
||||
|
||||
- name: Publish npm package and tag with "latest"
|
||||
run: yarn publish:npm
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
NPM_ENVIRONMENT: "production"
|
||||
|
||||
homebrew:
|
||||
needs: npm
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Ensure things are up to date
|
||||
# Suggested by homebrew maintainers
|
||||
# https://github.com/Homebrew/discussions/discussions/1532#discussioncomment-782633
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
|
||||
- name: Checkout code-server
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Configure git
|
||||
run: |
|
||||
git config --global user.name cdrci
|
||||
git config --global user.email opensource@coder.com
|
||||
|
||||
- name: Bump code-server homebrew version
|
||||
env:
|
||||
HOMEBREW_GITHUB_API_TOKEN: ${{secrets.HOMEBREW_GITHUB_API_TOKEN}}
|
||||
run: ./ci/steps/brew-bump.sh
|
||||
160
.github/workflows/publish.yaml
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
name: Publish code-server
|
||||
|
||||
on:
|
||||
# Shows the manual trigger in GitHub UI
|
||||
# helpful as a back-up in case the GitHub Actions Workflow fails
|
||||
workflow_dispatch:
|
||||
|
||||
release:
|
||||
types: [released]
|
||||
|
||||
# Cancel in-progress runs for pull requests when developers push
|
||||
# additional changes, and serialize builds in branches.
|
||||
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
jobs:
|
||||
# NOTE: this job requires curl, jq and yarn
|
||||
# All of them are included in ubuntu-latest.
|
||||
npm:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code-server
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Get version
|
||||
id: version
|
||||
run: echo "::set-output name=version::$(jq -r .version package.json)"
|
||||
|
||||
- name: Download artifact
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
id: download
|
||||
with:
|
||||
branch: release/v${{ steps.version.outputs.version }}
|
||||
workflow: ci.yaml
|
||||
workflow_conclusion: completed
|
||||
name: "npm-package"
|
||||
path: release-npm-package
|
||||
|
||||
- name: Publish npm package and tag with "latest"
|
||||
run: yarn publish:npm
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
NPM_ENVIRONMENT: "production"
|
||||
|
||||
homebrew:
|
||||
needs: npm
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Ensure things are up to date
|
||||
# Suggested by homebrew maintainers
|
||||
# https://github.com/Homebrew/discussions/discussions/1532#discussioncomment-782633
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
|
||||
- name: Checkout code-server
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Configure git
|
||||
run: |
|
||||
git config --global user.name cdrci
|
||||
git config --global user.email opensource@coder.com
|
||||
|
||||
- name: Bump code-server homebrew version
|
||||
env:
|
||||
HOMEBREW_GITHUB_API_TOKEN: ${{secrets.HOMEBREW_GITHUB_API_TOKEN}}
|
||||
run: ./ci/steps/brew-bump.sh
|
||||
|
||||
aur:
|
||||
needs: npm
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }}
|
||||
steps:
|
||||
# We need to checkout code-server so we can get the version
|
||||
- name: Checkout code-server
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
path: "./code-server"
|
||||
|
||||
- name: Get code-server version
|
||||
id: version
|
||||
run: |
|
||||
pushd code-server
|
||||
echo "::set-output name=version::$(jq -r .version package.json)"
|
||||
popd
|
||||
|
||||
- name: Checkout code-server-aur repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: "cdrci/code-server-aur"
|
||||
token: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }}
|
||||
|
||||
- name: Configure git
|
||||
run: |
|
||||
git config --global user.name cdrci
|
||||
git config --global user.email opensource@coder.com
|
||||
|
||||
- name: Validate package
|
||||
uses: hapakaien/archlinux-package-action@v2
|
||||
with:
|
||||
pkgver: ${{ steps.version.outputs.version }}
|
||||
updpkgsums: true
|
||||
srcinfo: true
|
||||
|
||||
- name: Open PR
|
||||
# We need to git push -u otherwise gh will prompt
|
||||
# asking where to push the branch.
|
||||
run: |
|
||||
git checkout -b update-version-${{ steps.version.outputs.version }}
|
||||
git add .
|
||||
git commit -m "chore: updating version to ${{ steps.version.outputs.version }}"
|
||||
git push -u origin $(git branch --show)
|
||||
gh pr create --repo coder/code-server-aur --title "chore: bump version to ${{ steps.version.outputs.version }}" --body "PR opened by @$GITHUB_ACTOR" --assignee $GITHUB_ACTOR
|
||||
docker:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout code-server
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Login to GHCR
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Get version
|
||||
id: version
|
||||
run: echo "::set-output name=version::$(jq -r .version package.json)"
|
||||
|
||||
- name: Download release artifacts
|
||||
uses: robinraju/release-downloader@v1.5
|
||||
with:
|
||||
repository: "coder/code-server"
|
||||
tag: v${{ steps.version.outputs.version }}
|
||||
fileName: "*.deb"
|
||||
out-file-path: "release-packages"
|
||||
|
||||
- name: Publish to Docker
|
||||
run: yarn publish:docker
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
2
.github/workflows/scripts.yml
vendored
@@ -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.14"
|
||||
container: "alpine:3.16"
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
|
||||
2
.github/workflows/trivy-docker.yaml
vendored
@@ -51,7 +51,7 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Run Trivy vulnerability scanner in image mode
|
||||
uses: aquasecurity/trivy-action@0105373003c89c494a3f436bd5efc57f3ac1ca20
|
||||
uses: aquasecurity/trivy-action@d63413b0a4a4482237085319f7f4a1ce99a8f2ac
|
||||
with:
|
||||
image-ref: "docker.io/codercom/code-server:latest"
|
||||
ignore-unfixed: true
|
||||
|
||||
113
CHANGELOG.md
@@ -20,6 +20,119 @@ Code v99.99.999
|
||||
|
||||
-->
|
||||
|
||||
## [4.7.0](https://github.com/coder/code-server/releases/tag/v4.7.0) - 2022-09-09
|
||||
|
||||
Code v1.71.0
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated Code to 1.71.0
|
||||
|
||||
### Removed
|
||||
|
||||
- Dropped heartbeat patch because it was implemented upstream
|
||||
|
||||
### Fixed
|
||||
|
||||
- Add flags --unsafe-perm --legacy-peer-deps in `npm-postinstsall.sh` which ensures installing with npm works correctly
|
||||
|
||||
## [4.6.1](https://github.com/coder/code-server/releases/tag/v4.6.1) - 2022-09-31
|
||||
|
||||
Code v1.70.2
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated Code to 1.70.2
|
||||
- Updated `argon2` to 0.29.0 which should fix issues on FreeBSD
|
||||
- Updated docs to suggest using `npm` instead of `yarn`
|
||||
|
||||
### Removed
|
||||
|
||||
- Dropped database migration patch affected to 4.0.2 versions and earlier.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed preservation of `process.execArgv` which means you can pass `--prof` to profile code-server
|
||||
|
||||
## [4.6.0](https://github.com/coder/code-server/releases/tag/v4.6.0) - 2022-08-17
|
||||
|
||||
Code v1.70.1
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated Code to 1.70.1.
|
||||
|
||||
### Added
|
||||
|
||||
- Added a heartbeat to sockets. This should prevent them from getting closed by
|
||||
reverse proxy timeouts when idle like NGINX's default 60-second timeout.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed logout option appearing even when authentication is disabled.
|
||||
|
||||
## [4.5.2](https://github.com/coder/code-server/releases/tag/v4.5.2) - 2022-08-15
|
||||
|
||||
Code v1.68.1
|
||||
|
||||
### Security
|
||||
|
||||
- Fixed the proxy route not performing authentication. For example if you were
|
||||
to run a development HTTP server using `python -m http.server 8000` then it
|
||||
would be accessible at `my.domain/proxy/8000/` without any authentication.
|
||||
|
||||
If all of the following apply to you please update as soon as possible:
|
||||
|
||||
- You run code-server with the built-in password authentication.
|
||||
- You run unprotected HTTP services on ports accessible by code-server.
|
||||
|
||||
### Changed
|
||||
|
||||
- Invoking `code-server` in the integrated terminal will now use the script that
|
||||
comes with upstream Code. This means flags like `--wait` will be
|
||||
automatically supported now. However the upstream script only has the ability
|
||||
to interact with the running code-server and cannot spawn new instances. If
|
||||
you need to spawn a new code-server from the integrated terminal please
|
||||
specify the full path to code-server's usual script (for example
|
||||
`/usr/bin/code-server`).
|
||||
|
||||
### Fixed
|
||||
|
||||
- Invoking `code-server` in the integrated terminal will now work instead of
|
||||
erroring about not finding Node.
|
||||
|
||||
## [4.5.1](https://github.com/coder/code-server/releases/tag/v4.5.1) - 2022-07-18
|
||||
|
||||
Code v1.68.1
|
||||
|
||||
### Changed
|
||||
|
||||
- We now use `release/v<0.0.0>` for the release branch name so it doesn't
|
||||
conflict with the tag name
|
||||
- Added `.prettierignore` to ignore formatting files in `lib/vscode`
|
||||
|
||||
### Added
|
||||
|
||||
- Allow more comprehensive affinity config in Helm chart
|
||||
- Added custom message in Homebrew PR to make sure code-server maintainers are
|
||||
tagged
|
||||
- Allow setting `priorityClassName` via Helm chart
|
||||
- Added troubleshooting docs to `CONTRIBUTING.md`
|
||||
|
||||
### Fixed
|
||||
|
||||
- Removed default memory limit which was set via `NODE_OPTIONS`
|
||||
- Changed output in pipe to make it easier to debug code-server when doing live
|
||||
edits
|
||||
- Fixed display-language patch to use correct path which broke in 4.5.0
|
||||
- Fixed multiple code-server windows opening when using the code-server CLI in
|
||||
the Integrated Terminal
|
||||
- Fixed Integrated Terminal not working when web base was not the root path
|
||||
|
||||
### Security
|
||||
|
||||
- Updated `glob-parent` version in dependencies
|
||||
|
||||
## [4.5.0](https://github.com/coder/code-server/releases/tag/v4.5.0) - 2022-06-29
|
||||
|
||||
Code v1.68.1
|
||||
|
||||
15
ci/Caddyfile
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
admin localhost:4444
|
||||
}
|
||||
:8000 {
|
||||
@portLocalhost path_regexp port ^/([0-9]+)\/ide
|
||||
handle @portLocalhost {
|
||||
uri strip_prefix {re.port.1}/ide
|
||||
reverse_proxy localhost:{re.port.1}
|
||||
}
|
||||
|
||||
handle {
|
||||
respond "Bad hostname" 400
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,6 +18,8 @@ main() {
|
||||
VSCODE_SRC_PATH="lib/vscode"
|
||||
VSCODE_OUT_PATH="$RELEASE_PATH/lib/vscode"
|
||||
|
||||
create_shrinkwraps
|
||||
|
||||
mkdir -p "$RELEASE_PATH"
|
||||
|
||||
bundle_code_server
|
||||
@@ -55,15 +57,6 @@ bundle_code_server() {
|
||||
EOF
|
||||
) > "$RELEASE_PATH/package.json"
|
||||
rsync yarn.lock "$RELEASE_PATH"
|
||||
|
||||
# To ensure deterministic dependency versions (even when code-server is installed with NPM), we seed
|
||||
# an npm-shrinkwrap file from our yarn lockfile and the current node-modules installed.
|
||||
synp --source-file yarn.lock
|
||||
npm shrinkwrap
|
||||
# HACK@edvincent: The shrinkwrap file will contain the devDependencies, which by default
|
||||
# are installed if present in a lockfile. To avoid every user having to specify --production
|
||||
# to skip them, we carefully remove them from the shrinkwrap file.
|
||||
json -f npm-shrinkwrap.json -I -e "Object.keys(this.dependencies).forEach(dependency => { if (this.dependencies[dependency].dev) { delete this.dependencies[dependency] } } )"
|
||||
mv npm-shrinkwrap.json "$RELEASE_PATH"
|
||||
|
||||
rsync ci/build/npm-postinstall.sh "$RELEASE_PATH/postinstall.sh"
|
||||
@@ -105,15 +98,44 @@ bundle_vscode() {
|
||||
"$VSCODE_SRC_PATH/package.json" > "$VSCODE_OUT_PATH/package.json"
|
||||
|
||||
rsync "$VSCODE_SRC_PATH/remote/yarn.lock" "$VSCODE_OUT_PATH/yarn.lock"
|
||||
mv "$VSCODE_SRC_PATH/remote/npm-shrinkwrap.json" "$VSCODE_OUT_PATH/npm-shrinkwrap.json"
|
||||
|
||||
# Include global extension dependencies as well.
|
||||
rsync "$VSCODE_SRC_PATH/extensions/package.json" "$VSCODE_OUT_PATH/extensions/package.json"
|
||||
rsync "$VSCODE_SRC_PATH/extensions/yarn.lock" "$VSCODE_OUT_PATH/extensions/yarn.lock"
|
||||
mv "$VSCODE_SRC_PATH/extensions/npm-shrinkwrap.json" "$VSCODE_OUT_PATH/extensions/npm-shrinkwrap.json"
|
||||
rsync "$VSCODE_SRC_PATH/extensions/postinstall.mjs" "$VSCODE_OUT_PATH/extensions/postinstall.mjs"
|
||||
}
|
||||
|
||||
pushd "$VSCODE_OUT_PATH"
|
||||
symlink_asar
|
||||
create_shrinkwraps() {
|
||||
# yarn.lock or package-lock.json files (used to ensure deterministic versions of dependencies) are
|
||||
# not packaged when publishing to the NPM registry.
|
||||
# To ensure deterministic dependency versions (even when code-server is installed with NPM), we create
|
||||
# an npm-shrinkwrap.json file from the currently installed node_modules. This ensures the versions used
|
||||
# from development (that the yarn.lock guarantees) are also the ones installed by end-users.
|
||||
# These will include devDependencies, but those will be ignored when installing globally (for code-server), and
|
||||
# because we use --omit=dev when installing vscode.
|
||||
|
||||
# We first generate the shrinkwrap file for code-server itself - which is the current directory
|
||||
create_shrinkwrap_keeping_yarn_lock
|
||||
|
||||
# Then the shrinkwrap files for the bundled VSCode
|
||||
pushd "$VSCODE_SRC_PATH/remote/"
|
||||
create_shrinkwrap_keeping_yarn_lock
|
||||
popd
|
||||
|
||||
pushd "$VSCODE_SRC_PATH/extensions/"
|
||||
create_shrinkwrap_keeping_yarn_lock
|
||||
popd
|
||||
}
|
||||
|
||||
create_shrinkwrap_keeping_yarn_lock() {
|
||||
# HACK@edvincent: Generating a shrinkwrap alters the yarn.lock which we don't want (with NPM URLs rather than the Yarn URLs)
|
||||
# But to generate a valid shrinkwrap, it has to exist... So we copy it to then restore it
|
||||
cp yarn.lock yarn.lock.temp
|
||||
npm shrinkwrap
|
||||
cp yarn.lock.temp yarn.lock
|
||||
rm yarn.lock.temp
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -27,8 +27,9 @@ main() {
|
||||
ln -s "./bin/code-server" "$RELEASE_PATH/code-server"
|
||||
ln -s "./lib/node" "$RELEASE_PATH/node"
|
||||
|
||||
cd "$RELEASE_PATH"
|
||||
yarn --production --frozen-lockfile
|
||||
pushd "$RELEASE_PATH"
|
||||
npm install --unsafe-perm --omit=dev
|
||||
popd
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -6,12 +6,38 @@ set -euo pipefail
|
||||
# MINIFY controls whether a minified version of vscode is built.
|
||||
MINIFY=${MINIFY-true}
|
||||
|
||||
delete-bin-script() {
|
||||
rm -f "lib/vscode-reh-web-linux-x64/bin/$1"
|
||||
}
|
||||
|
||||
copy-bin-script() {
|
||||
local script="$1"
|
||||
local dest="lib/vscode-reh-web-linux-x64/bin/$script"
|
||||
cp "lib/vscode/resources/server/bin/$script" "$dest"
|
||||
sed -i.bak "s/@@VERSION@@/$(vscode_version)/g" "$dest"
|
||||
sed -i.bak "s/@@COMMIT@@/$VSCODE_DISTRO_COMMIT/g" "$dest"
|
||||
sed -i.bak "s/@@APPNAME@@/code-server/g" "$dest"
|
||||
|
||||
# Fix Node path on Darwin and Linux.
|
||||
# We do not want expansion here; this text should make it to the file as-is.
|
||||
# shellcheck disable=SC2016
|
||||
sed -i.bak 's/^ROOT=\(.*\)$/VSROOT=\1\nROOT="$(dirname "$(dirname "$VSROOT")")"/g' "$dest"
|
||||
sed -i.bak 's/ROOT\/out/VSROOT\/out/g' "$dest"
|
||||
|
||||
# Fix Node path on Windows.
|
||||
sed -i.bak 's/^set ROOT_DIR=\(.*\)$/set ROOT_DIR=%~dp0..\\..\\..\\..\r\nset VSROOT_DIR=\1/g' "$dest"
|
||||
sed -i.bak 's/%ROOT_DIR%\\out/%VSROOT_DIR%\\out/g' "$dest"
|
||||
|
||||
chmod +x "$dest"
|
||||
rm "$dest.bak"
|
||||
}
|
||||
|
||||
main() {
|
||||
cd "$(dirname "${0}")/../.."
|
||||
|
||||
source ./ci/lib.sh
|
||||
|
||||
cd lib/vscode
|
||||
pushd lib/vscode
|
||||
|
||||
# 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
|
||||
@@ -58,13 +84,31 @@ main() {
|
||||
EOF
|
||||
) > product.json
|
||||
|
||||
# Any platform works since we have our own packaging step (for now).
|
||||
# Any platform here works since we will do our own packaging. We have to do
|
||||
# this because we have an NPM package that could be installed on any platform.
|
||||
# The correct platform dependencies and scripts will be installed as part of
|
||||
# the post-install during `npm install` or when building a standalone release.
|
||||
yarn gulp "vscode-reh-web-linux-x64${MINIFY:+-min}"
|
||||
|
||||
# Reset so if you develop after building you will not be stuck with the wrong
|
||||
# commit (the dev client will use `oss-dev` but the dev server will still use
|
||||
# product.json which will have `stable-$commit`).
|
||||
git checkout product.json
|
||||
|
||||
popd
|
||||
|
||||
# These provide a `code-server` command in the integrated terminal to open
|
||||
# files in the current instance.
|
||||
delete-bin-script remote-cli/code-server
|
||||
copy-bin-script remote-cli/code-darwin.sh
|
||||
copy-bin-script remote-cli/code-linux.sh
|
||||
copy-bin-script remote-cli/code.cmd
|
||||
|
||||
# These provide a way for terminal applications to open browser windows.
|
||||
delete-bin-script helpers/browser.sh
|
||||
copy-bin-script helpers/browser-darwin.sh
|
||||
copy-bin-script helpers/browser-linux.sh
|
||||
copy-bin-script helpers/browser.cmd
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -1,23 +1,69 @@
|
||||
#!/usr/bin/env sh
|
||||
set -eu
|
||||
|
||||
# Copied from arch() in ci/lib.sh.
|
||||
detect_arch() {
|
||||
case "$(uname -m)" in
|
||||
aarch64)
|
||||
echo arm64
|
||||
;;
|
||||
x86_64 | amd64)
|
||||
echo amd64
|
||||
;;
|
||||
*)
|
||||
# This will cause the download to fail, but is intentional
|
||||
uname -m
|
||||
;;
|
||||
# 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
|
||||
cygwin* | mingw*) osname="windows" ;;
|
||||
esac
|
||||
echo "$osname"
|
||||
}
|
||||
|
||||
# Create a symlink at $2 pointing to $1 on any platform. Anything that
|
||||
# currently exists at $2 will be deleted.
|
||||
symlink() {
|
||||
source="$1"
|
||||
dest="$2"
|
||||
rm -rf "$dest"
|
||||
case $OS in
|
||||
windows) mklink /J "$dest" "$source" ;;
|
||||
*) ln -s "$source" "$dest" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
ARCH="${NPM_CONFIG_ARCH:-$(detect_arch)}"
|
||||
# VS Code bundles some modules into an asar which is an archive format that
|
||||
# works like tar. It then seems to get unpacked into node_modules.asar.
|
||||
#
|
||||
# I don't know why they do this but all the dependencies they bundle already
|
||||
# exist in node_modules so just symlink it. We have to do this since not only
|
||||
# Code itself but also extensions will look specifically in this directory for
|
||||
# files (like the ripgrep binary or the oniguruma wasm).
|
||||
symlink_asar() {
|
||||
symlink node_modules node_modules.asar
|
||||
}
|
||||
|
||||
# Make a symlink at bin/$1/$3 pointing to the platform-specific version of the
|
||||
# script in $2. The extension of the link will be .cmd for Windows otherwise it
|
||||
# will be whatever is in $4 (or no extension if $4 is not set).
|
||||
symlink_bin_script() {
|
||||
oldpwd="$(pwd)"
|
||||
cd "bin/$1"
|
||||
source="$2"
|
||||
dest="$3"
|
||||
ext="${4-}"
|
||||
case $OS in
|
||||
windows) symlink "$source.cmd" "$dest.cmd" ;;
|
||||
darwin | macos) symlink "$source-darwin.sh" "$dest$ext" ;;
|
||||
*) symlink "$source-linux.sh" "$dest$ext" ;;
|
||||
esac
|
||||
cd "$oldpwd"
|
||||
}
|
||||
|
||||
ARCH="${NPM_CONFIG_ARCH:-$(arch)}"
|
||||
OS="$(os)"
|
||||
|
||||
# This is due to an upstream issue with RHEL7/CentOS 7 comptability with node-argon2
|
||||
# See: https://github.com/cdr/code-server/pull/3422#pullrequestreview-677765057
|
||||
export npm_config_build_from_source=true
|
||||
@@ -56,8 +102,6 @@ main() {
|
||||
;;
|
||||
esac
|
||||
|
||||
OS="$(uname | tr '[:upper:]' '[:lower:]')"
|
||||
|
||||
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
|
||||
@@ -66,7 +110,7 @@ main() {
|
||||
echo "Failed to download cloud agent; --link will not work"
|
||||
fi
|
||||
|
||||
if ! vscode_yarn; then
|
||||
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"
|
||||
exit 1
|
||||
@@ -79,25 +123,47 @@ main() {
|
||||
fi
|
||||
}
|
||||
|
||||
# This is a copy of symlink_asar in ../lib.sh. Look there for details.
|
||||
symlink_asar() {
|
||||
rm -rf node_modules.asar
|
||||
if [ "${WINDIR-}" ]; then
|
||||
mklink /J node_modules.asar node_modules
|
||||
else
|
||||
ln -s node_modules node_modules.asar
|
||||
fi
|
||||
install_with_yarn_or_npm() {
|
||||
# NOTE@edvincent: We want to keep using the package manager that the end-user was using to install the package.
|
||||
# This also ensures that when *we* run `yarn` in the development process, the yarn.lock file is used.
|
||||
case "${npm_config_user_agent-}" in
|
||||
yarn*)
|
||||
if [ -f "yarn.lock" ]; then
|
||||
yarn --production --frozen-lockfile --no-default-rc
|
||||
else
|
||||
echo "yarn.lock file not present, not running in development mode. use npm to install code-server!"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
npm*)
|
||||
if [ -f "yarn.lock" ]; then
|
||||
echo "yarn.lock file present, running in development mode. use yarn to install code-server!"
|
||||
exit 1
|
||||
else
|
||||
# HACK: NPM's use of semver doesn't like resolving some peerDependencies that vscode (upstream) brings in the form of pre-releases.
|
||||
# The legacy behavior doesn't complain about pre-releases being used, falling back to that for now.
|
||||
# See https://github.com//pull/5071
|
||||
npm install --unsafe-perm --legacy-peer-deps --omit=dev
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Could not determine which package manager is being used to install code-server"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
vscode_yarn() {
|
||||
vscode_install() {
|
||||
echo 'Installing Code dependencies...'
|
||||
cd lib/vscode
|
||||
yarn --production --frozen-lockfile --no-default-rc
|
||||
install_with_yarn_or_npm
|
||||
|
||||
symlink_asar
|
||||
symlink_bin_script remote-cli code code-server
|
||||
symlink_bin_script helpers browser browser .sh
|
||||
|
||||
cd extensions
|
||||
yarn --production --frozen-lockfile
|
||||
install_with_yarn_or_npm
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
CHECKMARK="\xE2\x9C\x94"
|
||||
DASH="-"
|
||||
|
||||
main() {
|
||||
if [ "${DRY_RUN-}" = 1 ]; then
|
||||
echo "Performing a dry run..."
|
||||
@@ -76,11 +79,12 @@ main() {
|
||||
CODE_SERVER_CURRENT_VERSION=$(node -pe "require('./package.json').version")
|
||||
# Ask which version we should update to
|
||||
# In the future, we'll automate this and determine the latest version automatically
|
||||
echo "Current version: ${CODE_SERVER_CURRENT_VERSION}"
|
||||
echo -e "$DASH Current version: ${CODE_SERVER_CURRENT_VERSION}"
|
||||
# The $'\n' adds a line break. See: https://stackoverflow.com/a/39581815/3015595
|
||||
read -r -p "What version of code-server do you want to update to?"$'\n' CODE_SERVER_VERSION_TO_UPDATE
|
||||
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"
|
||||
|
||||
echo -e "Great! We'll prep a PR for updating to $CODE_SERVER_VERSION_TO_UPDATE\n"
|
||||
$CMD rg -g '!yarn.lock' -g '!*.svg' -g '!CHANGELOG.md' -g '!lib/vscode/**' --files-with-matches --fixed-strings "${CODE_SERVER_CURRENT_VERSION}" | $CMD xargs sd "$CODE_SERVER_CURRENT_VERSION" "$CODE_SERVER_VERSION_TO_UPDATE"
|
||||
|
||||
$CMD git commit --no-verify -am "chore(release): bump version to $CODE_SERVER_VERSION_TO_UPDATE"
|
||||
@@ -90,7 +94,7 @@ main() {
|
||||
|
||||
echo -e "\nOpening a draft PR on GitHub"
|
||||
# To read about these flags, visit the docs: https://cli.github.com/manual/gh_pr_create
|
||||
$CMD gh pr create --base main --title "release: $CODE_SERVER_VERSION_TO_UPDATE" --body "$RELEASE_TEMPLATE_STRING" --reviewer @coder/code-server-reviewers --repo coder/code-server --draft --assignee "@me"
|
||||
$CMD gh pr create --base main --title "release: $CODE_SERVER_VERSION_TO_UPDATE" --body "$RELEASE_TEMPLATE_STRING" --reviewer @coder/code-server --repo coder/code-server --draft --assignee "@me"
|
||||
|
||||
# Open PR in browser
|
||||
$CMD gh pr view --web
|
||||
|
||||
@@ -15,9 +15,9 @@ type: application
|
||||
# This is the chart version. This version number should be incremented each time you make changes
|
||||
# to the chart and its templates, including the app version.
|
||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||
version: 2.6.0
|
||||
version: 3.2.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.5.0
|
||||
appVersion: 4.7.0
|
||||
|
||||
@@ -62,6 +62,17 @@ spec:
|
||||
securityContext:
|
||||
runAsUser: {{ .Values.securityContext.runAsUser }}
|
||||
{{- end }}
|
||||
{{- if .Values.lifecycle.enabled }}
|
||||
lifecycle:
|
||||
{{- if .Values.lifecycle.postStart }}
|
||||
postStart:
|
||||
{{ toYaml .Values.lifecycle.postStart | nindent 14 }}
|
||||
{{- end }}
|
||||
{{- if .Values.lifecycle.preStop }}
|
||||
preStop:
|
||||
{{ toYaml .Values.lifecycle.preStop | nindent 14 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
env:
|
||||
{{- if .Values.extraVars }}
|
||||
{{ toYaml .Values.extraVars | indent 10 }}
|
||||
|
||||
@@ -6,7 +6,7 @@ replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: codercom/code-server
|
||||
tag: '4.5.0'
|
||||
tag: '4.6.1'
|
||||
pullPolicy: Always
|
||||
|
||||
# Specifies one or more secrets to be used when pulling images from a
|
||||
@@ -127,6 +127,15 @@ persistence:
|
||||
# existingClaim: ""
|
||||
# hostPath: /data
|
||||
|
||||
lifecycle:
|
||||
enabled: false
|
||||
# postStart:
|
||||
# exec:
|
||||
# command:
|
||||
# - /bin/bash
|
||||
# - -c
|
||||
# - curl -s -L SOME_SCRIPT | bash
|
||||
|
||||
## Enable an Specify container in extraContainers.
|
||||
## This is meant to allow adding code-server dependencies, like docker-dind.
|
||||
extraContainers: |
|
||||
@@ -147,6 +156,25 @@ extraContainers: |
|
||||
# - name: DOCKER_DRIVER
|
||||
# value: "overlay2"
|
||||
|
||||
extraInitContainers: |
|
||||
# - name: customization
|
||||
# image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
|
||||
# imagePullPolicy: IfNotPresent
|
||||
# env:
|
||||
# - name: SERVICE_URL
|
||||
# value: https://open-vsx.org/vscode/gallery
|
||||
# - name: ITEM_URL
|
||||
# value: https://open-vsx.org/vscode/item
|
||||
# command:
|
||||
# - sh
|
||||
# - -c
|
||||
# - |
|
||||
# code-server --install-extension ms-python.python
|
||||
# code-server --install-extension golang.Go
|
||||
# volumeMounts:
|
||||
# - name: data
|
||||
# mountPath: /home/coder
|
||||
|
||||
## Additional code-server secret mounts
|
||||
extraSecretMounts: []
|
||||
# - name: secret-files
|
||||
|
||||
61
ci/lib.sh
@@ -18,35 +18,30 @@ vscode_version() {
|
||||
}
|
||||
|
||||
os() {
|
||||
local os
|
||||
os=$(uname | tr '[:upper:]' '[:lower:]')
|
||||
if [[ $os == "linux" ]]; then
|
||||
# Alpine's ldd doesn't have a version flag but if you use an invalid flag
|
||||
# (like --version) it outputs the version to stderr and exits with 1.
|
||||
local ldd_output
|
||||
ldd_output=$(ldd --version 2>&1 || true)
|
||||
if echo "$ldd_output" | grep -iq musl; then
|
||||
os="alpine"
|
||||
fi
|
||||
elif [[ $os == "darwin" ]]; then
|
||||
os="macos"
|
||||
fi
|
||||
echo "$os"
|
||||
osname=$(uname | tr '[:upper:]' '[:lower:]')
|
||||
case $osname in
|
||||
linux)
|
||||
# Alpine's ldd doesn't have a version flag but if you use an invalid flag
|
||||
# (like --version) it outputs the version to stderr and exits with 1.
|
||||
# TODO: Better to check /etc/os-release; see ../install.sh.
|
||||
ldd_output=$(ldd --version 2>&1 || true)
|
||||
if echo "$ldd_output" | grep -iq musl; then
|
||||
osname="alpine"
|
||||
fi
|
||||
;;
|
||||
darwin) osname="macos" ;;
|
||||
cygwin* | mingw*) osname="windows" ;;
|
||||
esac
|
||||
echo "$osname"
|
||||
}
|
||||
|
||||
arch() {
|
||||
cpu="$(uname -m)"
|
||||
case "$cpu" in
|
||||
aarch64)
|
||||
echo arm64
|
||||
;;
|
||||
x86_64 | amd64)
|
||||
echo amd64
|
||||
;;
|
||||
*)
|
||||
echo "$cpu"
|
||||
;;
|
||||
aarch64) cpu=arm64 ;;
|
||||
x86_64) cpu=amd64 ;;
|
||||
esac
|
||||
echo "$cpu"
|
||||
}
|
||||
|
||||
# Grabs the most recent ci.yaml github workflow run that was triggered from the
|
||||
@@ -57,7 +52,7 @@ arch() {
|
||||
# https://developer.github.com/v3/actions/workflow-runs/#list-workflow-runs
|
||||
get_artifacts_url() {
|
||||
local artifacts_url
|
||||
local version_branch="v$VERSION"
|
||||
local version_branch="release/v$VERSION"
|
||||
local workflow_runs_url="repos/:owner/:repo/actions/workflows/ci.yaml/runs?event=pull_request&branch=$version_branch"
|
||||
artifacts_url=$(gh api "$workflow_runs_url" | jq -r ".workflow_runs[] | select(.head_branch == \"$version_branch\") | .artifacts_url" | head -n 1)
|
||||
if [[ -z "$artifacts_url" ]]; then
|
||||
@@ -104,21 +99,3 @@ export OS
|
||||
# RELEASE_PATH is the destination directory for the release from the root.
|
||||
# Defaults to release
|
||||
RELEASE_PATH="${RELEASE_PATH-release}"
|
||||
|
||||
# VS Code bundles some modules into an asar which is an archive format that
|
||||
# works like tar. It then seems to get unpacked into node_modules.asar.
|
||||
#
|
||||
# I don't know why they do this but all the dependencies they bundle already
|
||||
# exist in node_modules so just symlink it. We have to do this since not only VS
|
||||
# Code itself but also extensions will look specifically in this directory for
|
||||
# files (like the ripgrep binary or the oniguruma wasm).
|
||||
symlink_asar() {
|
||||
rm -rf node_modules.asar
|
||||
if [ "${WINDIR-}" ]; then
|
||||
# mklink takes the link name first.
|
||||
mklink /J node_modules.asar node_modules
|
||||
else
|
||||
# ln takes the link name second.
|
||||
ln -s node_modules node_modules.asar
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -65,7 +65,8 @@ main() {
|
||||
# "production" - this means we tag with `latest` (default), allowing
|
||||
# a developer to install this version with `yarn add code-server@latest`
|
||||
if ! is_env_var_set "NPM_ENVIRONMENT"; then
|
||||
echo "NPM_ENVIRONMENT is not set. Determining in script based on GITHUB environment variables."
|
||||
echo "NPM_ENVIRONMENT is not set."
|
||||
echo "Determining in script based on GITHUB environment variables."
|
||||
|
||||
if [[ "$GITHUB_EVENT_NAME" == 'push' && "$GITHUB_REF" == 'refs/heads/main' ]]; then
|
||||
NPM_ENVIRONMENT="staging"
|
||||
@@ -73,7 +74,6 @@ main() {
|
||||
NPM_ENVIRONMENT="development"
|
||||
fi
|
||||
|
||||
echo "Using npm environment: $NPM_ENVIRONMENT"
|
||||
fi
|
||||
|
||||
# NOTE@jsjoeio - this script assumes we have the artifact downloaded on disk
|
||||
@@ -81,10 +81,6 @@ main() {
|
||||
# https://github.com/actions/upload-artifact/issues/38
|
||||
tar -xzf release-npm-package/package.tar.gz
|
||||
|
||||
# Ignore symlink when publishing npm package
|
||||
# See: https://github.com/coder/code-server/pull/3935
|
||||
echo "node_modules.asar" > release/.npmignore
|
||||
|
||||
# We use this to set the name of the package in the
|
||||
# package.json
|
||||
PACKAGE_NAME="code-server"
|
||||
@@ -100,9 +96,6 @@ main() {
|
||||
NPM_TAG="latest"
|
||||
else
|
||||
COMMIT_SHA="$GITHUB_SHA"
|
||||
echo "Not a production environment"
|
||||
echo "Found environment: $NPM_ENVIRONMENT"
|
||||
echo "Manually bumping npm version..."
|
||||
|
||||
if [[ "$NPM_ENVIRONMENT" == "staging" ]]; then
|
||||
NPM_VERSION="$VERSION-beta-$COMMIT_SHA"
|
||||
@@ -121,8 +114,10 @@ main() {
|
||||
NPM_TAG="$PR_NUMBER"
|
||||
fi
|
||||
|
||||
echo "using tag: $NPM_TAG"
|
||||
echo "using package name: $PACKAGE_NAME"
|
||||
echo "- tag: $NPM_TAG"
|
||||
echo "- version: $NPM_VERSION"
|
||||
echo "- package name: $PACKAGE_NAME"
|
||||
echo "- npm environment: $NPM_ENVIRONMENT"
|
||||
|
||||
# We modify the version in the package.json
|
||||
# to be the current version + the PR number + commit SHA
|
||||
@@ -144,13 +139,13 @@ main() {
|
||||
popd
|
||||
fi
|
||||
|
||||
# NOTE@jsjoeio
|
||||
# We need to make sure we haven't already published the version.
|
||||
# This is because npm view won't exit with non-zero so we have
|
||||
# to check the output.
|
||||
# If we get error, continue with script because we want to publish
|
||||
# If version is valid, we check if we're publishing the same one
|
||||
local hasVersion
|
||||
hasVersion=$(npm view "code-server@$NPM_VERSION" version)
|
||||
if [[ $hasVersion == "$NPM_VERSION" ]]; then
|
||||
echo "$NPM_VERSION is already published"
|
||||
if hasVersion=$(npm view "$PACKAGE_NAME@$NPM_VERSION" version 2> /dev/null) && [[ $hasVersion == "$NPM_VERSION" ]]; then
|
||||
echo "$NPM_VERSION is already published under $PACKAGE_NAME"
|
||||
return
|
||||
fi
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ Run your build:
|
||||
|
||||
```shell
|
||||
cd release
|
||||
yarn --production # Skip if you used KEEP_MODULES=1
|
||||
npm install --omit=dev # Skip if you used KEEP_MODULES=1
|
||||
# Runs the built JavaScript with Node.
|
||||
node .
|
||||
```
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
- [Workflow](#workflow)
|
||||
- [Milestones](#milestones)
|
||||
- [Triage](#triage)
|
||||
- [Project boards](#project-boards)
|
||||
- [Versioning](#versioning)
|
||||
- [Pull requests](#pull-requests)
|
||||
- [Merge strategies](#merge-strategies)
|
||||
@@ -42,7 +41,7 @@ Occasionally, other Coder employees may step in time to time to assist with code
|
||||
|
||||
To onboard a new maintainer to the project, please make sure to do the following:
|
||||
|
||||
- [ ] Add to [coder/code-server-reviewers](https://github.com/orgs/coder/teams/code-server-reviewers)
|
||||
- [ ] Add to [coder/code-server](https://github.com/orgs/coder/teams/code-server)
|
||||
- [ ] Add as Admin under [Repository Settings > Access](https://github.com/coder/code-server/settings/access)
|
||||
- [ ] Add to [npm Coder org](https://www.npmjs.com/org/coder)
|
||||
- [ ] Add as [AUR maintainer](https://aur.archlinux.org/packages/code-server/) (talk to Colin)
|
||||
@@ -72,7 +71,7 @@ Here are the milestones we use and how we use them:
|
||||
- "On Deck" -> Work under consideration for upcoming milestones.
|
||||
- "Backlog Candidates" -> Work that is not yet accepted for the backlog. We wait
|
||||
for the community to weigh in.
|
||||
- "<0.0.0>" -> Work to be done for a specific version.
|
||||
- "<Month>" -> Work to be done for said month.
|
||||
|
||||
With this flow, any un-assigned issues are essentially in triage state. Once
|
||||
triaged, issues are either "Backlog" or "Backlog Candidates". They will
|
||||
@@ -91,19 +90,6 @@ We use the following process for triaging GitHub issues:
|
||||
2. If not urgent, add to "Backlog"
|
||||
3. Otherwise, add to "Backlog Candidate" for future consideration
|
||||
|
||||
### Project boards
|
||||
|
||||
We use project boards for projects or goals that span multiple milestones.
|
||||
|
||||
Think of this as a place to put miscellaneous things (like testing, clean up
|
||||
stuff, etc). As a maintainer, random tasks may come up here and there. The
|
||||
project boards give you places to add temporary notes before opening a new
|
||||
issue. Given that our release milestones function off of issues, we believe
|
||||
tasks should have dedicated issues.
|
||||
|
||||
Project boards also give us a way to separate the issue triage from
|
||||
bigger-picture, long-term work.
|
||||
|
||||
## Versioning
|
||||
|
||||
`<major.minor.patch>`
|
||||
@@ -175,7 +161,7 @@ If you're the current release manager, follow these steps:
|
||||
1. Bump chart version in `Chart.yaml`.
|
||||
1. Summarize the major changes in the release notes and link to the relevant
|
||||
issues.
|
||||
1. Change the @ to target the version branch. Example: `v3.9.0 @ Target: v3.9.0`
|
||||
1. Change the @ to target the version branch. Example: `v3.9.0 @ Target: release/v3.9.0`
|
||||
1. Wait for the `npm-package`, `release-packages` and `release-images` artifacts
|
||||
to build.
|
||||
1. Run `yarn release:github-assets` to download the `release-packages` artifact.
|
||||
|
||||
@@ -14,20 +14,16 @@ access it in the browser.
|
||||
- Preserve battery life when you're on the go; all intensive tasks run on your
|
||||
server
|
||||
|
||||
> **Note**
|
||||
> To manage multiple IDEs, workspaces, and teams, see
|
||||
> our new project: [coder/coder](http://cdr.co/coder-github)
|
||||
|
||||
## Requirements
|
||||
|
||||
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 CPUs
|
||||
**TL;DR:** Linux machine with WebSockets enabled, 1 GB RAM, and 2 vCPUs
|
||||
|
||||
## Getting started
|
||||
|
||||
There are three ways to get started:
|
||||
There are four ways to get started:
|
||||
|
||||
1. Using the [install
|
||||
script](https://github.com/coder/code-server/blob/main/install.sh), which
|
||||
@@ -35,7 +31,8 @@ There are three ways to get started:
|
||||
possible.
|
||||
2. Manually [installing
|
||||
code-server](https://coder.com/docs/code-server/latest/install)
|
||||
3. Using our one-click buttons and guides to [deploy code-server to a cloud
|
||||
3. Deploy code-server to your team with [coder/coder](https://cdr.co/coder-github)
|
||||
4. Using our one-click buttons and guides to [deploy code-server to a cloud
|
||||
provider](https://github.com/coder/deploy-code-server) ⚡
|
||||
|
||||
If you use the install script, you can preview what occurs during the install
|
||||
@@ -54,6 +51,9 @@ curl -fsSL https://code-server.dev/install.sh | sh
|
||||
When done, the install script prints out instructions for running and starting
|
||||
code-server.
|
||||
|
||||
> **Note**
|
||||
> To manage code-server for a team on your infrastructure, see: [coder/coder](https://cdr.co/coder-github)
|
||||
|
||||
We also have an in-depth [setup and
|
||||
configuration](https://coder.com/docs/code-server/latest/guide) guide.
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
1. Install UserLAnd from [Google Play](https://play.google.com/store/apps/details?id=tech.ula&hl=en_US&gl=US)
|
||||
2. Install an Ubuntu VM
|
||||
3. Start app
|
||||
4. Install Node.js, `curl` and `yarn` using `sudo apt install nodejs npm yarn curl -y`
|
||||
4. Install Node.js and `curl` using `sudo apt install nodejs npm curl -y`
|
||||
5. Install `nvm`:
|
||||
|
||||
```shell
|
||||
@@ -18,6 +18,6 @@ nvm install 16
|
||||
nvm use 16
|
||||
```
|
||||
|
||||
8. Install code-server globally on device with: `npm i -g code-server`
|
||||
8. Install code-server globally on device with: `npm install --global code-server --unsafe-perm`
|
||||
9. Run code-server with `code-server`
|
||||
10. Access on localhost:8080 in your browser
|
||||
|
||||
1
docs/assets/images/icons/collab.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="20" height="20" viewBox="0 0 20 20"> <path d="M12.2 13.4357L9.5 11.4357C10.4 10.7357 11 9.7357 11 8.5357V7.7357C11 5.8357 9.6 4.1357 7.7 4.0357C5.7 3.9357 4 5.5357 4 7.5357V8.5357C4 9.7357 4.6 10.7357 5.5 11.4357L2.8 13.5357C2.3 13.9357 2 14.5357 2 15.1357V17.0357C2 17.6357 2.4 18.0357 3 18.0357H12C12.6 18.0357 13 17.6357 13 17.0357V15.0357C13 14.4357 12.7 13.8357 12.2 13.4357Z"/> <path d="M17.1 8.43436L15.3 7.23436C15.7 6.83436 16 6.23436 16 5.53436V4.63436C16 3.43436 15.1 2.23436 13.9 2.03436C12.7 1.83436 11.7 2.53436 11.2 3.43436C12.3 4.43436 13 5.83436 13 7.43436V8.43436C13 9.33436 12.8 10.2344 12.4 10.9344C12.4 10.9344 13.6 11.8344 13.6 11.9344H17C17.6 11.9344 18 11.5344 18 10.9344V10.1344C18 9.43436 17.7 8.83436 17.1 8.43436Z"/></svg>
|
||||
|
After Width: | Height: | Size: 854 B |
1
docs/assets/images/icons/contributing.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="20" height="20" fill="none" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M5 2.5V12.5" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M15 7.5C16.3807 7.5 17.5 6.38071 17.5 5C17.5 3.61929 16.3807 2.5 15 2.5C13.6193 2.5 12.5 3.61929 12.5 5C12.5 6.38071 13.6193 7.5 15 7.5Z" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M5 17.5C6.38071 17.5 7.5 16.3807 7.5 15C7.5 13.6193 6.38071 12.5 5 12.5C3.61929 12.5 2.5 13.6193 2.5 15C2.5 16.3807 3.61929 17.5 5 17.5Z" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M15 7.5C15 9.48912 14.2098 11.3968 12.8033 12.8033C11.3968 14.2098 9.48912 15 7.5 15" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
|
After Width: | Height: | Size: 909 B |
1
docs/assets/images/icons/faq.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"><path d="M10.0001 18.3333C14.6025 18.3333 18.3334 14.6024 18.3334 10C18.3334 5.39762 14.6025 1.66666 10.0001 1.66666C5.39771 1.66666 1.66675 5.39762 1.66675 10C1.66675 14.6024 5.39771 18.3333 10.0001 18.3333Z" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M7.57495 7.5C7.77087 6.94306 8.15758 6.47342 8.66658 6.17428C9.17558 5.87513 9.77403 5.76578 10.3559 5.86559C10.9378 5.96541 11.4656 6.26794 11.8458 6.71961C12.2261 7.17128 12.4342 7.74294 12.4333 8.33333C12.4333 10 9.93328 10.8333 9.93328 10.8333" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M10 14.1667H10.0083" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
|
After Width: | Height: | Size: 941 B |
1
docs/assets/images/icons/home.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 16 16" width="16px" xml:space="preserve"><path d="M15.45,7L14,5.551V2c0-0.55-0.45-1-1-1h-1c-0.55,0-1,0.45-1,1v0.553L9,0.555C8.727,0.297,8.477,0,8,0S7.273,0.297,7,0.555 L0.55,7C0.238,7.325,0,7.562,0,8c0,0.563,0.432,1,1,1h1v6c0,0.55,0.45,1,1,1h3v-5c0-0.55,0.45-1,1-1h2c0.55,0,1,0.45,1,1v5h3 c0.55,0,1-0.45,1-1V9h1c0.568,0,1-0.437,1-1C16,7.562,15.762,7.325,15.45,7z"></path></svg>
|
||||
|
After Width: | Height: | Size: 489 B |
1
docs/assets/images/icons/requirements.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"><path d="M6 2V11H2V15C2 16.7 3.3 18 5 18H15C16.7 18 18 16.7 18 15V2H6ZM16 15C16 15.6 15.6 16 15 16H8V4H16V15Z" /><path d="M14 7H10V9H14V7Z" /><path d="M14 11H10V13H14V11Z" /></svg>
|
||||
|
After Width: | Height: | Size: 321 B |
1
docs/assets/images/icons/upgrade.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"><path d="M17.8049 2.19795C17.7385 2.1311 17.6587 2.07899 17.5708 2.04504C17.4829 2.01108 17.3889 1.99604 17.2948 2.00089C7.89216 2.49153 4.4188 10.8673 4.38528 10.9517C4.33624 11.0736 4.32406 11.2071 4.5.028 11.3358C4.3765 11.4645 4.43995 11.5827 4.53274 11.6756L8.32449 15.4674C8.41787 15.5606 8.53669 15.6242 8.66606 15.6502C8.79543 15.6762 8.92959 15.6634 9.05174 15.6135C9.13552 15.5793 17.4664 12.0671 17.9986 2.7087C18.0039 2.61474 17.9895 2.5207 17.9561 2.4327C17.9227 2.3447 17.8712 2.26471 17.8049 2.19795ZM12.3314 9.56427C12.1439 9.75179 11.9051 9.87951 11.645 9.93126C11.385 9.98302 11.1154 9.9565 10.8704 9.85505C10.6254 9.7536 10.4161 9.58178 10.2687 9.36131C10.1214 9.14085 10.0428 8.88166 10.0428 8.6165C10.0428 8.35135 10.1214 8.09215 10.2687 7.87169C10.4161 7.65123 10.6254 7.47941 10.8704 7.37796C11.1154 7.27651 11.385 7.24998 11.645 7.30174C11.9051 7.3535 12.1439 7.48121 12.3314 7.66873C12.5827 7.92012 12.7239 8.26104 12.7239 8.6165C12.7239 8.97197 12.5827 9.31288 12.3314 9.56427Z"/><path d="M2.74602 14.5444C2.92281 14.3664 3.133 14.2251 3.36454 14.1285C3.59608 14.0319 3.8444 13.9819 4.09529 13.9815C4.34617 13.9811 4.59466 14.0.12 4.82653 14.126C5.05839 14.2218 5.26907 14.3624 5.44647 14.5398C5.62386 14.7172 5.7645 14.9279 5.86031 15.1598C5.95612 15.3916 6.00522 15.6401 6.00479 15.891C6.00437 16.1419 5.95442 16.3902 5.85782 16.6218C5.76122 16.8533 5.61987 17.0635 5.44186 17.2403C4.69719 17.985 2 18.0004 2 18.0004C2 18.0004 2 15.2884 2.74602 14.5444Z"/><path d="M8.9416 3.48269C7.99688 3.31826 7.02645 3.38371 6.11237 3.67352C5.19828 3.96332 4.36741 4.46894 3.68999 5.14765C3.33153 5.50944.5.01988 5.91477 2.76233 6.35415C2.68692 6.4822 2.6562 6.63169 2.67501 6.77911C2.69381 6.92652 2.76108 7.06351 2.86623 7.16853L4.1994 8.50238C5.43822 6.53634 7.04911 4.83119 8.9416 3.48269Z"/><path d="M16.5181 11.0585C16.6825 12.0033 16.6171 12.9737 16.3273 13.8878C16.0375 14.8019 15.5318 15.6327 14.8531 16.3101C14.4914 16.6686 14.086 16.9803 13.6466 17.2378C13.5186 17.3132 13.3691 17.3439 13.2217 17.3251C13.0743 17.3063 12.9373 17.2391 12.8323 17.1339L11.4984 15.8007C13.4645 14.5619 15.1696 12.951 16.5181 11.0585Z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
3
docs/assets/images/icons/usage.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1.8 3.6H0V16.2C0 17.19 0.81 18 1.8 18H14.4V16.2H1.8V3.6ZM16.2 0H5.4C4.41 0 3.6 0.81 3.6 1.8V12.6C3.6 13.59 4.41 14.4 5.4 14.4H16.2C17.19 14.4 18 13.59 18 12.6V1.8C18 0.81 17.19 0 16.2 0ZM16.2 9L13.95 7.65L11.7 9V1.8H16.2V9Z" fill="black"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 352 B |
1
docs/assets/images/icons/wrench.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true"><path d="M22.7 19l-9.1-9.1c.9-2.3.4-5-1.5-6.9-2-2-5-2.4-7.4-1.3L9 6 6 9 1.6 4.7C.4 7.1.9 10.1 2.9 12.1c1.9 1.9 4.6 2.4 6.9 1.5l9.1 9.1c.4.4 1 .4 1.4 0l2.3-2.3c.5-.4.5-1.1.1-1.4z"></path></svg>
|
||||
|
After Width: | Height: | Size: 271 B |
@@ -60,6 +60,6 @@ As `code-server` is based on VS Code, you can follow the steps described on Duck
|
||||
code-server --enable-proposed-api genuitecllc.codetogether
|
||||
```
|
||||
|
||||
Another option would be to add a value in code-server's [config file](https://coder.com/docs/code-server/v4.5.0/FAQ#how-does-the-config-file-work).
|
||||
Another option would be to add a value in code-server's [config file](https://coder.com/docs/code-server/latest/FAQ#how-does-the-config-file-work).
|
||||
|
||||
3. Refresh code-server and navigate to the CodeTogether icon in the sidebar to host or join a coding session.
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
- [Stripping `/proxy/<port>` from the request path](#stripping-proxyport-from-the-request-path)
|
||||
- [Proxying to create a React app](#proxying-to-create-a-react-app)
|
||||
- [Proxying to a Vue app](#proxying-to-a-vue-app)
|
||||
- [Proxying to an Angular app](#proxying-to-an-angular-app)
|
||||
- [SSH into code-server on VS Code](#ssh-into-code-server-on-vs-code)
|
||||
- [Option 1: cloudflared tunnel](#option-1-cloudflared-tunnel)
|
||||
- [Option 2: ngrok tunnel](#option-2-ngrok-tunnel)
|
||||
@@ -126,7 +127,7 @@ access code-server on an iPad or do not want to use SSH port forwarding.
|
||||
|
||||
```console
|
||||
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo apt-key add -
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
|
||||
sudo apt update
|
||||
sudo apt install caddy
|
||||
@@ -382,6 +383,15 @@ module.exports = {
|
||||
|
||||
Read more about `publicPath` in the [Vue.js docs](https://cli.vuejs.org/config/#publicpath)
|
||||
|
||||
### Proxying to an Angular app
|
||||
|
||||
In order to use code-server's built-in proxy with Angular, you need to make the following changes in your app:
|
||||
|
||||
1. use `<base href="./.">` in `src/index.html`
|
||||
2. add `--serve-path /absproxy/4200` to `ng serve` in your `package.json`
|
||||
|
||||
For additional context, see [this GitHub Discussion](https://github.com/coder/code-server/discussions/5439#discussioncomment-3371983).
|
||||
|
||||
## SSH into code-server on VS Code
|
||||
|
||||
[](https://ohmyz.sh/) [](https://img.shields.io/badge/Terminal-2E2E2E?style=for-the-badge&logo=Windows+Terminal&logoColor=ffffff) [](vscode:extension/ms-vscode-remote.remote-ssh)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# code-server Helm Chart
|
||||
|
||||
[](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square) [](https://img.shields.io/badge/Type-application-informational?style=flat-square) [](https://img.shields.io/badge/AppVersion-4.5.0-informational?style=flat-square)
|
||||
[](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square) [](https://img.shields.io/badge/Type-application-informational?style=flat-square) [](https://img.shields.io/badge/AppVersion-4.7.0-informational?style=flat-square)
|
||||
|
||||
[code-server](https://github.com/coder/code-server) code-server is VS Code running
|
||||
on a remote server, accessible through the browser.
|
||||
@@ -73,7 +73,7 @@ and their default values.
|
||||
| hostnameOverride | string | `""` |
|
||||
| image.pullPolicy | string | `"Always"` |
|
||||
| image.repository | string | `"codercom/code-server"` |
|
||||
| image.tag | string | `"4.5.0"` |
|
||||
| image.tag | string | `"4.7.0"` |
|
||||
| imagePullSecrets | list | `[]` |
|
||||
| ingress.enabled | bool | `false` |
|
||||
| nameOverride | string | `""` |
|
||||
|
||||
113
docs/install.md
@@ -4,11 +4,12 @@
|
||||
|
||||
- [install.sh](#installsh)
|
||||
- [Detection reference](#detection-reference)
|
||||
- [yarn, npm](#yarn-npm)
|
||||
- [npm](#npm)
|
||||
- [Standalone releases](#standalone-releases)
|
||||
- [Debian, Ubuntu](#debian-ubuntu)
|
||||
- [Fedora, CentOS, RHEL, SUSE](#fedora-centos-rhel-suse)
|
||||
- [Arch Linux](#arch-linux)
|
||||
- [Artix Linux](#artix-linux)
|
||||
- [macOS](#macos)
|
||||
- [Docker](#docker)
|
||||
- [Helm](#helm)
|
||||
@@ -19,7 +20,7 @@
|
||||
- [Uninstall](#uninstall)
|
||||
- [install.sh](#installsh-1)
|
||||
- [Homebrew](#homebrew)
|
||||
- [yarn, npm](#yarn-npm-1)
|
||||
- [npm](#npm-1)
|
||||
- [Debian, Ubuntu](#debian-ubuntu-1)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
@@ -87,17 +88,16 @@ _exact_ same commands presented in the rest of this document.
|
||||
|
||||
- Ensure that you add `~/.local/bin` to your `$PATH` to run code-server.
|
||||
|
||||
- For FreeBSD, code-server will install the [npm package](#yarn-npm) with `yarn`
|
||||
or `npm`.
|
||||
- For FreeBSD, code-server will install the [npm package](#npm) with `npm`
|
||||
|
||||
- If you're installing code-server onto architecture with no releases,
|
||||
code-server will install the [npm package](#yarn-npm) with `yarn` or `npm`
|
||||
code-server will install the [npm package](#npm) with `npm`
|
||||
- We currently offer releases for amd64 and arm64.
|
||||
- The [npm package](#yarn-npm) builds the native modules on post-install.
|
||||
- The [npm package](#npm) builds the native modules on post-install.
|
||||
|
||||
## yarn, npm
|
||||
## npm
|
||||
|
||||
We recommend installing with `yarn` or `npm` when:
|
||||
We recommend installing with `npm` when:
|
||||
|
||||
1. You aren't using a machine with `amd64` or `arm64`.
|
||||
1. You are installing code-server on Windows
|
||||
@@ -107,9 +107,9 @@ We recommend installing with `yarn` or `npm` when:
|
||||
[#1430](https://github.com/coder/code-server/issues/1430#issuecomment-629883198)
|
||||
for more information.
|
||||
|
||||
Installing code-server with `yarn` or `npm` builds native modules on install.
|
||||
Installing code-server with `npm` builds native modules on install.
|
||||
|
||||
This process requires C dependencies; see our guide on [installing with yarn and npm][./npm.md](./npm.md) for more information.
|
||||
This process requires C dependencies; see our guide on [installing with npm](./npm.md) for more information.
|
||||
|
||||
## Standalone releases
|
||||
|
||||
@@ -117,7 +117,7 @@ We publish self-contained `.tar.gz` archives for every release on
|
||||
[GitHub](https://github.com/coder/code-server/releases). The archives bundle the
|
||||
node binary and node modules.
|
||||
|
||||
We create the standalone releases using the [npm package](#yarn-npm), and we
|
||||
We create the standalone releases using the [npm package](#npm), and we
|
||||
then create the remaining releases using the standalone version.
|
||||
|
||||
The only requirement to use the standalone release is `glibc` >= 2.17 and
|
||||
@@ -151,11 +151,11 @@ code-server
|
||||
## Debian, Ubuntu
|
||||
|
||||
> The standalone arm64 .deb does not support Ubuntu 16.04 or earlier. Please
|
||||
> upgrade or [build with yarn](#yarn-npm).
|
||||
> upgrade or [build with npm](#npm).
|
||||
|
||||
```bash
|
||||
curl -fOL https://github.com/coder/code-server/releases/download/v$VERSION/code-server_$VERSION_amd64.deb
|
||||
sudo dpkg -i code-server_$VERSION_amd64.deb
|
||||
curl -fOL https://github.com/coder/code-server/releases/download/v$VERSION/code-server_${VERSION}_amd64.deb
|
||||
sudo dpkg -i code-server_${VERSION}_amd64.deb
|
||||
sudo systemctl enable --now code-server@$USER
|
||||
# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml
|
||||
```
|
||||
@@ -163,7 +163,7 @@ sudo systemctl enable --now code-server@$USER
|
||||
## Fedora, CentOS, RHEL, SUSE
|
||||
|
||||
> The standalone arm64 .rpm does not support CentOS 7. Please upgrade or [build
|
||||
> with yarn](#yarn-npm).
|
||||
> with npm](#npm).
|
||||
|
||||
```bash
|
||||
curl -fOL https://github.com/coder/code-server/releases/download/v$VERSION/code-server-$VERSION-amd64.rpm
|
||||
@@ -190,6 +190,72 @@ sudo systemctl enable --now code-server@$USER
|
||||
# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml
|
||||
```
|
||||
|
||||
## Artix Linux
|
||||
|
||||
```bash
|
||||
# Install code-server from the AUR
|
||||
git clone https://aur.archlinux.org/code-server.git
|
||||
cd code-server
|
||||
makepkg -si
|
||||
```
|
||||
|
||||
Save the file as `code-server` in `/etc/init.d/` and make it executable with `chmod +x code-server`. Put your username in line 3.
|
||||
|
||||
```bash
|
||||
#!/sbin/openrc-run
|
||||
name=$RC_SVCNAME
|
||||
description="$name - VS Code on a remote server"
|
||||
user="" # your username here
|
||||
homedir="/home/$user"
|
||||
command="$(which code-server)"
|
||||
# Just because you can do this does not mean you should. Use ~/.config/code-server/config.yaml instead
|
||||
#command_args="--extensions-dir $homedir/.local/share/$name/extensions --user-data-dir $homedir/.local/share/$name --disable-telemetry"
|
||||
command_user="$user:$user"
|
||||
pidfile="/run/$name/$name.pid"
|
||||
command_background="yes"
|
||||
extra_commands="report"
|
||||
|
||||
depend() {
|
||||
use logger dns
|
||||
need net
|
||||
}
|
||||
|
||||
start_pre() {
|
||||
checkpath --directory --owner $command_user --mode 0755 /run/$name /var/log/$name
|
||||
}
|
||||
|
||||
start() {
|
||||
default_start
|
||||
report
|
||||
}
|
||||
|
||||
stop() {
|
||||
default_stop
|
||||
}
|
||||
|
||||
status() {
|
||||
default_status
|
||||
report
|
||||
}
|
||||
|
||||
report() {
|
||||
# Report to the user
|
||||
einfo "Reading configuration from ~/.config/code-server/config.yaml"
|
||||
}
|
||||
```
|
||||
|
||||
Start on boot with default runlevel
|
||||
|
||||
```
|
||||
rc-update add code-server default
|
||||
```
|
||||
|
||||
Start the service immediately
|
||||
|
||||
```
|
||||
rc-service code-server start
|
||||
```
|
||||
|
||||
## macOS
|
||||
|
||||
```bash
|
||||
@@ -228,14 +294,15 @@ 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 [`yarn` or `npm`](#yarn-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
|
||||
|
||||
We recommend installing code-server onto Raspberry Pi with [`yarn` or
|
||||
`npm`](#yarn-npm).
|
||||
We recommend installing code-server onto Raspberry Pi with [`npm`](#npm).
|
||||
|
||||
If you see an error related to `node-gyp` during installation, See [#5174](https://github.com/coder/code-server/issues/5174) for more information.
|
||||
|
||||
## Termux
|
||||
|
||||
@@ -277,18 +344,12 @@ brew remove code-server
|
||||
brew uninstall code-server
|
||||
```
|
||||
|
||||
### yarn, npm
|
||||
### npm
|
||||
|
||||
To remove the code-server global module, run:
|
||||
|
||||
```shell
|
||||
yarn global remove code-server
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```shell
|
||||
npm uninstall -g code-server
|
||||
npm uninstall --global code-server
|
||||
```
|
||||
|
||||
### Debian, Ubuntu
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
{
|
||||
"versions": ["v4.5.0"],
|
||||
"versions": ["v4.7.0"],
|
||||
"routes": [
|
||||
{
|
||||
"title": "Home",
|
||||
"description": "Learn how to install and run code-server.",
|
||||
"path": "./README.md",
|
||||
"icon": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16px\" xml:space=\"preserve\"><path d=\"M15.45,7L14,5.551V2c0-0.55-0.45-1-1-1h-1c-0.55,0-1,0.45-1,1v0.553L9,0.555C8.727,0.297,8.477,0,8,0S7.273,0.297,7,0.555 L0.55,7C0.238,7.325,0,7.562,0,8c0,0.563,0.432,1,1,1h1v6c0,0.55,0.45,1,1,1h3v-5c0-0.55,0.45-1,1-1h2c0.55,0,1,0.45,1,1v5h3 c0.55,0,1-0.45,1-1V9h1c0.568,0,1-0.437,1-1C16,7.562,15.762,7.325,15.45,7z\"></path></svg>"
|
||||
"icon_path": "assets/images/icons/home.svg"
|
||||
},
|
||||
{
|
||||
"title": "Requirements",
|
||||
"description": "Learn about what you need to run code-server.",
|
||||
"icon": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 2V11H2V15C2 16.7 3.3 18 5 18H15C16.7 18 18 16.7 18 15V2H6ZM16 15C16 15.6 15.6 16 15 16H8V4H16V15Z\" /><path d=\"M14 7H10V9H14V7Z\" /><path d=\"M14 11H10V13H14V11Z\" /></svg>",
|
||||
"icon_path": "assets/images/icons/requirements.svg",
|
||||
"path": "./requirements.md"
|
||||
},
|
||||
{
|
||||
"title": "Install",
|
||||
"description": "How to install code-server.",
|
||||
"icon": "<svg class=\"MuiSvgIcon-root jss172\" focusable=\"false\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M22.7 19l-9.1-9.1c.9-2.3.4-5-1.5-6.9-2-2-5-2.4-7.4-1.3L9 6 6 9 1.6 4.7C.4 7.1.9 10.1 2.9 12.1c1.9 1.9 4.6 2.4 6.9 1.5l9.1 9.1c.4.4 1 .4 1.4 0l2.3-2.3c.5-.4.5-1.1.1-1.4z\"></path></svg>",
|
||||
"icon_path": "assets/images/icons/wrench.svg",
|
||||
"path": "./install.md",
|
||||
"children": [
|
||||
{
|
||||
"title": "npm",
|
||||
"description": "How to install code-server using npm or yarn",
|
||||
"description": "How to install code-server using npm",
|
||||
"path": "./npm.md"
|
||||
},
|
||||
{
|
||||
@@ -34,7 +34,7 @@
|
||||
{
|
||||
"title": "Usage",
|
||||
"description": "How to set up and use code-server.",
|
||||
"icon": "<svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 10l-2.5-1.5L15 12V4h5v8z\"></path></svg>",
|
||||
"icon_path": "assets/images/icons/usage.svg",
|
||||
"path": "./guide.md",
|
||||
"children": [
|
||||
{
|
||||
@@ -67,25 +67,25 @@
|
||||
{
|
||||
"title": "Collaboration",
|
||||
"description": "How to setup real time collaboration using code server.",
|
||||
"icon": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M12.2 13.4357L9.5 11.4357C10.4 10.7357 11 9.7357 11 8.5357V7.7357C11 5.8357 9.6 4.1357 7.7 4.0357C5.7 3.9357 4 5.5357 4 7.5357V8.5357C4 9.7357 4.6 10.7357 5.5 11.4357L2.8 13.5357C2.3 13.9357 2 14.5357 2 15.1357V17.0357C2 17.6357 2.4 18.0357 3 18.0357H12C12.6 18.0357 13 17.6357 13 17.0357V15.0357C13 14.4357 12.7 13.8357 12.2 13.4357Z\"/> <path d=\"M17.1 8.43436L15.3 7.23436C15.7 6.83436 16 6.23436 16 5.53436V4.63436C16 3.43436 15.1 2.23436 13.9 2.03436C12.7 1.83436 11.7 2.53436 11.2 3.43436C12.3 4.43436 13 5.83436 13 7.43436V8.43436C13 9.33436 12.8 10.2344 12.4 10.9344C12.4 10.9344 13.6 11.8344 13.6 11.9344H17C17.6 11.9344 18 11.5344 18 10.9344V10.1344C18 9.43436 17.7 8.83436 17.1 8.43436Z\"/></svg>",
|
||||
"icon_path": "assets/images/icons/collab.svg",
|
||||
"path": "./collaboration.md"
|
||||
},
|
||||
{
|
||||
"title": "Upgrade",
|
||||
"description": "How to upgrade code-server.",
|
||||
"icon": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M17.8049 2.19795C17.7385 2.1311 17.6587 2.07899 17.5708 2.04504C17.4829 2.01108 17.3889 1.99604 17.2948 2.00089C7.89216 2.49153 4.4188 10.8673 4.38528 10.9517C4.33624 11.0736 4.32406 11.2071 4.5.028 11.3358C4.3765 11.4645 4.43995 11.5827 4.53274 11.6756L8.32449 15.4674C8.41787 15.5606 8.53669 15.6242 8.66606 15.6502C8.79543 15.6762 8.92959 15.6634 9.05174 15.6135C9.13552 15.5793 17.4664 12.0671 17.9986 2.7087C18.0039 2.61474 17.9895 2.5207 17.9561 2.4327C17.9227 2.3447 17.8712 2.26471 17.8049 2.19795ZM12.3314 9.56427C12.1439 9.75179 11.9051 9.87951 11.645 9.93126C11.385 9.98302 11.1154 9.9565 10.8704 9.85505C10.6254 9.7536 10.4161 9.58178 10.2687 9.36131C10.1214 9.14085 10.0428 8.88166 10.0428 8.6165C10.0428 8.35135 10.1214 8.09215 10.2687 7.87169C10.4161 7.65123 10.6254 7.47941 10.8704 7.37796C11.1154 7.27651 11.385 7.24998 11.645 7.30174C11.9051 7.3535 12.1439 7.48121 12.3314 7.66873C12.5827 7.92012 12.7239 8.26104 12.7239 8.6165C12.7239 8.97197 12.5827 9.31288 12.3314 9.56427Z\"/><path d=\"M2.74602 14.5444C2.92281 14.3664 3.133 14.2251 3.36454 14.1285C3.59608 14.0319 3.8444 13.9819 4.09529 13.9815C4.34617 13.9811 4.59466 14.0.12 4.82653 14.126C5.05839 14.2218 5.26907 14.3624 5.44647 14.5398C5.62386 14.7172 5.7645 14.9279 5.86031 15.1598C5.95612 15.3916 6.00522 15.6401 6.00479 15.891C6.00437 16.1419 5.95442 16.3902 5.85782 16.6218C5.76122 16.8533 5.61987 17.0635 5.44186 17.2403C4.69719 17.985 2 18.0004 2 18.0004C2 18.0004 2 15.2884 2.74602 14.5444Z\"/><path d=\"M8.9416 3.48269C7.99688 3.31826 7.02645 3.38371 6.11237 3.67352C5.19828 3.96332 4.36741 4.46894 3.68999 5.14765C3.33153 5.50944.5.01988 5.91477 2.76233 6.35415C2.68692 6.4822 2.6562 6.63169 2.67501 6.77911C2.69381 6.92652 2.76108 7.06351 2.86623 7.16853L4.1994 8.50238C5.43822 6.53634 7.04911 4.83119 8.9416 3.48269Z\"/><path d=\"M16.5181 11.0585C16.6825 12.0033 16.6171 12.9737 16.3273 13.8878C16.0375 14.8019 15.5318 15.6327 14.8531 16.3101C14.4914 16.6686 14.086 16.9803 13.6466 17.2378C13.5186 17.3132 13.3691 17.3439 13.2217 17.3251C13.0743 17.3063 12.9373 17.2391 12.8323 17.1339L11.4984 15.8007C13.4645 14.5619 15.1696 12.951 16.5181 11.0585Z\"/></svg>",
|
||||
"icon_path": "assets/images/icons/upgrade.svg",
|
||||
"path": "./upgrade.md"
|
||||
},
|
||||
{
|
||||
"title": "FAQ",
|
||||
"description": "Frequently asked questions on installing and running code-server.",
|
||||
"icon": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.0001 18.3333C14.6025 18.3333 18.3334 14.6024 18.3334 10C18.3334 5.39762 14.6025 1.66666 10.0001 1.66666C5.39771 1.66666 1.66675 5.39762 1.66675 10C1.66675 14.6024 5.39771 18.3333 10.0001 18.3333Z\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.57495 7.5C7.77087 6.94306 8.15758 6.47342 8.66658 6.17428C9.17558 5.87513 9.77403 5.76578 10.3559 5.86559C10.9378 5.96541 11.4656 6.26794 11.8458 6.71961C12.2261 7.17128 12.4342 7.74294 12.4333 8.33333C12.4333 10 9.93328 10.8333 9.93328 10.8333\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M10 14.1667H10.0083\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>",
|
||||
"icon_path": "assets/images/icons/faq.svg",
|
||||
"path": "./FAQ.md"
|
||||
},
|
||||
{
|
||||
"title": "Contributing",
|
||||
"description": "How to contribute to code-server.",
|
||||
"icon": "<svg width=\"20\" height=\"20\" fill=\"none\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5 2.5V12.5\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M15 7.5C16.3807 7.5 17.5 6.38071 17.5 5C17.5 3.61929 16.3807 2.5 15 2.5C13.6193 2.5 12.5 3.61929 12.5 5C12.5 6.38071 13.6193 7.5 15 7.5Z\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M5 17.5C6.38071 17.5 7.5 16.3807 7.5 15C7.5 13.6193 6.38071 12.5 5 12.5C3.61929 12.5 2.5 13.6193 2.5 15C2.5 16.3807 3.61929 17.5 5 17.5Z\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M15 7.5C15 9.48912 14.2098 11.3968 12.8033 12.8033C11.3968 14.2098 9.48912 15 7.5 15\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>",
|
||||
"icon_path": "assets/images/icons/contributing.svg",
|
||||
"path": "./CONTRIBUTING.md",
|
||||
"children": [
|
||||
{
|
||||
|
||||
24
docs/npm.md
@@ -20,6 +20,11 @@ If you're installing code-server via `npm`, you'll need to install additional
|
||||
dependencies required to build the native modules used by VS Code. This article
|
||||
includes installing instructions based on your operating system.
|
||||
|
||||
> **WARNING**: Do not use `yarn` to install code-server. Unlike `npm`, it does not respect
|
||||
> lockfiles for distributed applications. It will instead use the latest version
|
||||
> available at installation time - which might not be the one used for a given
|
||||
> code-server release, and [might lead to unexpected behavior](https://github.com/coder/code-server/issues/4927).
|
||||
|
||||
## Node.js version
|
||||
|
||||
We use the same major version of Node.js shipped with Code's remote, which is
|
||||
@@ -72,7 +77,7 @@ Proceed to [installing](#installing)
|
||||
## FreeBSD
|
||||
|
||||
```sh
|
||||
pkg install -y git python npm-node16 yarn-node16 pkgconf
|
||||
pkg install -y git python npm-node16 pkgconf
|
||||
pkg install -y libinotify
|
||||
```
|
||||
|
||||
@@ -85,8 +90,7 @@ Installing code-server requires all of the [prerequisites for VS Code developmen
|
||||
Next, install code-server with:
|
||||
|
||||
```bash
|
||||
yarn global add code-server
|
||||
# Or: npm install -g code-server
|
||||
npm install --global code-server --unsafe-perm
|
||||
code-server
|
||||
# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml
|
||||
```
|
||||
@@ -96,8 +100,7 @@ A `postinstall.sh` script will attempt to run. Select your terminal (e.g., Git b
|
||||
If the `code-server` command is not found, you'll need to [add a directory to your PATH](https://www.architectryan.com/2018/03/17/add-to-the-path-on-windows-10/). To find the directory, use the following command:
|
||||
|
||||
```shell
|
||||
yarn global bin
|
||||
# Or: npm config get prefix
|
||||
npm config get prefix
|
||||
```
|
||||
|
||||
For help and additional troubleshooting, see [#1397](https://github.com/coder/code-server/issues/1397).
|
||||
@@ -107,8 +110,7 @@ For help and additional troubleshooting, see [#1397](https://github.com/coder/co
|
||||
After adding the dependencies for your OS, install the code-server package globally:
|
||||
|
||||
```bash
|
||||
yarn global add code-server
|
||||
# Or: npm install -g code-server
|
||||
npm install --global code-server --unsafe-perm
|
||||
code-server
|
||||
# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml
|
||||
```
|
||||
@@ -122,7 +124,7 @@ page](https://github.com/coder/code-server/discussions).
|
||||
|
||||
Occasionally, you may run into issues with Node.js.
|
||||
|
||||
If you install code-server using `yarn` or `npm`, and you upgrade your Node.js
|
||||
If you install code-server using `npm`, and you upgrade your Node.js
|
||||
version, you may need to reinstall code-server to recompile native modules.
|
||||
Sometimes, you can get around this by navigating into code-server's `lib/vscode`
|
||||
directory and running `npm rebuild` to recompile the modules.
|
||||
@@ -136,12 +138,12 @@ A step-by-step example of how you might do this is:
|
||||
|
||||
### Debugging install issues with npm
|
||||
|
||||
`yarn` suppresses logs when running `yarn global add`, so to debug installation issues, install with `npm` instead:
|
||||
To debug installation issues, install with `npm`:
|
||||
|
||||
```shell
|
||||
# Uninstall
|
||||
npm uninstall -g --unsafe-perm code-server > /dev/null 2>&1
|
||||
npm uninstall --global --unsafe-perm code-server > /dev/null 2>&1
|
||||
|
||||
# Install with logging
|
||||
npm install --loglevel verbose -g --unsafe-perm code-server
|
||||
npm install --loglevel verbose --global --unsafe-perm code-server
|
||||
```
|
||||
|
||||
@@ -21,7 +21,7 @@ for communication between the browser and the server.
|
||||
The following steps walk you through setting up a VM running Debian using Google
|
||||
Cloud (though you are welcome to use any machine or VM provider).
|
||||
|
||||
If you're [signing up with Google](https://console.cloud.google.com/getting-started) for the first time, you should get a 12-month trial with
|
||||
If you're [signing up with Google](https://console.cloud.google.com/getting-started) for the first time, you should get a 3-month trial with
|
||||
$300 of credits.
|
||||
|
||||
After you sign up and create a new Google Cloud Provider (GCP) project, create a
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# Termux
|
||||
|
||||
- [Install](#install)
|
||||
- [NPM Installation](#npm-installation)
|
||||
- [Upgrade](#upgrade)
|
||||
- [Known Issues](#known-issues)
|
||||
- [Git won't work in `/sdcard`](#git-wont-work-in-sdcard)
|
||||
@@ -65,6 +66,54 @@ curl -fsSL https://code-server.dev/install.sh | sh
|
||||
> Consider using a new user instead of root, read [here](https://www.howtogeek.com/124950/htg-explains-why-you-shouldnt-log-into-your-linux-system-as-root/) why using root is not recommended.\
|
||||
> Learn how to add a user [here](#create-a-new-user).
|
||||
|
||||
## NPM Installation
|
||||
|
||||
1. Get [Termux](https://f-droid.org/en/packages/com.termux/) from **F-Droid**.
|
||||
|
||||
2. We will now change using the following command.
|
||||
|
||||
```sh
|
||||
termux-change-repo
|
||||
```
|
||||
|
||||
Now select `Main Repository` then change repo to `Mirrors by Grimler Hosted on grimler.se`.
|
||||
|
||||
3. After successfully updating of repository update and upgrade all the packages by the following command
|
||||
|
||||
```sh
|
||||
pkg update
|
||||
pkg upgrade -y
|
||||
```
|
||||
|
||||
4. Now let's install requirement dependancy.
|
||||
|
||||
```sh
|
||||
pkg install -y \
|
||||
build-essential \
|
||||
binutils \
|
||||
pkg-config \
|
||||
python3 \
|
||||
nodejs-lts
|
||||
npm config set python python3
|
||||
node -v
|
||||
```
|
||||
|
||||
you will get node version `v16.15.0`
|
||||
|
||||
5. Now install code-server following our guide on [installing with npm][./npm.md](./npm.md)
|
||||
|
||||
6. Congratulation code-server is installed on your device using the following command.
|
||||
|
||||
```sh
|
||||
code-server --auth none
|
||||
```
|
||||
|
||||
7. If already installed then use the following command for upgradation.
|
||||
|
||||
```
|
||||
npm update --global code-server --unsafe-perm
|
||||
```
|
||||
|
||||
## Upgrade
|
||||
|
||||
1. Remove all previous installs `rm -rf ~/.local/lib/code-server-*`
|
||||
|
||||
41
flake.lock
generated
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"locked": {
|
||||
"lastModified": 1659877975,
|
||||
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1660639432,
|
||||
"narHash": "sha256-2WDiboOCfB0LhvnDVMXOAr8ZLDfm3WdO54CkoDPwN1A=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "6c6409e965a6c883677be7b9d87a95fab6c3472e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
25
flake.nix
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
description = "code-server";
|
||||
|
||||
inputs.flake-utils.url = "github:numtide/flake-utils";
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils }:
|
||||
flake-utils.lib.eachDefaultSystem
|
||||
(system:
|
||||
let pkgs = nixpkgs.legacyPackages.${system};
|
||||
nodejs = pkgs.nodejs-16_x;
|
||||
yarn' = pkgs.yarn.override { inherit nodejs; };
|
||||
in {
|
||||
devShells.default = pkgs.mkShell {
|
||||
nativeBuildInputs = with pkgs; [
|
||||
nodejs yarn' python pkg-config git rsync jq moreutils
|
||||
];
|
||||
buildInputs = with pkgs; (lib.optionals (!stdenv.isDarwin) [ libsecret ]
|
||||
++ (with xorg; [ libX11 libxkbfile ])
|
||||
++ lib.optionals stdenv.isDarwin [
|
||||
AppKit Cocoa CoreServices Security cctools xcbuild
|
||||
]);
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
19
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "code-server",
|
||||
"license": "MIT",
|
||||
"version": "4.5.0",
|
||||
"version": "4.7.0",
|
||||
"description": "Run VS Code on a remote server.",
|
||||
"homepage": "https://github.com/coder/code-server",
|
||||
"bugs": {
|
||||
@@ -18,6 +18,7 @@
|
||||
"release:github-assets": "./ci/build/release-github-assets.sh",
|
||||
"release:prep": "./ci/build/release-prep.sh",
|
||||
"test:e2e": "VSCODE_IPC_HOOK_CLI= ./ci/dev/test-e2e.sh",
|
||||
"test:e2e:proxy": "USE_PROXY=1 ./ci/dev/test-e2e.sh",
|
||||
"test:unit": "./ci/dev/test-unit.sh --forceExit --detectOpenHandles",
|
||||
"test:integration": "./ci/dev/test-integration.sh",
|
||||
"test:scripts": "./ci/dev/test-scripts.sh",
|
||||
@@ -41,14 +42,14 @@
|
||||
"@types/express": "^4.17.8",
|
||||
"@types/http-proxy": "^1.17.4",
|
||||
"@types/js-yaml": "^4.0.0",
|
||||
"@types/node": "^14.17.1",
|
||||
"@types/node": "^16.0.0",
|
||||
"@types/pem": "^1.9.5",
|
||||
"@types/proxy-from-env": "^1.0.1",
|
||||
"@types/safe-compare": "^1.1.0",
|
||||
"@types/semver": "^7.1.0",
|
||||
"@types/split2": "^3.2.0",
|
||||
"@types/trusted-types": "^2.0.2",
|
||||
"@types/ws": "^8.0.0",
|
||||
"@types/ws": "^8.5.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.23.0",
|
||||
"@typescript-eslint/parser": "^5.23.0",
|
||||
"audit-ci": "^6.0.0",
|
||||
@@ -58,13 +59,11 @@
|
||||
"eslint-import-resolver-typescript": "^2.5.0",
|
||||
"eslint-plugin-import": "^2.18.2",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"json": "^11.0.0",
|
||||
"prettier": "^2.2.1",
|
||||
"prettier-plugin-sh": "^0.12.0",
|
||||
"shellcheck": "^1.0.0",
|
||||
"stylelint": "^13.0.0",
|
||||
"stylelint-config-recommended": "^5.0.0",
|
||||
"synp": "^1.9.10",
|
||||
"ts-node": "^10.0.0",
|
||||
"typescript": "^4.6.2"
|
||||
},
|
||||
@@ -84,11 +83,12 @@
|
||||
"node-fetch": "^2.6.7",
|
||||
"nanoid": "^3.1.31",
|
||||
"minimist": "npm:minimist-lite@2.2.1",
|
||||
"glob-parent": "^6.0.1"
|
||||
"glob-parent": "^6.0.1",
|
||||
"@types/node": "^16.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@coder/logger": "1.1.16",
|
||||
"argon2": "^0.28.0",
|
||||
"@coder/logger": "^3.0.0",
|
||||
"argon2": "^0.29.0",
|
||||
"compression": "^1.7.4",
|
||||
"cookie-parser": "^1.4.5",
|
||||
"env-paths": "^2.2.0",
|
||||
@@ -106,8 +106,7 @@
|
||||
"semver": "^7.1.3",
|
||||
"split2": "^4.0.0",
|
||||
"ws": "^8.0.0",
|
||||
"xdg-basedir": "^4.0.0",
|
||||
"yarn": "^1.22.4"
|
||||
"xdg-basedir": "^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"code-server": "out/node/entry.js"
|
||||
|
||||
@@ -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
|
||||
@@ -157,7 +157,9 @@ class RemoteAuthoritiesImpl {
|
||||
@@ -162,7 +162,9 @@ class RemoteAuthoritiesImpl {
|
||||
return URI.from({
|
||||
scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource,
|
||||
authority: `${host}:${port}`,
|
||||
@@ -118,26 +118,25 @@ 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,14 +267,10 @@ export class WebClientServer {
|
||||
@@ -267,12 +267,11 @@ export class WebClientServer {
|
||||
return res.end();
|
||||
}
|
||||
|
||||
- let originalHost = req.headers['x-original-host'];
|
||||
- if (Array.isArray(originalHost)) {
|
||||
- originalHost = originalHost[0];
|
||||
- }
|
||||
- const remoteAuthority = originalHost || req.headers.host;
|
||||
- if (!remoteAuthority) {
|
||||
- return serveError(req, res, 400, `Bad request.`);
|
||||
- }
|
||||
+ // It is not possible to reliably detect the remote authority on the server
|
||||
+ // in all cases. Set this to something invalid to make sure we catch code
|
||||
+ // that is using this when it should not.
|
||||
- const getFirstHeader = (headerName: string) => {
|
||||
- const val = req.headers[headerName];
|
||||
- return Array.isArray(val) ? val[0] : val;
|
||||
- };
|
||||
-
|
||||
- const remoteAuthority = getFirstHeader('x-original-host') || getFirstHeader('x-forwarded-host') || req.headers.host;
|
||||
+ // For now we are getting the remote authority from the client to avoid
|
||||
+ // needing specific configuration for reverse proxies to work. Set this to
|
||||
+ // something invalid to make sure we catch code that is using this value
|
||||
+ // from the backend when it should not.
|
||||
+ const remoteAuthority = 'remote';
|
||||
|
||||
function asJSON(value: unknown): string {
|
||||
return JSON.stringify(value).replace(/"/g, '"');
|
||||
@@ -297,6 +293,8 @@ export class WebClientServer {
|
||||
if (!remoteAuthority) {
|
||||
return serveError(req, res, 400, `Bad request.`);
|
||||
}
|
||||
@@ -298,6 +297,8 @@ export class WebClientServer {
|
||||
scopes: [['user:email'], ['repo']]
|
||||
} : undefined;
|
||||
|
||||
@@ -146,7 +145,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
|
||||
const workbenchWebConfiguration = {
|
||||
remoteAuthority,
|
||||
@@ -308,6 +306,7 @@ export class WebClientServer {
|
||||
@@ -309,6 +310,7 @@ export class WebClientServer {
|
||||
workspaceUri: resolveWorkspaceURI(this._environmentService.args['default-workspace']),
|
||||
productConfiguration: <Partial<IProductConfiguration>>{
|
||||
codeServerVersion: this._productService.codeServerVersion,
|
||||
@@ -154,20 +153,29 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
embedderIdentifier: 'server-distro',
|
||||
extensionsGallery: this._webExtensionResourceUrlTemplate ? {
|
||||
...this._productService.extensionsGallery,
|
||||
@@ -328,8 +327,10 @@ export class WebClientServer {
|
||||
@@ -326,8 +328,10 @@ export class WebClientServer {
|
||||
const values: { [key: string]: string } = {
|
||||
WORKBENCH_WEB_CONFIGURATION: asJSON(workbenchWebConfiguration),
|
||||
WORKBENCH_AUTH_SESSION: authSessionInfo ? asJSON(authSessionInfo) : '',
|
||||
- WORKBENCH_WEB_BASE_URL: this._staticRoute,
|
||||
- WORKBENCH_NLS_BASE_URL: nlsBaseUrl ? `${nlsBaseUrl}${this._productService.commit}/${this._productService.version}/` : '',
|
||||
- WORKBENCH_NLS_BASE_URL: nlsBaseUrl ? `${nlsBaseUrl}${!nlsBaseUrl.endsWith('/') ? '/' : ''}${this._productService.commit}/${this._productService.version}/` : '',
|
||||
+ WORKBENCH_WEB_BASE_URL: vscodeBase + this._staticRoute,
|
||||
+ WORKBENCH_NLS_BASE_URL: vscodeBase + (nlsBaseUrl ? `${nlsBaseUrl}${this._productService.commit}/${this._productService.version}/` : ''),
|
||||
+ WORKBENCH_NLS_BASE_URL: vscodeBase + (nlsBaseUrl ? `${nlsBaseUrl}${!nlsBaseUrl.endsWith('/') ? '/' : ''}${this._productService.commit}/${this._productService.version}/` : ''),
|
||||
+ BASE: base,
|
||||
+ VS_BASE: vscodeBase,
|
||||
};
|
||||
|
||||
|
||||
@@ -419,3 +420,70 @@ export class WebClientServer {
|
||||
@@ -344,7 +348,7 @@ export class WebClientServer {
|
||||
'default-src \'self\';',
|
||||
'img-src \'self\' https: data: blob:;',
|
||||
'media-src \'self\';',
|
||||
- `script-src 'self' 'unsafe-eval' ${this._getScriptCspHashes(data).join(' ')} 'sha256-fh3TwPMflhsEIpR8g1OYTIMVWhXTLcjQ9kh2tIpmv54=' http://${remoteAuthority};`, // the sha is the same as in src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
|
||||
+ `script-src 'self' 'unsafe-eval' ${this._getScriptCspHashes(data).join(' ')} 'sha256-fh3TwPMflhsEIpR8g1OYTIMVWhXTLcjQ9kh2tIpmv54=';`, // the sha is the same as in src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
|
||||
'child-src \'self\';',
|
||||
`frame-src 'self' https://*.vscode-cdn.net data:;`,
|
||||
'worker-src \'self\' data:;',
|
||||
@@ -417,3 +421,70 @@ export class WebClientServer {
|
||||
return res.end(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,62 +13,15 @@ To test:
|
||||
The file or directory should only open from the instance attached to that
|
||||
terminal.
|
||||
|
||||
Index: code-server/lib/vscode/src/vs/server/node/remoteTerminalChannel.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/remoteTerminalChannel.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/remoteTerminalChannel.ts
|
||||
@@ -89,7 +89,7 @@ export class RemoteTerminalChannel exten
|
||||
uriTransformer: IURITransformer;
|
||||
}>();
|
||||
|
||||
- private readonly _onExecuteCommand = this._register(new Emitter<{ reqId: number; commandId: string; commandArgs: any[] }>());
|
||||
+ private readonly _onExecuteCommand = this._register(new Emitter<{ reqId: number; terminalId: number; commandId: string; commandArgs: any[] }>());
|
||||
readonly onExecuteCommand = this._onExecuteCommand.event;
|
||||
|
||||
constructor(
|
||||
@@ -240,20 +240,20 @@ export class RemoteTerminalChannel exten
|
||||
const ipcHandlePath = createRandomIPCHandle();
|
||||
env.VSCODE_IPC_HOOK_CLI = ipcHandlePath;
|
||||
const commandsExecuter: ICommandsExecuter = {
|
||||
- executeCommand: <T>(id: string, ...args: any[]): Promise<T> => this._executeCommand(id, args, uriTransformer)
|
||||
+ executeCommand: <T>(commandId: string, ...args: any[]): Promise<T> => this._executeCommand(terminalId, commandId, args, uriTransformer)
|
||||
};
|
||||
const cliServer = new CLIServerBase(commandsExecuter, this._logService, ipcHandlePath);
|
||||
|
||||
- const id = await this._ptyService.createProcess(shellLaunchConfig, initialCwd, args.cols, args.rows, args.unicodeVersion, env, baseEnv, args.options, args.shouldPersistTerminal, args.workspaceId, args.workspaceName);
|
||||
- this._ptyService.onProcessExit(e => e.id === id && cliServer.dispose());
|
||||
+ const terminalId = await this._ptyService.createProcess(shellLaunchConfig, initialCwd, args.cols, args.rows, args.unicodeVersion, env, baseEnv, args.options, args.shouldPersistTerminal, args.workspaceId, args.workspaceName);
|
||||
+ this._ptyService.onProcessExit(e => e.id === terminalId && cliServer.dispose());
|
||||
|
||||
return {
|
||||
- persistentTerminalId: id,
|
||||
+ persistentTerminalId: terminalId,
|
||||
resolvedShellLaunchConfig: shellLaunchConfig
|
||||
};
|
||||
}
|
||||
|
||||
- private _executeCommand<T>(commandId: string, commandArgs: any[], uriTransformer: IURITransformer): Promise<T> {
|
||||
+ private _executeCommand<T>(terminalId: number, commandId: string, commandArgs: any[], uriTransformer: IURITransformer): Promise<T> {
|
||||
let resolve!: (data: any) => void;
|
||||
let reject!: (err: any) => void;
|
||||
const result = new Promise<T>((_resolve, _reject) => {
|
||||
@@ -276,6 +276,7 @@ export class RemoteTerminalChannel exten
|
||||
});
|
||||
this._onExecuteCommand.fire({
|
||||
reqId,
|
||||
+ terminalId,
|
||||
commandId,
|
||||
commandArgs: serializedCommandArgs
|
||||
});
|
||||
Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
|
||||
@@ -94,10 +94,14 @@ class RemoteTerminalBackend extends Base
|
||||
this._remoteTerminalChannel.onExecuteCommand(async e => {
|
||||
@@ -99,10 +99,14 @@ class RemoteTerminalBackend extends Base
|
||||
}
|
||||
const reqId = e.reqId;
|
||||
const commandId = e.commandId;
|
||||
+ const terminalId = e.terminalId;
|
||||
+ const terminalId = e.persistentProcessId;
|
||||
if (!allowedCommands.includes(commandId)) {
|
||||
this._remoteTerminalChannel.sendCommandResult(reqId, true, 'Invalid remote cli command: ' + commandId);
|
||||
return;
|
||||
@@ -79,18 +32,3 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTe
|
||||
const commandArgs = e.commandArgs.map(arg => revive(arg));
|
||||
try {
|
||||
const result = await this._commandService.executeCommand(e.commandId, ...commandArgs);
|
||||
Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts
|
||||
@@ -88,8 +88,8 @@ export class RemoteTerminalChannelClient
|
||||
get onProcessOrphanQuestion(): Event<{ id: number }> {
|
||||
return this._channel.listen<{ id: number }>('$onProcessOrphanQuestion');
|
||||
}
|
||||
- get onExecuteCommand(): Event<{ reqId: number; commandId: string; commandArgs: any[] }> {
|
||||
- return this._channel.listen<{ reqId: number; commandId: string; commandArgs: any[] }>('$onExecuteCommand');
|
||||
+ get onExecuteCommand(): Event<{ reqId: number; terminalId: number; commandId: string; commandArgs: any[] }> {
|
||||
+ return this._channel.listen<{ reqId: number; terminalId: number; commandId: string; commandArgs: any[] }>('$onExecuteCommand');
|
||||
}
|
||||
get onDidRequestDetach(): Event<{ requestId: number; workspaceId: string; instanceId: number }> {
|
||||
return this._channel.listen<{ requestId: number; workspaceId: string; instanceId: number }>('$onDidRequestDetach');
|
||||
|
||||
@@ -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
|
||||
@@ -234,6 +234,10 @@ export class Extension implements IExten
|
||||
@@ -236,6 +236,10 @@ export class Extension implements IExten
|
||||
if (this.type === ExtensionType.System && this.productService.quality === 'stable') {
|
||||
return false;
|
||||
}
|
||||
@@ -18,7 +18,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
|
||||
if (!this.local.preRelease && this.gallery.properties.isPreReleaseVersion) {
|
||||
return false;
|
||||
}
|
||||
@@ -1088,6 +1092,10 @@ export class ExtensionsWorkbenchService
|
||||
@@ -1121,6 +1125,10 @@ export class ExtensionsWorkbenchService
|
||||
// Skip if check updates only for builtin extensions and current extension is not builtin.
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -250,6 +250,11 @@ export interface IWorkbenchConstructionO
|
||||
@@ -267,6 +267,11 @@ export interface IWorkbenchConstructionO
|
||||
*/
|
||||
readonly userDataPath?: string
|
||||
|
||||
@@ -52,7 +52,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi
|
||||
+ }
|
||||
+
|
||||
@memoize
|
||||
get settingsResource(): URI { return joinPath(this.userRoamingDataHome, 'settings.json'); }
|
||||
get argvResource(): URI { return joinPath(this.userRoamingDataHome, 'argv.json'); }
|
||||
|
||||
Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
===================================================================
|
||||
@@ -66,7 +66,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
@@ -94,6 +95,7 @@ export interface ServerParsedArgs {
|
||||
@@ -95,6 +96,7 @@ export interface ServerParsedArgs {
|
||||
/* ----- code-server ----- */
|
||||
'disable-update-check'?: boolean;
|
||||
'auth'?: string
|
||||
@@ -78,7 +78,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
|
||||
@@ -300,6 +300,7 @@ export class WebClientServer {
|
||||
@@ -304,6 +304,7 @@ export class WebClientServer {
|
||||
remoteAuthority,
|
||||
webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
|
||||
userDataPath: this._environmentService.userDataPath,
|
||||
@@ -93,7 +93,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
|
||||
@@ -7,12 +7,11 @@ import { Event } from 'vs/base/common/ev
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext } from 'vs/platform/contextkey/common/contextkeys';
|
||||
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext } from 'vs/platform/contextkey/common/contextkeys';
|
||||
-import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, EditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext } from 'vs/workbench/common/contextkeys';
|
||||
+import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, EditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, IsEnabledFileDownloads } from 'vs/workbench/common/contextkeys';
|
||||
import { TEXT_DIFF_EDITOR_ID, EditorInputCapabilities, SIDE_BY_SIDE_EDITOR_ID, DEFAULT_EDITOR_ASSOCIATION } from 'vs/workbench/common/editor';
|
||||
@@ -104,24 +104,24 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { WorkbenchState, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { IWorkbenchLayoutService, Parts, positionToString } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
@@ -24,6 +23,7 @@ import { IEditorResolverService } from '
|
||||
import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite';
|
||||
@@ -25,6 +24,7 @@ import { IPaneCompositePartService } fro
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { WebFileSystemAccess } from 'vs/platform/files/browser/webFileSystemAccess';
|
||||
+import { IBrowserWorkbenchEnvironmentService } from '../services/environment/browser/environmentService';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
+import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
|
||||
|
||||
export class WorkbenchContextKeysHandler extends Disposable {
|
||||
private inputFocusedContext: IContextKey<boolean>;
|
||||
@@ -75,7 +75,7 @@ export class WorkbenchContextKeysHandler
|
||||
@@ -76,7 +76,7 @@ export class WorkbenchContextKeysHandler
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
- @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
|
||||
+ @IBrowserWorkbenchEnvironmentService private readonly environmentService: IBrowserWorkbenchEnvironmentService,
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IEditorResolverService private readonly editorResolverService: IEditorResolverService,
|
||||
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
|
||||
@@ -194,6 +194,9 @@ export class WorkbenchContextKeysHandler
|
||||
@@ -199,6 +199,9 @@ export class WorkbenchContextKeysHandler
|
||||
this.auxiliaryBarVisibleContext = AuxiliaryBarVisibleContext.bindTo(this.contextKeyService);
|
||||
this.auxiliaryBarVisibleContext.set(this.layoutService.isVisible(Parts.AUXILIARYBAR_PART));
|
||||
|
||||
|
||||
@@ -5,19 +5,21 @@ We can remove this once upstream supports all language packs.
|
||||
1. Proxies language packs to the service on the backend.
|
||||
2. NLS configuration is embedded into the HTML for the browser to pick up. This
|
||||
code to generate this configuration is copied from the native portion.
|
||||
3. Remove navigator.language default since that will prevent the argv file from
|
||||
being created if you are changing the language to whatever your browser
|
||||
default happens to be.
|
||||
3. Remove configuredLocale since we have our own thing.
|
||||
4. Move the argv.json file to the server instead of in-browser storage. This is
|
||||
where the current locale is stored and currently the server needs to be able
|
||||
to read it.
|
||||
5. Add the locale flag.
|
||||
6. Remove the redundant locale verification. It does the same as the existing
|
||||
one but is worse because it does not handle non-existent or empty files.
|
||||
7. Replace some caching and Node requires because code-server does not restart
|
||||
when changing the language unlike native Code.
|
||||
|
||||
Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/serverServices.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/serverServices.ts
|
||||
@@ -202,6 +202,9 @@ export async function setupServerService
|
||||
@@ -212,6 +212,9 @@ export async function setupServerService
|
||||
const channel = new ExtensionManagementChannel(extensionManagementService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority));
|
||||
socketServer.registerChannel('extensions', channel);
|
||||
|
||||
@@ -31,14 +33,31 @@ Index: code-server/lib/vscode/src/vs/base/common/platform.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/base/common/platform.ts
|
||||
+++ code-server/lib/vscode/src/vs/base/common/platform.ts
|
||||
@@ -80,8 +80,19 @@ if (typeof navigator === 'object' && !is
|
||||
_isIOS = (_userAgent.indexOf('Macintosh') >= 0 || _userAgent.indexOf('iPad') >= 0 || _userAgent.indexOf('iPhone') >= 0) && !!navigator.maxTouchPoints && navigator.maxTouchPoints > 0;
|
||||
@@ -2,8 +2,6 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
-import * as nls from 'vs/nls';
|
||||
-
|
||||
const LANGUAGE_DEFAULT = 'en';
|
||||
|
||||
let _isWindows = false;
|
||||
@@ -81,17 +79,19 @@ if (typeof navigator === 'object' && !is
|
||||
_isLinux = _userAgent.indexOf('Linux') >= 0;
|
||||
_isWeb = true;
|
||||
- _locale = navigator.language;
|
||||
|
||||
- const configuredLocale = nls.getConfiguredDefaultLocale(
|
||||
- // This call _must_ be done in the file that calls `nls.getConfiguredDefaultLocale`
|
||||
- // to ensure that the NLS AMD Loader plugin has been loaded and configured.
|
||||
- // This is because the loader plugin decides what the default locale is based on
|
||||
- // how it's able to resolve the strings.
|
||||
- nls.localize({ key: 'ensureLoaderPluginIsLoaded', comment: ['{Locked}'] }, '_')
|
||||
- );
|
||||
-
|
||||
- _locale = configuredLocale || LANGUAGE_DEFAULT;
|
||||
+ _locale = LANGUAGE_DEFAULT;
|
||||
|
||||
_language = _locale;
|
||||
+
|
||||
+ const el = typeof document !== 'undefined' && document.getElementById('vscode-remote-nls-configuration');
|
||||
+ const rawNlsConfig = el && el.getAttribute('data-settings');
|
||||
+ if (rawNlsConfig) {
|
||||
@@ -66,21 +85,19 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html
|
||||
<!-- Workbench Icon/Manifest/CSS -->
|
||||
<link rel="icon" href="{{BASE}}/_static/src/browser/media/favicon-dark-support.svg" />
|
||||
<link rel="alternate icon" href="{{BASE}}/_static/src/browser/media/favicon.ico" type="image/x-icon" />
|
||||
@@ -43,17 +46,27 @@
|
||||
self.webPackagePaths[key] = `${baseUrl}/node_modules/${key}/${self.webPackagePaths[key]}`;
|
||||
});
|
||||
|
||||
- // Set up nls if the user is not using the default language (English)
|
||||
@@ -46,15 +49,26 @@
|
||||
// Set up nls if the user is not using the default language (English)
|
||||
const nlsConfig = {};
|
||||
- const locale = navigator.language;
|
||||
const locale = window.localStorage.getItem('vscode.nls.locale') || navigator.language;
|
||||
- if (!locale.startsWith('en')) {
|
||||
- nlsConfig['vs/nls'] = {
|
||||
- availableLanguages: {
|
||||
- '*': locale
|
||||
- },
|
||||
- baseUrl: '{{WORKBENCH_NLS_BASE_URL}}'
|
||||
- translationServiceUrl: '{{WORKBENCH_NLS_BASE_URL}}'
|
||||
- };
|
||||
- }
|
||||
-
|
||||
+ try {
|
||||
+ nlsConfig['vs/nls'] = JSON.parse(document.getElementById("vscode-remote-nls-configuration").getAttribute("data-settings"))
|
||||
+ if (nlsConfig['vs/nls']._resolvedLanguagePackCoreLocation) {
|
||||
@@ -101,14 +118,14 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html
|
||||
+ }
|
||||
+ }
|
||||
+ } catch (error) { /* Probably fine. */ }
|
||||
|
||||
require.config({
|
||||
baseUrl: `${baseUrl}/out`,
|
||||
recordStats: true,
|
||||
Index: code-server/lib/vscode/src/vs/platform/environment/common/environmentService.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/platform/environment/common/environmentService.ts
|
||||
+++ code-server/lib/vscode/src/vs/platform/environment/common/environmentService.ts
|
||||
@@ -108,7 +108,7 @@ export abstract class AbstractNativeEnvi
|
||||
@@ -105,7 +105,7 @@ export abstract class AbstractNativeEnvi
|
||||
return URI.file(join(vscodePortable, 'argv.json'));
|
||||
}
|
||||
|
||||
@@ -190,7 +207,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
import { CharCode } from 'vs/base/common/charCode';
|
||||
import { getRemoteServerRootPath } from 'vs/platform/remote/common/remoteHosts';
|
||||
|
||||
@@ -295,6 +296,8 @@ export class WebClientServer {
|
||||
@@ -299,6 +300,8 @@ export class WebClientServer {
|
||||
|
||||
const base = relativeRoot(getOriginalUrl(req))
|
||||
const vscodeBase = relativePath(getOriginalUrl(req))
|
||||
@@ -199,8 +216,8 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
|
||||
const workbenchWebConfiguration = {
|
||||
remoteAuthority,
|
||||
@@ -338,6 +341,7 @@ export class WebClientServer {
|
||||
WORKBENCH_NLS_BASE_URL: vscodeBase + (nlsBaseUrl ? `${nlsBaseUrl}${this._productService.commit}/${this._productService.version}/` : ''),
|
||||
@@ -339,6 +342,7 @@ export class WebClientServer {
|
||||
WORKBENCH_NLS_BASE_URL: vscodeBase + (nlsBaseUrl ? `${nlsBaseUrl}${!nlsBaseUrl.endsWith('/') ? '/' : ''}${this._productService.commit}/${this._productService.version}/` : ''),
|
||||
BASE: base,
|
||||
VS_BASE: vscodeBase,
|
||||
+ NLS_CONFIGURATION: asJSON(nlsConfiguration),
|
||||
@@ -219,7 +236,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
@@ -96,6 +97,7 @@ export interface ServerParsedArgs {
|
||||
@@ -97,6 +98,7 @@ export interface ServerParsedArgs {
|
||||
'disable-update-check'?: boolean;
|
||||
'auth'?: string
|
||||
'disable-file-downloads'?: boolean;
|
||||
@@ -231,39 +248,85 @@ Index: code-server/lib/vscode/src/vs/workbench/workbench.web.main.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/workbench.web.main.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/workbench.web.main.ts
|
||||
@@ -109,6 +109,12 @@ registerSingleton(IDiagnosticsService, N
|
||||
@@ -122,8 +122,9 @@ import 'vs/workbench/contrib/logs/browse
|
||||
// Explorer
|
||||
import 'vs/workbench/contrib/files/browser/files.web.contribution';
|
||||
|
||||
//#region --- workbench contributions
|
||||
|
||||
+// Localization. These do not actually import anything specific to Electron so
|
||||
+// they should be safe.
|
||||
+import 'vs/workbench/services/localization/electron-sandbox/localeService';
|
||||
-// Localization
|
||||
-import 'vs/workbench/contrib/localization/browser/localization.contribution';
|
||||
+// Localization. This does not actually import anything specific to Electron so
|
||||
+// it should be safe.
|
||||
+import 'vs/workbench/contrib/localization/electron-sandbox/localization.contribution';
|
||||
+import 'vs/platform/languagePacks/browser/languagePacks';
|
||||
+
|
||||
// Output
|
||||
import 'vs/workbench/contrib/output/common/outputChannelModelService';
|
||||
|
||||
// Performance
|
||||
import 'vs/workbench/contrib/performance/browser/performance.web.contribution';
|
||||
Index: code-server/lib/vscode/src/vs/platform/languagePacks/browser/languagePacks.ts
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
--- code-server.orig/lib/vscode/src/vs/platform/languagePacks/browser/languagePacks.ts
|
||||
+++ code-server/lib/vscode/src/vs/platform/languagePacks/browser/languagePacks.ts
|
||||
@@ -0,0 +1,18 @@
|
||||
@@ -4,10 +4,23 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ILanguagePackItem, LanguagePackBaseService } from 'vs/platform/languagePacks/common/languagePacks';
|
||||
+import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
+import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
+import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks';
|
||||
+import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||
+
|
||||
+// @ts-ignore: interface is implemented via proxy
|
||||
+export class LanguagePackService implements ILanguagePackService {
|
||||
+
|
||||
+ declare readonly _serviceBrand: undefined;
|
||||
+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(
|
||||
+ @IRemoteAgentService remoteAgentService: IRemoteAgentService,
|
||||
+ @IExtensionGalleryService extensionGalleryService: IExtensionGalleryService
|
||||
+ ) {
|
||||
+ return ProxyChannel.toService<ILanguagePackService>(remoteAgentService.getConnection()!.getChannel('languagePacks'));
|
||||
+ super(extensionGalleryService)
|
||||
+ this.languagePackService = ProxyChannel.toService<ILanguagePackService>(remoteAgentService.getConnection()!.getChannel('languagePacks'));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+registerSingleton(ILanguagePackService, LanguagePackService, true);
|
||||
getInstalledLanguages(): Promise<ILanguagePackItem[]> {
|
||||
- return Promise.resolve([]);
|
||||
+ return this.languagePackService.getInstalledLanguages()
|
||||
}
|
||||
}
|
||||
Index: code-server/lib/vscode/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts
|
||||
@@ -41,7 +41,8 @@ export class NativeLocaleService impleme
|
||||
@IProductService private readonly productService: IProductService
|
||||
) { }
|
||||
|
||||
- private async validateLocaleFile(): Promise<boolean> {
|
||||
+ // Make public just so we do not have to patch all the unused code out.
|
||||
+ public async validateLocaleFile(): Promise<boolean> {
|
||||
try {
|
||||
const content = await this.textFileService.read(this.environmentService.argvResource, { encoding: 'utf8' });
|
||||
|
||||
@@ -68,9 +69,6 @@ export class NativeLocaleService impleme
|
||||
}
|
||||
|
||||
private async writeLocaleValue(locale: string | undefined): Promise<boolean> {
|
||||
- if (!(await this.validateLocaleFile())) {
|
||||
- return false;
|
||||
- }
|
||||
await this.jsonEditingService.write(this.environmentService.argvResource, [{ path: ['locale'], value: locale }], true);
|
||||
return true;
|
||||
}
|
||||
Index: code-server/lib/vscode/src/vs/base/node/languagePacks.js
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/base/node/languagePacks.js
|
||||
+++ code-server/lib/vscode/src/vs/base/node/languagePacks.js
|
||||
@@ -73,7 +73,10 @@
|
||||
function getLanguagePackConfigurations(userDataPath) {
|
||||
const configFile = path.join(userDataPath, 'languagepacks.json');
|
||||
try {
|
||||
- return nodeRequire(configFile);
|
||||
+ // This must not use Node's require otherwise it will be cached forever.
|
||||
+ // Code can get away with this since the process actually restarts but
|
||||
+ // that is not currently the case with code-server.
|
||||
+ return JSON.parse(fs.readFileSync(configFile, "utf8"));
|
||||
} catch (err) {
|
||||
// Do nothing. If we can't read the file we have no
|
||||
// language pack config.
|
||||
|
||||
24
patches/exec-argv.diff
Normal 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}`];
|
||||
}
|
||||
@@ -20,14 +20,14 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
+import { localize } from 'vs/nls';
|
||||
+import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
|
||||
|
||||
export class CodeServerClient extends Disposable {
|
||||
constructor (
|
||||
+ @INotificationService private notificationService: INotificationService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -42,5 +45,32 @@ export class CodeServerClient extends Di
|
||||
@@ -42,5 +45,31 @@ export class CodeServerClient extends Di
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -49,7 +49,6 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
|
||||
+ class: undefined,
|
||||
+ enabled: true,
|
||||
+ checked: true,
|
||||
+ dispose: () => undefined,
|
||||
+ run: () => {
|
||||
+ return Promise.resolve();
|
||||
+ },
|
||||
|
||||
@@ -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';
|
||||
@@ -109,6 +110,9 @@ export class BrowserMain extends Disposa
|
||||
@@ -116,6 +117,9 @@ export class BrowserMain extends Disposa
|
||||
// Startup
|
||||
const instantiationService = workbench.startup();
|
||||
|
||||
@@ -263,7 +263,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -307,6 +307,7 @@ export class WebClientServer {
|
||||
@@ -308,6 +308,7 @@ export class WebClientServer {
|
||||
folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']),
|
||||
workspaceUri: resolveWorkspaceURI(this._environmentService.args['default-workspace']),
|
||||
productConfiguration: <Partial<IProductConfiguration>>{
|
||||
|
||||
@@ -20,7 +20,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
|
||||
@@ -299,6 +299,7 @@ export class WebClientServer {
|
||||
@@ -303,6 +303,7 @@ export class WebClientServer {
|
||||
const workbenchWebConfiguration = {
|
||||
remoteAuthority,
|
||||
webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
|
||||
@@ -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
|
||||
@@ -245,6 +245,11 @@ export interface IWorkbenchConstructionO
|
||||
@@ -262,6 +262,11 @@ export interface IWorkbenchConstructionO
|
||||
*/
|
||||
readonly configurationDefaults?: Record<string, any>;
|
||||
|
||||
@@ -63,4 +63,4 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi
|
||||
+ }
|
||||
|
||||
@memoize
|
||||
get settingsResource(): URI { return joinPath(this.userRoamingDataHome, 'settings.json'); }
|
||||
get argvResource(): URI { return joinPath(this.userRoamingDataHome, 'argv.json'); }
|
||||
|
||||
@@ -7,7 +7,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -300,7 +300,10 @@ export class WebClientServer {
|
||||
@@ -304,7 +304,10 @@ export class WebClientServer {
|
||||
remoteAuthority,
|
||||
webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
|
||||
_wrapWebWorkerExtHostInIframe,
|
||||
|
||||
@@ -28,7 +28,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
@@ -92,6 +93,7 @@ export const serverOptions: OptionDescri
|
||||
@@ -93,6 +94,7 @@ export const serverOptions: OptionDescri
|
||||
export interface ServerParsedArgs {
|
||||
/* ----- code-server ----- */
|
||||
'disable-update-check'?: boolean;
|
||||
@@ -40,11 +40,11 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -309,6 +309,7 @@ export class WebClientServer {
|
||||
@@ -313,6 +313,7 @@ export class WebClientServer {
|
||||
codeServerVersion: this._productService.codeServerVersion,
|
||||
rootEndpoint: base,
|
||||
updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
|
||||
+ logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined,
|
||||
+ logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined,
|
||||
embedderIdentifier: 'server-distro',
|
||||
extensionsGallery: this._productService.extensionsGallery,
|
||||
},
|
||||
|
||||
@@ -48,7 +48,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -308,14 +308,7 @@ export class WebClientServer {
|
||||
@@ -312,14 +312,7 @@ export class WebClientServer {
|
||||
codeServerVersion: this._productService.codeServerVersion,
|
||||
rootEndpoint: base,
|
||||
embedderIdentifier: 'server-distro',
|
||||
|
||||
@@ -9,7 +9,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/extensions/common/abstra
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/services/extensions/common/abstractExtensionService.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/services/extensions/common/abstractExtensionService.ts
|
||||
@@ -1451,7 +1451,7 @@ class ProposedApiController {
|
||||
@@ -1458,7 +1458,7 @@ class ProposedApiController {
|
||||
|
||||
this._envEnabledExtensions = new Set((_environmentService.extensionEnabledProposedApi ?? []).map(id => ExtensionIdentifier.toKey(id)));
|
||||
|
||||
|
||||
@@ -32,46 +32,42 @@ Index: code-server/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityReso
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
-import { IRemoteAuthorityResolverService, IRemoteConnectionData, ResolvedAuthority, ResolverResult } from 'vs/platform/remote/common/remoteAuthorityResolver';
|
||||
+import { IRemoteAuthorityResolverService, IRemoteConnectionData, ResolvedAuthority, ResolvedOptions, ResolverResult } from 'vs/platform/remote/common/remoteAuthorityResolver';
|
||||
import { getRemoteServerRootPath } from 'vs/platform/remote/common/remoteHosts';
|
||||
import { getRemoteServerRootPath, parseAuthorityWithOptionalPort } from 'vs/platform/remote/common/remoteHosts';
|
||||
|
||||
export class RemoteAuthorityResolverService extends Disposable implements IRemoteAuthorityResolverService {
|
||||
@@ -22,7 +22,7 @@ export class RemoteAuthorityResolverServ
|
||||
private readonly _connectionToken: string | undefined;
|
||||
@@ -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: string | undefined, resourceUriProvider: ((uri: URI) => URI) | undefined) {
|
||||
+ constructor(@IProductService productService: IProductService, connectionToken: string | undefined, resourceUriProvider: ((uri: URI) => URI) | undefined, private readonly proxyEndpointTemplate?: 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();
|
||||
this._cache = new Map<string, ResolverResult>();
|
||||
this._connectionToken = connectionToken;
|
||||
@@ -62,12 +62,17 @@ export class RemoteAuthorityResolverServ
|
||||
this._connectionTokens = new Map<string, string>();
|
||||
@@ -61,9 +61,14 @@ export class RemoteAuthorityResolverServ
|
||||
|
||||
private _doResolveAuthority(authority: string): ResolverResult {
|
||||
const connectionToken = this._connectionTokens.get(authority) || this._connectionToken;
|
||||
+ let options: ResolvedOptions | undefined
|
||||
private async _doResolveAuthority(authority: string): Promise<ResolverResult> {
|
||||
const connectionToken = await Promise.resolve(this._connectionTokens.get(authority) || this._connectionToken);
|
||||
+ let options: ResolvedOptions | undefined;
|
||||
+ if (this.proxyEndpointTemplate) {
|
||||
+ const proxyUrl = new URL(this.proxyEndpointTemplate, window.location.href);
|
||||
+ options = { extensionHostEnv: { VSCODE_PROXY_URI: decodeURIComponent(proxyUrl.toString()) }}
|
||||
+ }
|
||||
if (authority.indexOf(':') >= 0) {
|
||||
const pieces = authority.split(':');
|
||||
- return { authority: { authority, host: pieces[0], port: parseInt(pieces[1], 10), connectionToken } };
|
||||
+ return { authority: { authority, host: pieces[0], port: parseInt(pieces[1], 10), connectionToken }, options };
|
||||
}
|
||||
const port = (/^https:/.test(window.location.href) ? 443 : 80);
|
||||
- return { authority: { authority, host: authority, port: port, connectionToken } };
|
||||
+ return { authority: { authority, host: authority, port: port, connectionToken }, options };
|
||||
}
|
||||
|
||||
_clearResolvedAuthority(authority: string): void {
|
||||
const defaultPort = (/^https:/.test(window.location.href) ? 443 : 80);
|
||||
const { host, port } = parseAuthorityWithOptionalPort(authority, defaultPort);
|
||||
- const result: ResolverResult = { authority: { authority, host: host, port: port, connectionToken } };
|
||||
+ const result: ResolverResult = { authority: { authority, host: host, port: port, connectionToken }, options };
|
||||
RemoteAuthorities.set(authority, result.authority.host, result.authority.port);
|
||||
this._cache.set(authority, result);
|
||||
this._onDidChangeConnectionData.fire();
|
||||
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
|
||||
@@ -310,6 +310,7 @@ export class WebClientServer {
|
||||
@@ -314,6 +314,7 @@ export class WebClientServer {
|
||||
rootEndpoint: base,
|
||||
updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
|
||||
logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined,
|
||||
logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined,
|
||||
+ proxyEndpointTemplate: base + '/proxy/{{port}}',
|
||||
embedderIdentifier: 'server-distro',
|
||||
extensionsGallery: this._productService.extensionsGallery,
|
||||
@@ -80,7 +76,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.main.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/browser/web.main.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/browser/web.main.ts
|
||||
@@ -209,7 +209,7 @@ export class BrowserMain extends Disposa
|
||||
@@ -247,7 +247,7 @@ export class BrowserMain extends Disposa
|
||||
|
||||
// Remote
|
||||
const connectionToken = environmentService.options.connectionToken || getCookieValue(connectionTokenCookieName);
|
||||
|
||||
13
patches/safari-console.diff
Normal file
@@ -0,0 +1,13 @@
|
||||
Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts
|
||||
@@ -286,7 +286,7 @@ export class XtermTerminal extends Dispo
|
||||
}
|
||||
|
||||
private _shouldLoadCanvas(): boolean {
|
||||
- return (this._configHelper.config.gpuAcceleration === 'auto' && (XtermTerminal._suggestedRendererType === undefined || XtermTerminal._suggestedRendererType === 'canvas')) || this._configHelper.config.gpuAcceleration === 'canvas';
|
||||
+ return !isSafari && (this._configHelper.config.gpuAcceleration === 'auto' && (XtermTerminal._suggestedRendererType === undefined || XtermTerminal._suggestedRendererType === 'canvas')) || this._configHelper.config.gpuAcceleration === 'canvas';
|
||||
}
|
||||
|
||||
forceRedraw() {
|
||||
@@ -20,3 +20,5 @@ disable-downloads.diff
|
||||
telemetry.diff
|
||||
display-language.diff
|
||||
cli-window-open.diff
|
||||
exec-argv.diff
|
||||
safari-console.diff
|
||||
|
||||
@@ -21,9 +21,9 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -315,6 +315,10 @@ export class WebClientServer {
|
||||
@@ -319,6 +319,10 @@ export class WebClientServer {
|
||||
updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
|
||||
logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined,
|
||||
logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined,
|
||||
proxyEndpointTemplate: base + '/proxy/{{port}}',
|
||||
+ serviceWorker: {
|
||||
+ scope: vscodeBase + '/',
|
||||
|
||||
@@ -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
|
||||
@@ -194,8 +194,7 @@ function packageTask(type, platform, arc
|
||||
@@ -196,8 +196,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) => {
|
||||
@@ -234,9 +233,9 @@ function packageTask(type, platform, arc
|
||||
@@ -236,9 +235,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;
|
||||
@@ -371,7 +370,7 @@ function tweakProductForServerWeb(produc
|
||||
@@ -373,7 +372,7 @@ function tweakProductForServerWeb(produc
|
||||
const minifyTask = task.define(`minify-vscode-${type}`, task.series(
|
||||
optimizeTask,
|
||||
util.rimraf(`out-vscode-${type}-min`),
|
||||
|
||||
@@ -24,7 +24,7 @@ Index: code-server/lib/vscode/src/vs/workbench/api/node/extHostExtensionService.
|
||||
import * as performance from 'vs/base/common/performance';
|
||||
import { createApiFactoryAndRegisterActors } from 'vs/workbench/api/common/extHost.api.impl';
|
||||
import { RequireInterceptor } from 'vs/workbench/api/common/extHostRequireInterceptor';
|
||||
@@ -69,6 +71,10 @@ export class ExtHostExtensionService ext
|
||||
@@ -72,6 +74,10 @@ export class ExtHostExtensionService ext
|
||||
if (this._initData.remote.isRemote && this._initData.remote.authority) {
|
||||
const cliServer = this._instaService.createInstance(CLIServer);
|
||||
process.env['VSCODE_IPC_HOOK_CLI'] = cliServer.ipcHandlePath;
|
||||
|
||||
@@ -1,127 +1,57 @@
|
||||
Add support for telemetry endpoint
|
||||
|
||||
Contains some fixes included in https://github.com/microsoft/vscode/commit/b108bc8294ce920fcf2ee8d53f97c3bcf3316e1c
|
||||
|
||||
To test:
|
||||
1. Look inside a build of code-server, inside `lib/vscode/vs/server/node/server.main.js`
|
||||
2. Search for a `JSON.stringify` near `TelemetryClient`
|
||||
3. throw in a `console.log()` before it and make sure it logs telemetry data
|
||||
|
||||
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 { REMOTE_FILE_SYSTEM_CHANNEL_NAME
|
||||
import { ExtensionHostStatusService, IExtensionHostStatusService } from 'vs/server/node/extensionHostStatusService';
|
||||
import { IExtensionsScannerService } from 'vs/platform/extensionManagement/common/extensionsScannerService';
|
||||
@@ -71,6 +71,7 @@ import { IExtensionsScannerService } fro
|
||||
import { ExtensionsScannerService } from 'vs/server/node/extensionsScannerService';
|
||||
import { ExtensionsProfileScannerService, IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService';
|
||||
import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
|
||||
+import { TelemetryClient } from "vs/server/node/telemetryClient";
|
||||
import { NullPolicyService } from 'vs/platform/policy/common/policy';
|
||||
import { OneDataSystemAppender } from 'vs/platform/telemetry/node/1dsAppender';
|
||||
|
||||
const eventPrefix = 'monacoworkbench';
|
||||
@@ -123,7 +124,11 @@ export async function setupServerService
|
||||
let appInsightsAppender: ITelemetryAppender = NullAppender;
|
||||
@@ -133,10 +134,13 @@ export async function setupServerService
|
||||
const machineId = await getMachineId();
|
||||
const isInternal = isInternalTelemetry(productService, configurationService);
|
||||
if (supportsTelemetry(productService, environmentService)) {
|
||||
- if (productService.aiConfig && productService.aiConfig.asimovKey) {
|
||||
- if (productService.aiConfig && productService.aiConfig.ariaKey) {
|
||||
+ const telemetryEndpoint = process.env.CS_TELEMETRY_URL || "https://v1.telemetry.coder.com/track";
|
||||
+ if (telemetryEndpoint) {
|
||||
+ appInsightsAppender = new AppInsightsAppender(eventPrefix, null, () => new TelemetryClient(telemetryEndpoint) as any);
|
||||
+ disposables.add(toDisposable(() => appInsightsAppender!.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
|
||||
+ } else if (productService.aiConfig && productService.aiConfig.asimovKey) {
|
||||
appInsightsAppender = new AppInsightsAppender(eventPrefix, null, productService.aiConfig.asimovKey);
|
||||
disposables.add(toDisposable(() => appInsightsAppender!.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
|
||||
+ oneDsAppender = new OneDataSystemAppender(false, eventPrefix, null, () => new TelemetryClient(telemetryEndpoint));
|
||||
+ } else if (productService.aiConfig && productService.aiConfig.ariaKey) {
|
||||
oneDsAppender = new OneDataSystemAppender(isInternal, eventPrefix, null, productService.aiConfig.ariaKey);
|
||||
- disposables.add(toDisposable(() => oneDsAppender?.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
|
||||
}
|
||||
+ disposables.add(toDisposable(() => oneDsAppender?.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
|
||||
|
||||
const config: ITelemetryServiceConfig = {
|
||||
appenders: [oneDsAppender],
|
||||
Index: code-server/lib/vscode/src/vs/server/node/telemetryClient.ts
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ code-server/lib/vscode/src/vs/server/node/telemetryClient.ts
|
||||
@@ -0,0 +1,135 @@
|
||||
+import * as appInsights from 'applicationinsights';
|
||||
@@ -0,0 +1,49 @@
|
||||
+import { AppInsightsCore, IExtendedTelemetryItem, ITelemetryItem } from '@microsoft/1ds-core-js';
|
||||
+import * as https from 'https';
|
||||
+import * as http from 'http';
|
||||
+import * as os from 'os';
|
||||
+
|
||||
+class Channel {
|
||||
+ public get _sender() {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+ public get _buffer() {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public setUseDiskRetryCaching(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+ public send(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+ public triggerSend(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+// Unable to use implements because TypeScript tells you a private property is
|
||||
+// missing but if you add it then it complains they have different private
|
||||
+// properties. Uncommenting it during development can be helpful though to see
|
||||
+// if anything is missing.
|
||||
+export class TelemetryClient /* implements appInsights.TelemetryClient */ {
|
||||
+ private _telemetryProcessors: any = undefined;
|
||||
+ public context: any = undefined;
|
||||
+ public commonProperties: any = undefined;
|
||||
+ public config: any = {};
|
||||
+ public quickPulseClient: any = undefined;
|
||||
+
|
||||
+ public channel: any = new Channel();
|
||||
+
|
||||
+export class TelemetryClient extends AppInsightsCore {
|
||||
+ public constructor(private readonly endpoint: string) {
|
||||
+ // Nothing to do.
|
||||
+ super();
|
||||
+ }
|
||||
+
|
||||
+ public addTelemetryProcessor(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public clearTelemetryProcessors(): void {
|
||||
+ if (this._telemetryProcessors) {
|
||||
+ this._telemetryProcessors = undefined;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public runTelemetryProcessors(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public trackTrace(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public trackMetric(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public trackException(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public trackRequest(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public trackDependency(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public track(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public trackNodeHttpRequestSync(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public trackNodeHttpRequest(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public trackNodeHttpDependency(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public trackEvent(options: appInsights.Contracts.EventTelemetry): void {
|
||||
+ public override track(item: IExtendedTelemetryItem | ITelemetryItem): void {
|
||||
+ const options = item.baseData || {}
|
||||
+ if (!options.properties) {
|
||||
+ options.properties = {};
|
||||
+ }
|
||||
@@ -158,51 +88,88 @@ Index: code-server/lib/vscode/src/vs/server/node/telemetryClient.ts
|
||||
+ request.end();
|
||||
+ } catch (error) {}
|
||||
+ }
|
||||
+
|
||||
+ public flush(options: { callback: (v: string) => void }): void {
|
||||
+ if (options.callback) {
|
||||
+ options.callback('');
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
Index: code-server/lib/vscode/src/vs/workbench/services/telemetry/browser/telemetryService.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/services/telemetry/browser/telemetryService.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/services/telemetry/browser/telemetryService.ts
|
||||
@@ -120,16 +120,19 @@ export class TelemetryService extends Di
|
||||
@@ -15,7 +15,7 @@ import { ClassifiedEvent, IGDPRProperty,
|
||||
import { ITelemetryData, ITelemetryInfo, ITelemetryService, TelemetryLevel, TELEMETRY_SETTING_ID } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { TelemetryLogAppender } from 'vs/platform/telemetry/common/telemetryLogAppender';
|
||||
import { ITelemetryServiceConfig, TelemetryService as BaseTelemetryService } from 'vs/platform/telemetry/common/telemetryService';
|
||||
-import { isInternalTelemetry, ITelemetryAppender, NullTelemetryService, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
+import { getTelemetryLevel, isInternalTelemetry, ITelemetryAppender, NullTelemetryService, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
|
||||
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||
import { resolveWorkbenchCommonProperties } from 'vs/workbench/services/telemetry/browser/workbenchCommonProperties';
|
||||
@@ -24,7 +24,7 @@ export class TelemetryService extends Di
|
||||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
- private impl: ITelemetryService;
|
||||
+ private impl: ITelemetryService = NullTelemetryService;
|
||||
public readonly sendErrorTelemetry = true;
|
||||
|
||||
constructor(
|
||||
@@ -37,11 +37,7 @@ export class TelemetryService extends Di
|
||||
) {
|
||||
super();
|
||||
|
||||
- if (supportsTelemetry(productService, environmentService) && productService.aiConfig?.asimovKey) {
|
||||
+ if (supportsTelemetry(productService, environmentService)) {
|
||||
- if (supportsTelemetry(productService, environmentService) && productService.aiConfig?.ariaKey) {
|
||||
- this.impl = this.initializeService(environmentService, loggerService, configurationService, storageService, productService, remoteAgentService);
|
||||
- } else {
|
||||
- this.impl = NullTelemetryService;
|
||||
- }
|
||||
+ this.impl = this.initializeService(environmentService, loggerService, configurationService, storageService, productService, remoteAgentService);
|
||||
|
||||
// When the level changes it could change from off to on and we want to make sure telemetry is properly intialized
|
||||
this._register(configurationService.onDidChangeConfiguration(e => {
|
||||
@@ -64,23 +60,28 @@ export class TelemetryService extends Di
|
||||
productService: IProductService,
|
||||
remoteAgentService: IRemoteAgentService
|
||||
) {
|
||||
- const telemetrySupported = supportsTelemetry(productService, environmentService) && productService.aiConfig?.ariaKey;
|
||||
- if (telemetrySupported && this.impl === NullTelemetryService && this.telemetryLevel.value !== TelemetryLevel.NONE) {
|
||||
+ const telemetrySupported = supportsTelemetry(productService, environmentService);
|
||||
+ if (telemetrySupported && getTelemetryLevel(configurationService) !== TelemetryLevel.NONE && this.impl === NullTelemetryService) {
|
||||
// If remote server is present send telemetry through that, else use the client side appender
|
||||
- const telemetryProvider: ITelemetryAppender = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : new WebAppInsightsAppender('monacoworkbench', productService.aiConfig?.asimovKey);
|
||||
const appenders = [];
|
||||
const isInternal = isInternalTelemetry(productService, configurationService);
|
||||
- const telemetryProvider: ITelemetryAppender = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : new OneDataSystemWebAppender(isInternal, 'monacoworkbench', null, productService.aiConfig?.ariaKey);
|
||||
- appenders.push(telemetryProvider);
|
||||
- appenders.push(new TelemetryLogAppender(loggerService, environmentService));
|
||||
- const config: ITelemetryServiceConfig = {
|
||||
- appenders: [new WebTelemetryAppender(telemetryProvider), new TelemetryLogAppender(loggerService, environmentService)],
|
||||
- commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.remoteAuthority, productService.embedderIdentifier, productService.removeTelemetryMachineId, environmentService.options && environmentService.options.resolveCommonTelemetryProperties),
|
||||
- appenders,
|
||||
- commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, isInternal, environmentService.remoteAuthority, productService.embedderIdentifier, productService.removeTelemetryMachineId, environmentService.options && environmentService.options.resolveCommonTelemetryProperties),
|
||||
- sendErrorTelemetry: this.sendErrorTelemetry,
|
||||
- };
|
||||
-
|
||||
- this.impl = this._register(new BaseTelemetryService(config, configurationService, productService));
|
||||
+ const telemetryProvider: ITelemetryAppender | undefined = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : productService.aiConfig?.asimovKey ? new WebAppInsightsAppender('monacoworkbench', productService.aiConfig?.asimovKey) : undefined;
|
||||
+ const telemetryProvider: ITelemetryAppender | undefined = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : productService.aiConfig?.ariaKey ? new OneDataSystemWebAppender(isInternal, 'monacoworkbench', null, productService.aiConfig?.ariaKey) : undefined;
|
||||
+ if (telemetryProvider) {
|
||||
+ appenders.push(telemetryProvider);
|
||||
+ appenders.push(new TelemetryLogAppender(loggerService, environmentService));
|
||||
+ const config: ITelemetryServiceConfig = {
|
||||
+ appenders: [new WebTelemetryAppender(telemetryProvider), new TelemetryLogAppender(loggerService, environmentService)],
|
||||
+ commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.remoteAuthority, productService.embedderIdentifier, productService.removeTelemetryMachineId, environmentService.options && environmentService.options.resolveCommonTelemetryProperties),
|
||||
+ appenders,
|
||||
+ commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, isInternal, environmentService.remoteAuthority, productService.embedderIdentifier, productService.removeTelemetryMachineId, environmentService.options && environmentService.options.resolveCommonTelemetryProperties),
|
||||
+ sendErrorTelemetry: this.sendErrorTelemetry,
|
||||
+ };
|
||||
+ this.impl = this._register(new BaseTelemetryService(config, configurationService, productService));
|
||||
+
|
||||
+ return this._register(new BaseTelemetryService(config, configurationService, productService));
|
||||
+ } else {
|
||||
+ this.impl = NullTelemetryService;
|
||||
+ return this.impl;
|
||||
+ }
|
||||
} else {
|
||||
this.impl = NullTelemetryService;
|
||||
|
||||
- return this._register(new BaseTelemetryService(config, configurationService, productService));
|
||||
}
|
||||
- return NullTelemetryService;
|
||||
+ return this.impl;
|
||||
}
|
||||
|
||||
setExperimentProperty(name: string, value: string): void {
|
||||
Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -320,6 +320,7 @@ export class WebClientServer {
|
||||
@@ -324,6 +324,7 @@ export class WebClientServer {
|
||||
scope: vscodeBase + '/',
|
||||
path: base + '/_static/out/browser/serviceWorker.js',
|
||||
},
|
||||
|
||||
@@ -9,55 +9,28 @@ ensures that different browser paths will be unique (for example /workspace1 and
|
||||
The easiest way to test is to open files in the same workspace using both / and
|
||||
/vscode and make sure they are not interacting with each other.
|
||||
|
||||
It should also migrate old databases which can be tested by opening in an old
|
||||
code-server.
|
||||
|
||||
This has e2e tests.
|
||||
|
||||
Index: code-server/lib/vscode/src/vs/platform/storage/browser/storageService.ts
|
||||
Index: code-server/lib/vscode/src/vs/workbench/services/storage/browser/storageService.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/platform/storage/browser/storageService.ts
|
||||
+++ code-server/lib/vscode/src/vs/platform/storage/browser/storageService.ts
|
||||
@@ -13,6 +13,7 @@ import { InMemoryStorageDatabase, isStor
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { AbstractStorageService, IS_NEW_KEY, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/services/storage/browser/storageService.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/services/storage/browser/storageService.ts
|
||||
@@ -17,6 +17,7 @@ import { AbstractStorageService, isProfi
|
||||
import { IUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile';
|
||||
import { IAnyWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace';
|
||||
import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile';
|
||||
+import { hash } from 'vs/base/common/hash';
|
||||
|
||||
export class BrowserStorageService extends AbstractStorageService {
|
||||
|
||||
@@ -36,7 +37,11 @@ export class BrowserStorageService exten
|
||||
}
|
||||
|
||||
private getId(scope: StorageScope): string {
|
||||
- return scope === StorageScope.GLOBAL ? 'global' : this.payload.id;
|
||||
+ // Add a unique ID based on the current path for per-workspace databases.
|
||||
+ // This prevents workspaces on different machines that share the same domain
|
||||
+ // and file path from colliding (since it does not appear IndexedDB can be
|
||||
+ // scoped to a path) as long as they are hosted on different paths.
|
||||
+ return scope === StorageScope.GLOBAL ? 'global' : (this.payload.id + '-' + hash(location.pathname.toString().replace(/\/$/, "")).toString(16));
|
||||
}
|
||||
|
||||
protected async doInitialize(): Promise<void> {
|
||||
@@ -75,6 +80,21 @@ export class BrowserStorageService exten
|
||||
const firstWorkspaceOpen = this.workspaceStorage.getBoolean(IS_NEW_KEY);
|
||||
if (firstWorkspaceOpen === undefined) {
|
||||
this.workspaceStorage.set(IS_NEW_KEY, true);
|
||||
+ // Migrate the old database.
|
||||
+ let db: IIndexedDBStorageDatabase | undefined
|
||||
+ try {
|
||||
+ db = await IndexedDBStorageDatabase.create({ id: this.payload.id }, this.logService)
|
||||
+ const items = await db.getItems()
|
||||
+ for (const [key, value] of items) {
|
||||
+ this.workspaceStorage.set(key, value);
|
||||
+ }
|
||||
+ } catch (error) {
|
||||
+ this.logService.error(`[IndexedDB Storage ${this.payload.id}] migrate error: ${toErrorMessage(error)}`);
|
||||
+ } finally {
|
||||
+ if (db) {
|
||||
+ db.close()
|
||||
+ }
|
||||
+ }
|
||||
} else if (firstWorkspaceOpen) {
|
||||
this.workspaceStorage.set(IS_NEW_KEY, false);
|
||||
@@ -67,7 +68,11 @@ export class BrowserStorageService exten
|
||||
return `global-${this.profileStorageProfile.id}`;
|
||||
}
|
||||
case StorageScope.WORKSPACE:
|
||||
- return this.payload.id;
|
||||
+ // Add a unique ID based on the current path for per-workspace databases.
|
||||
+ // This prevents workspaces on different machines that share the same domain
|
||||
+ // and file path from colliding (since it does not appear IndexedDB can be
|
||||
+ // scoped to a path) as long as they are hosted on different paths.
|
||||
+ return this.payload.id + '-' + hash(location.pathname.toString().replace(/\/$/, "")).toString(16);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ const lastNoti = this.storageService.getNumber('csLastUpdateNotification', StorageScope.GLOBAL);
|
||||
+ const lastNoti = this.storageService.getNumber('csLastUpdateNotification', StorageScope.APPLICATION);
|
||||
+ if (lastNoti) {
|
||||
+ // Only remind them again after 1 week.
|
||||
+ const timeout = 1000 * 60 * 60 * 24 * 7;
|
||||
@@ -67,7 +67,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ this.storageService.store('csLastUpdateNotification', Date.now(), StorageScope.GLOBAL, StorageTarget.MACHINE);
|
||||
+ this.storageService.store('csLastUpdateNotification', Date.now(), StorageScope.APPLICATION, StorageTarget.MACHINE);
|
||||
+
|
||||
+ this.notificationService.notify({
|
||||
+ severity: Severity.Info,
|
||||
@@ -105,7 +105,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -308,6 +308,7 @@ export class WebClientServer {
|
||||
@@ -312,6 +312,7 @@ export class WebClientServer {
|
||||
productConfiguration: <Partial<IProductConfiguration>>{
|
||||
codeServerVersion: this._productService.codeServerVersion,
|
||||
rootEndpoint: base,
|
||||
@@ -126,7 +126,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
@@ -88,6 +90,8 @@ export const serverOptions: OptionDescri
|
||||
@@ -89,6 +91,8 @@ export const serverOptions: OptionDescri
|
||||
};
|
||||
|
||||
export interface ServerParsedArgs {
|
||||
|
||||
@@ -24,7 +24,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
|
||||
@@ -183,7 +183,7 @@ export class BrowserWorkbenchEnvironment
|
||||
@@ -177,7 +177,7 @@ export class BrowserWorkbenchEnvironment
|
||||
|
||||
@memoize
|
||||
get webviewExternalEndpoint(): string {
|
||||
@@ -37,7 +37,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -298,6 +298,7 @@ export class WebClientServer {
|
||||
@@ -302,6 +302,7 @@ export class WebClientServer {
|
||||
|
||||
const workbenchWebConfiguration = {
|
||||
remoteAuthority,
|
||||
@@ -53,8 +53,8 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<meta http-equiv="Content-Security-Policy"
|
||||
- content="default-src 'none'; script-src 'sha256-xgIcbQmGjpT42GEj54VFSNh6MI15PZ2D1+DdVehfYBI=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
|
||||
+ content="default-src 'none'; script-src 'sha256-aOCIU83V9nV+0ERJudbrKLqgIVOHqU71i4Lv5urjGTI=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
|
||||
- content="default-src 'none'; script-src 'sha256-JpX/ganPoxpavjxWCz9DUZgwVZ59o2lwSYTQrziPsdU=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
|
||||
+ content="default-src 'none'; script-src 'sha256-BRi/ZOLWtsisl3jAheglVzKmoA1T6n2Mmf2NM4UnIXE=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
|
||||
|
||||
<!-- Disable pinch zooming -->
|
||||
<meta name="viewport"
|
||||
@@ -96,8 +96,8 @@ Index: code-server/lib/vscode/src/vs/workbench/services/extensions/worker/webWor
|
||||
<meta http-equiv="Content-Security-Policy" content="
|
||||
default-src 'none';
|
||||
child-src 'self' data: blob:;
|
||||
- script-src 'self' 'unsafe-eval' 'sha256-fh3TwPMflhsEIpR8g1OYTIMVWhXTLcjQ9kh2tIpmv54=' https:;
|
||||
+ script-src 'self' 'unsafe-eval' 'sha256-yHVIAbzODFRINjoLGID5qWPP45HzMtwhyVRC+7yiuXg=' https:;
|
||||
- script-src 'self' 'unsafe-eval' 'sha256-/r7rqQ+yrxt57sxLuQ6AMYcy/lUpvAIzHjIJt/OeLWU=' https:;
|
||||
+ script-src 'self' 'unsafe-eval' 'sha256-TkIM/TmudlFEe0ZRp0ptvN54LClwk30Rql4ZPE0hm/I=' https:;
|
||||
connect-src 'self' https: wss: http://localhost:* http://127.0.0.1:* ws://localhost:* ws://127.0.0.1:*;"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -501,7 +501,7 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
|
||||
args.verbose = false
|
||||
break
|
||||
case LogLevel.Warn:
|
||||
logger.level = Level.Warning
|
||||
logger.level = Level.Warn
|
||||
args.verbose = false
|
||||
break
|
||||
case LogLevel.Error:
|
||||
|
||||
@@ -94,8 +94,8 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
|
||||
app.router.use("/", domainProxy.router)
|
||||
app.wsRouter.use("/", domainProxy.wsRouter.router)
|
||||
|
||||
app.router.all("/proxy/(:port)(/*)?", (req, res) => {
|
||||
pathProxy.proxy(req, res)
|
||||
app.router.all("/proxy/(:port)(/*)?", async (req, res) => {
|
||||
await pathProxy.proxy(req, res)
|
||||
})
|
||||
app.wsRouter.get("/proxy/(:port)(/*)?", async (req) => {
|
||||
await pathProxy.wsProxy(req as pluginapi.WebsocketRequest)
|
||||
@@ -103,8 +103,8 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
|
||||
// These two routes pass through the path directly.
|
||||
// So the proxied app must be aware it is running
|
||||
// under /absproxy/<someport>/
|
||||
app.router.all("/absproxy/(:port)(/*)?", (req, res) => {
|
||||
pathProxy.proxy(req, res, {
|
||||
app.router.all("/absproxy/(:port)(/*)?", async (req, res) => {
|
||||
await pathProxy.proxy(req, res, {
|
||||
passthroughPath: true,
|
||||
})
|
||||
})
|
||||
|
||||
@@ -14,14 +14,14 @@ const getProxyTarget = (req: Request, passthroughPath?: boolean): string => {
|
||||
return `http://0.0.0.0:${req.params.port}/${req.params[0] || ""}${query ? `?${query}` : ""}`
|
||||
}
|
||||
|
||||
export function proxy(
|
||||
export async function proxy(
|
||||
req: Request,
|
||||
res: Response,
|
||||
opts?: {
|
||||
passthroughPath?: boolean
|
||||
},
|
||||
): void {
|
||||
if (!authenticated(req)) {
|
||||
): Promise<void> {
|
||||
if (!(await authenticated(req))) {
|
||||
// If visiting the root (/:port only) redirect to the login page.
|
||||
if (!req.params[0] || req.params[0] === "/") {
|
||||
const to = self(req)
|
||||
|
||||
@@ -127,7 +127,10 @@ export class CodeServerRouteWrapper {
|
||||
|
||||
private $proxyWebsocket = async (req: WebsocketRequest) => {
|
||||
const wrappedSocket = await this._socketProxyProvider.createProxy(req.ws)
|
||||
this._codeServerMain.handleUpgrade(req, wrappedSocket)
|
||||
// This should actually accept a duplex stream but it seems Code has not
|
||||
// been updated to match the Node 16 types so cast for now. There does not
|
||||
// appear to be any code specific to sockets so this should be fine.
|
||||
this._codeServerMain.handleUpgrade(req, wrappedSocket as net.Socket)
|
||||
|
||||
req.ws.resume()
|
||||
}
|
||||
@@ -170,7 +173,7 @@ export class CodeServerRouteWrapper {
|
||||
|
||||
constructor() {
|
||||
this.router.get("/", this.ensureCodeServerLoaded, this.$root)
|
||||
this.router.get(/manifest.json$/, this.manifest)
|
||||
this.router.get("/manifest.json", this.manifest)
|
||||
this.router.all("*", ensureAuthenticated, this.ensureCodeServerLoaded, this.$proxyRequest)
|
||||
this._wsRouterWrapper.ws("*", ensureAuthenticated, this.ensureCodeServerLoaded, this.$proxyWebsocket)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { promises as fs } from "fs"
|
||||
import * as net from "net"
|
||||
import * as path from "path"
|
||||
import * as stream from "stream"
|
||||
import * as tls from "tls"
|
||||
import { Emitter } from "../common/emitter"
|
||||
import { generateUuid } from "../common/util"
|
||||
@@ -27,10 +28,13 @@ export class SocketProxyProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a socket proxy for TLS sockets. If it's not a TLS socket the
|
||||
* original socket is returned. This will spawn a proxy server on demand.
|
||||
* Create a socket proxy for TLS sockets. If it is not a TLS socket the
|
||||
* original socket or stream is returned. This will spawn a proxy server on
|
||||
* demand.
|
||||
*/
|
||||
public async createProxy(socket: net.Socket): Promise<net.Socket> {
|
||||
public async createProxy(socket: tls.TLSSocket | net.Socket): Promise<net.Socket>
|
||||
public async createProxy(socket: stream.Duplex): Promise<stream.Duplex>
|
||||
public async createProxy(socket: tls.TLSSocket | net.Socket | stream.Duplex): Promise<net.Socket | stream.Duplex> {
|
||||
if (!(socket instanceof tls.TLSSocket)) {
|
||||
return socket
|
||||
}
|
||||
|
||||
@@ -317,8 +317,7 @@ export class ParentProcess extends Process {
|
||||
}
|
||||
|
||||
private spawn(): cp.ChildProcess {
|
||||
// Use spawn (instead of fork) to use the new binary in case it was updated.
|
||||
return cp.spawn(process.argv[0], process.argv.slice(1), {
|
||||
return cp.fork(path.join(__dirname, "entry"), {
|
||||
env: {
|
||||
...process.env,
|
||||
CODE_SERVER_PARENT_PID: process.pid.toString(),
|
||||
|
||||
@@ -8,13 +8,14 @@ export const handleUpgrade = (app: express.Express, server: http.Server): void =
|
||||
server.on("upgrade", (req, socket, head) => {
|
||||
socket.pause()
|
||||
|
||||
req.ws = socket
|
||||
req.head = head
|
||||
req._ws_handled = false
|
||||
const wreq = req as InternalWebsocketRequest
|
||||
wreq.ws = socket
|
||||
wreq.head = head
|
||||
wreq._ws_handled = false
|
||||
|
||||
// Send the request off to be handled by Express.
|
||||
;(app as any).handle(req, new http.ServerResponse(req), () => {
|
||||
if (!req._ws_handled) {
|
||||
;(app as any).handle(wreq, new http.ServerResponse(wreq), () => {
|
||||
if (!wreq._ws_handled) {
|
||||
socket.end("HTTP/1.1 404 Not Found\r\n\r\n")
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { field, logger } from "@coder/logger"
|
||||
import { test as base } from "@playwright/test"
|
||||
import { CodeServer, CodeServerPage } from "./models/CodeServer"
|
||||
|
||||
@@ -11,14 +10,13 @@ import { CodeServer, CodeServerPage } from "./models/CodeServer"
|
||||
*/
|
||||
export const describe = (
|
||||
name: string,
|
||||
includeCredentials: boolean,
|
||||
codeServerArgs: string[],
|
||||
codeServerEnv: NodeJS.ProcessEnv,
|
||||
fn: (codeServer: CodeServer) => void,
|
||||
) => {
|
||||
test.describe(name, () => {
|
||||
// This will spawn on demand so nothing is necessary on before.
|
||||
const codeServer = new CodeServer(name, codeServerArgs, codeServerEnv)
|
||||
const codeServer = new CodeServer(name, codeServerArgs, codeServerEnv, undefined)
|
||||
|
||||
// Kill code-server after the suite has ended. This may happen even without
|
||||
// doing it explicitly but it seems prudent to be sure.
|
||||
@@ -26,22 +24,10 @@ export const describe = (
|
||||
await codeServer.close()
|
||||
})
|
||||
|
||||
const storageState = JSON.parse(process.env.STORAGE || "{}")
|
||||
|
||||
// Sanity check to ensure the cookie is set.
|
||||
const cookies = storageState?.cookies
|
||||
if (includeCredentials && (!cookies || cookies.length !== 1 || !!cookies[0].key)) {
|
||||
logger.error("no cookies", field("storage", JSON.stringify(cookies)))
|
||||
throw new Error("no credentials to include")
|
||||
}
|
||||
|
||||
test.use({
|
||||
// Makes `codeServer` and `authenticated` available to the extend call
|
||||
// below.
|
||||
codeServer,
|
||||
authenticated: includeCredentials,
|
||||
// This provides a cookie that authenticates with code-server.
|
||||
storageState: includeCredentials ? storageState : {},
|
||||
// NOTE@jsjoeio some tests use --cert which uses a self-signed certificate
|
||||
// without this option, those tests will fail.
|
||||
ignoreHTTPSErrors: true,
|
||||
@@ -52,7 +38,6 @@ export const describe = (
|
||||
}
|
||||
|
||||
interface TestFixtures {
|
||||
authenticated: boolean
|
||||
codeServer: CodeServer
|
||||
codeServerPage: CodeServerPage
|
||||
}
|
||||
@@ -62,15 +47,14 @@ interface TestFixtures {
|
||||
* ready.
|
||||
*/
|
||||
export const test = base.extend<TestFixtures>({
|
||||
authenticated: false,
|
||||
codeServer: undefined, // No default; should be provided through `test.use`.
|
||||
codeServerPage: async ({ authenticated, codeServer, page }, use) => {
|
||||
codeServerPage: async ({ codeServer, page }, use) => {
|
||||
// It's possible code-server might prevent navigation because of unsaved
|
||||
// changes (seems to happen based on timing even if no changes have been
|
||||
// made too). In these cases just accept.
|
||||
page.on("dialog", (d) => d.accept())
|
||||
|
||||
const codeServerPage = new CodeServerPage(codeServer, page, authenticated)
|
||||
const codeServerPage = new CodeServerPage(codeServer, page)
|
||||
await codeServerPage.navigate()
|
||||
await use(codeServerPage)
|
||||
},
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import * as cp from "child_process"
|
||||
import { promises as fs } from "fs"
|
||||
import * as os from "os"
|
||||
import * as path from "path"
|
||||
import * as util from "util"
|
||||
import { getMaybeProxiedCodeServer } from "../utils/helpers"
|
||||
import { describe, test, expect } from "./baseFixture"
|
||||
import { CodeServer } from "./models/CodeServer"
|
||||
|
||||
describe("code-server", true, [], {}, () => {
|
||||
describe("code-server", [], {}, () => {
|
||||
// TODO@asher: Generalize this? Could be nice if we were to ever need
|
||||
// multiple migration tests in other suites.
|
||||
const instances = new Map<string, CodeServer>()
|
||||
@@ -16,30 +14,6 @@ describe("code-server", true, [], {}, () => {
|
||||
await Promise.all(procs.map((cs) => cs.close()))
|
||||
})
|
||||
|
||||
/**
|
||||
* Spawn a specific version of code-server using the install script.
|
||||
*/
|
||||
const spawn = async (version: string, dir?: string): Promise<CodeServer> => {
|
||||
let instance = instances.get(version)
|
||||
if (!instance) {
|
||||
await util.promisify(cp.exec)(`./install.sh --method standalone --version ${version}`, {
|
||||
cwd: path.join(__dirname, "../.."),
|
||||
})
|
||||
|
||||
instance = new CodeServer(
|
||||
"code-server@" + version,
|
||||
["--auth=none"],
|
||||
{ VSCODE_DEV: "" },
|
||||
dir,
|
||||
`${os.homedir()}/.local/lib/code-server-${version}`,
|
||||
)
|
||||
|
||||
instances.set(version, instance)
|
||||
}
|
||||
|
||||
return instance
|
||||
}
|
||||
|
||||
test("should navigate to home page", async ({ codeServerPage }) => {
|
||||
// We navigate codeServer before each test
|
||||
// and we start the test with a storage state
|
||||
@@ -48,7 +22,8 @@ describe("code-server", true, [], {}, () => {
|
||||
const url = codeServerPage.page.url()
|
||||
// We use match because there may be a / at the end
|
||||
// so we don't want it to fail if we expect http://localhost:8080 to match http://localhost:8080/
|
||||
expect(url).toMatch(await codeServerPage.address())
|
||||
const address = await getMaybeProxiedCodeServer(codeServerPage)
|
||||
expect(url).toMatch(address)
|
||||
})
|
||||
|
||||
test("should always see the code-server editor", async ({ codeServerPage }) => {
|
||||
@@ -66,51 +41,4 @@ describe("code-server", true, [], {}, () => {
|
||||
await fs.writeFile(file, "bar")
|
||||
await codeServerPage.openFile(file)
|
||||
})
|
||||
|
||||
test("should migrate state to avoid collisions", async ({ codeServerPage }) => {
|
||||
// This can take a very long time in development because of how long pages
|
||||
// take to load and we are doing a lot of that here.
|
||||
test.slow()
|
||||
|
||||
const dir = await codeServerPage.workspaceDir
|
||||
const files = [path.join(dir, "foo"), path.join(dir, "bar")]
|
||||
await Promise.all(
|
||||
files.map((file) => {
|
||||
return fs.writeFile(file, path.basename(file))
|
||||
}),
|
||||
)
|
||||
|
||||
// Open a file in the latest instance.
|
||||
await codeServerPage.openFile(files[0])
|
||||
await codeServerPage.stateFlush()
|
||||
|
||||
// Open a file in an older version of code-server. It should not see the
|
||||
// file opened in the new instance since the database has a different
|
||||
// name. This must be accessed through the proxy so it shares the same
|
||||
// domain and can write to the same database.
|
||||
const cs = await spawn("4.0.2", dir)
|
||||
const address = new URL(await cs.address())
|
||||
await codeServerPage.navigate("/proxy/" + address.port + "/")
|
||||
await codeServerPage.openFile(files[1])
|
||||
expect(await codeServerPage.tabIsVisible(files[0])).toBe(false)
|
||||
await codeServerPage.stateFlush()
|
||||
|
||||
// Move back to latest code-server. We should see the file we previously
|
||||
// opened with it but not the old code-server file because the new instance
|
||||
// already created its own database on this path and will avoid migrating.
|
||||
await codeServerPage.navigate()
|
||||
await codeServerPage.waitForTab(files[0])
|
||||
expect(await codeServerPage.tabIsVisible(files[1])).toBe(false)
|
||||
|
||||
// Open a new path in latest code-server. This one should migrate the
|
||||
// database from old code-server but see nothing from the new database
|
||||
// created on the root.
|
||||
await codeServerPage.navigate("/vscode")
|
||||
await codeServerPage.waitForTab(files[1])
|
||||
expect(await codeServerPage.tabIsVisible(files[0])).toBe(false)
|
||||
// Should still be open after a reload.
|
||||
await codeServerPage.navigate("/vscode")
|
||||
await codeServerPage.waitForTab(files[1])
|
||||
expect(await codeServerPage.tabIsVisible(files[0])).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
14
test/e2e/displayLang.test.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import * as path from "path"
|
||||
import { describe, test, expect } from "./baseFixture"
|
||||
|
||||
// Given a code-server environment with Spanish Language Pack extension installed
|
||||
// and a languagepacks.json in the data-dir
|
||||
describe("--locale es", ["--extensions-dir", path.join(__dirname, "./extensions"), "--locale", "es"], {}, () => {
|
||||
test("should load code-server in Spanish", async ({ codeServerPage }) => {
|
||||
// When
|
||||
const visible = await codeServerPage.page.isVisible("text=Explorador")
|
||||
|
||||
// Then
|
||||
expect(visible).toBe(true)
|
||||
})
|
||||
})
|
||||
@@ -3,7 +3,7 @@ import * as path from "path"
|
||||
import { clean } from "../utils/helpers"
|
||||
import { describe, test, expect } from "./baseFixture"
|
||||
|
||||
describe("Downloads (enabled)", true, [], {}, async () => {
|
||||
describe("Downloads (enabled)", [], {}, async () => {
|
||||
const testName = "downloads-enabled"
|
||||
test.beforeAll(async () => {
|
||||
await clean(testName)
|
||||
@@ -25,7 +25,7 @@ describe("Downloads (enabled)", true, [], {}, async () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("Downloads (disabled)", true, ["--disable-file-downloads"], {}, async () => {
|
||||
describe("Downloads (disabled)", ["--disable-file-downloads"], {}, async () => {
|
||||
const testName = "downloads-disabled"
|
||||
test.beforeAll(async () => {
|
||||
await clean(testName)
|
||||
|
||||
@@ -1,23 +1,38 @@
|
||||
import { test as base } from "@playwright/test"
|
||||
import * as path from "path"
|
||||
import { describe, test } from "./baseFixture"
|
||||
import { getMaybeProxiedCodeServer } from "../utils/helpers"
|
||||
import { describe, test, expect } from "./baseFixture"
|
||||
|
||||
function runTestExtensionTests() {
|
||||
// This will only work if the test extension is loaded into code-server.
|
||||
test("should have access to VSCODE_PROXY_URI", async ({ codeServerPage }) => {
|
||||
const address = await codeServerPage.address()
|
||||
const address = await getMaybeProxiedCodeServer(codeServerPage)
|
||||
|
||||
await codeServerPage.waitForTestExtensionLoaded()
|
||||
await codeServerPage.executeCommandViaMenus("code-server: Get proxy URI")
|
||||
|
||||
await codeServerPage.page.waitForSelector(`text=${address}/proxy/{{port}}`)
|
||||
await codeServerPage.page.waitForSelector("text=proxyUri", { timeout: 3000 })
|
||||
const text = await codeServerPage.page.locator("text=proxyUri").first().textContent()
|
||||
// Remove end slash in address
|
||||
const normalizedAddress = address.replace(/\/+$/, "")
|
||||
expect(text).toBe(`Info: proxyUri: ${normalizedAddress}/proxy/{{port}}`)
|
||||
})
|
||||
}
|
||||
|
||||
const flags = ["--extensions-dir", path.join(__dirname, "./extensions")]
|
||||
|
||||
describe("Extensions", true, flags, {}, () => {
|
||||
describe("Extensions", flags, {}, () => {
|
||||
runTestExtensionTests()
|
||||
})
|
||||
|
||||
describe("Extensions with --cert", true, [...flags, "--cert"], {}, () => {
|
||||
runTestExtensionTests()
|
||||
})
|
||||
if (process.env.USE_PROXY !== "1") {
|
||||
describe("Extensions with --cert", [...flags, "--cert"], {}, () => {
|
||||
runTestExtensionTests()
|
||||
})
|
||||
} else {
|
||||
base.describe("Extensions with --cert", () => {
|
||||
base.skip("skipped because USE_PROXY is set", () => {
|
||||
// Playwright will not show this without a function.
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "vscode-language-pack-es",
|
||||
"displayName": "Spanish Language Pack for Visual Studio Code",
|
||||
"description": "Language pack extension for Spanish",
|
||||
"version": "1.70.0",
|
||||
"publisher": "MS-CEINTL",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/vscode-loc"
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.70.0"
|
||||
},
|
||||
"categories": [
|
||||
"Language Packs"
|
||||
],
|
||||
"contributes": {
|
||||
"localizations": [
|
||||
{
|
||||
"languageId": "es",
|
||||
"languageName": "Spanish",
|
||||
"localizedLanguageName": "español",
|
||||
"translations": [
|
||||
{
|
||||
"id": "vscode",
|
||||
"path": "./translations/main.i18n.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"": [
|
||||
"--------------------------------------------------------------------------------------------",
|
||||
"Copyright (c) Microsoft Corporation. All rights reserved.",
|
||||
"Licensed under the MIT License. See License.txt in the project root for license information.",
|
||||
"--------------------------------------------------------------------------------------------",
|
||||
"Do not edit this file. It is machine generated."
|
||||
],
|
||||
"version": "1.0.0",
|
||||
"contents": {
|
||||
"vs/workbench/contrib/files/browser/explorerViewlet": {
|
||||
"explore": "Explorador"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
import * as vscode from "vscode"
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
vscode.window.showInformationMessage("test extension loaded")
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand("codeServerTest.proxyUri", () => {
|
||||
if (process.env.VSCODE_PROXY_URI) {
|
||||
vscode.window.showInformationMessage(process.env.VSCODE_PROXY_URI)
|
||||
vscode.window.showInformationMessage(`proxyUri: ${process.env.VSCODE_PROXY_URI}`)
|
||||
} else {
|
||||
vscode.window.showErrorMessage("No proxy URI was set")
|
||||
}
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
"description": "code-server test extension",
|
||||
"version": "0.0.1",
|
||||
"publisher": "coder",
|
||||
"license": "MIT",
|
||||
"activationEvents": [
|
||||
"onCommand:codeServerTest.proxyUri"
|
||||
"onStartupFinished"
|
||||
],
|
||||
"engines": {
|
||||
"vscode": "^1.56.0"
|
||||
|
||||
@@ -2,7 +2,7 @@ import { test as base } from "@playwright/test"
|
||||
import { describe, expect, test } from "./baseFixture"
|
||||
|
||||
if (process.env.GITHUB_TOKEN) {
|
||||
describe("GitHub token", true, [], {}, () => {
|
||||
describe("GitHub token", [], {}, () => {
|
||||
test("should be logged in to pull requests extension", async ({ codeServerPage }) => {
|
||||
await codeServerPage.exec("git init")
|
||||
await codeServerPage.exec("git remote add origin https://github.com/coder/code-server")
|
||||
@@ -16,7 +16,7 @@ if (process.env.GITHUB_TOKEN) {
|
||||
})
|
||||
})
|
||||
|
||||
describe("No GitHub token", true, [], { GITHUB_TOKEN: "" }, () => {
|
||||
describe("No GitHub token", [], { GITHUB_TOKEN: "" }, () => {
|
||||
test("should not be logged in to pull requests extension", async ({ codeServerPage }) => {
|
||||
await codeServerPage.exec("git init")
|
||||
await codeServerPage.exec("git remote add origin https://github.com/coder/code-server")
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import { describe, test, expect } from "./baseFixture"
|
||||
|
||||
// This test is to make sure the globalSetup works as expected
|
||||
// meaning globalSetup ran and stored the storageState
|
||||
describe("globalSetup", true, [], {}, () => {
|
||||
test("should keep us logged in using the storageState", async ({ codeServerPage }) => {
|
||||
// Make sure the editor actually loaded
|
||||
expect(await codeServerPage.isEditorVisible()).toBe(true)
|
||||
})
|
||||
})
|
||||
@@ -1,7 +1,7 @@
|
||||
import { PASSWORD } from "../utils/constants"
|
||||
import { describe, test, expect } from "./baseFixture"
|
||||
|
||||
describe("login", false, [], {}, () => {
|
||||
describe("login", ["--auth", "password"], {}, () => {
|
||||
test("should see the login page", async ({ codeServerPage }) => {
|
||||
// It should send us to the login page
|
||||
expect(await codeServerPage.page.title()).toBe("code-server login")
|
||||
|
||||
@@ -4,10 +4,10 @@ import { promises as fs } from "fs"
|
||||
import * as path from "path"
|
||||
import { Page } from "playwright"
|
||||
import * as util from "util"
|
||||
import { logError, plural } from "../../../src/common/util"
|
||||
import { logError, normalize, plural } from "../../../src/common/util"
|
||||
import { onLine } from "../../../src/node/util"
|
||||
import { PASSWORD, workspaceDir } from "../../utils/constants"
|
||||
import { idleTimer, tmpdir } from "../../utils/helpers"
|
||||
import { getMaybeProxiedCodeServer, idleTimer, tmpdir } from "../../utils/helpers"
|
||||
|
||||
interface CodeServerProcess {
|
||||
process: cp.ChildProcess
|
||||
@@ -58,6 +58,7 @@ export class CodeServer {
|
||||
this.process = this.spawn()
|
||||
}
|
||||
const { address } = await this.process
|
||||
|
||||
return address
|
||||
}
|
||||
|
||||
@@ -87,6 +88,30 @@ export class CodeServer {
|
||||
}),
|
||||
"utf8",
|
||||
)
|
||||
|
||||
const extensionsDir = path.join(__dirname, "../extensions")
|
||||
const languagepacksContent = {
|
||||
es: {
|
||||
hash: "8d919a946475223861fa0c62665a4c50",
|
||||
extensions: [
|
||||
{
|
||||
extensionIdentifier: {
|
||||
id: "ms-ceintl.vscode-language-pack-es",
|
||||
uuid: "47e020a1-33db-4cc0-a1b4-42f97781749a",
|
||||
},
|
||||
version: "1.70.0",
|
||||
},
|
||||
],
|
||||
translations: {
|
||||
vscode: `${extensionsDir}/ms-ceintl.vscode-language-pack-es-1.70.0/translations/main.i18n.json`,
|
||||
},
|
||||
label: "español",
|
||||
},
|
||||
}
|
||||
|
||||
// NOTE@jsjoeio - code-server should automatically generate the languagepacks.json for
|
||||
// using different display languages. This is a temporary workaround until we fix that.
|
||||
await fs.writeFile(path.join(dir, "languagepacks.json"), JSON.stringify(languagepacksContent))
|
||||
return dir
|
||||
}
|
||||
|
||||
@@ -104,6 +129,8 @@ export class CodeServer {
|
||||
this.entry,
|
||||
"--extensions-dir",
|
||||
path.join(dir, "extensions"),
|
||||
"--auth",
|
||||
"none",
|
||||
...this.args,
|
||||
// Using port zero will spawn on a random port.
|
||||
"--bind-addr",
|
||||
@@ -124,6 +151,10 @@ export class CodeServer {
|
||||
env: {
|
||||
...process.env,
|
||||
...this.env,
|
||||
// Set to empty string to prevent code-server from
|
||||
// using the existing instance when running the e2e tests
|
||||
// from an integrated terminal.
|
||||
VSCODE_IPC_HOOK_CLI: "",
|
||||
PASSWORD,
|
||||
},
|
||||
})
|
||||
@@ -183,6 +214,13 @@ export class CodeServer {
|
||||
proc.kill()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not authentication is enabled.
|
||||
*/
|
||||
authEnabled(): boolean {
|
||||
return this.args.includes("password")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -195,11 +233,7 @@ export class CodeServer {
|
||||
export class CodeServerPage {
|
||||
private readonly editorSelector = "div.monaco-workbench"
|
||||
|
||||
constructor(
|
||||
private readonly codeServer: CodeServer,
|
||||
public readonly page: Page,
|
||||
private readonly authenticated: boolean,
|
||||
) {
|
||||
constructor(private readonly codeServer: CodeServer, public readonly page: Page) {
|
||||
this.page.on("console", (message) => {
|
||||
this.codeServer.logger.debug(message.text())
|
||||
})
|
||||
@@ -224,12 +258,16 @@ export class CodeServerPage {
|
||||
* editor to become available.
|
||||
*/
|
||||
async navigate(endpoint = "/") {
|
||||
const to = new URL(endpoint, await this.codeServer.address())
|
||||
const address = await getMaybeProxiedCodeServer(this.codeServer)
|
||||
const noramlizedUrl = normalize(address + endpoint, true)
|
||||
const to = new URL(noramlizedUrl)
|
||||
|
||||
this.codeServer.logger.info(`navigating to ${to}`)
|
||||
await this.page.goto(to.toString(), { waitUntil: "networkidle" })
|
||||
|
||||
// Only reload editor if authenticated. Otherwise we'll get stuck
|
||||
// Only reload editor if auth is not enabled. Otherwise we'll get stuck
|
||||
// reloading the login page.
|
||||
if (this.authenticated) {
|
||||
if (!this.codeServer.authEnabled()) {
|
||||
await this.reloadUntilEditorIsReady()
|
||||
}
|
||||
}
|
||||
@@ -283,19 +321,41 @@ export class CodeServerPage {
|
||||
}
|
||||
|
||||
/**
|
||||
* Focuses Integrated Terminal
|
||||
* by using "Terminal: Focus Terminal"
|
||||
* from the Command Palette
|
||||
* Checks if the test extension loaded
|
||||
*/
|
||||
async waitForTestExtensionLoaded(): Promise<void> {
|
||||
const selector = "text=test extension loaded"
|
||||
this.codeServer.logger.debug("Waiting for test extension to load...")
|
||||
|
||||
await this.page.waitForSelector(selector)
|
||||
}
|
||||
|
||||
/**
|
||||
* Focuses the integrated terminal by navigating through the command palette.
|
||||
*
|
||||
* This should focus the terminal no matter
|
||||
* if it already has focus and/or is or isn't
|
||||
* visible already.
|
||||
* This should focus the terminal no matter if it already has focus and/or is
|
||||
* or isn't visible already. It will always create a new terminal to avoid
|
||||
* clobbering parallel tests.
|
||||
*/
|
||||
async focusTerminal() {
|
||||
await this.executeCommandViaMenus("Terminal: Focus Terminal")
|
||||
const doFocus = async (): Promise<boolean> => {
|
||||
await this.executeCommandViaMenus("Terminal: Create New Terminal")
|
||||
try {
|
||||
await this.page.waitForLoadState("load")
|
||||
await this.page.waitForSelector("textarea.xterm-helper-textarea:focus-within", { timeout: 5000 })
|
||||
return true
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for terminal textarea to show up
|
||||
await this.page.waitForSelector("textarea.xterm-helper-textarea")
|
||||
let attempts = 1
|
||||
while (!(await doFocus())) {
|
||||
++attempts
|
||||
this.codeServer.logger.debug(`no focused terminal textarea, retrying (${attempts}/∞)`)
|
||||
}
|
||||
|
||||
this.codeServer.logger.debug(`opening terminal took ${attempts} ${plural(attempts, "attempt")}`)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -423,7 +483,7 @@ export class CodeServerPage {
|
||||
let context = new Context()
|
||||
while (!(await Promise.race([openThenWaitClose(context), navigate(context)]))) {
|
||||
++attempts
|
||||
logger.debug("closed, retrying (${attempt}/∞)")
|
||||
logger.debug(`closed, retrying (${attempts}/∞)`)
|
||||
context.cancel()
|
||||
context = new Context()
|
||||
}
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import { version } from "../../src/node/constants"
|
||||
import { describe, test, expect } from "./baseFixture"
|
||||
|
||||
describe("Open Help > About", true, [], {}, () => {
|
||||
describe("Open Help > About", [], {}, () => {
|
||||
test("should see code-server version in about dialog", async ({ codeServerPage }) => {
|
||||
// Open using the menu.
|
||||
await codeServerPage.navigateMenus(["Help", "About"])
|
||||
|
||||
const isDevMode = process.env.VSCODE_DEV === "1"
|
||||
|
||||
// Look for code-server info div.
|
||||
const element = await codeServerPage.page.waitForSelector(`div[role="dialog"] >> text=code-server`)
|
||||
const element = await codeServerPage.page.waitForSelector(
|
||||
`div[role="dialog"] >> text=code-server: ${isDevMode ? "Unknown" : "v" + version}`,
|
||||
)
|
||||
expect(element).not.toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import * as cp from "child_process"
|
||||
import { promises as fs } from "fs"
|
||||
import * as path from "path"
|
||||
import util from "util"
|
||||
import { clean, tmpdir } from "../utils/helpers"
|
||||
import { clean, getMaybeProxiedCodeServer, tmpdir } from "../utils/helpers"
|
||||
import { describe, expect, test } from "./baseFixture"
|
||||
|
||||
describe("Integrated Terminal", true, [], {}, () => {
|
||||
describe("Integrated Terminal", [], {}, () => {
|
||||
const testName = "integrated-terminal"
|
||||
test.beforeAll(async () => {
|
||||
await clean(testName)
|
||||
@@ -21,13 +22,25 @@ describe("Integrated Terminal", true, [], {}, () => {
|
||||
// Open terminal and type in value
|
||||
await codeServerPage.focusTerminal()
|
||||
|
||||
await codeServerPage.page.waitForLoadState("load")
|
||||
await codeServerPage.page.keyboard.type(`printenv VSCODE_PROXY_URI > ${tmpFile}`)
|
||||
await codeServerPage.page.keyboard.press("Enter")
|
||||
// It may take a second to process
|
||||
await codeServerPage.page.waitForTimeout(1000)
|
||||
|
||||
const { stdout } = await output
|
||||
expect(stdout).toMatch(await codeServerPage.address())
|
||||
const address = await getMaybeProxiedCodeServer(codeServerPage)
|
||||
expect(stdout).toMatch(address)
|
||||
})
|
||||
|
||||
test("should be able to invoke `code-server` to open a file", async ({ codeServerPage }) => {
|
||||
const tmpFolderPath = await tmpdir(testName)
|
||||
const tmpFile = path.join(tmpFolderPath, "test-file")
|
||||
await fs.writeFile(tmpFile, "test")
|
||||
const fileName = path.basename(tmpFile)
|
||||
|
||||
await codeServerPage.focusTerminal()
|
||||
|
||||
await codeServerPage.page.keyboard.type(`code-server ${tmpFile}`)
|
||||
await codeServerPage.page.keyboard.press("Enter")
|
||||
|
||||
await codeServerPage.waitForTab(fileName)
|
||||
})
|
||||
})
|
||||
|
||||
13
test/integration/help.test.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { runCodeServerCommand } from "../utils/runCodeServerCommand"
|
||||
|
||||
// NOTE@jsjoeio
|
||||
// We have this test to ensure that native modules
|
||||
// work as expected. If this is called on the wrong
|
||||
// platform, the test will fail.
|
||||
describe("--help", () => {
|
||||
it("should list code-server usage", async () => {
|
||||
const expectedOutput = "Usage: code-server [options] [path]"
|
||||
const { stdout } = await runCodeServerCommand(["--help"])
|
||||
expect(stdout).toMatch(expectedOutput)
|
||||
}, 20000)
|
||||
})
|
||||
@@ -1,5 +1,3 @@
|
||||
import { stat } from "fs/promises"
|
||||
import path from "path"
|
||||
import { clean, tmpdir } from "../utils/helpers"
|
||||
import { runCodeServerCommand } from "../utils/runCodeServerCommand"
|
||||
|
||||
@@ -13,13 +11,11 @@ describe("--install-extension", () => {
|
||||
tempDir = await tmpdir(testName)
|
||||
setupFlags = ["--extensions-dir", tempDir]
|
||||
})
|
||||
it("should install an extension", async () => {
|
||||
const extName = `wesbos.theme-cobalt2-2.1.6`
|
||||
const vsixFileName = "wesbos.theme-cobalt2-2.1.6.vsix"
|
||||
const extensionFixture = path.resolve(`./test/integration/fixtures/${vsixFileName}`)
|
||||
await runCodeServerCommand([...setupFlags, "--install-extension", extensionFixture])
|
||||
const pathToExtFolder = path.join(tempDir, extName)
|
||||
const statInfo = await stat(pathToExtFolder)
|
||||
expect(statInfo.isDirectory()).toBe(true)
|
||||
}, 20000)
|
||||
it("should use EXTENSIONS_GALLERY when set", async () => {
|
||||
const extName = `author.extension-1.0.0`
|
||||
const { stderr } = await runCodeServerCommand([...setupFlags, "--install-extension", extName], {
|
||||
EXTENSIONS_GALLERY: "{}",
|
||||
})
|
||||
expect(stderr).toMatch("No extension gallery service configured")
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
import extract from "extract-zip"
|
||||
import { rename } from "fs/promises"
|
||||
import path from "path"
|
||||
import { clean, tmpdir } from "../utils/helpers"
|
||||
import { runCodeServerCommand } from "../utils/runCodeServerCommand"
|
||||
|
||||
describe("--list-extensions", () => {
|
||||
const testName = "listExtensions"
|
||||
const extName = `wesbos.theme-cobalt2`
|
||||
const extVersion = "2.1.6"
|
||||
const vsixFileName = `${extName}-${extVersion}.vsix`
|
||||
let tempDir: string
|
||||
let setupFlags: string[]
|
||||
|
||||
beforeEach(async () => {
|
||||
await clean(testName)
|
||||
tempDir = await tmpdir(testName)
|
||||
setupFlags = ["--extensions-dir", tempDir]
|
||||
const extensionFixture = path.resolve(`./test/integration/fixtures/${vsixFileName}`)
|
||||
// Make folder because this is where we'll move the extension
|
||||
const pathToUnpackedExtension = path.join(tempDir, `${extName}-${extVersion}`)
|
||||
const tempPathToUnpackedExtension = path.join(tempDir, `${extName}-temp`)
|
||||
await extract(extensionFixture, { dir: tempPathToUnpackedExtension })
|
||||
await rename(path.join(tempPathToUnpackedExtension, "extension"), pathToUnpackedExtension)
|
||||
})
|
||||
it("should list installed extensions", async () => {
|
||||
const { stdout } = await runCodeServerCommand([...setupFlags, "--list-extensions"])
|
||||
expect(stdout).toMatch(extName)
|
||||
}, 20000)
|
||||
})
|
||||
@@ -12,6 +12,8 @@ const config: PlaywrightTestConfig = {
|
||||
testDir: path.join(__dirname, "e2e"), // Search for tests in this directory.
|
||||
timeout: 60000, // Each test is given 60 seconds.
|
||||
retries: process.env.CI ? 2 : 1, // Retry in CI due to flakiness.
|
||||
// Limit the number of failures on CI to save resources
|
||||
maxFailures: process.env.CI ? 3 : undefined,
|
||||
globalSetup: require.resolve("./utils/globalE2eSetup.ts"),
|
||||
reporter: "list",
|
||||
// Put any shared options on the top level.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"name": "test-plugin",
|
||||
"version": "1.0.0",
|
||||
"engines": {
|
||||
"code-server": "^4.0.1"
|
||||
"code-server": "^4.7.0"
|
||||
},
|
||||
"main": "out/index.js",
|
||||
"devDependencies": {
|
||||
|
||||
@@ -67,7 +67,7 @@ describe("update", () => {
|
||||
|
||||
// Anything else is a 404.
|
||||
response.writeHead(404)
|
||||
response.end("not found")
|
||||
return response.end("not found")
|
||||
})
|
||||
|
||||
let _settings: SettingsProvider<UpdateSettings> | undefined
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
export const PASSWORD = "e45432jklfdsab"
|
||||
export const workspaceDir = "workspaces"
|
||||
export const REVERSE_PROXY_BASE_PATH = process.env.CS_TEST_REVERSE_PROXY_BASE_PATH || "ide"
|
||||
export const REVERSE_PROXY_PORT = process.env.CS_TEST_REVERSE_PROXY_PORT || "8000"
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import { Cookie } from "playwright"
|
||||
import { CookieKeys } from "../../src/common/http"
|
||||
import { hash } from "../../src/node/util"
|
||||
import { PASSWORD, workspaceDir } from "./constants"
|
||||
import { workspaceDir } from "./constants"
|
||||
import { clean } from "./helpers"
|
||||
import * as wtfnode from "./wtfnode"
|
||||
|
||||
@@ -20,25 +17,5 @@ export default async function () {
|
||||
wtfnode.setup()
|
||||
}
|
||||
|
||||
// TODO: Replace this with a call to code-server to get the cookie. To avoid
|
||||
// too much overhead we can do an http POST request and avoid spawning a
|
||||
// browser for it.
|
||||
const cookies: Cookie[] = [
|
||||
{
|
||||
domain: "localhost",
|
||||
expires: -1,
|
||||
httpOnly: false,
|
||||
name: CookieKeys.Session,
|
||||
path: "/",
|
||||
sameSite: "Lax",
|
||||
secure: false,
|
||||
value: await hash(PASSWORD),
|
||||
},
|
||||
]
|
||||
|
||||
// Save storage state and store as an env variable
|
||||
// More info: https://playwright.dev/docs/auth/#reuse-authentication-state
|
||||
process.env.STORAGE = JSON.stringify({ cookies })
|
||||
|
||||
console.log("✅ Global Setup for Playwright End-to-End Tests is now complete.")
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ import { promises as fs } from "fs"
|
||||
import * as net from "net"
|
||||
import * as os from "os"
|
||||
import * as path from "path"
|
||||
import { CodeServer, CodeServerPage } from "../e2e/models/CodeServer"
|
||||
import { REVERSE_PROXY_PORT, REVERSE_PROXY_BASE_PATH } from "./constants"
|
||||
|
||||
/**
|
||||
* Spy on the logger and console and replace with mock implementations to
|
||||
@@ -119,3 +121,18 @@ export function isAddressInfo(address: unknown): address is net.AddressInfo {
|
||||
(address as net.AddressInfo).address !== undefined
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* If using a proxy, return the address of the proxy.
|
||||
*
|
||||
* Otherwise, return the direct address of code-server.
|
||||
*/
|
||||
export async function getMaybeProxiedCodeServer(codeServer: CodeServerPage | CodeServer): Promise<string> {
|
||||
const address = await codeServer.address()
|
||||
if (process.env.USE_PROXY === "1") {
|
||||
const uri = new URL(address)
|
||||
return `http://${uri.hostname}:${REVERSE_PROXY_PORT}/${uri.port}/${REVERSE_PROXY_BASE_PATH}/`
|
||||
}
|
||||
|
||||
return address
|
||||
}
|
||||
|
||||