Compare commits

..

20 Commits

Author SHA1 Message Date
dependabot[bot]
18005c0ae5 chore: bump docker/setup-qemu-action from 4.1.0 to 4.2.0
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 4.1.0 to 4.2.0.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](06116385d9...96fe6ef7f3)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-version: 4.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-01 11:04:07 +00:00
cdrci
2b2f8b3d5c Update Helm chart and changelog with 4.135.0 (#7964) 2026-08-27 11:46:21 -08:00
cdrci
de89acbcdc Update Code to 1.135.0 (#7963) 2026-08-26 14:54:52 -08:00
cdrci
e08e907889 Update Helm chart and changelog with 4.134.0 (#7961) 2026-08-24 14:00:49 -08:00
Asher
92f44d9c7b Fix changelog typo 2026-08-24 13:44:38 -08:00
cdrci
88c2b7432e Update Code to 1.134.0 (#7954) 2026-08-20 21:45:25 +00:00
Robert Gingras
4cb856c475 Add --socket-fd CLI option (#7940) 2026-08-20 13:24:49 -08:00
Asher
2d5dbf0b77 Update codeql actions to 4.37.6
One was updated by Dependabot, but not the others.
2026-08-19 14:57:47 -08:00
dependabot[bot]
7833136337 Bump js-yaml from 4.3.1 to 5.2.3 (#7916) 2026-08-19 14:53:50 -08:00
dependabot[bot]
1735f6d3fb Bump brace-expansion from 1.1.11 to 1.1.18 in /test (#7957) 2026-08-19 14:45:44 -08:00
dependabot[bot]
0a7b4b1e16 Bump brace-expansion (#7958) 2026-08-19 22:45:03 +00:00
Asher
fa4426393e Run unit tests when npm deps change 2026-08-19 14:31:06 -08:00
Fernando Softov
04ce2301a7 Add VSCODE_OPTIONS and --vscode-option for Code flags (#1528) (#7952) 2026-08-19 13:44:48 -08:00
dependabot[bot]
2edeb1c991 chore: bump github/codeql-action/upload-sarif from 4.36.2 to 4.37.6 (#7917) 2026-08-19 13:28:08 -08:00
dependabot[bot]
02badb2056 chore: bump github/codeql-action/init from 4.36.2 to 4.37.6 (#7918) 2026-08-19 13:24:38 -08:00
dependabot[bot]
fb43d02d10 chore: bump docker/login-action from 4.2.0 to 4.6.0 (#7919) 2026-08-19 13:23:12 -08:00
dependabot[bot]
b9653442b3 chore: bump softprops/action-gh-release from 3.0.1 to 3.0.2 (#7920) 2026-08-19 13:22:48 -08:00
dependabot[bot]
30852bb006 chore: bump actions/setup-node from 6.4.0 to 7.0.0 (#7921) 2026-08-19 13:22:13 -08:00
dependabot[bot]
f69d40ce6f Bump js-yaml from 4.3.0 to 4.3.1 (#7935) 2026-08-19 13:21:37 -08:00
Anthony Holten
876304f95f Remove --unsafe-perm flag from install scripts (#7953)
npm 12 rejects unknown CLI flags, so the npm install path crashes
with EUNKNOWNCONFIG before installing. The flag has been a no-op
since npm 7; remove it from install.sh and the postinstall guard.
2026-08-19 13:18:20 -08:00
36 changed files with 348 additions and 103 deletions

View File

@@ -21,7 +21,8 @@ jobs:
outputs:
ci: ${{ steps.filter.outputs.ci }}
code: ${{ steps.filter.outputs.code }}
deps: ${{ steps.filter.outputs.deps }}
npm: ${{ steps.filter.outputs.npm }}
vscode: ${{ steps.filter.outputs.vscode }}
docs: ${{ steps.filter.outputs.docs }}
helm: ${{ steps.filter.outputs.helm }}
steps:
@@ -42,11 +43,12 @@ jobs:
code:
- "src/**"
- "test/**"
deps:
- "lib/**"
- "patches/**"
npm:
- "package-lock.json"
- "test/package-lock.json"
vscode:
- "lib/**"
- "patches/**"
- id: debug
run: |
echo "${{ toJSON(steps.filter )}}"
@@ -56,7 +58,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6
with:
node-version-file: .node-version
cache: npm
@@ -73,7 +75,7 @@ jobs:
if: needs.changes.outputs.docs == 'true'
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6
with:
node-version-file: .node-version
cache: npm
@@ -102,7 +104,7 @@ jobs:
if: needs.changes.outputs.code == 'true'
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6
with:
node-version-file: .node-version
cache: npm
@@ -130,10 +132,10 @@ jobs:
name: Run unit tests
runs-on: ubuntu-22.04
needs: changes
if: needs.changes.outputs.code == 'true'
if: needs.changes.outputs.code == 'true' || needs.changes.outputs.npm == 'true'
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6
with:
node-version-file: .node-version
cache: npm
@@ -170,7 +172,7 @@ jobs:
with:
submodules: true
- run: quilt push -a
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6
with:
node-version-file: .node-version
cache: npm
@@ -214,11 +216,11 @@ jobs:
env:
LOG_LEVEL: debug
needs: [changes, build]
if: needs.changes.outputs.code == 'true' || needs.changes.outputs.deps == 'true' || needs.changes.outputs.ci == 'true'
if: needs.changes.outputs.code == 'true' || needs.changes.outputs.npm == 'true' || needs.changes.outputs.vscode == 'true' || needs.changes.outputs.ci == 'true'
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6
with:
node-version-file: .node-version
cache: npm
@@ -250,7 +252,7 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
LOG_LEVEL: debug
needs: [changes, build]
if: needs.changes.outputs.code == 'true' || needs.changes.outputs.deps == 'true' || needs.changes.outputs.ci == 'true'
if: needs.changes.outputs.code == 'true' || needs.changes.outputs.npm == 'true' || needs.changes.outputs.vscode == 'true' || needs.changes.outputs.ci == 'true'
steps:
- name: Cache Caddy
@@ -268,7 +270,7 @@ jobs:
tar -xzf caddy_2.5.2_linux_amd64.tar.gz --directory ~/.cache/caddy
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6
with:
node-version-file: .node-version
cache: npm

View File

@@ -34,7 +34,7 @@ jobs:
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6
with:
node-version-file: .node-version
@@ -109,14 +109,14 @@ jobs:
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
- uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
- uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0
- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}

View File

@@ -80,7 +80,7 @@ jobs:
with:
submodules: true
- run: quilt push -a
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6
with:
node-version-file: .node-version
cache: npm
@@ -174,7 +174,7 @@ jobs:
with:
submodules: true
- run: quilt push -a
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6
with:
node-version-file: .node-version
cache: npm

View File

@@ -30,7 +30,7 @@ jobs:
fetch-depth: 0
- name: Install Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6
with:
node-version-file: .node-version
@@ -62,7 +62,7 @@ jobs:
severity: "HIGH,CRITICAL"
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4
uses: github/codeql-action/upload-sarif@5595ccaf912efad79be6eef63a5619ff05969be3 # v4
with:
sarif_file: "trivy-repo-results.sarif"
@@ -80,13 +80,13 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4
uses: github/codeql-action/init@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6
with:
config-file: ./.github/codeql-config.yml
languages: javascript
- name: Autobuild
uses: github/codeql-action/autobuild@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4
uses: github/codeql-action/autobuild@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4
uses: github/codeql-action/analyze@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6

View File

@@ -58,6 +58,6 @@ jobs:
severity: "HIGH,CRITICAL"
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4
uses: github/codeql-action/upload-sarif@5595ccaf912efad79be6eef63a5619ff05969be3 # v4
with:
sarif_file: "trivy-image-results.sarif"

View File

@@ -1 +1 @@
24.18.0
24.18.1

View File

@@ -22,6 +22,37 @@ Code v99.99.999
## Unreleased
## [4.135.0](https://github.com/coder/code-server/releases/tag/v4.135.0) - 2026-08-27
Code v1.135.0
### Changed
- Update to Code 1.135.0
## [4.134.0](https://github.com/coder/code-server/releases/tag/v4.134.0) - 2026-08-24
Code v1.134.0
### Added
- New `--socket-fd` flag that can be used to listen on a file descriptor. In
particular, this allows using code-server with systemd's socket activation.
- New `--vscode-option` repeatable flag that can be used to pass through options
to VS Code. It requires `flag=value` or simply `flag` for booleans. For
example: `--vscode-option enable-sandbox --vscode-option agents=true`. The
`VSCODE_OPTIONS` environment variable may also be used. For example:
`VSCODE_OPTIONS="enable-sandbox agents=true"`. Note that code-server simply
splits this variable on spaces and is not aware of quoting.
### Changed
- Update to Code 1.134.0
- Remove `--unsafe-perm` from installation scripts. This flag results in an
error when used with npm since v12 and has been a no-op since v7. If you are
installing with a version of npm older than v7 as root, installation may not
work correctly.
## [4.133.0](https://github.com/coder/code-server/releases/tag/v4.133.0) - 2026-08-17
Code v1.133.0

View File

@@ -76,20 +76,6 @@ main() {
exit 1
fi
# Under npm, if we are running as root, we need --unsafe-perm otherwise
# post-install scripts will not have sufficient permissions to do their thing.
if is_root; then
case "${npm_config_user_agent-}" in npm*)
if [ "${npm_config_unsafe_perm-}" != "true" ]; then
echo "Please pass --unsafe-perm to npm to install code-server"
echo "Otherwise post-install scripts will not have permissions to run"
echo "See https://docs.npmjs.com/misc/config#unsafe-perm"
echo "See https://stackoverflow.com/questions/49084929/npm-sudo-global-installation-unsafe-perm"
exit 1
fi
;;
esac
fi
if ! vscode_install; then
echo "You may not have the required dependencies to build the native modules."
@@ -110,7 +96,7 @@ install_with_yarn_or_npm() {
# end-user we want to keep using whatever package manager is in use.
case "${npm_config_user_agent-}" in
npm*)
if ! npm install --unsafe-perm --omit=dev; then
if ! npm install --omit=dev; then
return 1
fi
;;

View File

@@ -15,9 +15,9 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 3.48.0
version: 3.50.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
appVersion: 4.133.0
appVersion: 4.135.0

View File

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

View File

@@ -41,6 +41,7 @@
- [How do I disable the proxy?](#how-do-i-disable-the-proxy)
- [How do I disable file download?](#how-do-i-disable-file-download)
- [Why do web views not work?](#why-do-web-views-not-work)
- [Can I run code-server with systemd socket activation?](#can-i-run-code-server-with-systemd-socket-activation)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- prettier-ignore-end -->
@@ -560,3 +561,41 @@ To fix this, you must either:
create and trust a certificate manually).
- Disable security if your browser allows it. For example, in Chromium see
`chrome://flags/#unsafely-treat-insecure-origin-as-secure`
## Can I run code-server with systemd socket activation?
Yes. Pass the inherited socket to code-server with `--socket-fd`. systemd
passes the first listening socket as file descriptor `3`.
Create a socket unit, `~/.config/systemd/user/code-server.socket`:
```ini
[Socket]
ListenStream=8080
[Install]
WantedBy=sockets.target
```
And a matching service unit, `~/.config/systemd/user/code-server.service`:
```ini
[Service]
ExecStart=/usr/bin/code-server --socket-fd 3
```
Then enable and start the socket:
```bash
systemctl --user enable --now code-server.socket
```
code-server will start on the first connection and listen on the socket
systemd created. `--socket-fd` takes precedence over `--socket` and
`--bind-addr`/`--port`/`--host`, and `--socket-mode` is ignored because
systemd owns the socket's permissions.
Socket activation only changes how code-server binds; your usual
authentication still applies (it keeps prompting for the configured password
unless you set `--auth none`), so keep authentication enabled when exposing the
server.

View File

@@ -436,7 +436,7 @@ install_npm() {
fi
echoh "Installing with npm."
echoh
"$sh_c" "$NPM_PATH" install -g "code-server@$VERSION" --unsafe-perm
"$sh_c" "$NPM_PATH" install -g "code-server@$VERSION"
NPM_BIN_DIR="\$($NPM_PATH bin -g)" echo_npm_postinstall
return
fi

47
package-lock.json generated
View File

@@ -20,7 +20,7 @@
"http-proxy": "^1.18.1",
"httpolyglot": "^0.1.2",
"i18next": "^26.3.1",
"js-yaml": "^4.1.0",
"js-yaml": "^5.2.3",
"limiter": "^2.1.0",
"pem": "^1.14.8",
"proxy-agent": "^6.3.1",
@@ -268,6 +268,29 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@eslint/eslintrc/node_modules/js-yaml": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz",
"integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/puzrin"
},
{
"type": "github",
"url": "https://github.com/sponsors/nodeca"
}
],
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/@eslint/js": {
"version": "9.39.3",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.3.tgz",
@@ -953,16 +976,16 @@
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
"version": "5.0.6",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz",
"integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==",
"version": "5.0.9",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz",
"integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^4.0.2"
},
"engines": {
"node": "18 || 20 || >=22"
"node": "20 || >=22"
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
@@ -1677,9 +1700,9 @@
"license": "BSD-2-Clause"
},
"node_modules/brace-expansion": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz",
"integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==",
"version": "1.1.18",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz",
"integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4153,9 +4176,9 @@
"license": "ISC"
},
"node_modules/js-yaml": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz",
"integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.2.3.tgz",
"integrity": "sha512-n+mUVyUX5bVv7G/G2zyIHOhdxfuU1dY2NOFzTQUWiMUbFss8b57NFlgCCaggU78wSw5KVS9cllzeLyzyR+n5nw==",
"funding": [
{
"type": "github",
@@ -4171,7 +4194,7 @@
"argparse": "^2.0.1"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
"js-yaml": "bin/js-yaml.mjs"
}
},
"node_modules/json-buffer": {

View File

@@ -76,7 +76,7 @@
"http-proxy": "^1.18.1",
"httpolyglot": "^0.1.2",
"i18next": "^26.3.1",
"js-yaml": "^4.1.0",
"js-yaml": "^5.2.3",
"limiter": "^2.1.0",
"pem": "^1.14.8",
"proxy-agent": "^6.3.1",

View File

@@ -32,7 +32,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -366,8 +366,11 @@ export class WebClientServer {
@@ -362,8 +362,11 @@ export class WebClientServer {
linkProtectionTrustedDomains.push(...this._productService.linkProtectionTrustedDomains);
}

View File

@@ -10,7 +10,7 @@ Index: code-server/lib/vscode/src/vs/base/common/network.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/base/common/network.ts
+++ code-server/lib/vscode/src/vs/base/common/network.ts
@@ -245,7 +245,9 @@ class RemoteAuthoritiesImpl {
@@ -251,7 +251,9 @@ class RemoteAuthoritiesImpl {
return URI.from({
scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource,
authority: `${host}:${port}`,
@@ -111,7 +111,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
@@ -265,7 +265,9 @@ export class WebClientServer {
@@ -263,7 +263,9 @@ export class WebClientServer {
};
// Prefix routes with basePath for clients
@@ -120,9 +120,9 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
+ const vscodeBase = relativePath(getOriginalUrl(req))
+ const basePath = vscodeBase || getFirstHeader('x-forwarded-prefix') || this._basePath;
const queryConnectionToken = parsedUrl.query[connectionTokenQueryName];
if (typeof queryConnectionToken === 'string') {
@@ -304,10 +306,14 @@ export class WebClientServer {
const queryConnectionTokens = parsedUrl.searchParams.getAll(connectionTokenQueryName);
if (queryConnectionTokens.length === 1) {
@@ -300,10 +302,14 @@ export class WebClientServer {
};
const useTestResolver = (!this._environmentService.isBuilt && this._environmentService.args['use-test-resolver']);
@@ -138,7 +138,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
);
if (!remoteAuthority) {
return serveError(req, res, 400, `Bad request.`);
@@ -354,6 +360,7 @@ export class WebClientServer {
@@ -350,6 +356,7 @@ export class WebClientServer {
const productConfiguration: Partial<Mutable<IProductConfiguration>> = {
codeServerVersion: this._productService.codeServerVersion,
@@ -146,7 +146,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
embedderIdentifier: 'server-distro',
voiceWsUrl: this._productService.voiceWsUrl,
extensionsGallery: this._webExtensionResourceUrlTemplate && this._productService.extensionsGallery ? {
@@ -403,7 +410,9 @@ export class WebClientServer {
@@ -399,7 +406,9 @@ export class WebClientServer {
WORKBENCH_AUTH_SESSION: authSessionInfo ? asJSON(authSessionInfo) : '',
WORKBENCH_WEB_BASE_URL: staticRoute,
WORKBENCH_NLS_URL,
@@ -157,7 +157,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
};
// DEV ---------------------------------------------------------------------------------------
@@ -440,7 +449,7 @@ export class WebClientServer {
@@ -436,7 +445,7 @@ export class WebClientServer {
'default-src \'self\';',
'img-src \'self\' https: data: blob:;',
'media-src \'self\';',
@@ -166,7 +166,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
'child-src \'self\';',
`frame-src 'self' https://*.vscode-cdn.net data:;`,
'worker-src \'self\' data: blob:;',
@@ -513,3 +522,70 @@ export class WebClientServer {
@@ -509,3 +518,70 @@ export class WebClientServer {
return void res.end(data);
}
}

View File

@@ -78,7 +78,7 @@ Index: code-server/lib/vscode/src/vs/platform/environment/common/argv.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/environment/common/argv.ts
+++ code-server/lib/vscode/src/vs/platform/environment/common/argv.ts
@@ -146,6 +146,7 @@ export interface NativeParsedArgs {
@@ -147,6 +147,7 @@ export interface NativeParsedArgs {
'disable-chromium-sandbox'?: boolean;
sandbox?: boolean;
'enable-coi'?: boolean;
@@ -102,7 +102,7 @@ Index: code-server/lib/vscode/src/vs/server/node/server.cli.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/server.cli.ts
+++ code-server/lib/vscode/src/vs/server/node/server.cli.ts
@@ -77,6 +77,7 @@ const isSupportedForPipe = (optionId: ke
@@ -78,6 +78,7 @@ const isSupportedForPipe = (optionId: ke
case 'verbose':
case 'remote':
case 'locate-shell-integration-path':
@@ -110,7 +110,7 @@ Index: code-server/lib/vscode/src/vs/server/node/server.cli.ts
return true;
default:
return false;
@@ -300,6 +301,22 @@ export async function main(desc: Product
@@ -307,6 +308,22 @@ export async function main(desc: Product
}
}
} else {

View File

@@ -153,7 +153,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
@@ -25,6 +25,7 @@ import { URI } from '../../base/common/u
@@ -24,6 +24,7 @@ import { URI } from '../../base/common/u
import { streamToBuffer } from '../../base/common/buffer.js';
import { IProductConfiguration } from '../../base/common/product.js';
import { isString, Mutable } from '../../base/common/types.js';
@@ -161,7 +161,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
import { CharCode } from '../../base/common/charCode.js';
import { IExtensionManifest } from '../../platform/extensions/common/extensions.js';
import { ICSSDevelopmentService } from '../../platform/cssDev/node/cssDevService.js';
@@ -401,14 +402,22 @@ export class WebClientServer {
@@ -397,14 +398,22 @@ export class WebClientServer {
};
const cookies = cookie.parse(req.headers.cookie || '');

View File

@@ -112,7 +112,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
@@ -384,6 +384,8 @@ export class WebClientServer {
@@ -380,6 +380,8 @@ export class WebClientServer {
serverBasePath: basePath,
webviewEndpoint: staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
userDataPath: this._environmentService.userDataPath,
@@ -207,7 +207,7 @@ Index: code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
@@ -40,6 +40,9 @@ export const EmbedderIdentifierContext =
@@ -42,6 +42,9 @@ export const EmbedderIdentifierContext =
export const InAutomationContext = new RawContextKey<boolean>('inAutomation', false, localize('inAutomation', "Whether VS Code is running under automation/smoke test"));

View File

@@ -201,7 +201,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
@@ -388,6 +388,7 @@ export class WebClientServer {
@@ -384,6 +384,7 @@ export class WebClientServer {
userDataPath: this._environmentService.userDataPath,
isEnabledFileDownloads: !this._environmentService.args['disable-file-downloads'],
isEnabledFileUploads: !this._environmentService.args['disable-file-uploads'],
@@ -234,7 +234,7 @@ Index: code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
@@ -42,6 +42,7 @@ export const InAutomationContext = new R
@@ -44,6 +44,7 @@ export const InAutomationContext = new R
export const IsEnabledFileDownloads = new RawContextKey<boolean>('isEnabledFileDownloads', true, true);
export const IsEnabledFileUploads = new RawContextKey<boolean>('isEnabledFileUploads', true, true);

View File

@@ -251,7 +251,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
@@ -353,6 +353,7 @@ export class WebClientServer {
@@ -349,6 +349,7 @@ export class WebClientServer {
} : undefined;
const productConfiguration: Partial<Mutable<IProductConfiguration>> = {
@@ -326,7 +326,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialog.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialog.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialog.ts
@@ -47,8 +47,11 @@ export function createWorkbenchDialogOpt
@@ -54,8 +54,11 @@ export function createWorkbenchDialogOpt
export function createBrowserAboutDialogDetails(productService: IProductService): { title: string; details: string; detailsToCopy: string } {
const detailString = (useAgo: boolean): string => {

View File

@@ -18,7 +18,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
@@ -379,6 +379,7 @@ export class WebClientServer {
@@ -375,6 +375,7 @@ export class WebClientServer {
remoteAuthority,
serverBasePath: basePath,
webviewEndpoint: staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',

View File

@@ -40,7 +40,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -361,6 +361,7 @@ export class WebClientServer {
@@ -357,6 +357,7 @@ export class WebClientServer {
codeServerVersion: this._productService.codeServerVersion,
rootEndpoint: rootBase,
updateEndpoint: !this._environmentService.args['disable-update-check'] ? rootBase + '/update/check' : undefined,

View File

@@ -41,7 +41,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
@@ -346,7 +346,6 @@ export class WebClientServer {
@@ -342,7 +342,6 @@ export class WebClientServer {
const staticRoute = posix.join(basePath, this._productPath, STATIC_PATH);
const callbackRoute = posix.join(basePath, this._productPath, CALLBACK_PATH);
@@ -49,7 +49,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
const resolveWorkspaceURI = (defaultLocation?: string) => defaultLocation && URI.file(resolve(defaultLocation)).with({ scheme: Schemas.vscodeRemote, authority: remoteAuthority });
@@ -363,14 +362,7 @@ export class WebClientServer {
@@ -359,14 +358,7 @@ export class WebClientServer {
rootEndpoint: rootBase,
embedderIdentifier: 'server-distro',
voiceWsUrl: this._productService.voiceWsUrl,

View File

@@ -71,7 +71,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
@@ -362,6 +362,7 @@ export class WebClientServer {
@@ -358,6 +358,7 @@ export class WebClientServer {
rootEndpoint: rootBase,
updateEndpoint: !this._environmentService.args['disable-update-check'] ? rootBase + '/update/check' : undefined,
logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? rootBase + '/logout' : undefined,

View File

@@ -54,7 +54,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
@@ -363,6 +363,10 @@ export class WebClientServer {
@@ -359,6 +359,10 @@ export class WebClientServer {
updateEndpoint: !this._environmentService.args['disable-update-check'] ? rootBase + '/update/check' : undefined,
logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? rootBase + '/logout' : undefined,
proxyEndpointTemplate: process.env.VSCODE_PROXY_URI ?? rootBase + '/proxy/{{port}}/',

View File

@@ -126,7 +126,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
@@ -367,6 +367,8 @@ export class WebClientServer {
@@ -363,6 +363,8 @@ export class WebClientServer {
scope: vscodeBase + '/',
path: rootBase + '/_static/out/browser/serviceWorker.js',
},
@@ -151,7 +151,7 @@ Index: code-server/lib/vscode/src/vs/platform/product/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/product/common/product.ts
+++ code-server/lib/vscode/src/vs/platform/product/common/product.ts
@@ -113,7 +113,8 @@ else {
@@ -74,7 +74,8 @@ else if (globalThis._VSCODE_PRODUCT_JSON
resourceUrlTemplate: "https://open-vsx.org/vscode/asset/{publisher}/{name}/{version}/Microsoft.VisualStudio.Code.WebResources/{path}",
controlUrl: "",
recommendationsUrl: "",

View File

@@ -24,7 +24,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
@@ -358,6 +358,14 @@ export class WebClientServer {
@@ -354,6 +354,14 @@ export class WebClientServer {
scopes: [['user:email'], ['repo']]
} : undefined;
@@ -39,7 +39,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
const productConfiguration: Partial<Mutable<IProductConfiguration>> = {
codeServerVersion: this._productService.codeServerVersion,
rootEndpoint: rootBase,
@@ -373,6 +381,7 @@ export class WebClientServer {
@@ -369,6 +377,7 @@ export class WebClientServer {
embedderIdentifier: 'server-distro',
voiceWsUrl: this._productService.voiceWsUrl,
extensionsGallery: this._productService.extensionsGallery,

View File

@@ -113,7 +113,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
@@ -360,6 +360,7 @@ export class WebClientServer {
@@ -356,6 +356,7 @@ export class WebClientServer {
const productConfiguration: Partial<Mutable<IProductConfiguration>> = {
codeServerVersion: this._productService.codeServerVersion,
rootEndpoint: rootBase,

View File

@@ -41,7 +41,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
@@ -375,6 +375,7 @@ export class WebClientServer {
@@ -371,6 +371,7 @@ export class WebClientServer {
const workbenchWebConfiguration = {
remoteAuthority,
serverBasePath: basePath,

View File

@@ -13,7 +13,8 @@ import { EditorSessionManager, makeEditorSessionManagerServer } from "./vscodeSo
import { handleUpgrade } from "./wsRouter"
type SocketOptions = { socket: string; "socket-mode"?: string }
type ListenOptions = DefaultedArgs | SocketOptions
type FdOptions = { "socket-fd": number }
type ListenOptions = DefaultedArgs | SocketOptions | FdOptions
export interface App extends Disposable {
/** Handles regular HTTP requests. */
@@ -30,8 +31,12 @@ const isSocketOpts = (opts: ListenOptions): opts is SocketOptions => {
return !!(opts as SocketOptions).socket || !(opts as DefaultedArgs).host
}
export const isFdOpts = (opts: ListenOptions): opts is FdOptions => {
return typeof (opts as FdOptions)["socket-fd"] === "number"
}
export const listen = async (server: http.Server, opts: ListenOptions) => {
if (isSocketOpts(opts)) {
if (!isFdOpts(opts) && isSocketOpts(opts)) {
try {
await fs.unlink(opts.socket)
} catch (error: any) {
@@ -46,7 +51,9 @@ export const listen = async (server: http.Server, opts: ListenOptions) => {
server.on("error", (err) => util.logError(logger, "http server error", err))
resolve()
}
if (isSocketOpts(opts)) {
if (isFdOpts(opts)) {
server.listen({ fd: opts["socket-fd"] }, onListen)
} else if (isSocketOpts(opts)) {
server.listen(opts.socket, onListen)
} else {
// [] is the correct format when using :: but Node errors with them.
@@ -56,7 +63,7 @@ export const listen = async (server: http.Server, opts: ListenOptions) => {
// NOTE@jsjoeio: we need to chmod after the server is finished
// listening. Otherwise, the socket may not have been created yet.
if (isSocketOpts(opts)) {
if (!isFdOpts(opts) && isSocketOpts(opts)) {
if (opts["socket-mode"]) {
await fs.chmod(opts.socket, opts["socket-mode"])
}

View File

@@ -83,6 +83,7 @@ export interface UserProvidedArgs extends UserProvidedCodeArgs {
open?: boolean
"bind-addr"?: string
socket?: string
"socket-fd"?: number
"socket-mode"?: string
"trusted-origins"?: string[]
version?: boolean
@@ -97,6 +98,7 @@ export interface UserProvidedArgs extends UserProvidedCodeArgs {
"abs-proxy-base-path"?: string
i18n?: string
"idle-timeout-seconds"?: number
"vscode-option"?: string[]
/* Positional arguments. */
_?: string[]
}
@@ -235,6 +237,10 @@ export const options: Options<Required<UserProvidedArgs>> = {
port: { type: "number", description: "" },
socket: { type: "string", path: true, description: "Path to a socket (bind-addr will be ignored)." },
"socket-fd": {
type: "number",
description: "File descriptor of a pre-bound, listening socket to use (for systemd socket activation).",
},
"socket-mode": { type: "string", description: "File mode of the socket." },
"trusted-origins": {
type: "string[]",
@@ -322,6 +328,13 @@ export const options: Options<Required<UserProvidedArgs>> = {
"Override the reconnection grace time in seconds. Clients who disconnect for longer than this duration will need to \n" +
"reload the window. Defaults to 10800 (3 hours).",
},
"vscode-option": {
type: "string[]",
description:
"Pass an option straight through to the VS Code server as flag=value, or as a bare flag for a \n" +
"boolean. Repeatable; repeating the same flag builds an array. Use this to reach VS Code options \n" +
"code-server does not model itself, e.g. --vscode-option enable-sandbox --vscode-option agents=true.",
},
}
export const optionDescriptions = (opts: Partial<Options<Required<UserProvidedArgs>>> = options): string[] => {
@@ -643,6 +656,15 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
args["reconnection-grace-time"] = process.env.CODE_SERVER_RECONNECTION_GRACE_TIME
}
// Space-separated, like NODE_OPTIONS. Appended to any flags rather than
// replacing them so the two can be combined.
if (process.env.VSCODE_OPTIONS) {
args["vscode-option"] = [
...(args["vscode-option"] ?? []),
...process.env.VSCODE_OPTIONS.split(/\s+/).filter((option) => option),
]
}
if (process.env.CODE_SERVER_IDLE_TIMEOUT_SECONDS) {
if (isNaN(Number(process.env.CODE_SERVER_IDLE_TIMEOUT_SECONDS))) {
logger.info("CODE_SERVER_IDLE_TIMEOUT_SECONDS must be a number")
@@ -909,17 +931,58 @@ export interface CodeArgs extends UserProvidedCodeArgs {
log?: string[]
}
/**
* Expand --vscode-option entries into VS Code server arguments.
*
* An entry is `flag=value`, or a bare `flag` meaning true. A leading `--` on
* the flag is optional, so both spellings people reach for work. Repeating a
* flag collects the values into an array, since several VS Code options take
* one.
*
* `true` and `false` become booleans rather than strings. VS Code tests these
* flags for truthiness and the string "false" is truthy, so passing it along
* verbatim would quietly do the opposite of what was asked.
*/
export const parseVscodeOptions = (entries: string[]): Record<string, string | boolean | string[]> => {
const parsed: Record<string, string | boolean | string[]> = {}
for (const entry of entries) {
const [flag, rawValue] = splitOnFirstEquals(entry.replace(/^--/, ""))
if (!flag) {
throw new Error(`--vscode-option requires a flag name (got "${entry}")`)
}
const value: string | boolean =
typeof rawValue === "undefined" || rawValue === "true" ? true : rawValue === "false" ? false : rawValue
const existing = parsed[flag]
if (typeof existing === "undefined") {
parsed[flag] = value
} else if (Array.isArray(existing)) {
existing.push(String(value))
} else {
parsed[flag] = [String(existing), String(value)]
}
}
return parsed
}
/**
* Convert our arguments to equivalent VS Code server arguments.
* Does not add any extra arguments.
*/
export const toCodeArgs = async (args: DefaultedArgs): Promise<CodeArgs> => {
// The passthrough option is ours; VS Code has no idea what it is.
const { "vscode-option": vscodeOptions, ...rest } = args
return {
...args,
...rest,
/** Type casting. */
help: !!args.help,
version: !!args.version,
port: args.port?.toString(),
log: args.log ? [args.log] : undefined,
}
// Last, so that reaching an option code-server does model still works.
...parseVscodeOptions(vscodeOptions ?? []),
} as CodeArgs
}

View File

@@ -1498,9 +1498,9 @@
"license": "MIT"
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"version": "1.1.18",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz",
"integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==",
"dev": true,
"license": "MIT",
"dependencies": {

View File

@@ -3,7 +3,7 @@ import { promises } from "fs"
import * as http from "http"
import * as https from "https"
import * as path from "path"
import { createApp, ensureAddress, handleArgsSocketCatchError, listen } from "../../../src/node/app"
import { createApp, ensureAddress, handleArgsSocketCatchError, isFdOpts, listen } from "../../../src/node/app"
import { OptionalString, setDefaults } from "../../../src/node/cli"
import { generateCertificate } from "../../../src/node/util"
import { clean, mockLogger, getAvailablePort, tmpdir } from "../../utils/helpers"
@@ -261,3 +261,47 @@ describe("listen", () => {
}
})
})
describe("listen (socket-fd)", () => {
// Wrap a bound-but-not-yet-listening TCP socket so we get a real file
// descriptor that listen({ fd }) can adopt, mirroring the systemd socket
// activation case where the process inherits an fd and calls listen(2) on it.
// Using a live net.Server's fd instead fails with EEXIST because the socket
// is already listening in-process.
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { TCP, constants: TCPConstants } = (process as any).binding("tcp_wrap")
let inherited: any
let httpServer: http.Server
let unlinkSpy: jest.SpyInstance
beforeEach(async () => {
mockLogger()
unlinkSpy = jest.spyOn(promises, "unlink")
inherited = new TCP(TCPConstants.SERVER)
inherited.bind("127.0.0.1", 0)
httpServer = http.createServer()
})
afterEach(() => {
httpServer.close()
try {
inherited.close()
} catch {
// The fd is adopted by httpServer.close() above; ignore double-close.
}
jest.clearAllMocks()
})
it("isFdOpts detects a numeric socket-fd", () => {
expect(isFdOpts({ "socket-fd": 3 })).toBe(true)
expect(isFdOpts({ socket: "/tmp/x.sock" } as any)).toBe(false)
})
it("listens on an inherited fd without unlinking", async () => {
const fd = inherited.fd as number
await listen(httpServer, { "socket-fd": fd })
expect(httpServer.address()).not.toBeNull()
expect(unlinkSpy).not.toHaveBeenCalled()
})
})

View File

@@ -51,6 +51,7 @@ describe("parser", () => {
delete process.env.CODE_SERVER_RECONNECTION_GRACE_TIME
delete process.env.VSCODE_PROXY_URI
delete process.env.CS_DISABLE_PROXY
delete process.env.VSCODE_OPTIONS
console.log = jest.fn()
})
@@ -413,6 +414,17 @@ describe("parser", () => {
})
})
it("should use env var VSCODE_OPTIONS", async () => {
process.env.VSCODE_OPTIONS = "--enable-sandbox agents=true"
const args = parse(["--vscode-option", "verbose-logging"])
const defaultArgs = await setDefaults(args)
expect(defaultArgs).toEqual({
...defaults,
"vscode-option": ["verbose-logging", "--enable-sandbox", "agents=true"],
})
})
it("should use env var CS_DISABLE_GETTING_STARTED_OVERRIDE", async () => {
process.env.CS_DISABLE_GETTING_STARTED_OVERRIDE = "1"
const args = parse([])
@@ -1006,6 +1018,44 @@ describe("toCodeArgs", () => {
_: [file],
})
})
it("should pass through --vscode-option", async () => {
const args = parse([
"--vscode-option",
"enable-sandbox",
"--vscode-option",
"agents=true",
"--vscode-option",
"enable-smoke-test-driver=false",
])
expect(await toCodeArgs(await setDefaults(args))).toStrictEqual({
...vscodeDefaults,
"enable-sandbox": true,
agents: true,
"enable-smoke-test-driver": false,
})
})
it("should collect a repeated --vscode-option into an array", async () => {
const args = parse([
"--vscode-option",
"locate-extension=a",
"--vscode-option",
"locate-extension=b",
"--vscode-option",
"locate-extension=c",
])
expect(await toCodeArgs(await setDefaults(args))).toStrictEqual({
...vscodeDefaults,
"locate-extension": ["a", "b", "c"],
})
})
it("should error if --vscode-option has no flag", async () => {
await expect(toCodeArgs(await setDefaults(parse(["--vscode-option", "=nothing"])))).rejects.toThrow(
"--vscode-option requires a flag name",
)
})
})
describe("optionDescriptions", () => {