Compare commits

..

5 Commits

Author SHA1 Message Date
Joe Previte
afc7a0ea98 Merge branch 'main' into jsjoeio/nfpm-fix 2022-12-16 08:55:24 -07:00
Joe Previte
6702b2d0af Merge branch 'main' into jsjoeio/nfpm-fix 2022-12-15 14:25:40 -07:00
Joe Previte
7305f2b216 Update ci/README.md 2022-12-15 09:40:47 -07:00
Joe Previte
d808347794 trigger ci 2022-12-13 11:10:21 -07:00
Joe Previte
ac38d6ed58 fix: dst path in nfpm 2022-12-13 11:01:55 -07:00
52 changed files with 546 additions and 665 deletions

2
.github/CODEOWNERS vendored
View File

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

View File

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

View File

@@ -83,7 +83,7 @@ jobs:
- name: Install helm
if: steps.changed-files.outputs.any_changed == 'true'
uses: azure/setup-helm@v3.5
uses: azure/setup-helm@v3.4
with:
token: ${{ secrets.GITHUB_TOKEN }}
@@ -139,67 +139,6 @@ jobs:
if: steps.changed-files.outputs.any_changed == 'true'
run: yarn lint:ts
lint-actions:
name: Lint GitHub Actions
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Check workflow files
run: |
bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/7fdc9630cc360ea1a469eed64ac6d78caeda1234/scripts/download-actionlint.bash)
./actionlint -color -shellcheck= -ignore "set-output"
shell: bash
test-unit:
name: Run unit tests
runs-on: ubuntu-20.04
timeout-minutes: 5
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 2
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v26.1
with:
files: |
**/*.ts
files_ignore: |
lib/vscode/**
- name: Install Node.js v16
if: steps.changed-files.outputs.any_changed == 'true'
uses: actions/setup-node@v3
with:
node-version: "16"
- name: Fetch dependencies from cache
if: steps.changed-files.outputs.any_changed == 'true'
id: cache-node-modules
uses: actions/cache@v3
with:
path: "**/node_modules"
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
yarn-build-
- name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true' && steps.cache-node-modules.outputs.cache-hit != 'true'
run: SKIP_SUBMODULE_DEPS=1 yarn --frozen-lockfile
- name: Run unit tests
if: steps.changed-files.outputs.any_changed == 'true'
run: yarn test:unit
- name: Upload coverage report to Codecov
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
if: success()
build:
name: Build code-server
runs-on: ubuntu-20.04
@@ -231,17 +170,15 @@ jobs:
uses: actions/cache@v3
with:
path: "**/node_modules"
key: yarn-build-code-server-${{ hashFiles('**/yarn.lock') }}
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
yarn-build-code-server-
yarn-build-
- name: Install dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: yarn --frozen-lockfile
- name: Build code-server
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: yarn build
# Get Code's git hash. When this changes it means the content is
@@ -267,6 +204,19 @@ jobs:
if: steps.cache-vscode.outputs.cache-hit != 'true'
run: yarn build:vscode
# Our code imports code from VS Code's `out` directory meaning VS Code
# must be built before running these tests.
# TODO: Move to its own step?
- name: Run code-server unit tests
run: yarn test:unit
if: success()
- name: Upload coverage report to Codecov
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
if: success()
# The release package does not contain any native modules
# and is neutral to architecture/os/libc version.
- name: Create release package
@@ -283,6 +233,65 @@ jobs:
name: npm-package
path: ./package.tar.gz
npm:
name: Publish npm package
# the npm-package gets uploaded as an artifact in Build
# so we need that to complete before this runs
needs: build
# This environment "npm" requires someone from
# coder/code-server-reviewers to approve the PR before this job runs.
environment: npm
# Only run if PR comes from base repo or event is not a PR
# Reason: forks cannot access secrets and this will always fail
if: github.event.pull_request.head.repo.full_name == github.repository || github.event_name != 'pull_request'
runs-on: ubuntu-20.04
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Download artifact
uses: actions/download-artifact@v3
id: download
with:
name: "npm-package"
path: release-npm-package
- name: Run ./ci/steps/publish-npm.sh
run: yarn publish:npm
env:
# NOTE@jsjoeio
# This is because npm enforces semantic versioning
# so it has to be a valid version. We only use this
# to publish dev versions from prs
# and beta versions from main.
VERSION: "0.0.0"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
# NOTE@jsjoeio
# NPM_ENVIRONMENT intentionally not set here.
# Instead, itis determined in publish-npm.sh script
# using GITHUB environment variables
- name: Comment npm information
uses: marocchino/sticky-pull-request-comment@v2
with:
GITHUB_TOKEN: ${{ github.token }}
header: npm-dev-build
message: |
✨ code-server dev build published to npm for PR #${{ github.event.number }}!
* _Last publish status_: success
* _Commit_: ${{ github.event.pull_request.head.sha }}
To install in a local project, run:
```shell-session
npm install @coder/code-server-pr@${{ github.event.number }}
```
To install globally, run:
```shell-session
npm install -g @coder/code-server-pr@${{ github.event.number }}
```
test-e2e:
name: Run e2e tests
needs: build
@@ -327,7 +336,7 @@ jobs:
./test/node_modules/.bin/playwright install
- name: Run end-to-end tests
run: CODE_SERVER_TEST_ENTRY=./release yarn test:e2e
run: CODE_SERVER_TEST_ENTRY=./release yarn test:e2e --global-timeout 840000
- name: Upload test artifacts
if: always()
@@ -383,7 +392,7 @@ jobs:
./test/node_modules/.bin/playwright install
- name: Cache Caddy
uses: actions/cache@v3
uses: actions/cache@v2
id: caddy-cache
with:
path: |
@@ -396,7 +405,7 @@ jobs:
if: steps.caddy-cache.outputs.cache-hit != 'true'
run: |
gh release download v2.5.2 --repo caddyserver/caddy --pattern "caddy_2.5.2_linux_amd64.tar.gz"
mkdir -p ~/.cache/caddy
mkdir -p ~/.cache/caddy
tar -xzf caddy_2.5.2_linux_amd64.tar.gz --directory ~/.cache/caddy
- name: Start Caddy

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

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

View File

@@ -30,7 +30,7 @@ jobs:
uses: actions/checkout@v3
- name: Download npm package from release artifacts
uses: robinraju/release-downloader@v1.7
uses: robinraju/release-downloader@v1.6
with:
repository: "coder/code-server"
tag: ${{ github.event.inputs.version || github.ref_name }}
@@ -137,14 +137,12 @@ jobs:
- name: Open PR
# We need to git push -u otherwise gh will prompt
# asking where to push the branch.
env:
VERSION: ${{ env.VERSION }}
run: |
git checkout -b update-version-${{ env.VERSION }}
git checkout -b update-version-${{ steps.version.outputs.version }}
git add .
git commit -m "chore: updating version to ${{ env.VERSION }}"
git commit -m "chore: updating version to ${{ steps.version.outputs.version }}"
git push -u origin $(git branch --show)
gh pr create --repo coder/code-server-aur --title "chore: bump version to ${{ env.VERSION }}" --body "PR opened by @$GITHUB_ACTOR" --assignee $GITHUB_ACTOR
gh pr create --repo coder/code-server-aur --title "chore: bump version to ${{ steps.version.outputs.version }}" --body "PR opened by @$GITHUB_ACTOR" --assignee $GITHUB_ACTOR
docker:
runs-on: ubuntu-20.04
steps:
@@ -178,7 +176,7 @@ jobs:
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- name: Download release artifacts
uses: robinraju/release-downloader@v1.7
uses: robinraju/release-downloader@v1.6
with:
repository: "coder/code-server"
tag: v${{ env.VERSION }}

View File

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

View File

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

View File

@@ -20,20 +20,6 @@ Code v99.99.999
-->
## [4.9.1](https://github.com/coder/code-server/releases/tag/v4.9.1) - 2022-12-15
Code v1.73.1
### Changed
- Updated a couple steps in the build and release process to ensure we're using
`npm` and `yarn` consistently depending on the step.
### Fixed
- Fixed an issue with code-server version not displaying in the Help > About window.
- Fixed terminal not loading on macOS clients.
## [4.9.0](https://github.com/coder/code-server/releases/tag/v4.9.0) - 2022-12-06
Code v1.73.1

View File

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

View File

@@ -1,4 +1,4 @@
import { spawn, ChildProcess } from "child_process"
import { spawn, fork, ChildProcess } from "child_process"
import * as path from "path"
import { onLine, OnLineCallback } from "../../src/node/util"
@@ -30,7 +30,7 @@ class Watcher {
// Pass CLI args, save for `node` and the initial script name.
const args = process.argv.slice(2)
this.webServer = spawn("node", [path.join(this.rootPath, "out/node/entry.js"), ...args])
this.webServer = fork(path.join(this.rootPath, "out/node/entry.js"), args)
const { pid } = this.webServer
this.webServer.on("exit", () => console.log("[Code Server]", `Web process ${pid} exited`))

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.4.1
version: 3.4.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
appVersion: 4.9.1
appVersion: 4.9.0

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -37,11 +37,6 @@
"icon_path": "assets/images/icons/usage.svg",
"path": "./guide.md",
"children": [
{
"title": "Coder",
"description": "How to run code-server in Coder",
"path": "./coder.md"
},
{
"title": "--link",
"description": "How to run code-server --link",

View File

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

View File

@@ -88,16 +88,15 @@
},
"dependencies": {
"@coder/logger": "^3.0.0",
"argon2": "0.30.3",
"argon2": "0.30.2",
"compression": "^1.7.4",
"cookie-parser": "^1.4.5",
"env-paths": "^2.2.0",
"express": "5.0.0-alpha.8",
"http-proxy": "^1.18.0",
"httpolyglot": "^0.1.2",
"i18next": "^22.4.6",
"js-yaml": "^4.0.0",
"limiter": "^2.1.0",
"limiter": "^1.1.5",
"pem": "^1.14.2",
"proxy-agent": "^5.0.0",
"qs": "6.11.0",

View File

@@ -10,7 +10,7 @@ Index: code-server/lib/vscode/src/vs/base/common/network.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/base/common/network.ts
+++ code-server/lib/vscode/src/vs/base/common/network.ts
@@ -166,7 +166,9 @@ class RemoteAuthoritiesImpl {
@@ -162,7 +162,9 @@ class RemoteAuthoritiesImpl {
return URI.from({
scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource,
authority: `${host}:${port}`,

View File

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

View File

@@ -7,7 +7,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts
@@ -243,6 +243,10 @@ export class Extension implements IExten
@@ -237,6 +237,10 @@ export class Extension implements IExten
if (this.type === ExtensionType.System && this.productService.quality === 'stable') {
return false;
}
@@ -18,3 +18,14 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
if (!this.local.preRelease && this.gallery.properties.isPreReleaseVersion) {
return false;
}
@@ -1237,6 +1241,10 @@ export class ExtensionsWorkbenchService
// Skip if check updates only for builtin extensions and current extension is not builtin.
continue;
}
+ if (installed.type !== ExtensionType.User) {
+ // Never update builtin extensions.
+ continue;
+ }
if (installed.isBuiltin && (!installed.local?.identifier.uuid || (!isWeb && this.productService.quality === 'stable'))) {
// Skip checking updates for a builtin extension if it does not has Marketplace identifier or the current product is VS Code Desktop stable.
continue;

View File

@@ -12,7 +12,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
@@ -266,6 +266,11 @@ export interface IWorkbenchConstructionO
@@ -271,6 +271,11 @@ export interface IWorkbenchConstructionO
*/
readonly userDataPath?: string
@@ -23,7 +23,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
+
//#endregion
//#region Profile options
Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
@@ -40,7 +40,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi
}
export class BrowserWorkbenchEnvironmentService implements IBrowserWorkbenchEnvironmentService {
@@ -104,6 +109,13 @@ export class BrowserWorkbenchEnvironment
@@ -87,6 +92,13 @@ export class BrowserWorkbenchEnvironment
return this.options.userDataPath;
}
@@ -143,8 +143,8 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions
+import { DirtyWorkingCopiesContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, WorkbenchStateContext, WorkspaceFolderCountContext, SidebarFocusContext, ActiveEditorCanRevertContext, ActiveEditorContext, ResourceContextKey, ActiveEditorAvailableEditorIdsContext, IsEnabledFileDownloads } from 'vs/workbench/common/contextkeys';
import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { ThemeIcon } from 'vs/base/common/themables';
@@ -484,13 +484,16 @@ MenuRegistry.appendMenuItem(MenuId.Explo
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
@@ -483,13 +483,16 @@ MenuRegistry.appendMenuItem(MenuId.Explo
id: DOWNLOAD_COMMAND_ID,
title: DOWNLOAD_LABEL
},

View File

@@ -19,7 +19,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/serverServices.ts
+++ code-server/lib/vscode/src/vs/server/node/serverServices.ts
@@ -220,6 +220,9 @@ export async function setupServerService
@@ -216,6 +216,9 @@ export async function setupServerService
const channel = new ExtensionManagementChannel(extensionManagementService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority));
socketServer.registerChannel('extensions', channel);
@@ -42,7 +42,7 @@ Index: code-server/lib/vscode/src/vs/base/common/platform.ts
export const LANGUAGE_DEFAULT = 'en';
let _isWindows = false;
@@ -86,17 +84,19 @@ if (typeof navigator === 'object' && !is
@@ -83,17 +81,19 @@ if (typeof navigator === 'object' && !is
_isMobile = _userAgent?.indexOf('Mobi') >= 0;
_isWeb = true;
@@ -125,7 +125,7 @@ Index: code-server/lib/vscode/src/vs/platform/environment/common/environmentServ
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/environment/common/environmentService.ts
+++ code-server/lib/vscode/src/vs/platform/environment/common/environmentService.ts
@@ -107,7 +107,7 @@ export abstract class AbstractNativeEnvi
@@ -110,7 +110,7 @@ export abstract class AbstractNativeEnvi
return URI.file(join(vscodePortable, 'argv.json'));
}

View File

@@ -10,7 +10,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts
@@ -60,7 +60,7 @@ import { GettingStartedIndexList } from
@@ -62,7 +62,7 @@ import { GettingStartedIndexList } from
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { getTelemetryLevel } from 'vs/platform/telemetry/common/telemetryUtils';
@@ -19,7 +19,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
import { OpenFolderViaWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions';
import { OpenRecentAction } from 'vs/workbench/browser/actions/windowActions';
import { Toggle } from 'vs/base/browser/ui/toggle/toggle';
@@ -759,6 +759,72 @@ export class GettingStartedPage extends
@@ -758,6 +758,72 @@ export class GettingStartedPage extends
$('p.subtitle.description', {}, localize({ key: 'gettingStarted.editingEvolved', comment: ['Shown as subtitle on the Welcome page.'] }, "Editing evolved"))
);
@@ -72,7 +72,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
+ 'align-items: center',
+ ].join(';'),
+ }, 'Get started ', $('span', {
+ class: ThemeIcon.asClassName(Codicon.arrowRight),
+ class: Codicon.arrowRight.classNames,
+ style: [
+ 'color: white',
+ 'margin-left: 8px',
@@ -92,7 +92,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
const leftColumn = $('.categories-column.categories-column-left', {},);
const rightColumn = $('.categories-column.categories-column-right', {},);
@@ -776,13 +842,23 @@ export class GettingStartedPage extends
@@ -775,13 +841,23 @@ export class GettingStartedPage extends
const layoutLists = () => {
if (gettingStartedList.itemCount) {
this.container.classList.remove('noWalkthroughs');
@@ -143,7 +143,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
@@ -271,6 +271,11 @@ export interface IWorkbenchConstructionO
@@ -276,6 +276,11 @@ export interface IWorkbenchConstructionO
*/
readonly isEnabledFileDownloads?: boolean
@@ -154,7 +154,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
+
//#endregion
//#region Profile options
Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
@@ -171,7 +171,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi
}
export class BrowserWorkbenchEnvironmentService implements IBrowserWorkbenchEnvironmentService {
@@ -116,6 +121,13 @@ export class BrowserWorkbenchEnvironment
@@ -99,6 +104,13 @@ export class BrowserWorkbenchEnvironment
return this.options.isEnabledFileDownloads;
}

View File

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

View File

@@ -32,7 +32,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
@@ -261,6 +261,11 @@ export interface IWorkbenchConstructionO
@@ -266,6 +266,11 @@ export interface IWorkbenchConstructionO
*/
readonly configurationDefaults?: Record<string, any>;
@@ -43,12 +43,12 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
+
//#endregion
//#region Profile options
Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
@@ -95,7 +95,14 @@ export class BrowserWorkbenchEnvironment
@@ -78,7 +78,14 @@ export class BrowserWorkbenchEnvironment
get logFile(): URI { return joinPath(this.windowLogsPath, 'window.log'); }
@memoize

View File

@@ -19,7 +19,7 @@ Index: code-server/lib/vscode/src/vs/platform/product/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/product/common/product.ts
+++ code-server/lib/vscode/src/vs/platform/product/common/product.ts
@@ -47,6 +47,16 @@ else if (globalThis._VSCODE_PRODUCT_JSON
@@ -53,6 +53,16 @@ else if (typeof require?.__$__nodeRequir
version: pkg.version
});
}

View File

@@ -10,7 +10,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/extensions/common/abstra
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/extensions/common/abstractExtensionService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/extensions/common/abstractExtensionService.ts
@@ -1486,7 +1486,7 @@ class ProposedApiController {
@@ -1482,7 +1482,7 @@ class ProposedApiController {
this._envEnabledExtensions = new Set((_environmentService.extensionEnabledProposedApi ?? []).map(id => ExtensionIdentifier.toKey(id)));

View File

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

View File

@@ -32,7 +32,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js
let version = packageJson.version;
const quality = product.quality;
@@ -389,7 +388,7 @@ function tweakProductForServerWeb(produc
@@ -388,7 +387,7 @@ function tweakProductForServerWeb(produc
const minifyTask = task.define(`minify-vscode-${type}`, task.series(
optimizeTask,
util.rimraf(`out-vscode-${type}-min`),

View File

@@ -1,7 +1,7 @@
Add support for telemetry endpoint
To test:
1. Create a mock API using [RequestBin](https://requestbin.io/) or [Beeceptor](https://beeceptor.com/)
1. Create a RequestBin - https://requestbin.io/
2. Run code-server with `CS_TELEMETRY_URL` set:
i.e. `CS_TELEMETRY_URL="https://requestbin.io/1ebub9z1" ./code-server-<version>-macos-amd64/bin/code-server`
NOTE: it has to be a production build.
@@ -12,15 +12,15 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/serverServices.ts
+++ code-server/lib/vscode/src/vs/server/node/serverServices.ts
@@ -70,6 +70,7 @@ import { IExtensionsScannerService } fro
@@ -71,6 +71,7 @@ import { IExtensionsScannerService } fro
import { ExtensionsScannerService } from 'vs/server/node/extensionsScannerService';
import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService';
import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
import { ExtensionsProfileScannerService, IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService';
import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
+import { TelemetryClient } from "vs/server/node/telemetryClient";
import { NullPolicyService } from 'vs/platform/policy/common/policy';
import { OneDataSystemAppender } from 'vs/platform/telemetry/node/1dsAppender';
import { LoggerService } from 'vs/platform/log/node/loggerService';
@@ -142,10 +143,13 @@ export async function setupServerService
@@ -139,10 +140,13 @@ export async function setupServerService
const machineId = await getMachineId();
const isInternal = isInternalTelemetry(productService, configurationService);
if (supportsTelemetry(productService, environmentService)) {

View File

@@ -41,7 +41,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
@@ -224,7 +224,7 @@ export class BrowserWorkbenchEnvironment
@@ -210,7 +210,7 @@ export class BrowserWorkbenchEnvironment
@memoize
get webviewExternalEndpoint(): string {
@@ -62,15 +62,6 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
_wrapWebWorkerExtHostInIframe,
developmentOptions: { enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined, logLevel: this._logService.getLevel() },
settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined,
@@ -344,7 +345,7 @@ export class WebClientServer {
`script-src 'self' 'unsafe-eval' ${this._getScriptCspHashes(data).join(' ')} 'sha256-fh3TwPMflhsEIpR8g1OYTIMVWhXTLcjQ9kh2tIpmv54=';`, // the sha is the same as in src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
'child-src \'self\';',
`frame-src 'self' https://*.vscode-cdn.net data:;`,
- 'worker-src \'self\' data:;',
+ 'worker-src \'self\' data: blob:;',
'style-src \'self\' \'unsafe-inline\';',
'connect-src \'self\' ws: wss: https:;',
'font-src \'self\' blob:;',
Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index.html
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index.html
@@ -79,12 +70,12 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy"
- content="default-src 'none'; script-src 'sha256-RaCvj6SRgHm+2C3LKzSAamDwa3Bp4u4iQ1Y2Sm+97tE=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
+ content="default-src 'none'; script-src 'sha256-mi72idjvdhsPSBMKFqU82FG/kZVJjKR0TfHLE13gB+w=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
- content="default-src 'none'; script-src 'sha256-lC8sxUeeYqUtmkCpPt/OX/HQdE0JbHG1Z3dzrilsRU0=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
+ content="default-src 'none'; script-src 'sha256-/9/YQU12wvTeVXCsIGB4shLwdWrMceCpKojfkloNjPU=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
<!-- Disable pinch zooming -->
<meta name="viewport"
@@ -325,6 +325,12 @@
@@ -331,6 +331,12 @@
const hostname = location.hostname;
@@ -101,7 +92,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html
+++ code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html
@@ -322,6 +322,12 @@
@@ -330,6 +330,12 @@
const hostname = location.hostname;

View File

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

View File

@@ -10,7 +10,7 @@
http-equiv="Content-Security-Policy"
content="style-src 'self'; script-src 'self' 'unsafe-inline'; manifest-src 'self'; img-src 'self' data:; font-src 'self' data:;"
/>
<title>{{I18N_LOGIN_TITLE}}</title>
<title>{{APP_NAME}} login</title>
<link rel="icon" href="{{CS_STATIC_BASE}}/src/browser/media/favicon-dark-support.svg" />
<link rel="alternate icon" href="{{CS_STATIC_BASE}}/src/browser/media/favicon.ico" />
<link rel="manifest" href="{{BASE}}/manifest.json" crossorigin="use-credentials" />
@@ -25,7 +25,7 @@
<div class="card-box">
<div class="header">
<h1 class="main">{{WELCOME_TEXT}}</h1>
<div class="sub">{{I18N_LOGIN_BELOW}} {{PASSWORD_MSG}}</div>
<div class="sub">Please log in below. {{PASSWORD_MSG}}</div>
</div>
<div class="content">
<form class="login-form" method="post">
@@ -38,11 +38,11 @@
autofocus
class="password"
type="password"
placeholder="{{I18N_PASSWORD_PLACEHOLDER}}"
placeholder="PASSWORD"
name="password"
autocomplete="current-password"
/>
<input class="submit -button" value="{{I18N_SUBMIT}}" type="submit" />
<input class="submit -button" value="SUBMIT" type="submit" />
</div>
{{ERROR}}
</form>

View File

@@ -180,14 +180,7 @@ export const options: Options<Required<UserProvidedArgs>> = {
enable: { type: "string[]" },
help: { type: "boolean", short: "h", description: "Show this output." },
json: { type: "boolean" },
locale: {
// The preferred way to set the locale is via the UI.
type: "string",
description: `
Set vscode display language and language to show on the login page, more info see
https://en.wikipedia.org/wiki/IETF_language_tag
`,
},
locale: { type: "string" }, // The preferred way to set the locale is via the UI.
open: { type: "boolean", description: "Open in browser on startup. Does not work remotely." },
"bind-addr": {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

157
yarn.lock
View File

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