Compare commits

..

83 Commits

Author SHA1 Message Date
Asher
325181d414 fixup! Catch up changelog 2022-03-03 19:40:50 +00:00
Asher
7b2b0e0b21 Add release as valid semantic tag 2022-03-03 19:31:37 +00:00
Asher
ae83e049b9 Catch up changelog 2022-03-03 19:31:37 +00:00
Asher
b2ac660763 Rename VS Code to Code in changelog 2022-03-03 19:22:07 +00:00
Asher
7d5bade76c release: bump version to 4.1.0 2022-03-03 19:21:56 +00:00
Asher
b61a8addcf feat: migrate state to new database name (#4938)
* Merge setup and navigate functions

Whenever we navigate we probably want to make sure the editor is ready
so might as well just have one function.

* Add customizable entry and workspace directory

* Add test for state db migration

* Update Code

This contains the state migrations.
2022-03-03 12:32:43 -06:00
Ciel
c4d87580ef feat: cli arg for file permission of socket (#4923) 2022-03-03 09:54:35 -07:00
Joe Previte
78658f1cf4 refactor: remove folder/workspace from vsCodeCliArgs (#4932)
* refactor: remove folder/workspace from vsCodeCliArgs

Since we handle this in the vscode.ts route, we no longer need to pass it to VS
Code as a CLI arg since it's deprecated on that side.

* feat(vscode): redirect to folder from cli

* Update src/node/routes/vscode.ts

Co-authored-by: Asher <ash@coder.com>

* fixup!: update _: type

* fixup!: move vars to lower if block

* fixup!: share redirect block

* fixup!: mmove req.query.ew block into if

* fixup!: refactor vscode tests

* refactor: make vscode.ts logic easier to read

* fixup!: fix broken tests and clean up logic

* chore: upgrade vscode version

* fixup!: delete unnecessary if closed block

* Update src/node/routes/vscode.ts

Co-authored-by: Asher <ash@coder.com>

* fixup!: rename to FOLDER_OR_WORKSPACE_WAS_CLOSED

Co-authored-by: Asher <ash@coder.com>
2022-03-02 15:36:38 -07:00
renovate[bot]
b0181120d4 chore(deps): update actions/download-artifact action to v3 (#4937)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-03-02 14:31:21 -07:00
Asher
0e78a147b6 feat: github-auth flag (#4926)
* feat: github-auth flag

This will allow injecting credentials into code-server if you already
have them.

* Update Code

Contains the GitHub auth changes.

* Add e2e test for GitHub token
2022-03-02 14:02:51 -06:00
renovate[bot]
3f3a489f33 chore(deps): update actions/checkout action to v3 (#4931)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
Co-authored-by: Jonathan Yu <jonathan@coder.com>
2022-03-01 16:31:32 -07:00
Jonathan Yu
83269ba658 chore: limit concurrency for build jobs (#4929)
* Configure build jobs to cancel previous builds when new changes
  are pushed to a pull request branch, and serialize builds when
  running in a branch from a push event
* Reduce privileges of GitHub token for scripts workflow
2022-03-01 15:03:39 -08:00
Jonathan Yu
2c785779b5 feat: add version of Code OSS to output (#4925)
Show the bundled version of Code OSS in the text-based output
for --version and --help, in addition to the JSON output
(--version --json)

Closes: #4874
2022-03-01 12:20:43 -08:00
Joe Previte
506d3f43ed feat(http): keep slashes in queryParams in redirects (#4928)
* refactor(http): extract logic into constructRedirectPath

This allows us to easily test our redirect path construction logic where we get
the relative path, the query string and construct a redirect path.

By extracting this from `redirect`, we can easily test this logic in a unit
test.

I did this so we could test some logic where slashes in query strings should be
made human-friendly for users.

* feat(testing): add tests for constructRedirectPath

Co-authored-by: Asher <ash@coder.com>
2022-03-01 12:11:56 -07:00
Edouard Vincent
1465d8d510 fix: Pin express to 5.0.0-alpha.8 (#4918)
Co-authored-by: Joe Previte <jjprevite@gmail.com>
2022-03-01 11:24:06 -07:00
Edouard Vincent
b3cf4c32ff style: cookie doman => cookie domain (#4919)
Co-authored-by: Joe Previte <jjprevite@gmail.com>
2022-03-01 08:43:41 -07:00
Jonathan Yu
44d74c170f feat: add version string functions to constants (#4920)
Introduce helper functions for getting human- and machine-readable
version strings from the constants package, and cover it in unit
tests.

This is a first step to resolving #4874.
2022-02-28 13:55:47 -08:00
renovate[bot]
a989e0c387 chore(deps): update aquasecurity/trivy-action commit hash to 2962126 (#4907)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-02-25 13:53:58 -07:00
renovate[bot]
769aceacc3 chore(deps): update actions/setup-node action to v3 (#4908)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-02-25 09:09:09 -07:00
Joe Previte
793e4d35ec feat(testing): add new test for cli.ts (#4898)
* feat(testing): add new test for cli.ts

* fixup!: update parse test
2022-02-24 11:07:42 -07:00
Asher
f9402a6318 fix: state collision (#4881)
* Add helper for navigating the quick picker

This has problems similar to the menu except instead of closing it gets
re-created which interrupts the hover call and causes the test to fail.
Now it will keep trying just like the menu.

* Add a test for opening a file

* Add test for colliding state

* Update VS Code

This contains the colliding state fix.
2022-02-22 12:43:13 -06:00
Joe Previte
23734d356a fix: skip docs/npm workflows on forks (#4875)
Co-authored-by: Asher <ash@coder.com>
2022-02-22 10:13:20 -07:00
Tim
d7c1894fb4 Update requirements.md (#4882)
Grammar/typo correction.

Co-authored-by: Joe Previte <jjprevite@gmail.com>
2022-02-18 11:06:58 -07:00
Joe Previte
01a0e95174 docs: update sync vscode instructions (#4879)
* docs: update sync vscode instructions

* fixup!

* fixup: formatting
2022-02-17 15:18:17 -07:00
Joe Previte
94f378c196 feat(testing): add test for parse when error in args + config (#4866)
* chore: fmt cleanup

* feat(parse): add test error w/config
2022-02-15 16:19:22 -07:00
Joe Previte
e3e9f052c4 fix: wrap socket in proxy before passing to vscode (#4840)
* chore: add ipc hook to e2e script

* refactor: allow codeServerArgs in e2e tests

* feat: add --cert e2e extension test

* fix: wrap websocket in proxy

* fixup: remvoe ignoreHTTPSErrors

* fixup: make codeServerArgs readonly

* fixup! add back ignoreHTTPSErrors
2022-02-15 14:51:42 -07:00
Joe Previte
b26cce589f chore: update vscode commit (#4857)
* chore: update vscode commit

This includes two fixes from coder/vscode:
- https://github.com/coder/vscode/pull/43
- https://github.com/coder/vscode/pull/42

* fix: use double-bracket in ext. e2e test
2022-02-15 14:15:53 -07:00
Joe Previte
8fc4832722 chore: update follow-redirects resolution (#4868)
* chore: update follow-redirects resolution

* chore: update vm2 resolution
2022-02-15 13:40:53 -07:00
Ben Potter
36eae3b9f2 fix: Slack community link (#4864)
resolves #4843

Co-authored-by: Joe Previte <jjprevite@gmail.com>
2022-02-14 18:23:20 -06:00
Thomas John Wesolowski
3ad618db97 feat: Add support for imagePullSecrets to Helm chart (#4838)
* add support for imagePullSecrets

* Add doc and example value for imagePullSecrets

* simplify syntax for imagePullSecrets

Co-authored-by: Joe Previte <jjprevite@gmail.com>
2022-02-14 15:34:07 -07:00
Joe Previte
c9c5c54cda feat: add tests for update.ts (#4835)
* feat: add isAddressInfo helper function

* feat(update): add test for rejection UpdateProvider

* feat: add more tests for UpdateProvider

* fixup! move isAddressInfo, add .address check

* fixup! remove extra writeHead

* fixup! use -1 in redirect logic

* fixup! remove unnecessary String call

* fixup! use /latest for redirect

* fixup! use match group for regex

* fixup!: replace match/split logic
2022-02-14 13:53:28 -07:00
Lorenz Brun
102478bdea fix: ensure dumb-init is PID 1 (#4846)
Exec to dumb-init in entrypoint script, so that it can
handle signals and reap subprocesses.
2022-02-11 11:44:01 -08:00
Jonathan Yu
03c62242ee chore: allow overwriting Docker images (#4850)
Allow Docker images to be overwritten, which is required to update
dependencies in the base image when the upstream vendor resolves
security issues.
2022-02-11 09:32:02 -08:00
Jonathan Yu
8135d2ecc3 chore: update Docker image publish workflow (#4847)
* Use official action to log in to Docker Hub
* Run using pinned ubuntu-20.04 environment
2022-02-10 17:40:41 -08:00
Winston R. Milling
177f0ed163 feat: support ingressClassName in Helm Chart (#4844)
Allow configuring the ingress class via a value.
2022-02-10 15:16:35 -08:00
Joe Previte
25b1340771 revert: @node-rs/argon2 -> node-argon2 (#4829)
* revert: partial revert of 723469ab5b

This reverts part of the changes introduced in refactor: migrate from argon2 ->
@node-rs/argon2 (#4733)

Switching to @node-rs/argon2 introduced bugs that we couldn't solve due to
limitations in npm.

see here
https://github.com/coder/code-server/issues/4804#issuecomment-1030338395
2022-02-04 15:52:42 -07:00
Joe Previte
00224fa73a feat: add test for hash when error (#4814) 2022-02-03 14:22:16 -07:00
Joe Previte
fd643dcbc3 refactor(ci): fix npm workflows (#4797)
* feat: refactor npm workflows to use download-artifact

This refactors the npm workflows to use the download-artifact GitHub Action. We
had problems in the past with our download_artifact custom bash function. This
also fixes an issue where we weren't downloading the correct artifacts when
publishing beta and dev tags to npm.

* fixup: remove unused env var

* fixup! add download-artifcat to npm-brew"

* fixup! remove unnecessary code comment

* fixup! move NPM_ENVIRONMENT logic to script
2022-02-03 13:54:36 -07:00
renovate[bot]
79412eb137 chore(deps): update aquasecurity/trivy-action commit hash to a7a829a (#4821)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-02-03 12:43:31 -07:00
LG
10f57bac65 docs: Update some more links (#4806)
* Update links in package.json

I will try checking the docs too

* docs: Update links in triage.md

* docs: Update links in npm.md

* docs: Update links in whatever files that have `cdr`

* Replace globally, thanks @bpmct!

* fix: coderer instead of coder
I should've used all three toggles in the Search/Replace tab in the GItHub.dev editor.

* Code Formatting
2022-02-01 09:45:19 -07:00
Asher
439f27c568 release: v4.0.2 (#4801)
* Disable BROWSER env var

Right now the browser helper script does not actually work.  It seems
safer to skip this until we can fix it.

* Bump to 4.0.2

* Update changelog for 4.0.2
2022-01-27 19:00:06 -06:00
Asher
c20b0b390b fix: make browser helper executable (#4792)
Surprisingly it does not come already executable like the dev-bin
scripts.
2022-01-25 17:18:45 -06:00
Joe Previte
14d0feff0d chore(deps): update node-fetch and nanoid (#4787) 2022-01-25 10:52:17 -07:00
Joe Previte
9954a88d3a refactor(ci): clean up npm workflows (#4786)
This extracst the publish on npm workflow from ci.yaml and adds a new workflow
called `npm-beta.yaml`.

Now we have three workflows that publish to npm.
- `npm-beta.yaml` only runs on pushes and merges into `main`
- `npm-dev.yaml` only runs on PRs into `main` with approval from
  code-server-reviewers team
- `npm-brew.yaml` only runs on releases

This should fix problems we had previously where anyone could open a PR and
publish under the code-server namespace. It also separates out the workflows
based on environment and when they should run.
2022-01-24 15:33:42 -07:00
Joe Previte
48bbbd6c37 chore: update bug-report.yaml (#4780)
* chore: update bug-report.yml

Fix `OS/Web Information` section and don't render as Markdown

* chore: add repro steps to bug template
2022-01-24 14:58:26 -07:00
Joe Previte
8816ab93fe fix: update npm-dev.yaml (#4781) 2022-01-22 08:48:57 -07:00
Joe Previte
a2f530161f feat: publish beta and development tags on npm (#4769)
* feat: add logic to publish beta/dev npm

This adds new log to publish the npm package both while working on PRs and when
PRs are merged into main, allowing us to easily test changes in a
production-like setting.

Co-authored-by: Asher <ash@coder.com>
2022-01-21 16:28:56 -07:00
Asher
63f99da087 fix: package bin/helper directory in the right spot (#4776)
VS Code moves this as part of their packaging task.  We will probably
want to look into using theirs instead of replicating it.

Fixes https://github.com/coder/code-server/issues/4721
2022-01-21 10:54:48 -06:00
LG
6e04501ec5 docs: Fix links (#4770)
* docs: Change `cdr` to `coder`, read desc please

Yeah, includes links.

* docs: Update README (links and the extra comma)

Co-authored-by: Joe Previte <jjprevite@gmail.com>
2022-01-20 11:38:19 -07:00
Joe Previte
51818dc419 chore: update issue templates (#4768)
* chore: delete release issue template

* chore: use bug-report form template

* chore: clean up config.yml for templates

* chore: clean up doc issue template

* chore: clean up feature request template
2022-01-20 09:39:31 -07:00
n1ghtBl00d
48cd3c8b11 Fix Typos in guide.md (#4674)
The Guide mentioned "HTTP/HTTP traffic" when it should say "HTTP/HTTPS traffic"

Co-authored-by: Joe Previte <jjprevite@gmail.com>
2022-01-18 16:44:02 -07:00
Joe Previte
723469ab5b refactor: migrate from argon2 -> @node-rs/argon2 (#4733)
* chore(deps): replace argon2 w/@node-rs/argon2

* refactor: clean up hashPassword functions

* refactor(util): pass in process.platform

* fix: use correct settings for test-extension

Before, it was running into errors with an @types package.

Now, we're correctly running `tsc` so it picks up our `tsconfig.json` and we're
telling TypeScript to not typecheck our lib and exclude `node_modules`
2022-01-18 16:13:39 -07:00
renovate[bot]
2752d95ff6 chore(deps): update minor dependency updates (#4722)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-01-14 21:48:52 +00:00
Joe Previte
b621911e61 chore: use 1.14.7 follow-redirects (#4742) 2022-01-13 11:07:19 -07:00
Joe Previte
48ddad8351 fix: reverse logic in brew-bump env fns (#4732) 2022-01-12 15:51:11 -07:00
Dmitriy Fishman
15500bb388 docs: fix a typo in guide.md (#4728) 2022-01-12 13:00:58 -07:00
Jonathan Yu
ad81a30db5 chore: add configuration for Semantic Pull Requests app (#4652)
* chore: add configuration for Semantic Pull Requests app

* update lists

* remove tests scope
2022-01-10 15:11:59 -07:00
Joe Previte
70c91c857a feat: add tests for node/settings.ts (#4717) 2022-01-10 20:44:28 +00:00
Dmitriy Fishman
33c50972bc docs: fix a typo in MAINTAINING.md (#4711) 2022-01-10 11:38:43 -07:00
Asher
ca15d4b7a0 docs: add marketplace change to changelog (#4692) 2022-01-06 13:20:11 -06:00
Joe Previte
484429b5da release: 4.0.1 (#4678)
* chore(release): bump version to 4.0.1

* fix: ignore pre-commit hook for release-prep script

* chore: bump helm-chart to 2.0.0

* chore: update CHANGELOG for 4.0.1
2022-01-05 13:06:32 -07:00
Asher
3d999986b2 feat: proxy URI environment variable (#4681)
* Add test extension

This will let us test extension-related features (like the proxy URI).

I removed the environment variables in the script because they override
the ones you set yourself. We still set defaults in constants.ts.

* Add changelog entry for VSCODE_PROXY_URI

* Add terminal test for VSCODE_PROXY_URI

* Update VS Code

This adds the VSCODE_PROXY_URI environment variable.
2022-01-04 15:02:25 -06:00
Asher
f04fcf2d64 chore: update vscode (#4680)
* Update VS Code

Fixes https://github.com/coder/code-server/issues/4598
Fixes https://github.com/coder/code-server/issues/4620
Fixes https://github.com/coder/code-server/issues/4600

* Add locale flag back

This is valid again now that we have restored display language support.
2022-01-04 12:37:11 -06:00
Joe Previte
7695de2831 fix(ci): add environment to docs-preview (#4677) 2022-01-04 11:05:04 -07:00
Asher
003480881b fix: infinite proxy loop (#4676)
I think the problem is that when a proxy is not in use proxy-agent
returns the global agent...which is itself since we set it globally,
causing the loop.

VS Code already covers proxies meaning we only need to do it in our own
requests so to fix this pass in the agent in the version fetch request
instead of overidding globally.

Also avoid proxy-from-env and pass in the proxy URI instead as both
http_proxy and https_proxy can be used for either http or https requests
but it does not allow that.
2022-01-03 18:19:21 -06:00
Simon Elsbrock
47f0b6f4fa docs(ipad): fix link to ios-ipad related issues (#4651)
Co-authored-by: Joe Previte <jjprevite@gmail.com>
2021-12-28 12:45:28 -07:00
renovate[bot]
047a4f01f2 chore(deps): update aquasecurity/trivy-action commit hash to 8f4c716 (#4650)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-12-27 10:38:13 -07:00
Joe Previte
95d965a27b fix: add codeServerVersion to vscode/product.json (#4632)
* fix: add codeServerVersion to vscode/product/json

* chore: update vscode

* chore: update modulePathIgnorePattern jest
2021-12-17 12:58:46 -07:00
Asher
c4c480a068 Implement last opened functionality (#4633)
* Implement last opened functionality

Fixes https://github.com/cdr/code-server/issues/4619

* Fix test temp dirs not being cleaned up

* Mock logger everywhere

This suppresses all the error and debug output we generate which makes
it hard to actually find which test has failed.  It also gives us a
standard way to test logging for the few places we do that.

* Use separate data directories for unit test instances

Exactly as we do for the e2e tests.

* Add integration tests for vscode route

* Make settings use --user-data-dir

Without this test instances step on each other feet and they also
clobber your own non-test settings.

* Make redirects consistent

They will preserve the trailing slash if there is one.

* Remove compilation check

If you do a regular non-watch build there are no compilation stats so
this bricks VS Code in CI when running the unit tests.

I am not sure how best to fix this for the case where you have a build
that has not been packaged yet so I just removed it for now and added a
message to check if VS Code is compiling when in dev mode.

* Update code-server update endpoint name
2021-12-17 13:06:52 -06:00
Jonathan Yu
b990dabed1 chore: use readonly deploy key for preview (#4645) 2021-12-17 10:27:22 -07:00
Joe Previte
4943e9418d docs: fix install.sh link (#4627)
Co-authored-by: Asher <ash@coder.com>
2021-12-16 16:59:07 -07:00
Asher
f10ef42f04 Add codeowner group for new name (#4641) 2021-12-16 16:43:05 -06:00
Asher
c27dbd0463 Revert .editorconfig (#4640)
I have been wondering why my editor is not defaulting to two spaces and
it is because indent_size was removed from the * block.

I am not sure why we would need a separate block for package.json and
yaml anyway since they use the same settings as the rest of our code.

I would revert the commit but this change was made in a larger commit
with a bunch of unrelated changes.
2021-12-16 15:30:07 -06:00
Kyle Carberry
ec3d9974b3 fix: Update install.sh to use "coder" GitHub organization (#4638)
* fix: Update install.sh to use "coder" GitHub organization

* Update docs preview
2021-12-16 10:49:16 -06:00
Asher
73e0b79d7f Update VS Code (#4631)
Fixes https://github.com/cdr/code-server/issues/3410
Fixes https://github.com/cdr/code-server/issues/4604
Fixes https://github.com/cdr/code-server/issues/4607
Fixes https://github.com/cdr/code-server/issues/4608
Fixes https://github.com/cdr/code-server/issues/4609

Also has the foundation for
https://github.com/cdr/code-server/issues/4619.
2021-12-15 15:26:59 -07:00
Joe Previte
3059d72a5d docs: add section for Android (#4621)
* Add Instructions To Install 100% In Android (#4536)

* Add Instructions To Install 100% In Android

Thx

* Update android.md

Co-authored-by: Joe Previte <jjprevite@gmail.com>

* docs: clean up android.md

* docs: add android to manifest

* Add missing backtick

Co-authored-by: The AliX Legend <alixgamer175@gmail.com>
Co-authored-by: Asher <ash@coder.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2021-12-15 20:37:16 +00:00
Joe Previte
6e9e411542 fix: add --clobber to release-github-assets script (#4628)
Co-authored-by: Asher <ash@coder.com>
2021-12-15 20:11:35 +00:00
renovate[bot]
7561fc4306 chore(deps): update aquasecurity/trivy-action commit hash to 81cc8cd (#4601)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
Co-authored-by: Joe Previte <jjprevite@gmail.com>
2021-12-15 10:38:18 -07:00
Len
259363bcdb Support browsers from before 2020 (#4579)
* Support browsers from before 2020

As reported in #2825, #2826 and #3051, almost everything works in older browsers. This setting here prevented me from updating and I think it is an obvious enhancement to not restrict to browsers from 2020+. There should not be any measurable downsides of this change since es6 and es2020 are pretty similar with only minor differences.

* Include lib (polyfills) for <es2020 targets

* Assume all modern dom features despite es6 syntax

* Add modern dom iterators to es6 environment

Co-authored-by: Joe Previte <jjprevite@gmail.com>
Co-authored-by: Asher <ash@coder.com>
2021-12-15 10:07:42 -07:00
Joe Previte
1b796d19bf docs: add section for iOS (#4622)
* Added instructions to install it on iOSi (#4614)

* Added instructions to install it on iOS

* Update ios.md

Co-authored-by: Joe Previte <jjprevite@gmail.com>

* docs: add ios to manifest

* docs: clean up ios docs

Co-authored-by: The AliX Legend <alixgamer175@gmail.com>
2021-12-14 23:43:52 +00:00
hyk
5960a6728c support git-lfs default (#4611)
Co-authored-by: Joe Previte <jjprevite@gmail.com>
2021-12-14 16:08:25 -07:00
Leask Wong
18e66c4299 adding option --edge to install latest edge / preview version (#4605)
* adding option --edge to install latest edge / preview version

* updated arg --edge parsing to match the style of --dryrun
2021-12-14 15:30:35 -07:00
Joe Previte
c77999bcd3 release: 4.0.0 (#4597)
* chore(release): bump version to 4.0.0

* Bump test plugin code-server engine

Co-authored-by: Asher <ash@coder.com>
2021-12-10 13:30:53 -07:00
119 changed files with 3466 additions and 3253 deletions

View File

@@ -3,9 +3,4 @@ root = true
[*]
indent_style = space
trim_trailing_whitespace = true
# The indent size used in the `package.json` file cannot be changed
# https://github.com/npm/npm/pull/3180#issuecomment-16336516
[{*.yml,*.yaml,package.json}]
indent_style = space
indent_size = 2

2
.github/CODEOWNERS vendored
View File

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

View File

@@ -1,79 +0,0 @@
---
name: Bug report
about: Report a bug and help us improve
title: ""
labels: ""
assignees: ""
---
<!--
Hi there! 👋
Thanks for reporting a bug.
Please search for existing issues before filing, as they may contain additional
information about the problem and descriptions of workarounds. Provide as much
information as you can, so that we can reproduce the issue. Otherwise, we may
not be able to help diagnose the problem, and may close the issue as
unreproducible or incomplete. For visual defects, please include screenshots to
help us understand the issue.
-->
## OS/Web Information
- Web Browser:
- Local OS:
- Remote OS:
- Remote Architecture:
- `code-server --version`:
## Steps to Reproduce
1.
2.
3.
## Expected
<!-- What should happen? -->
## Actual
<!-- What actually happens? -->
## Logs
<!--
First run code-server with at least debug logging (or trace to be really
thorough) by setting the --log flag or the LOG_LEVEL environment variable. -vvv
and --verbose are aliases for --log trace. For example:
code-server --log debug
Once this is done, replicate the issue you're having then collect logging
information from the following places:
1. The most recent files from ~/.local/share/code-server/coder-logs.
2. The browser console.
3. The browser network tab.
Additionally, collecting core dumps (you may need to enable them first) if
code-server crashes can be helpful.
-->
<!--
If you're having issues with installation please include the installation logs
i.e. the output of `yarn global add code-server` if you installed with `yarn`
-->
## Screenshot
<!-- Ideally provide a screenshot, gif, video or screen recording. -->
## Notes
<!-- If you can reproduce the issue on vanilla VS Code,
please file the issue at the VS Code repository instead. -->
This issue can be reproduced in VS Code: Yes/No

86
.github/ISSUE_TEMPLATE/bug-report.yml vendored Normal file
View File

@@ -0,0 +1,86 @@
name: Bug report
description: File a bug report
title: "[Bug]: "
labels: ["bug", "triage"]
body:
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the bug you encountered.
options:
- label: I have searched the existing issues
required: true
- type: textarea
attributes:
label: OS/Web Information
description: |
examples:
- **Web Browser**: Chrome
- **Local OS**: macOS
- **Remote OS**: Ubuntu
- **Remote Architecture**: amd64
- **`code-server --version`**: 4.0.1
value: |
- Web Browser:
- Local OS:
- Remote OS:
- Remote Architecture:
- `code-server --version`:
validations:
required: true
- type: textarea
attributes:
label: Steps to Reproduce
description: |
1. open code-server
2. install extension
3. run command
value: |
1.
2.
3.
validations:
required: true
- type: textarea
attributes:
label: Expected
description: What should happen?
validations:
required: true
- type: textarea
attributes:
label: Actual
description: What actually happens?
validations:
required: true
- type: textarea
id: logs
attributes:
label: Logs
description: Run code-server with the --verbose flag and then paste any relevant logs from the server, from the browser console and/or the browser network tab. For issues with installation, include installation logs (i.e. output of `yarn global add code-server`).
- type: textarea
attributes:
label: Screenshot/Video
description: Please include a screenshot, gif or screen recording of your issue.
validations:
required: false
- type: checkboxes
attributes:
label: Does this issue happen in VS Code?
description: Please try reproducing this issue in VS Code
options:
- label: I cannot reproduce this in VS Code.
required: true
- type: checkboxes
attributes:
label: Are you accessing code-server over HTTPS?
description: code-server relies on service workers for many features. Double-check that you are using HTTPS.
options:
- label: I am using HTTPS.
required: true
- type: textarea
attributes:
label: Notes
description: Please include any addition notes that will help us resolve this issue.
validations:
required: false

View File

@@ -1,8 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Question
url: https://github.com/cdr/code-server/discussions/new?category_id=22503114
- name: Question?
url: https://github.com/coder/code-server/discussions/new?category_id=22503114
about: Ask the community for help on our GitHub Discussions board
- name: Chat
about: Need immediate help or just want to talk? Hop in our Slack
- name: code-server Slack Community
about: Need immediate help or just want to talk? Hop in our Slack. Note - this Slack is not actively monitored by code-server maintainers.
url: https://cdr.co/join-community

View File

@@ -1,7 +1,13 @@
---
name: Documentation improvement
about: Suggest a documentation improvement
title: ""
title: "[Docs]: "
labels: "docs"
assignees: ""
assignees: "@jsjoeio"
---
## What is your suggestion?
## How will this improve the docs?
## Are you interested in submitting a PR for this?

View File

@@ -1,13 +1,15 @@
---
name: Feature request
about: Suggest an idea
title: ""
labels: feature
about: Suggest an idea to improve code-server
title: "[Feat]: "
labels: enhancement
assignees: ""
---
<!--
Please search for existing issues before filing.
## What is your suggestion?
Please describe the feature as clearly as possible!
-->
## Why do you want this feature?
## Are there any workarounds to get this functionality today?
## Are you interested in submitting a PR for this?

View File

@@ -1,16 +0,0 @@
---
name: Release
about: "*For maintainers only*"
title: "release: 0.0.0"
labels: ""
assignees: "@cdr/code-server-reviewers"
---
<!-- Maintainer: fill out the checklist -->
## Checklist
- [ ] Assign to next release manager
- [ ] Close previous release milestone
- [ ] Create next release milestone
- [ ] Associate issue with next release milestone

66
.github/semantic.yaml vendored Normal file
View File

@@ -0,0 +1,66 @@
###############################################################################
# This file configures "Semantic Pull Requests", which is documented here:
# https://github.com/zeke/semantic-pull-requests
###############################################################################
# Scopes are optionally supplied after a 'type'. For example, in
#
# feat(docs): autostart ui
#
# '(docs)' is the scope. Scopes are used to signify where the change occurred.
scopes:
# docs: changes to the code-server documentation.
- docs
# vendor: changes to vendored dependencies.
- vendor
# deps: changes to code-server's dependencies.
- deps
# cs: changes to code specific to code-server.
- cs
# cli: changes to the command-line interface.
- cli
# We only check that the PR title is semantic. The PR title is automatically
# applied to the "Squash & Merge" flow as the suggested commit message, so this
# should suffice unless someone drastically alters the message in that flow.
titleOnly: true
# Types are the 'tag' types in a commit or PR title. For example, in
#
# chore: fix thing
#
# 'chore' is the type.
types:
# A build of any kind.
- build
# A user-facing change that corrects a defect in code-server.
- fix
# Any code task that is ignored for changelog purposes. Examples include
# devbin scripts and internal-only configurations.
- chore
# Any work performed on CI.
- ci
# Work that directly implements or supports the implementation of a feature.
- feat
# A refactor changes code structure without any behavioral change.
- refactor
# A git revert for any style of commit.
- revert
# Adding tests of any kind. Should be separate from feature or fix
# implementations. For example, if a commit adds a fix + test, it's a fix
# commit. If a commit is simply bumping coverage, it's a test commit.
- test
# A new release.
- release

View File

@@ -8,6 +8,13 @@ on:
branches:
- main
# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
# Note: if: success() is used in several jobs -
# this ensures that it only executes if all previous jobs succeeded.
@@ -21,10 +28,10 @@ jobs:
timeout-minutes: 15
steps:
- name: Checkout repo
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Install Node.js v14
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: "14"
@@ -34,7 +41,7 @@ jobs:
# NOTE@jsjoeio
# disabling this until we can audit the build process
# and the usefulness of this step
# See: https://github.com/cdr/code-server/issues/4287
# See: https://github.com/coder/code-server/issues/4287
# - name: Fetch dependencies from cache
# id: cache-yarn
# uses: actions/cache@v2
@@ -63,10 +70,10 @@ jobs:
timeout-minutes: 15
steps:
- name: Checkout repo
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Install Node.js v14
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: "14"
@@ -95,12 +102,12 @@ jobs:
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install Node.js v14
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: "14"
@@ -177,6 +184,36 @@ jobs:
name: npm-package
path: ./package.tar.gz
npm:
# the npm-package gets uploaded as an artifact in Build
# so we need that to complete before this runs
needs: build
# This environment "npm" requires someone from
# coder/code-server-reviewers to approve the PR before this job runs.
environment: npm
# Only run if PR comes from base repo
# Reason: forks cannot access secrets and this will always fail
if: github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/download-artifact@v3
id: download
with:
name: "npm-package"
path: release-npm-package
- name: Run ./ci/steps/publish-npm.sh
run: yarn publish:npm
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
# NOTE@jsjoeio
# NPM_ENVIRONMENT intentionally not set here.
# Instead, itis determined in publish-npm.sh script
# using GITHUB environment variables
# TODO: cache building yarn --production
# possibly 2m30s of savings(?)
# this requires refactoring our release scripts
@@ -188,10 +225,10 @@ jobs:
container: "centos:7"
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install Node.js v14
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: "14"
@@ -212,7 +249,7 @@ jobs:
run: npm install -g yarn
- name: Download npm package
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: npm-package
@@ -277,10 +314,10 @@ jobs:
NODE_VERSION: v14.17.4
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install Node.js v14
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: "14"
@@ -295,7 +332,7 @@ jobs:
PACKAGE: ${{ format('g++-{0}', matrix.prefix) }}
- name: Download npm package
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: npm-package
@@ -326,10 +363,10 @@ jobs:
runs-on: macos-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install Node.js v14
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: "14"
@@ -339,7 +376,7 @@ jobs:
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Download npm package
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: npm-package
@@ -371,10 +408,10 @@ jobs:
# since VS Code will load faster due to the bundling.
CODE_SERVER_TEST_ENTRY: "./release-packages/code-server-linux-amd64"
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install Node.js v14
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: "14"
@@ -388,7 +425,7 @@ jobs:
yarn-build-
- name: Download release packages
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: release-packages
path: ./release-packages
@@ -425,10 +462,10 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Run Trivy vulnerability scanner in repo mode
#Commit SHA for v0.0.17
uses: aquasecurity/trivy-action@0769bbf0d2a77b3c15b3b57fbcdd2edd25a1c3f0
uses: aquasecurity/trivy-action@296212627a1e693efa09c00adc3e03b2ba8edf18
with:
scan-type: "fs"
scan-ref: "."

View File

@@ -10,6 +10,13 @@ on:
# Runs every Monday morning PST
- cron: "17 15 * * 1"
# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
analyze:
name: Analyze
@@ -17,7 +24,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL

View File

@@ -6,13 +6,22 @@ on:
workflow_dispatch:
release:
types: [released]
types:
- released
# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
docker-images:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Checkout
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
@@ -20,9 +29,13 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Run ./ci/steps/docker-buildx-push.sh
run: ./ci/steps/docker-buildx-push.sh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
GITHUB_TOKEN: ${{ github.token }}

View File

@@ -17,25 +17,36 @@ permissions:
security-events: none
statuses: none
# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
preview:
name: Docs preview
runs-on: ubuntu-20.04
environment: CI
# 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
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.9.1
- name: Checkout m
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
repository: cdr/m
repository: coder/m
ref: refs/heads/master
token: ${{ secrets.GH_ACCESS_TOKEN }}
ssh-key: ${{ secrets.READONLY_M_DEPLOY_KEY }}
submodules: true
fetch-depth: 0
- name: Install Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: 14

View File

@@ -12,13 +12,20 @@ on:
paths:
- "install.sh"
# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
ubuntu:
name: Test installer on Ubuntu
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Install code-server
run: ./install.sh
@@ -32,7 +39,7 @@ jobs:
container: "alpine:3.14"
steps:
- name: Checkout repo
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Install curl
run: apk add curl
@@ -50,7 +57,7 @@ jobs:
steps:
- name: Checkout repo
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Install code-server
run: ./install.sh

View File

@@ -8,19 +8,33 @@ on:
release:
types: [released]
# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
# NOTE: this job requires curl, jq and yarn
# All of them are included in ubuntu-latest.
npm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Run ./ci/steps/publish-npm.sh
run: ./ci/steps/publish-npm.sh
- uses: actions/download-artifact@v3
id: download
with:
name: "npm-package"
path: release-npm-package
- name: Publish npm package and tag with "latest"
run: yarn publish:npm
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_ENVIRONMENT: "production"
homebrew:
# The newest version of code-server needs to be available on npm when this runs
@@ -35,7 +49,7 @@ jobs:
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@master
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Configure git
run: |
git config user.name github-actions

View File

@@ -14,6 +14,25 @@ on:
- "**.sh"
- "**.bats"
permissions:
actions: none
checks: none
contents: read
deployments: none
issues: none
packages: none
pull-requests: none
repository-projects: none
security-events: none
statuses: none
# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
test:
name: Run script unit tests
@@ -22,7 +41,7 @@ jobs:
container: "alpine:3.14"
steps:
- name: Checkout repo
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Install test utilities
run: apk add bats checkbashisms

View File

@@ -50,7 +50,7 @@
{
"file": "src/node/heart.ts",
"line": 7,
"description": "code-server's heart beats to indicate recent activity.\n\nAlso documented here: [https://github.com/cdr/code-server/blob/master/docs/FAQ.md#heartbeat-file](https://github.com/cdr/code-server/blob/master/docs/FAQ.md#heartbeat-file)"
"description": "code-server's heart beats to indicate recent activity.\n\nAlso documented here: [https://github.com/coder/code-server/blob/master/docs/FAQ.md#heartbeat-file](https://github.com/coder/code-server/blob/master/docs/FAQ.md#heartbeat-file)"
},
{
"file": "src/node/socket.ts",
@@ -80,12 +80,12 @@
{
"file": "src/node/routes/domainProxy.ts",
"line": 18,
"description": "code-server provides a built-in proxy to help in developing web-based applications. This is the code for the domain-based proxy.\n\nAlso documented here: [https://github.com/cdr/code-server/blob/master/docs/FAQ.md#how-do-i-securely-access-web-services](https://github.com/cdr/code-server/blob/master/docs/FAQ.md#how-do-i-securely-access-web-services)"
"description": "code-server provides a built-in proxy to help in developing web-based applications. This is the code for the domain-based proxy.\n\nAlso documented here: [https://github.com/coder/code-server/blob/master/docs/FAQ.md#how-do-i-securely-access-web-services](https://github.com/coder/code-server/blob/master/docs/FAQ.md#how-do-i-securely-access-web-services)"
},
{
"file": "src/node/routes/pathProxy.ts",
"line": 19,
"description": "Here is the path-based version of the proxy.\n\nAlso documented here: [https://github.com/cdr/code-server/blob/master/docs/FAQ.md#how-do-i-securely-access-web-services](https://github.com/cdr/code-server/blob/master/docs/FAQ.md#how-do-i-securely-access-web-services)"
"description": "Here is the path-based version of the proxy.\n\nAlso documented here: [https://github.com/coder/code-server/blob/master/docs/FAQ.md#how-do-i-securely-access-web-services](https://github.com/coder/code-server/blob/master/docs/FAQ.md#how-do-i-securely-access-web-services)"
},
{
"file": "src/node/proxy.ts",
@@ -95,7 +95,7 @@
{
"file": "src/node/routes/health.ts",
"line": 5,
"description": "A simple endpoint that lets you see if code-server is up.\n\nAlso documented here: [https://github.com/cdr/code-server/blob/master/docs/FAQ.md#healthz-endpoint](https://github.com/cdr/code-server/blob/master/docs/FAQ.md#healthz-endpoint)"
"description": "A simple endpoint that lets you see if code-server is up.\n\nAlso documented here: [https://github.com/coder/code-server/blob/master/docs/FAQ.md#healthz-endpoint](https://github.com/coder/code-server/blob/master/docs/FAQ.md#healthz-endpoint)"
},
{
"file": "src/node/routes/login.ts",
@@ -145,7 +145,7 @@
{
"directory": "vendor/modules/code-oss-dev",
"line": 1,
"description": "code-server makes use of VS Code's frontend web/remote support. Most of the modifications implement the remote server since that portion of the code is closed source and not released with VS Code.\n\nWe also have a few bug fixes and have added some features (like client-side extensions). See [https://github.com/cdr/code-server/blob/master/docs/CONTRIBUTING.md#modifications-to-vs-code](https://github.com/cdr/code-server/blob/master/docs/CONTRIBUTING.md#modifications-to-vs-code) for a list.\n\nWe make an effort to keep the modifications as few as possible."
"description": "code-server makes use of VS Code's frontend web/remote support. Most of the modifications implement the remote server since that portion of the code is closed source and not released with VS Code.\n\nWe also have a few bug fixes and have added some features (like client-side extensions). See [https://github.com/coder/code-server/blob/master/docs/CONTRIBUTING.md#modifications-to-vs-code](https://github.com/coder/code-server/blob/master/docs/CONTRIBUTING.md#modifications-to-vs-code) for a list.\n\nWe make an effort to keep the modifications as few as possible."
}
]
}

View File

@@ -20,7 +20,7 @@
{
"file": "src/node/app.ts",
"line": 62,
"description": "## That's it!\n\n\nThat's all there is to it! When this tour ends, your terminal session may stop, but just use `yarn watch` to start developing from here on out!\n\n\nIf you haven't already, be sure to check out these resources:\n- [Tour: Contributing](command:codetour.startTourByTitle?[\"Contributing\")\n- [Docs: FAQ.md](https://github.com/cdr/code-server/blob/master/docs/FAQ.md)\n- [Docs: CONTRIBUTING.md](https://github.com/cdr/code-server/blob/master/docs/CONTRIBUTING.md)\n- [Community: GitHub Discussions](https://github.com/cdr/code-server/discussions)\n- [Community: Slack](https://community.coder.com)"
"description": "## That's it!\n\n\nThat's all there is to it! When this tour ends, your terminal session may stop, but just use `yarn watch` to start developing from here on out!\n\n\nIf you haven't already, be sure to check out these resources:\n- [Tour: Contributing](command:codetour.startTourByTitle?[\"Contributing\")\n- [Docs: FAQ.md](https://github.com/coder/code-server/blob/master/docs/FAQ.md)\n- [Docs: CONTRIBUTING.md](https://github.com/coder/code-server/blob/master/docs/CONTRIBUTING.md)\n- [Community: GitHub Discussions](https://github.com/coder/code-server/discussions)\n- [Community: Slack](https://community.coder.com)"
}
]
}

View File

@@ -20,9 +20,67 @@ VS Code v99.99.999
-->
## [Unreleased](https://github.com/cdr/code-server/releases)
## [Unreleased](https://github.com/coder/code-server/releases)
VS Code v1.63.0
Code v0.00.0
### Changed
- Add here
## [4.1.0](https://github.com/coder/code-server/releases/tag/v4.1.0) - 2022-03-03
Code v1.63.0
### Added
- Support for injecting GitHub token into Code so extensions can make use of it.
This can be done with the `GITHUB_TOKEN` environment variable or `github-auth`
in the config file.
- New flag `--socket-mode` allows setting the mode (file permissions) of the
socket created when using `--socket`.
- The version of Code bundled with code-server now appears when using the
`--version` flag. For example: `4.0.2 5cdfe74686aa73e023f8354a9a6014eb30caa7dd with Code 1.63.0`.
If you have been parsing this flag for the version you might want to use
`--version --json` instead as doing that will be more stable.
### Changed
- The workspace or folder passed on the CLI will now use the same redirect
method that the last opened workspace or folder uses. This means if you use
something like `code-server /path/to/dir` you will now get a query parameter
added (like so: `my-domain.tld?folder=/path/to/dir`), making it easier to edit
by hand and making it consistent with the last opened and menu open behaviors.
- The folder/workspace query parameter no longer has encoded slashes, making
them more readable and editable by hand. This was only affecting the last
opened behavior, not opens from the menu.
### Fixed
- Fix web sockets not connecting when using `--cert`.
- Prevent workspace state collisions when opening a workspace that shares the
same file path with another workspace on a different machine that shares the
same domain. This was causing files opened in one workspace to be "re-"opened
in the other workspace when the other workspace is opened.
- Pin the Express version which should make installing from npm work again.
- Propagate signals to code-server in the Docker image which means it should
stop more quickly and gracefully.
- Fix missing argon binaries in the standalone releases on arm machines.
## [4.0.2](https://github.com/coder/code-server/releases/tag/v4.0.2) - 2022-01-27
Code v1.63.0
### Fixed
- Unset the `BROWSER` environment variable. This fixes applications that hard
exit when trying to spawn the helper script `BROWSER` points to because the
file is missing. While we do include the script now we are leaving the
variable omitted because the script does not work yet.
## [4.0.1](https://github.com/coder/code-server/releases/tag/v4.0.1) - 2022-01-04
Code v1.63.0
code-server has been rebased on upstream's newly open-sourced server
implementation (#4414).
@@ -31,13 +89,24 @@ implementation (#4414).
- Web socket compression has been made the default (when supported). This means
the `--enable` flag will no longer take `permessage-deflate` as an option.
- Extra extension directories have been removed. The `--extra-extensions-dir`
and `--extra-builtin-extensions-dir` will no longer be accepted.
- The `--install-source` and `--locale` flags have been removed.
- The static endpoint can no longer reach outside code-server. However the
vscode-remote-resource endpoint still can.
- OpenVSX has been made the default marketplace. However this means web
extensions like Vim may be broken.
- OpenVSX has been made the default marketplace.
- The last opened folder/workspace is no longer stored separately in the
settings file (we rely on the already-existing query object instead).
- The marketplace override environment variables `SERVICE_URL` and `ITEM_URL`
have been replaced with a single `EXTENSIONS_GALLERY` variable that
corresponds to `extensionsGallery` in Code's `product.json`.
### Added
- `VSCODE_PROXY_URI` env var for use in the terminal and extensions.
### Removed
- Extra extension directories have been removed. The `--extra-extensions-dir`
and `--extra-builtin-extensions-dir` flags will no longer be accepted.
- The `--install-source` flag has been removed.
### Deprecated
@@ -47,29 +116,29 @@ implementation (#4414).
- We fixed a XSS vulnerability by escaping HTML from messages in the error page (#4430).
## [3.12.0](https://github.com/cdr/code-server/releases/tag/v3.12.0) - 2021-09-15
## [3.12.0](https://github.com/coder/code-server/releases/tag/v3.12.0) - 2021-09-15
VS Code v1.60.0
Code v1.60.0
### Changed
- Upgrade VS Code to 1.60.0.
- Upgrade Code to 1.60.0.
### Fixed
- Fix logout when using a base path (#3608).
## [3.11.1](https://github.com/cdr/code-server/releases/tag/v3.11.1) - 2021-08-06
## [3.11.1](https://github.com/coder/code-server/releases/tag/v3.11.1) - 2021-08-06
Undocumented (see releases page).
## [3.11.0](https://github.com/cdr/code-server/releases/tag/v3.11.0) - 2021-06-14
## [3.11.0](https://github.com/coder/code-server/releases/tag/v3.11.0) - 2021-06-14
Undocumented (see releases page).
## [3.10.2](https://github.com/cdr/code-server/releases/tag/v3.10.2) - 2021-05-21
## [3.10.2](https://github.com/coder/code-server/releases/tag/v3.10.2) - 2021-05-21
VS Code v1.56.1
Code v1.56.1
### Added
@@ -83,9 +152,9 @@ VS Code v1.56.1
- Fix "Open Folder" on welcome page (#3437).
## [3.10.1](https://github.com/cdr/code-server/releases/tag/v3.10.1) - 2021-05-17
## [3.10.1](https://github.com/coder/code-server/releases/tag/v3.10.1) - 2021-05-17
VS Code v1.56.1
Code v1.56.1
### Fixed
@@ -97,15 +166,15 @@ VS Code v1.56.1
- Use xdgBasedir.runtime instead of tmp (#3304).
## [3.10.0](https://github.com/cdr/code-server/releases/tag/v3.10.0) - 2021-05-10
## [3.10.0](https://github.com/coder/code-server/releases/tag/v3.10.0) - 2021-05-10
VS Code v1.56.0
Code v1.56.0
### Changed
- Update to VS Code 1.56.0 (#3269).
- Update to Code 1.56.0 (#3269).
- Minor connections refactor (#3178). Improves connection stability.
- Use ptyHostService (#3308). This brings us closer to upstream VS Code.
- Use ptyHostService (#3308). This brings us closer to upstream Code.
### Added
@@ -128,4 +197,4 @@ VS Code v1.56.0
This was added with `3.10.0`, which means any previous versions are not
documented in the changelog.
To see those, please visit the [Releases page](https://github.com/cdr/code-server/releases).
To see those, please visit the [Releases page](https://github.com/coder/code-server/releases).

View File

@@ -26,7 +26,7 @@ main() {
echo "Downloading the cloud agent..."
set +e
curl -fsSL "https://github.com/cdr/cloud-agent/releases/latest/download/cloud-agent-$OS-$ARCH" -o ./lib/coder-cloud-agent
curl -fsSL "https://github.com/coder/cloud-agent/releases/latest/download/cloud-agent-$OS-$ARCH" -o ./lib/coder-cloud-agent
chmod +x ./lib/coder-cloud-agent
set -e
fi

View File

@@ -82,6 +82,13 @@ bundle_vscode() {
mkdir -p "$VSCODE_OUT_PATH/resources/"
rsync "$VSCODE_SRC_PATH/resources/" "$VSCODE_OUT_PATH/resources/"
# TODO: We should look into using VS Code's packaging task (see
# gulpfile.reh.js). For now copy this directory into the right spot (for some
# reason VS Code uses a different path in production).
mkdir -p "$VSCODE_OUT_PATH/bin/helpers"
rsync "$VSCODE_SRC_PATH/resources/server/bin/helpers/" "$VSCODE_OUT_PATH/bin/helpers"
chmod +x "$VSCODE_OUT_PATH/bin/helpers/browser.sh"
# Add the commit and date and enable telemetry. This just makes telemetry
# available; telemetry can still be disabled by flag or setting.
jq --slurp '.[0] * .[1]' "$VSCODE_SRC_PATH/product.json" <(
@@ -90,7 +97,8 @@ bundle_vscode() {
"enableTelemetry": true,
"commit": "$(cd "$VSCODE_SRC_PATH" && git rev-parse HEAD)",
"quality": "stable",
"date": $(jq -n 'now | todate')
"date": $(jq -n 'now | todate'),
"codeServerVersion": "$VERSION"
}
EOF
) > "$VSCODE_OUT_PATH/product.json"

View File

@@ -5,7 +5,7 @@ set -eu
# Runs code-server with the bundled node binary.
_realpath() {
# See https://github.com/cdr/code-server/issues/1537 on why no realpath or readlink -f.
# See https://github.com/coder/code-server/issues/1537 on why no realpath or readlink -f.
script="$1"
cd "$(dirname "$script")"
@@ -16,7 +16,7 @@ _realpath() {
&& cat package.json | grep -q '^ "name": "code-server",$'; then
echo "***** Please use the script in bin/code-server instead!" >&2
echo "***** This script will soon be removed!" >&2
echo "***** See the release notes at https://github.com/cdr/code-server/releases/tag/v3.4.0" >&2
echo "***** See the release notes at https://github.com/coder/code-server/releases/tag/v3.4.0" >&2
fi
script="$(readlink "$(basename "$script")")"

View File

@@ -8,7 +8,7 @@ maintainer: "Anmol Sethi <hi@nhooyr.io>"
description: |
Run VS Code in the browser.
vendor: "Coder"
homepage: "https://github.com/cdr/code-server"
homepage: "https://github.com/coder/code-server"
license: "MIT"
contents:

View File

@@ -60,7 +60,7 @@ main() {
mkdir -p ./lib
if curl -fsSL "https://github.com/cdr/cloud-agent/releases/latest/download/cloud-agent-$OS-$ARCH" -o ./lib/coder-cloud-agent; then
if curl -fsSL "https://github.com/coder/cloud-agent/releases/latest/download/cloud-agent-$OS-$ARCH" -o ./lib/coder-cloud-agent; then
chmod +x ./lib/coder-cloud-agent
else
echo "Failed to download cloud agent; --link will not work"
@@ -68,7 +68,7 @@ main() {
if ! vscode_yarn; then
echo "You may not have the required dependencies to build the native modules."
echo "Please see https://github.com/cdr/code-server/blob/master/docs/npm.md"
echo "Please see https://github.com/coder/code-server/blob/master/docs/npm.md"
exit 1
fi

View File

@@ -13,7 +13,7 @@ main() {
download_artifact release-packages ./release-packages
local assets=(./release-packages/code-server*"$VERSION"*{.tar.gz,.deb,.rpm})
EDITOR=true gh release upload "v$VERSION" "${assets[@]}"
EDITOR=true gh release upload "v$VERSION" "${assets[@]}" --clobber
}
main "$@"

View File

@@ -83,14 +83,14 @@ main() {
echo -e "Great! We'll prep a PR for updating to $CODE_SERVER_VERSION_TO_UPDATE\n"
$CMD rg -g '!yarn.lock' -g '!*.svg' -g '!CHANGELOG.md' --files-with-matches --fixed-strings "${CODE_SERVER_CURRENT_VERSION}" | $CMD xargs sd "$CODE_SERVER_CURRENT_VERSION" "$CODE_SERVER_VERSION_TO_UPDATE"
$CMD git commit -am "chore(release): bump version to $CODE_SERVER_VERSION_TO_UPDATE"
$CMD git commit --no-verify -am "chore(release): bump version to $CODE_SERVER_VERSION_TO_UPDATE"
# This runs from the root so that's why we use this path vs. ../../
RELEASE_TEMPLATE_STRING=$(cat ./.github/PULL_REQUEST_TEMPLATE/release_template.md)
echo -e "\nOpening a draft PR on GitHub"
# To read about these flags, visit the docs: https://cli.github.com/manual/gh_pr_create
$CMD gh pr create --base main --title "release: $CODE_SERVER_VERSION_TO_UPDATE" --body "$RELEASE_TEMPLATE_STRING" --reviewer @cdr/code-server-reviewers --repo cdr/code-server --draft --assignee "@me"
$CMD gh pr create --base main --title "release: $CODE_SERVER_VERSION_TO_UPDATE" --body "$RELEASE_TEMPLATE_STRING" --reviewer @coder/code-server-reviewers --repo coder/code-server --draft --assignee "@me"
# Open PR in browser
$CMD gh pr view --web

View File

@@ -3,20 +3,30 @@ set -euo pipefail
main() {
cd "$(dirname "$0")/../.."
source ./ci/lib.sh
echo "Installing code-server test dependencies..."
pushd test
echo "Installing dependencies for $PWD"
yarn install
popd
local args=(install)
if [[ ${CI-} ]]; then
args+=(--frozen-lockfile)
fi
cd test
pushd test
echo "Installing dependencies for $PWD"
yarn "${args[@]}"
cd ..
popd
cd vendor
echo "Installing vendor dependencies..."
pushd test/e2e/extensions/test-extension
echo "Installing dependencies for $PWD"
yarn "${args[@]}"
popd
pushd vendor
echo "Installing dependencies for $PWD"
# We install in 'modules' instead of 'node_modules' because VS Code's
# extensions use a webpack config which cannot differentiate between its own
@@ -33,6 +43,8 @@ main() {
# Finally, run the vendor `postinstall`
yarn run postinstall
popd
}
main "$@"

View File

@@ -13,6 +13,11 @@ main() {
source ./ci/lib.sh
pushd test/e2e/extensions/test-extension
echo "Building test extension"
yarn build
popd
local dir="$PWD"
if [[ ! ${CODE_SERVER_TEST_ENTRY-} ]]; then
echo "Set CODE_SERVER_TEST_ENTRY to test another build of code-server"

View File

@@ -6,6 +6,7 @@ main() {
source ./ci/lib.sh
echo "Building test plugin"
pushd test/unit/node/test-plugin
make -s out/index.js
popd

View File

@@ -1,7 +1,6 @@
import { spawn, fork, ChildProcess } from "child_process"
import { promises as fs } from "fs"
import * as path from "path"
import { CompilationStats, onLine, OnLineCallback } from "../../src/node/util"
import { onLine, OnLineCallback } from "../../src/node/util"
interface DevelopmentCompilers {
[key: string]: ChildProcess | undefined
@@ -16,7 +15,6 @@ class Watcher {
private readonly paths = {
/** Path to uncompiled VS Code source. */
vscodeDir: path.join(this.rootPath, "vendor", "modules", "code-oss-dev"),
compilationStatsFile: path.join(this.rootPath, "out", "watcher.json"),
pluginDir: process.env.PLUGIN_DIR,
}
@@ -88,7 +86,6 @@ class Watcher {
if (strippedLine.includes("Finished compilation with")) {
console.log("[VS Code] ✨ Finished compiling! ✨", "(Refresh your web browser ♻️)")
this.emitCompilationStats()
this.reloadWebServer()
}
}
@@ -118,19 +115,6 @@ class Watcher {
//#region Utilities
/**
* Emits a file containing compilation data.
* This is especially useful when Express needs to determine if VS Code is still compiling.
*/
private emitCompilationStats(): Promise<void> {
const stats: CompilationStats = {
lastCompiledAt: new Date(),
}
console.log("Writing watcher stats...")
return fs.writeFile(this.paths.compilationStatsFile, JSON.stringify(stats, null, 2))
}
private dispose(code: number | null): void {
for (const [processName, devProcess] of Object.entries(this.compilers)) {
console.log(`[${processName}]`, "Killing...\n")

View File

@@ -1,6 +1,6 @@
apiVersion: v2
name: code-server
description: A Helm chart for cdr/code-server
description: A Helm chart for coder/code-server
# A chart can be either an 'application' or a 'library' chart.
#
@@ -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: 1.0.5
version: 2.2.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.0.0
appVersion: 4.1.0

View File

@@ -21,6 +21,7 @@ spec:
app.kubernetes.io/name: {{ include "code-server.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
imagePullSecrets: {{- toYaml .Values.imagePullSecrets | nindent 8 }}
{{- if .Values.hostnameOverride }}
hostname: {{ .Values.hostnameOverride }}
{{- end }}

View File

@@ -18,6 +18,9 @@ metadata:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.ingressClassName }}
ingressClassName: {{ .Values.ingress.ingressClassName }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}

View File

@@ -6,10 +6,15 @@ replicaCount: 1
image:
repository: codercom/code-server
tag: '4.0.0'
tag: '4.1.0'
pullPolicy: Always
# Specifies one or more secrets to be used when pulling images from a
# private container repository
# https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry
imagePullSecrets: []
# - name: registry-creds
nameOverride: ""
fullnameOverride: ""
hostnameOverride: ""
@@ -35,13 +40,12 @@ service:
ingress:
enabled: false
#annotations:
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
#hosts:
# - host: code-server.example.loc
# paths:
# - /
ingressClassName: ""
#tls:
# - secretName: code-server
# hosts:

View File

@@ -10,11 +10,13 @@ RUN apt-get update \
man \
nano \
git \
git-lfs \
procps \
openssh-client \
sudo \
vim.tiny \
lsb-release \
&& git lfs install \
&& rm -rf /var/lib/apt/lists/*
# https://wiki.debian.org/Locale#Manually

View File

@@ -18,4 +18,4 @@ if [ "${DOCKER_USER-}" ]; then
fi
fi
dumb-init /usr/bin/code-server "$@"
exec dumb-init /usr/bin/code-server "$@"

View File

@@ -10,23 +10,23 @@ main() {
echo "Checking environment variables"
# We need VERSION to bump the brew formula
if is_env_var_set "VERSION"; then
if ! is_env_var_set "VERSION"; then
echo "VERSION is not set"
exit 1
fi
# We need HOMEBREW_GITHUB_API_TOKEN to push up commits
if is_env_var_set "HOMEBREW_GITHUB_API_TOKEN"; then
if ! is_env_var_set "HOMEBREW_GITHUB_API_TOKEN"; then
echo "HOMEBREW_GITHUB_API_TOKEN is not set"
exit 1
fi
# NOTE: we need to make sure cdrci/homebrew-core
# NOTE: we need to make sure coderci/homebrew-core
# is up-to-date
# otherwise, brew bump-formula-pr will use an
# outdated base
echo "Cloning cdrci/homebrew-core"
git clone https://github.com/cdrci/homebrew-core.git
echo "Cloning coderci/homebrew-core"
git clone https://github.com/coderci/homebrew-core.git
# Make sure the git clone step is successful
if directory_exists "homebrew-core"; then
@@ -57,7 +57,7 @@ main() {
echo "Merging in latest Homebrew/homebrew-core changes"
git merge upstream/master
echo "Pushing changes to cdrci/homebrew-core fork on GitHub"
echo "Pushing changes to coderci/homebrew-core fork on GitHub"
# GIT_ASKPASS lets us use the password when pushing without revealing it in the process list
# See: https://serverfault.com/a/912788
@@ -86,7 +86,7 @@ main() {
# Export the variables so git sees them
export HOMEBREW_GITHUB_API_TOKEN="$HOMEBREW_GITHUB_API_TOKEN"
export GIT_ASKPASS="$PATH_TO_ASKPASS"
git push https://cdr-oss@github.com/cdr-oss/homebrew-core.git --all
git push https://coder-oss@github.com/coder-oss/homebrew-core.git --all
# Find the docs for bump-formula-pr here
# https://github.com/Homebrew/brew/blob/master/Library/Homebrew/dev-cmd/bump-formula-pr.rb#L18

View File

@@ -1,36 +1,15 @@
#!/usr/bin/env bash
set -euo pipefail
# See if this version already exists on Docker Hub.
function version_exists() {
local output
output=$(curl --silent "https://index.docker.io/v1/repositories/codercom/code-server/tags/$VERSION")
if [[ $output == "Tag not found" ]]; then
return 1
else
return 0
fi
}
main() {
cd "$(dirname "$0")/../.."
# ci/lib.sh sets VERSION and provides download_artifact here
source ./ci/lib.sh
if version_exists; then
echo "$VERSION is already pushed"
return
fi
# Download the release-packages artifact
download_artifact release-packages ./release-packages
# Login to Docker
if [[ ${CI-} ]]; then
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
fi
docker buildx bake -f ci/release-image/docker-bake.hcl --push
}

View File

@@ -4,27 +4,144 @@ set -euo pipefail
main() {
cd "$(dirname "$0")/../.."
source ./ci/lib.sh
source ./ci/steps/steps-lib.sh
# npm view won't exit with non-zero so we have to check the output.
local hasVersion
hasVersion=$(npm view "code-server@$VERSION" version)
if [[ $hasVersion == "$VERSION" ]]; then
echo "$VERSION is already published"
return
## Authentication tokens
# Needed to publish on NPM
if ! is_env_var_set "NPM_TOKEN"; then
echo "NPM_TOKEN is not set. Cannot publish to npm without credentials."
exit 1
fi
# NOTE@jsjoeio - only needed if we use the download_artifact
# because we talk to the GitHub API.
# Needed to use GitHub API
if ! is_env_var_set "GITHUB_TOKEN"; then
echo "GITHUB_TOKEN is not set. Cannot download npm release artifact without GitHub credentials."
exit 1
fi
## Publishing Information
# All the variables below are used to determine how we should publish
# the npm package. We also use this information for bumping the version.
# This is because npm won't publish your package unless it's a new version.
# i.e. for development, we bump the version to <current version>-<pr number>-<commit sha>
# example: "version": "4.0.1-4769-ad7b23cfe6ffd72914e34781ef7721b129a23040"
# We need the current package.json VERSION
if ! is_env_var_set "VERSION"; then
echo "VERSION is not set. Cannot publish to npm without VERSION."
exit 1
fi
# We use this to grab the PR_NUMBER
if ! is_env_var_set "GITHUB_REF"; then
echo "GITHUB_REF is not set. Are you running this locally? We rely on values provided by GitHub."
exit 1
fi
# We use this when setting NPM_VERSION
if ! is_env_var_set "GITHUB_SHA"; then
echo "GITHUB_SHA is not set. Are you running this locally? We rely on values provided by GitHub."
exit 1
fi
# We use this to determine the NPM_ENVIRONMENT
if ! is_env_var_set "GITHUB_EVENT_NAME"; then
echo "GITHUB_EVENT_NAME is not set. Are you running this locally? We rely on values provided by GitHub."
exit 1
fi
# This allows us to publish to npm in CI workflows
if [[ ${CI-} ]]; then
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
fi
download_artifact npm-package ./release-npm-package
## Environment
# This string is used to determine how we should tag the npm release.
# Environment can be one of three choices:
# "development" - this means we tag with the PR number, allowing
# a developer to install this version with `yarn add code-server@<pr-number>`
# "staging" - this means we tag with `beta`, allowing
# a developer to install this version with `yarn add code-server@beta`
# "production" - this means we tag with `latest` (default), allowing
# a developer to install this version with `yarn add code-server@latest`
if ! is_env_var_set "NPM_ENVIRONMENT"; then
echo "NPM_ENVIRONMENT is not set. Determining in script based on GITHUB environment variables."
if [[ "$GITHUB_EVENT_NAME" == 'push' && "$GITHUB_REF" == 'refs/heads/main' ]]; then
NPM_ENVIRONMENT="staging"
else
NPM_ENVIRONMENT="development"
fi
echo "Using npm environment: $NPM_ENVIRONMENT"
fi
# NOTE@jsjoeio - this script assumes we have the artifact downloaded on disk
# That happens in CI as a step before we run this.
# https://github.com/actions/upload-artifact/issues/38
tar -xzf release-npm-package/package.tar.gz
# Ignore symlink when publishing npm package
# See: https://github.com/cdr/code-server/pull/3935
# See: https://github.com/coder/code-server/pull/3935
echo "node_modules.asar" > release/.npmignore
yarn publish --non-interactive release
# NOTES:@jsjoeio
# We only need to run npm version for "development" and "staging".
# This is because our release:prep script automatically bumps the version
# in the package.json and we commit it as part of the release PR.
if [[ "$NPM_ENVIRONMENT" == "production" ]]; then
NPM_VERSION="$VERSION"
# This means the npm version will be published as "stable"
# and installed when a user runs `yarn install code-server`
NPM_TAG="latest"
else
COMMIT_SHA="$GITHUB_SHA"
echo "Not a production environment"
echo "Found environment: $NPM_ENVIRONMENT"
echo "Manually bumping npm version..."
if [[ "$NPM_ENVIRONMENT" == "staging" ]]; then
NPM_VERSION="$VERSION-beta-$COMMIT_SHA"
# This means the npm version will be tagged with "beta"
# and installed when a user runs `yarn install code-server@beta`
NPM_TAG="beta"
fi
if [[ "$NPM_ENVIRONMENT" == "development" ]]; then
# Source: https://github.com/actions/checkout/issues/58#issuecomment-614041550
PR_NUMBER=$(echo "$GITHUB_REF" | awk 'BEGIN { FS = "/" } ; { print $3 }')
NPM_VERSION="$VERSION-$PR_NUMBER-$COMMIT_SHA"
# This means the npm version will be tagged with "<pr number>"
# and installed when a user runs `yarn install code-server@<pr number>`
NPM_TAG="$PR_NUMBER"
fi
echo "using tag: $NPM_TAG"
# We modify the version in the package.json
# to be the current version + the PR number + commit SHA
# or we use current version + beta + commit SHA
# Example: "version": "4.0.1-4769-ad7b23cfe6ffd72914e34781ef7721b129a23040"
# Example: "version": "4.0.1-beta-ad7b23cfe6ffd72914e34781ef7721b129a23040"
pushd release
# NOTE:@jsjoeio
# I originally tried to use `yarn version` but ran into issues and abandoned it.
npm version "$NPM_VERSION"
popd
fi
# We need to make sure we haven't already published the version.
# This is because npm view won't exit with non-zero so we have
# to check the output.
local hasVersion
hasVersion=$(npm view "code-server@$NPM_VERSION" version)
if [[ $hasVersion == "$NPM_VERSION" ]]; then
echo "$NPM_VERSION is already published"
return
fi
yarn publish --non-interactive release --tag "$NPM_TAG"
}
main "$@"

View File

@@ -61,7 +61,7 @@ These are required by VS Code. See [their Wiki](https://github.com/microsoft/vsc
## Creating pull requests
Please create a [GitHub Issue](https://github.com/cdr/code-server/issues) that
Please create a [GitHub Issue](https://github.com/coder/code-server/issues) that
includes context for issues that you see. You can skip this if the proposed fix
is minor.
@@ -78,12 +78,12 @@ we'll guide you.
## Development workflow
The current development workflow is a bit tricky because we have this repo and we use our `cdr/vscode` fork inside it with [`yarn link`](https://classic.yarnpkg.com/lang/en/docs/cli/link/).
The current development workflow is a bit tricky because we have this repo and we use our `coder/vscode` fork inside it with [`yarn link`](https://classic.yarnpkg.com/lang/en/docs/cli/link/).
Here are these steps you should follow to get your dev environment setup:
1. `git clone https://github.com/cdr/code-server.git` - Clone `code-server`
2. `git clone https://github.com/cdr/vscode.git` - Clone `vscode`
1. `git clone https://github.com/coder/code-server.git` - Clone `code-server`
2. `git clone https://github.com/coder/vscode.git` - Clone `vscode`
3. `cd vscode && yarn install` - install the dependencies in the `vscode` repo
4. `cd code-server && yarn install` - install the dependencies in the `code-server` repo
5. `cd vscode && yarn link` - use `yarn` to create a symlink to the `vscode` repo (`code-oss-dev` package)
@@ -92,14 +92,14 @@ Here are these steps you should follow to get your dev environment setup:
### Updates to VS Code
If changes are made and merged into `main` in the [`cdr/vscode`](https://github.com/cdr/vscode) repo, then you'll need to update the version in the `code-server` repo by following these steps:
If changes are made and merged into `main` in the [`coder/vscode`](https://github.com/coder/vscode) repo, then you'll need to update the version in the `code-server` repo by following these steps:
1. Update the package tag listed in `vendor/package.json`:
```json
{
"devDependencies": {
"vscode": "cdr/vscode#<latest-commit-sha>"
"vscode": "coder/vscode#<latest-commit-sha>"
}
}
```
@@ -148,7 +148,7 @@ yarn package
### Help
If you get stuck or need help, you can always start a new GitHub Discussion [here](https://github.com/cdr/code-server/discussions). One of the maintainers will respond and help you out.
If you get stuck or need help, you can always start a new GitHub Discussion [here](https://github.com/coder/code-server/discussions). One of the maintainers will respond and help you out.
## Test

View File

@@ -37,7 +37,7 @@
## Questions?
Please file all questions and support requests at
<https://github.com/cdr/code-server/discussions>.
<https://github.com/coder/code-server/discussions>.
## How should I expose code-server to the internet?
@@ -111,11 +111,11 @@ These are the closed-source extensions that are presently unavailable:
1. [Live Share](https://visualstudio.microsoft.com/services/live-share). We may
implement something similar (see
[#33](https://github.com/cdr/code-server/issues/33))
[#33](https://github.com/coder/code-server/issues/33))
1. [Remote Extensions (SSH, Containers,
WSL)](https://github.com/microsoft/vscode-remote-release). We may implement
these again at some point, see
([#1315](https://github.com/cdr/code-server/issues/1315)).
([#1315](https://github.com/coder/code-server/issues/1315)).
For more about the closed source portions of VS Code, see [vscodium/vscodium](https://github.com/VSCodium/vscodium#why-does-this-exist).
@@ -222,7 +222,7 @@ You may have to give Node.js full disk access, since it doesn't implement any of
Privacy** > **Privacy** > **Full Disk Access**. Then, click the 🔒 to unlock,
click **+**, and select the Node.js binary you located in the previous step.
See [#2794](https://github.com/cdr/code-server/issues/2794) for additional context.
See [#2794](https://github.com/coder/code-server/issues/2794) for additional context.
## How do I direct server-side requests through a proxy?
@@ -302,7 +302,7 @@ after a predetermined amount of time, you can do so by checking continuously for
the last modified time on the heartbeat file. If it is older than X minutes (or
whatever amount of time you'd like), you can kill code-server.
Eventually, [#1636](https://github.com/cdr/code-server/issues/1636) will make
Eventually, [#1636](https://github.com/coder/code-server/issues/1636) will make
this process better.
## How do I change the password?
@@ -376,7 +376,7 @@ Theia doesn't allow you to reuse your existing VS Code config.
## What's the difference between code-server and OpenVSCode-Server?
code-server and OpenVSCode-Server both allow you to access VS Code via a
browser. The two projects also use their own [forks of VS Code](https://github.com/cdr/vscode) to
browser. The two projects also use their own [forks of VS Code](https://github.com/coder/vscode) to
leverage modern VS Code APIs and stay up to date with the upsteam version.
However, OpenVSCode-Server is scoped at only making VS Code available in the web browser.
@@ -388,7 +388,7 @@ code-server includes some other features:
- plugin API
- settings sync (coming soon)
For more details, see [this discussion post](https://github.com/cdr/code-server/discussions/4267#discussioncomment-1411583).
For more details, see [this discussion post](https://github.com/coder/code-server/discussions/4267#discussioncomment-1411583).
## What's the difference between code-server and GitHub Codespaces?
@@ -406,7 +406,7 @@ minute plus an additional twelve per hour.
## Are there community projects involving code-server?
Visit the [awesome-code-server](https://github.com/cdr/awesome-code-server)
Visit the [awesome-code-server](https://github.com/coder/awesome-code-server)
repository to view community projects and guides with code-server! Feel free to
add your own!

View File

@@ -34,26 +34,25 @@ as well as share our workflow for maintaining the project.
Current maintainers:
- @code-asher
- @TeffenEllis
- @jsjoeio
Occassionally, other Coder employees may step in time to time to assist with code-server.
Occasionally, other Coder employees may step in time to time to assist with code-server.
### Onboarding
To onboard a new maintainer to the project, please make sure to do the following:
- [ ] Add to [cdr/code-server-reviewers](https://github.com/orgs/cdr/teams/code-server-reviewers)
- [ ] Add as Admin under [Repository Settings > Access](https://github.com/cdr/code-server/settings/access)
- [ ] Add to [coder/code-server-reviewers](https://github.com/orgs/coder/teams/code-server-reviewers)
- [ ] Add as Admin under [Repository Settings > Access](https://github.com/coder/code-server/settings/access)
- [ ] Add to [npm Coder org](https://www.npmjs.com/org/coder)
- [ ] Add as [AUR maintainer](https://aur.archlinux.org/packages/code-server/) (talk to Colin)
- [ ] Introduce to community via Discussion (see [example](https://github.com/cdr/code-server/discussions/3955))
- [ ] Introduce to community via Discussion (see [example](https://github.com/coder/code-server/discussions/3955))
### Offboarding
Very similar to Onboarding but Remove maintainer from all teams and revoke access. Please also do the following:
- [ ] Write farewell post via Discussion (see [example](https://github.com/cdr/code-server/discussions/3933))
- [ ] Write farewell post via Discussion (see [example](https://github.com/coder/code-server/discussions/3933))
## Workflow
@@ -64,7 +63,7 @@ contributing on day one.
### Milestones
We operate mainly using
[milestones](https://github.com/cdr/code-server/milestones). This was heavily
[milestones](https://github.com/coder/code-server/milestones). This was heavily
inspired by our friends over at [vscode](https://github.com/microsoft/vscode).
Here are the milestones we use and how we use them:
@@ -185,12 +184,12 @@ If you're the current release manager, follow these steps:
artifacts, publish the NPM package from `npm-package`, and publish the Docker
Hub image from `release-images`.
1. Update the AUR package. Instructions for updating the AUR package are at
[cdr/code-server-aur](https://github.com/cdr/code-server-aur).
[coder/code-server-aur](https://github.com/coder/code-server-aur).
1. Wait for the npm package to be published.
#### AUR
We publish to AUR as a package [here](https://aur.archlinux.org/packages/code-server/). This process is manual and can be done by following the steps in [this repo](https://github.com/cdr/code-server-aur).
We publish to AUR as a package [here](https://aur.archlinux.org/packages/code-server/). This process is manual and can be done by following the steps in [this repo](https://github.com/coder/code-server-aur).
#### Docker
@@ -202,7 +201,7 @@ This is currently automated with the release process.
We publish code-server on Homebrew [here](https://github.com/Homebrew/homebrew-core/blob/master/Formula/code-server.rb).
This is currently automated with the release process (but may fail occassionally). If it does, run this locally:
This is currently automated with the release process (but may fail occasionally). If it does, run this locally:
```shell
# Replace VERSION with version
@@ -217,21 +216,22 @@ This is currently automated with the release process.
## Syncing with Upstream VS Code
The VS Code portion of code-server lives under [`cdr/vscode`](https://github.com/cdr/vscode). To update VS Code for code-server, follow these steps:
The VS Code portion of code-server lives under [`coder/vscode`](https://github.com/coder/vscode). To update VS Code for code-server, follow these steps:
1. `git checkout -b vscode-update` - Create a new branch locally based off `main`
2. `git fetch upstream` - Fetch upstream (VS Code)'s latest `main` branch
3. `git merge upstream/main` - Merge it locally
1. If there are merge conflicts, fix them locally
2. `git fetch upstream` - Fetch upstream (VS Code)'s latest branches
3. `git merge upstream/release/1.64` - Merge it locally
1. replace `1.64` with the version you're upgrading to
1. If there are merge conflicts, commit first, then fix them locally.
4. Open a PR merging your branch (`vscode-update`) into `main` and add the code-server review team
Ideally, our fork stays as close to upstream as possible. See the differences between our fork and upstream [here](https://github.com/microsoft/vscode/compare/main...cdr:main).
Ideally, our fork stays as close to upstream as possible. See the differences between our fork and upstream [here](https://github.com/microsoft/vscode/compare/main...coder:main).
## Testing
Our testing structure is laid out under our [Contributing docs](https://coder.com/docs/code-server/latest/CONTRIBUTING#test).
We hope to eventually hit 100% test converage with our unit tests, and maybe one day our scripts (coverage not tracked currently).
We hope to eventually hit 100% test coverage with our unit tests, and maybe one day our scripts (coverage not tracked currently).
If you're ever looking to add more tests, here are a few ways to get started:
@@ -247,7 +247,7 @@ Otherwise, talk to a current maintainer and ask which part of the codebase is la
Our docs are hosted on [Vercel](https://vercel.com/). Vercel only shows logs in realtime, which means you need to have the logs open in one tab and reproduce your error in another tab. Since our logs are private to Coder the organization, you can only follow these steps if you're a Coder employee. Ask a maintainer for help if you need it.
Taking a real scenario, let's say you wanted to troubleshoot [this docs change](https://github.com/cdr/code-server/pull/4042). Here is how you would do it:
Taking a real scenario, let's say you wanted to troubleshoot [this docs change](https://github.com/coder/code-server/pull/4042). Here is how you would do it:
1. Go to https://vercel.com/codercom/codercom
2. Click "View Function Logs"

View File

@@ -1,6 +1,6 @@
# code-server
[!["GitHub Discussions"](https://img.shields.io/badge/%20GitHub-%20Discussions-gray.svg?longCache=true&logo=github&colorB=purple)](https://github.com/cdr/code-server/discussions) [!["Join us on Slack"](https://img.shields.io/badge/join-us%20on%20slack-gray.svg?longCache=true&logo=slack&colorB=brightgreen)](https://cdr.co/join-community) [![Twitter Follow](https://img.shields.io/twitter/follow/CoderHQ?label=%40CoderHQ&style=social)](https://twitter.com/coderhq) [![codecov](https://codecov.io/gh/cdr/code-server/branch/main/graph/badge.svg?token=5iM9farjnC)](https://codecov.io/gh/cdr/code-server) [![See v4.0.0 docs](https://img.shields.io/static/v1?label=Docs&message=see%20v4.0.0%20&color=blue)](https://github.com/cdr/code-server/tree/v4.0.0/docs)
[!["GitHub Discussions"](https://img.shields.io/badge/%20GitHub-%20Discussions-gray.svg?longCache=true&logo=github&colorB=purple)](https://github.com/coder/code-server/discussions) [!["Join us on Slack"](https://img.shields.io/badge/join-us%20on%20slack-gray.svg?longCache=true&logo=slack&colorB=brightgreen)](https://coder.com/community) [![Twitter Follow](https://img.shields.io/twitter/follow/CoderHQ?label=%40CoderHQ&style=social)](https://twitter.com/coderhq) [![codecov](https://codecov.io/gh/coder/code-server/branch/main/graph/badge.svg?token=5iM9farjnC)](https://codecov.io/gh/coder/code-server) [![See v4.1.0 docs](https://img.shields.io/static/v1?label=Docs&message=see%20v4.1.0%20&color=blue)](https://github.com/coder/code-server/tree/v4.1.0/docs)
Run [VS Code](https://github.com/Microsoft/vscode) on any machine anywhere and
access it in the browser.
@@ -14,7 +14,7 @@ access it in the browser.
- Preserve battery life when you're on the go; all intensive tasks run on your
server
| 🔔 code-server is a free browser-based IDE while [Coder](https://coder.com/), is our enterprise developer workspace platform. For more information, visit [Coder.com](https://coder.com/docs/comparison)
| 🔔 code-server is a free browser-based IDE while [Coder](https://coder.com/) is our enterprise developer workspace platform. For more information, visit [Coder.com](https://coder.com/docs/comparison)
| ---
## Requirements
@@ -29,13 +29,13 @@ on how to set up a Google VM on which you can install code-server.
There are three ways to get started:
1. Using the [install
script](https://github.com/cdr/code-server/blob/main/install.sh), which
script](https://github.com/coder/code-server/blob/main/install.sh), which
automates most of the process. The script uses the system package manager if
possible.
2. Manually [installing
code-server](https://coder.com/docs/code-server/latest/install)
3. Using our one-click buttons and guides to [deploy code-server to a cloud
provider](https://github.com/cdr/deploy-code-server) ⚡
provider](https://github.com/coder/deploy-code-server) ⚡
If you use the install script, you can preview what occurs during the install
process:

View File

@@ -26,9 +26,9 @@ We use the following tools to help us stay on top of vulnerability mitigation.
Coder sponsors the development and maintenance of the code-server project. We will fix security issues within 90 days of receiving a report and publish the fix in a subsequent release. The code-server project does not provide backports or patch releases for security issues at this time.
| Version | Supported |
| ----------------------------------------------------- | ------------------ |
| [Latest](https://github.com/cdr/code-server/releases) | :white_check_mark: |
| Version | Supported |
| ------------------------------------------------------- | ------------------ |
| [Latest](https://github.com/coder/code-server/releases) | :white_check_mark: |
## Reporting a Vulnerability

23
docs/android.md Normal file
View File

@@ -0,0 +1,23 @@
# Running code-server using UserLAnd
1. Install UserLAnd from [Google Play](https://play.google.com/store/apps/details?id=tech.ula&hl=en_US&gl=US)
2. Install an Ubuntu VM
3. Start app
4. Install Node.js, `curl` and `yarn` using `sudo apt install nodejs npm yarn curl -y`
5. Install `nvm`:
```shell
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
```
6. Exit the terminal using `exit` and then reopen the terminal
7. Install and use Node.js 14:
```shell
nvm install 14
nvm use 14
```
8. Install code-server globally on device with: `npm i -g code-server`
9. Run code-server with `code-server`
10. Access on localhost:8080 in your browser

View File

@@ -60,6 +60,6 @@ As `code-server` is based on VS Code, you can follow the steps described on Duck
code-server --enable-proposed-api genuitecllc.codetogether
```
Another option would be to add a value in code-server's [config file](https://coder.com/docs/code-server/v4.0.0/FAQ#how-does-the-config-file-work).
Another option would be to add a value in code-server's [config file](https://coder.com/docs/code-server/v4.1.0/FAQ#how-does-the-config-file-work).
3. Refresh code-server and navigate to the CodeTogether icon in the sidebar to host or join a coding session.

View File

@@ -115,7 +115,7 @@ we recommend using another method, such as [Let's Encrypt](#let-encrypt) instead
Using [Let's Encrypt](https://letsencrypt.org) is an option if you want to
access code-server on an iPad or do not want to use SSH port forwarding.
1. This option requires that the remote machine be exposed to the internet. Make sure that your instance allows HTTP/HTTP traffic.
1. This option requires that the remote machine be exposed to the internet. Make sure that your instance allows HTTP/HTTPS traffic.
1. You'll need a domain name (if you don't have one, you can purchase one from
[Google Domains](https://domains.google.com) or the domain service of your
@@ -162,7 +162,7 @@ At this point, you should be able to access code-server via
### Using Let's Encrypt with NGINX
1. This option requires that the remote machine be exposed to the internet. Make sure that your instance allows HTTP/HTTP traffic.
1. This option requires that the remote machine be exposed to the internet. Make sure that your instance allows HTTP/HTTPS traffic.
1. You'll need a domain name (if you don't have one, you can purchase one from
[Google Domains](https://domains.google.com) or the domain service of your
@@ -229,7 +229,7 @@ code-server. You should only proceed with this option if:
To use a self-signed certificate:
1. This option requires that the remote machine be exposed to the internet. Make
sure that your instance allows HTTP/HTTP traffic.
sure that your instance allows HTTP/HTTPS traffic.
1. SSH into your instance and edit your code-server config file to use a
randomly generated self-signed certificate:
@@ -294,7 +294,7 @@ Note: if you set `proxy_set_header Host $host;` in your reverse proxy config, it
## Accessing web services
If you're working on web services and want to access it locally, code-server
If you're working on web services and want to access them locally, code-server
can proxy to any port using either a subdomain or a subpath, allowing you to
securely access these services using code-server's built-in authentication.
@@ -345,8 +345,8 @@ instead and the path will be passed as is (e.g., `/absproxy/3000/my-app-path`).
### Proxying to create a React app
You must use `/absproxy/<port>` with `create-react-app` (see
[#2565](https://github.com/cdr/code-server/issues/2565) and
[#2222](https://github.com/cdr/code-server/issues/2222) for more information).
[#2565](https://github.com/coder/code-server/issues/2565) and
[#2222](https://github.com/coder/code-server/issues/2222) for more information).
You will need to inform `create-react-app` of the path at which you are serving
via `$PUBLIC_URL` and webpack via `$WDS_SOCKET_PATH`:
@@ -396,7 +396,7 @@ sudo apt update
sudo apt install wget unzip openssh-server
```
2. Start the SSH server and set the password for your user, if you haven't already. If you use [deploy-code-server](https://github.com/cdr/deploy-code-server),
2. Start the SSH server and set the password for your user, if you haven't already. If you use [deploy-code-server](https://github.com/coder/deploy-code-server),
```bash
sudo service ssh start

View File

@@ -1,8 +1,8 @@
# code-server Helm Chart
[![Version: 1.0.0](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square)](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square) [![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)](https://img.shields.io/badge/Type-application-informational?style=flat-square) [![AppVersion: 4.0.0](https://img.shields.io/badge/AppVersion-4.0.0-informational?style=flat-square)](https://img.shields.io/badge/AppVersion-4.0.0-informational?style=flat-square)
[![Version: 1.0.0](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square)](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square) [![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)](https://img.shields.io/badge/Type-application-informational?style=flat-square) [![AppVersion: 4.1.0](https://img.shields.io/badge/AppVersion-4.1.0-informational?style=flat-square)](https://img.shields.io/badge/AppVersion-4.1.0-informational?style=flat-square)
[code-server](https://github.com/cdr/code-server) code-server is VS Code running
[code-server](https://github.com/coder/code-server) code-server is VS Code running
on a remote server, accessible through the browser.
This chart is community maintained by [@Matthew-Beckett](https://github.com/Matthew-Beckett) and [@alexgorbatchev](https://github.com/alexgorbatchev)
@@ -10,7 +10,7 @@ This chart is community maintained by [@Matthew-Beckett](https://github.com/Matt
## Quickstart
```console
$ git clone https://github.com/cdr/code-server
$ git clone https://github.com/coder/code-server
$ cd code-server
$ helm upgrade --install code-server ci/helm-chart
```
@@ -30,7 +30,7 @@ package manager.
To install the chart with the release name `code-server`:
```console
$ git clone https://github.com/cdr/code-server
$ git clone https://github.com/coder/code-server
$ cd code-server
$ helm upgrade --install code-server ci/helm-chart
```
@@ -73,7 +73,7 @@ and their default values.
| hostnameOverride | string | `""` |
| image.pullPolicy | string | `"Always"` |
| image.repository | string | `"codercom/code-server"` |
| image.tag | string | `"4.0.0"` |
| image.tag | string | `"4.1.0"` |
| imagePullSecrets | list | `[]` |
| ingress.enabled | bool | `false` |
| nameOverride | string | `""` |

View File

@@ -30,7 +30,7 @@ operating systems.
## install.sh
The easiest way to install code-server is to use our [install
script](../install.sh) for Linux, macOS and FreeBSD. The install script
script](https://github.com/coder/code-server/blob/main/install.sh) for Linux, macOS and FreeBSD. The install script
[attempts to use the system package manager](#detection-reference) if possible.
You can preview what occurs during the install process:
@@ -67,7 +67,7 @@ code-server.
If you prefer to install code-server manually, despite the [detection
references](#detection-reference) and `--dry-run` feature, then continue on for
information on how to do this. The [`install.sh`](../install.sh) script runs the
information on how to do this. The [`install.sh`](https://github.com/coder/code-server/blob/main/install.sh) script runs the
_exact_ same commands presented in the rest of this document.
### Detection reference
@@ -104,7 +104,7 @@ We recommend installing with `yarn` or `npm` when:
1. You're on Linux with `glibc` < v2.17, `glibcxx` < v3.4.18 on `amd64`, `glibc`
< v2.23, or `glibcxx` < v3.4.21 on `arm64`.
1. You're running Alpine Linux or are using a non-glibc libc. See
[#1430](https://github.com/cdr/code-server/issues/1430#issuecomment-629883198)
[#1430](https://github.com/coder/code-server/issues/1430#issuecomment-629883198)
for more information.
Installing code-server with `yarn` or `npm` builds native modules on install.
@@ -114,7 +114,7 @@ This process requires C dependencies; see our guide on [installing with yarn and
## Standalone releases
We publish self-contained `.tar.gz` archives for every release on
[GitHub](https://github.com/cdr/code-server/releases). The archives bundle the
[GitHub](https://github.com/coder/code-server/releases). The archives bundle the
node binary and node modules.
We create the standalone releases using the [npm package](#yarn-npm), and we
@@ -127,7 +127,7 @@ requirement).
To use a standalone release:
1. Download the latest release archive for your system from
[GitHub](https://github.com/cdr/code-server/releases).
[GitHub](https://github.com/coder/code-server/releases).
2. Unpack the release.
3. Run code-server by executing `./bin/code-server`.
@@ -139,7 +139,7 @@ release on Linux:
```bash
mkdir -p ~/.local/lib ~/.local/bin
curl -fL https://github.com/cdr/code-server/releases/download/v$VERSION/code-server-$VERSION-linux-amd64.tar.gz \
curl -fL https://github.com/coder/code-server/releases/download/v$VERSION/code-server-$VERSION-linux-amd64.tar.gz \
| tar -C ~/.local/lib -xz
mv ~/.local/lib/code-server-$VERSION-linux-amd64 ~/.local/lib/code-server-$VERSION
ln -s ~/.local/lib/code-server-$VERSION/bin/code-server ~/.local/bin/code-server
@@ -154,7 +154,7 @@ code-server
> upgrade or [build with yarn](#yarn-npm).
```bash
curl -fOL https://github.com/cdr/code-server/releases/download/v$VERSION/code-server_$VERSION_amd64.deb
curl -fOL https://github.com/coder/code-server/releases/download/v$VERSION/code-server_$VERSION_amd64.deb
sudo dpkg -i code-server_$VERSION_amd64.deb
sudo systemctl enable --now code-server@$USER
# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml
@@ -166,7 +166,7 @@ sudo systemctl enable --now code-server@$USER
> with yarn](#yarn-npm).
```bash
curl -fOL https://github.com/cdr/code-server/releases/download/v$VERSION/code-server-$VERSION-amd64.rpm
curl -fOL https://github.com/coder/code-server/releases/download/v$VERSION/code-server-$VERSION-amd64.rpm
sudo rpm -i code-server-$VERSION-amd64.rpm
sudo systemctl enable --now code-server@$USER
# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml
@@ -228,9 +228,9 @@ You can install code-server using the [Helm package manager](https://coder.com/d
## Windows
We currently [do not publish Windows releases](https://github.com/cdr/code-server/issues/1397). We recommend installing code-server onto Windows with [`yarn` or `npm`](#yarn-npm).
We currently [do not publish Windows releases](https://github.com/coder/code-server/issues/1397). We recommend installing code-server onto Windows with [`yarn` or `npm`](#yarn-npm).
> Note: You will also need to [build cdr/cloud-agent manually](https://github.com/cdr/cloud-agent/issues/17) if you would like to use `code-server --link` on Windows.
> Note: You will also need to [build coder/cloud-agent manually](https://github.com/coder/cloud-agent/issues/17) if you would like to use `code-server --link` on Windows.
## Raspberry Pi
@@ -245,7 +245,7 @@ information.
## Cloud providers
We maintain [one-click apps and install scripts for cloud
providers](https://github.com/cdr/deploy-code-server) such as DigitalOcean,
providers](https://github.com/coder/deploy-code-server) such as DigitalOcean,
Railway, Heroku, and Azure.
## Uninstall

7
docs/ios.md Normal file
View File

@@ -0,0 +1,7 @@
# Using code-server on iOS with iSH
1. Install iSH from the [App Store](https://apps.apple.com/us/app/ish-shell/id1436902243)
2. Install `curl` with `apk add curl`
3. Install code-server with `curl -fsSL https://code-server.dev/install.sh | sh`
4. Run code-server with `code-server`
5. Access on localhost:8080 in your browser

View File

@@ -104,7 +104,7 @@ and tricks helpful:
process](#access-code-server-with-a-self-signed-certificate-on-an-ipad)
- Keyboard issues:
- The keyboard disappear sometimes
[#979](https://github.com/cdr/code-server/issues/979)
[#979](https://github.com/coder/code-server/issues/979)
- Some expectations regarding shortcuts may not be met:
- `cmd + n` opens new browser window instead of new file, and it's difficult
to set alternative as a workaround
@@ -112,18 +112,18 @@ and tricks helpful:
- There's no escape key by default on the Magic Keyboard, so most users set
the globe key to be an escape key
- Trackpad scrolling does not work on iPadOS < 14.5
([#1455](https://github.com/cdr/code-server/issues/1455))
([#1455](https://github.com/coder/code-server/issues/1455))
- [WebKit fix](https://bugs.webkit.org/show_bug.cgi?id=210071#c13)
- Keyboard may lose focus in Safari / split view [#4182](https://github.com/cdr/code-server/issues/4182)
- Terminal text does not appear by default [#3824](https://github.com/cdr/code-server/issues/3824)
- Copy & paste in terminal does not work well with keyboard shortcuts [#3491](https://github.com/cdr/code-server/issues/3491)
- Keyboard may lose focus in Safari / split view [#4182](https://github.com/coder/code-server/issues/4182)
- Terminal text does not appear by default [#3824](https://github.com/coder/code-server/issues/3824)
- Copy & paste in terminal does not work well with keyboard shortcuts [#3491](https://github.com/coder/code-server/issues/3491)
- `ctrl+c` does not stop a long-running process in the browser
- Tracking upstream issue here:
[#114009](https://github.com/microsoft/vscode/issues/114009)
- See [workaround](#ctrl-c-workaround)
Additionally, see [issues in the code-server repo that are tagged with the iPad
label](https://github.com/cdr/code-server/issues?q=is%3Aopen+is%3Aissue+label%3AiPad)
Additionally, see [issues in the code-server repo that are tagged with the `os-ios`
label](https://github.com/coder/code-server/issues?q=is%3Aopen+is%3Aissue+label%3Aos-ios)
for more information.
### Workaround for issue with `ctrl+c` not stopping a running process in the terminal

View File

@@ -7,5 +7,5 @@ for accessing your IDE out of the box.
```console
$ code-server --link
Proxying code-server, you can access your IDE at https://example.cdr.co
Proxying code-server, you can access your IDE at https://example.coder.co
```

View File

@@ -1,5 +1,5 @@
{
"versions": ["v4.0.0"],
"versions": ["v4.1.0"],
"routes": [
{
"title": "Home",
@@ -51,6 +51,16 @@
"title": "Termux",
"description": "How to install Termux to run code-server on an Android device.",
"path": "./termux.md"
},
{
"title": "iOS",
"description": "How to use code-server on iOS with iSH.",
"path": "./ios.md"
},
{
"title": "Android",
"description": "How to run code-server on an Android device using UserLAnd.",
"path": "./android.md"
}
]
},
@@ -63,7 +73,7 @@
{
"title": "Upgrade",
"description": "How to upgrade code-server.",
"icon": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M17.8049 2.19795C17.7385 2.1311 17.6587 2.07899 17.5708 2.04504C17.4829 2.01108 17.3889 1.99604 17.2948 2.00089C7.89216 2.49153 4.4188 10.8673 4.38528 10.9517C4.33624 11.0736 4.32406 11.2071 4.35028 11.3358C4.3765 11.4645 4.43995 11.5827 4.53274 11.6756L8.32449 15.4674C8.41787 15.5606 8.53669 15.6242 8.66606 15.6502C8.79543 15.6762 8.92959 15.6634 9.05174 15.6135C9.13552 15.5793 17.4664 12.0671 17.9986 2.7087C18.0039 2.61474 17.9895 2.5207 17.9561 2.4327C17.9227 2.3447 17.8712 2.26471 17.8049 2.19795ZM12.3314 9.56427C12.1439 9.75179 11.9051 9.87951 11.645 9.93126C11.385 9.98302 11.1154 9.9565 10.8704 9.85505C10.6254 9.7536 10.4161 9.58178 10.2687 9.36131C10.1214 9.14085 10.0428 8.88166 10.0428 8.6165C10.0428 8.35135 10.1214 8.09215 10.2687 7.87169C10.4161 7.65123 10.6254 7.47941 10.8704 7.37796C11.1154 7.27651 11.385 7.24998 11.645 7.30174C11.9051 7.3535 12.1439 7.48121 12.3314 7.66873C12.5827 7.92012 12.7239 8.26104 12.7239 8.6165C12.7239 8.97197 12.5827 9.31288 12.3314 9.56427Z\"/><path d=\"M2.74602 14.5444C2.92281 14.3664 3.133 14.2251 3.36454 14.1285C3.59608 14.0319 3.8444 13.9819 4.09529 13.9815C4.34617 13.9811 4.59466 14.0302 4.82653 14.126C5.05839 14.2218 5.26907 14.3624 5.44647 14.5398C5.62386 14.7172 5.7645 14.9279 5.86031 15.1598C5.95612 15.3916 6.00522 15.6401 6.00479 15.891C6.00437 16.1419 5.95442 16.3902 5.85782 16.6218C5.76122 16.8533 5.61987 17.0635 5.44186 17.2403C4.69719 17.985 2 18.0004 2 18.0004C2 18.0004 2 15.2884 2.74602 14.5444Z\"/><path d=\"M8.9416 3.48269C7.99688 3.31826 7.02645 3.38371 6.11237 3.67352C5.19828 3.96332 4.36741 4.46894 3.68999 5.14765C3.33153 5.50944 3.01988 5.91477 2.76233 6.35415C2.68692 6.4822 2.6562 6.63169 2.67501 6.77911C2.69381 6.92652 2.76108 7.06351 2.86623 7.16853L4.1994 8.50238C5.43822 6.53634 7.04911 4.83119 8.9416 3.48269Z\"/><path d=\"M16.5181 11.0585C16.6825 12.0033 16.6171 12.9737 16.3273 13.8878C16.0375 14.8019 15.5318 15.6327 14.8531 16.3101C14.4914 16.6686 14.086 16.9803 13.6466 17.2378C13.5186 17.3132 13.3691 17.3439 13.2217 17.3251C13.0743 17.3063 12.9373 17.2391 12.8323 17.1339L11.4984 15.8007C13.4645 14.5619 15.1696 12.951 16.5181 11.0585Z\"/></svg>",
"icon": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M17.8049 2.19795C17.7385 2.1311 17.6587 2.07899 17.5708 2.04504C17.4829 2.01108 17.3889 1.99604 17.2948 2.00089C7.89216 2.49153 4.4188 10.8673 4.38528 10.9517C4.33624 11.0736 4.32406 11.2071 4.35028 11.3358C4.3765 11.4645 4.43995 11.5827 4.53274 11.6756L8.32449 15.4674C8.41787 15.5606 8.53669 15.6242 8.66606 15.6502C8.79543 15.6762 8.92959 15.6634 9.05174 15.6135C9.13552 15.5793 17.4664 12.0671 17.9986 2.7087C18.0039 2.61474 17.9895 2.5207 17.9561 2.4327C17.9227 2.3447 17.8712 2.26471 17.8049 2.19795ZM12.3314 9.56427C12.1439 9.75179 11.9051 9.87951 11.645 9.93126C11.385 9.98302 11.1154 9.9565 10.8704 9.85505C10.6254 9.7536 10.4161 9.58178 10.2687 9.36131C10.1214 9.14085 10.0428 8.88166 10.0428 8.6165C10.0428 8.35135 10.1214 8.09215 10.2687 7.87169C10.4161 7.65123 10.6254 7.47941 10.8704 7.37796C11.1154 7.27651 11.385 7.24998 11.645 7.30174C11.9051 7.3535 12.1439 7.48121 12.3314 7.66873C12.5827 7.92012 12.7239 8.26104 12.7239 8.6165C12.7239 8.97197 12.5827 9.31288 12.3314 9.56427Z\"/><path d=\"M2.74602 14.5444C2.92281 14.3664 3.133 14.2251 3.36454 14.1285C3.59608 14.0319 3.8444 13.9819 4.09529 13.9815C4.34617 13.9811 4.59466 14.0.12 4.82653 14.126C5.05839 14.2218 5.26907 14.3624 5.44647 14.5398C5.62386 14.7172 5.7645 14.9279 5.86031 15.1598C5.95612 15.3916 6.00522 15.6401 6.00479 15.891C6.00437 16.1419 5.95442 16.3902 5.85782 16.6218C5.76122 16.8533 5.61987 17.0635 5.44186 17.2403C4.69719 17.985 2 18.0004 2 18.0004C2 18.0004 2 15.2884 2.74602 14.5444Z\"/><path d=\"M8.9416 3.48269C7.99688 3.31826 7.02645 3.38371 6.11237 3.67352C5.19828 3.96332 4.36741 4.46894 3.68999 5.14765C3.33153 5.50944 3.01988 5.91477 2.76233 6.35415C2.68692 6.4822 2.6562 6.63169 2.67501 6.77911C2.69381 6.92652 2.76108 7.06351 2.86623 7.16853L4.1994 8.50238C5.43822 6.53634 7.04911 4.83119 8.9416 3.48269Z\"/><path d=\"M16.5181 11.0585C16.6825 12.0033 16.6171 12.9737 16.3273 13.8878C16.0375 14.8019 15.5318 15.6327 14.8531 16.3101C14.4914 16.6686 14.086 16.9803 13.6466 17.2378C13.5186 17.3132 13.3691 17.3439 13.2217 17.3251C13.0743 17.3063 12.9373 17.2391 12.8323 17.1339L11.4984 15.8007C13.4645 14.5619 15.1696 12.951 16.5181 11.0585Z\"/></svg>",
"path": "./upgrade.md"
},
{

View File

@@ -27,7 +27,7 @@ which is currently `14.x`. VS Code also [lists Node.js
requirements](https://github.com/microsoft/vscode/wiki/How-to-Contribute#prerequisites).
Using other versions of Node.js [may lead to unexpected
behavior](https://github.com/cdr/code-server/issues/1633).
behavior](https://github.com/coder/code-server/issues/1633).
## Ubuntu, Debian
@@ -100,7 +100,7 @@ yarn global bin
# Or: npm config get prefix
```
For help and additional troubleshooting, see [#1397](https://github.com/cdr/code-server/issues/1397).
For help and additional troubleshooting, see [#1397](https://github.com/coder/code-server/issues/1397).
## Installing
@@ -116,7 +116,7 @@ code-server
## Troubleshooting
If you need further assistance, post on our [GitHub Discussions
page](https://github.com/cdr/code-server/discussions).
page](https://github.com/coder/code-server/discussions).
### Issues with Node.js after version upgrades

View File

@@ -33,7 +33,7 @@ new Compute Engine VM instance:
4. Choose the **region** that's closest to you based on [GCP
ping](https://gcping.com/).
5. Choose a **zone** (any option is fine).
6. We recommend choose an **E2 series instance** from the [general-purpose
6. We recommend choosing an **E2 series instance** from the [general-purpose
family](https://cloud.google.com/compute/docs/machine-types#general_purpose).
7. Change the instance type to **custom** and set at least **2 cores** and **2
GB of RAM**. You can add more resources if desired, though you can also edit

View File

@@ -28,8 +28,8 @@ This will show issues that:
1. If more information is required, please ask the submitter and tag as
`waiting-for-info` and wait.
1. Finally, the issue should be moved into the
[code-server](https://github.com/cdr/code-server/projects/1) project where we
[code-server](https://github.com/coder/code-server/projects/1) project where we
pick out issues to fix and track their progress.
We also use [milestones](https://github.com/cdr/code-server/milestones) to track
We also use [milestones](https://github.com/coder/code-server/milestones) to track
what issues are planned/or were closed for what release.

View File

@@ -23,7 +23,7 @@ The remote host must have internet access.
${not_curl_usage-}
Usage:
$arg0 [--dry-run] [--version X.X.X] [--method detect] \
$arg0 [--dry-run] [--version X.X.X] [--edge] [--method detect] \
[--prefix ~/.local] [--rsh ssh] [user@host]
--dry-run
@@ -32,6 +32,9 @@ Usage:
--version X.X.X
Install a specific version instead of the latest.
--edge
Install the latest edge version instead of the latest stable version.
--method [detect | standalone]
Choose the installation method. Defaults to detect.
- detect detects the system package manager and tries to use it.
@@ -71,9 +74,13 @@ EOF
}
echo_latest_version() {
# https://gist.github.com/lukechilds/a83e1d7127b78fef38c2914c4ececc3c#gistcomment-2758860
version="$(curl -fsSLI -o /dev/null -w "%{url_effective}" https://github.com/cdr/code-server/releases/latest)"
version="${version#https://github.com/cdr/code-server/releases/tag/}"
if [ "${EDGE-}" ]; then
version="$(curl -fsSL https://api.github.com/repos/coder/code-server/releases | awk 'match($0,/.*"html_url": "(.*\/releases\/tag\/.*)".*/)' | head -n 1 | awk -F '"' '{print $4}')"
else
# https://gist.github.com/lukechilds/a83e1d7127b78fef38c2914c4ececc3c#gistcomment-2758860
version="$(curl -fsSLI -o /dev/null -w "%{url_effective}" https://github.com/coder/code-server/releases/latest)"
fi
version="${version#https://github.com/coder/code-server/releases/tag/}"
version="${version#v}"
echo "$version"
}
@@ -135,6 +142,7 @@ main() {
OPTIONAL \
ALL_FLAGS \
RSH_ARGS \
EDGE \
RSH
ALL_FLAGS=""
@@ -170,6 +178,9 @@ main() {
--version=*)
VERSION="$(parse_arg "$@")"
;;
--edge)
EDGE=1
;;
--rsh)
RSH="$(parse_arg "$@")"
shift
@@ -340,7 +351,7 @@ install_deb() {
echoh "Installing v$VERSION of the $ARCH deb package from GitHub."
echoh
fetch "https://github.com/cdr/code-server/releases/download/v$VERSION/code-server_${VERSION}_$ARCH.deb" \
fetch "https://github.com/coder/code-server/releases/download/v$VERSION/code-server_${VERSION}_$ARCH.deb" \
"$CACHE_DIR/code-server_${VERSION}_$ARCH.deb"
sudo_sh_c dpkg -i "$CACHE_DIR/code-server_${VERSION}_$ARCH.deb"
@@ -351,7 +362,7 @@ install_rpm() {
echoh "Installing v$VERSION of the $ARCH rpm package from GitHub."
echoh
fetch "https://github.com/cdr/code-server/releases/download/v$VERSION/code-server-$VERSION-$ARCH.rpm" \
fetch "https://github.com/coder/code-server/releases/download/v$VERSION/code-server-$VERSION-$ARCH.rpm" \
"$CACHE_DIR/code-server-$VERSION-$ARCH.rpm"
sudo_sh_c rpm -i "$CACHE_DIR/code-server-$VERSION-$ARCH.rpm"
@@ -377,7 +388,7 @@ install_standalone() {
echoh "Installing v$VERSION of the $ARCH release from GitHub."
echoh
fetch "https://github.com/cdr/code-server/releases/download/v$VERSION/code-server-$VERSION-$OS-$ARCH.tar.gz" \
fetch "https://github.com/coder/code-server/releases/download/v$VERSION/code-server-$VERSION-$OS-$ARCH.tar.gz" \
"$CACHE_DIR/code-server-$VERSION-$OS-$ARCH.tar.gz"
# -w only works if the directory exists so try creating it first. If this

View File

@@ -1,13 +1,13 @@
{
"name": "code-server",
"license": "MIT",
"version": "4.0.0",
"version": "4.1.0",
"description": "Run VS Code on a remote server.",
"homepage": "https://github.com/cdr/code-server",
"homepage": "https://github.com/coder/code-server",
"bugs": {
"url": "https://github.com/cdr/code-server/issues"
"url": "https://github.com/coder/code-server/issues"
},
"repository": "https://github.com/cdr/code-server",
"repository": "https://github.com/coder/code-server",
"scripts": {
"clean": "./ci/build/clean.sh",
"build": "./ci/build/build-code-server.sh",
@@ -17,12 +17,13 @@
"release:github-draft": "./ci/build/release-github-draft.sh",
"release:github-assets": "./ci/build/release-github-assets.sh",
"release:prep": "./ci/build/release-prep.sh",
"test:e2e": "./ci/dev/test-e2e.sh",
"test:e2e": "VSCODE_IPC_HOOK_CLI= ./ci/dev/test-e2e.sh",
"test:standalone-release": "./ci/build/test-standalone-release.sh",
"test:unit": "./ci/dev/test-unit.sh --forceExit --detectOpenHandles",
"test:scripts": "./ci/dev/test-scripts.sh",
"package": "./ci/build/build-packages.sh",
"postinstall": "./ci/dev/postinstall.sh",
"publish:npm": "./ci/steps/publish-npm.sh",
"_audit": "./ci/dev/audit.sh",
"fmt": "./ci/dev/fmt.sh",
"lint": "./ci/dev/lint.sh",
@@ -77,7 +78,10 @@
"vfile-message": "^2.0.2",
"tar": "^6.1.9",
"path-parse": "^1.0.7",
"vm2": "^3.9.4"
"vm2": "^3.9.6",
"follow-redirects": "^1.14.8",
"node-fetch": "^2.6.7",
"nanoid": "^3.1.31"
},
"dependencies": {
"@coder/logger": "1.1.16",
@@ -85,15 +89,14 @@
"compression": "^1.7.4",
"cookie-parser": "^1.4.5",
"env-paths": "^2.2.0",
"express": "^5.0.0-alpha.8",
"express": "5.0.0-alpha.8",
"http-proxy": "^1.18.0",
"httpolyglot": "^0.1.2",
"js-yaml": "^4.0.0",
"limiter": "^1.1.5",
"pem": "^1.14.2",
"proxy-agent": "^5.0.0",
"proxy-from-env": "^1.1.0",
"qs": "6.10.2",
"qs": "6.10.3",
"rotating-file-stream": "^3.0.0",
"safe-buffer": "^5.1.1",
"safe-compare": "^1.1.4",
@@ -154,10 +157,12 @@
"<rootDir>/release-standalone",
"<rootDir>/release-npm-package",
"<rootDir>/release-gcp",
"<rootDir>/release-images"
"<rootDir>/release-images",
"<rootDir>/vendor"
],
"moduleNameMapper": {
"^.+\\.(css|less)$": "<rootDir>/test/utils/cssStub.ts"
}
},
"globalSetup": "<rootDir>/test/utils/globalUnitSetup.ts"
}
}

View File

@@ -11,7 +11,7 @@ import { disposer } from "./http"
import { isNodeJSErrnoException } from "./util"
import { handleUpgrade } from "./wsRouter"
type ListenOptions = Pick<DefaultedArgs, "socket" | "port" | "host">
type ListenOptions = Pick<DefaultedArgs, "socket-mode" | "socket" | "port" | "host">
export interface App extends Disposable {
/** Handles regular HTTP requests. */
@@ -22,7 +22,7 @@ export interface App extends Disposable {
server: http.Server
}
const listen = (server: http.Server, { host, port, socket }: ListenOptions) => {
const listen = (server: http.Server, { host, port, socket, "socket-mode": mode }: ListenOptions) => {
return new Promise<void>(async (resolve, reject) => {
server.on("error", reject)
@@ -31,7 +31,16 @@ const listen = (server: http.Server, { host, port, socket }: ListenOptions) => {
server.off("error", reject)
server.on("error", (err) => util.logError(logger, "http server error", err))
resolve()
if (socket && mode) {
fs.chmod(socket, mode)
.then(resolve)
.catch((err) => {
util.logError(logger, "socket chmod", err)
reject(err)
})
} else {
resolve()
}
}
if (socket) {

View File

@@ -3,15 +3,7 @@ import { promises as fs } from "fs"
import yaml from "js-yaml"
import * as os from "os"
import * as path from "path"
import {
canConnect,
generateCertificate,
generatePassword,
humanPath,
paths,
isNodeJSErrnoException,
isFile,
} from "./util"
import { canConnect, generateCertificate, generatePassword, humanPath, paths, isNodeJSErrnoException } from "./util"
const DEFAULT_SOCKET_PATH = path.join(os.tmpdir(), "vscode-ipc")
@@ -57,12 +49,14 @@ export interface UserProvidedArgs {
enable?: string[]
help?: boolean
host?: string
locale?: string
port?: number
json?: boolean
log?: LogLevel
open?: boolean
"bind-addr"?: string
socket?: string
"socket-mode"?: string
version?: boolean
"proxy-domain"?: string[]
"reuse-window"?: boolean
@@ -86,6 +80,7 @@ export interface UserProvidedArgs {
"locate-extension"?: string[]
"show-versions"?: boolean
category?: string
"github-auth"?: string
}
interface Option<T> {
@@ -163,6 +158,7 @@ const options: Options<Required<UserProvidedArgs>> = {
enable: { type: "string[]" },
help: { type: "boolean", short: "h", description: "Show this output." },
json: { type: "boolean" },
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": {
@@ -180,6 +176,7 @@ 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-mode": { type: "string", description: "File mode of the socket." },
version: { type: "boolean", short: "v", description: "Display version information." },
_: { type: "string[]" },
@@ -203,6 +200,10 @@ const options: Options<Required<UserProvidedArgs>> = {
},
"uninstall-extension": { type: "string[]", description: "Uninstall a VS Code extension by id." },
"show-versions": { type: "boolean", description: "Show VS Code extension versions." },
"github-auth": {
type: "string",
description: "GitHub authentication token (can only be passed in via $GITHUB_TOKEN or the config file).",
},
"proxy-domain": { type: "string[]", description: "Domain used for proxying ports." },
"ignore-last-opened": {
type: "boolean",
@@ -227,7 +228,7 @@ const options: Options<Required<UserProvidedArgs>> = {
type: OptionalString,
description: `
Securely bind code-server via our cloud service with the passed name. You'll get a URL like
https://hostname-username.cdr.co at which you can easily access your code-server instance.
https://hostname-username.coder.co at which you can easily access your code-server instance.
Authorization is done via GitHub.
`,
deprecated: true,
@@ -334,6 +335,10 @@ export const parse = (
throw new Error("--hashed-password can only be set in the config file or passed in via $HASHED_PASSWORD")
}
if (key === "github-auth" && !opts?.configFile) {
throw new Error("--github-auth can only be set in the config file or passed in via $GITHUB_TOKEN")
}
const option = options[key]
if (option.type === "boolean") {
;(args[key] as boolean) = true
@@ -407,7 +412,12 @@ export const parse = (
logger.debug(() => [
`parsed ${opts?.configFile ? "config" : "command line"}`,
field("args", { ...args, password: undefined }),
field("args", {
...args,
password: args.password ? "<redacted>" : undefined,
"hashed-password": args["hashed-password"] ? "<redacted>" : undefined,
"github-auth": args["github-auth"] ? "<redacted>" : undefined,
}),
])
return args
@@ -432,7 +442,7 @@ export interface DefaultedArgs extends ConfigArgs {
"extensions-dir": string
"user-data-dir": string
/* Positional arguments. */
_: []
_: string[]
}
/**
@@ -505,6 +515,7 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
args.host = "localhost"
args.port = 0
args.socket = undefined
args["socket-mode"] = undefined
args.cert = undefined
args.auth = AuthType.None
}
@@ -528,9 +539,14 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
usingEnvPassword = false
}
if (process.env.GITHUB_TOKEN) {
args["github-auth"] = process.env.GITHUB_TOKEN
}
// Ensure they're not readable by child processes.
delete process.env.PASSWORD
delete process.env.HASHED_PASSWORD
delete process.env.GITHUB_TOKEN
// Filter duplicate proxy domains and remove any leading `*.`.
const proxyDomains = new Set((args["proxy-domain"] || []).map((d) => d.replace(/^\*\./, "")))
@@ -749,25 +765,9 @@ export const shouldOpenInExistingInstance = async (args: UserProvidedArgs): Prom
* Convert our arguments to VS Code server arguments.
*/
export const toVsCodeArgs = async (args: DefaultedArgs): Promise<CodeServerLib.ServerParsedArgs> => {
let workspace = ""
let folder = ""
if (args._.length) {
const lastEntry = path.resolve(args._[args._.length - 1])
const entryIsFile = await isFile(lastEntry)
if (entryIsFile && path.extname(lastEntry) === ".code-workspace") {
workspace = lastEntry
} else if (!entryIsFile) {
folder = lastEntry
}
// Otherwise it is a regular file. Spawning VS Code with a file is not yet
// supported but it can be done separately after code-server spawns.
}
return {
"connection-token": "0000",
...args,
workspace,
folder,
"accept-server-license-terms": true,
/** Type casting. */
help: !!args.help,

View File

@@ -3,7 +3,7 @@ import { spawn } from "child_process"
import path from "path"
import split2 from "split2"
// https://github.com/cdr/coder-cloud
// https://github.com/coder/coder-cloud
const coderCloudAgent = path.resolve(__dirname, "../../lib/coder-cloud-agent")
function runAgent(...args: string[]): Promise<void> {

View File

@@ -17,11 +17,35 @@ export function getPackageJson(relativePath: string): JSONSchemaForNPMPackageJso
}
const pkg = getPackageJson("../../package.json")
const codePkg = getPackageJson("../../vendor/modules/code-oss-dev/package.json")
export const pkgName = pkg.name || "code-server"
export const version = pkg.version || "development"
export const commit = pkg.commit || "development"
export const rootPath = path.resolve(__dirname, "../..")
export const vsRootPath = path.join(rootPath, "vendor/modules/code-oss-dev")
export const codeVersion = codePkg.version || "development"
export const tmpdir = path.join(os.tmpdir(), "code-server")
export const isDevMode = commit === "development"
export const httpProxyUri =
process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY || process.env.http_proxy
/**
* getVersionString returns a human-readable version string suitable
* for outputting to the console.
*/
export function getVersionString(): string {
return [version, commit, "with Code", codeVersion].join(" ")
}
/**
* getVersionJsonString returns a machine-readable version string
* suitable for outputting to the console.
*/
export function getVersionJsonString(): string {
return JSON.stringify({
codeServer: version,
commit,
vscode: codeVersion,
})
}

View File

@@ -1,13 +1,10 @@
import { logger } from "@coder/logger"
import { optionDescriptions, parse, readConfigFile, setDefaults, shouldOpenInExistingInstance } from "./cli"
import { commit, version } from "./constants"
import { getVersionString, getVersionJsonString } from "./constants"
import { openInExistingInstance, runCodeServer, runVsCodeCli, shouldSpawnCliProcess } from "./main"
import { monkeyPatchProxyProtocols } from "./proxy_agent"
import { isChild, wrapper } from "./wrapper"
async function entry(): Promise<void> {
monkeyPatchProxyProtocols()
// There's no need to check flags like --help or to spawn in an existing
// instance for the child process because these would have already happened in
// the parent and the child wouldn't have been spawned. We also get the
@@ -27,7 +24,7 @@ async function entry(): Promise<void> {
const args = await setDefaults(cliArgs, configArgs)
if (args.help) {
console.log("code-server", version, commit)
console.log("code-server", getVersionString())
console.log("")
console.log(`Usage: code-server [options] [path]`)
console.log(` - Opening a directory: code-server ./path/to/your/project`)
@@ -42,15 +39,9 @@ async function entry(): Promise<void> {
if (args.version) {
if (args.json) {
console.log(
JSON.stringify({
codeServer: version,
commit,
vscode: require("../../vendor/modules/code-oss-dev/package.json").version,
}),
)
console.log(getVersionJsonString())
} else {
console.log(version, commit)
console.log(getVersionString())
}
return
}

View File

@@ -10,6 +10,8 @@ import { normalize } from "../common/util"
import { AuthType, DefaultedArgs } from "./cli"
import { version as codeServerVersion } from "./constants"
import { Heart } from "./heart"
import { CoderSettings, SettingsProvider } from "./settings"
import { UpdateProvider } from "./update"
import { getPasswordMethod, IsCookieValidArgs, isCookieValid, sanitizeString, escapeHtml, escapeJSON } from "./util"
/**
@@ -29,6 +31,8 @@ declare global {
export interface Request {
args: DefaultedArgs
heart: Heart
settings: SettingsProvider<CoderSettings>
updater: UpdateProvider
}
}
}
@@ -135,8 +139,23 @@ export const relativeRoot = (originalUrl: string): string => {
}
/**
* Redirect relatively to `/${to}`. Query variables on the current URI will be preserved.
* `to` should be a simple path without any query parameters
* A helper function to construct a redirect path based on
* an Express Request, query and a path to redirect to.
*
* Redirect path is relative to `/${to}`.
*/
export const constructRedirectPath = (req: express.Request, query: qs.ParsedQs, to: string): string => {
const relativePath = normalize(`${relativeRoot(req.originalUrl)}/${to}`, true)
// %2f or %2F are both equalivent to an encoded slash /
const queryString = qs.stringify(query).replace(/%2[fF]/g, "/")
const redirectPath = `${relativePath}${queryString ? `?${queryString}` : ""}`
return redirectPath
}
/**
* Redirect relatively to `/${to}`. Query variables on the current URI will be
* preserved. `to` should be a simple path without any query parameters
* `override` will merge with the existing query (use `undefined` to unset).
*/
export const redirect = (
@@ -152,9 +171,7 @@ export const redirect = (
}
})
const relativePath = normalize(`${relativeRoot(req.originalUrl)}/${to}`, true)
const queryString = qs.stringify(query)
const redirectPath = `${relativePath}${queryString ? `?${queryString}` : ""}`
const redirectPath = constructRedirectPath(req, query, to)
logger.debug(`redirecting from ${req.originalUrl} to ${redirectPath}`)
res.redirect(redirectPath)
}
@@ -192,7 +209,7 @@ export const getCookieDomain = (host: string, proxyDomains: string[]): string |
// default NGINX does this).
!host.includes(".")
) {
logger.debug("no valid cookie doman", field("host", host))
logger.debug("no valid cookie domain", field("host", host))
return undefined
}
@@ -202,7 +219,7 @@ export const getCookieDomain = (host: string, proxyDomains: string[]): string |
}
})
logger.debug("got cookie doman", field("host", host))
logger.debug("got cookie domain", field("host", host))
return host || undefined
}
@@ -284,3 +301,10 @@ export const getCookieOptions = (req: express.Request): express.CookieOptions =>
sameSite: "lax",
}
}
/**
* Return the full path to the current page, preserving any trailing slash.
*/
export const self = (req: express.Request): string => {
return normalize(`${req.baseUrl}${req.originalUrl.endsWith("/") ? "/" : ""}`, true)
}

View File

@@ -1,71 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Coder Technologies. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import ProxyAgent from "proxy-agent"
import { getProxyForUrl } from "proxy-from-env"
/**
* This file has nothing to do with the code-server proxy.
* It is to support $HTTP_PROXY, $HTTPS_PROXY and $NO_PROXY.
*
* - https://github.com/cdr/code-server/issues/124
* - https://www.npmjs.com/package/proxy-agent
* - https://www.npmjs.com/package/proxy-from-env
*
*/
/**
* monkeyPatch patches the node http,https modules to route all requests through the
* agent we get from the proxy-agent package.
*
* This approach only works if there is no code specifying an explicit agent when making
* a request.
*
* None of our code ever passes in a explicit agent to the http,https modules.
* VS Code's does sometimes but only when a user sets the http.proxy configuration.
* See https://code.visualstudio.com/docs/setup/network#_legacy-proxy-server-support
*
* Even if they do, it's probably the same proxy so we should be fine! And those knobs
* are deprecated anyway.
*/
export function monkeyPatchProxyProtocols(): void {
if (!shouldEnableProxy()) {
return
}
const http = require("http")
const https = require("https")
// If we do not pass in a proxy URL, proxy-agent will get the URL from the environment.
// See https://www.npmjs.com/package/proxy-from-env.
// Also see shouldEnableProxy.
const pa = new ProxyAgent()
http.globalAgent = pa
https.globalAgent = pa
}
const sampleUrls = [new URL("http://example.com"), new URL("https://example.com")]
// If they have $NO_PROXY set to example.com then this check won't work!
// But that's drastically unlikely.
export function shouldEnableProxy(): boolean {
const testedProxyEndpoints = sampleUrls.map((url) => {
return {
url,
proxyUrl: getProxyForUrl(url.toString()),
}
})
let shouldEnable = false
for (const { url, proxyUrl } of testedProxyEndpoints) {
if (proxyUrl) {
console.debug(`${url.protocol} -- Using "${proxyUrl}"`)
shouldEnable = true
}
}
return shouldEnable
}

View File

@@ -1,7 +1,6 @@
import { Request, Router } from "express"
import { HttpCode, HttpError } from "../../common/http"
import { normalize } from "../../common/util"
import { authenticated, ensureAuthenticated, redirect } from "../http"
import { authenticated, ensureAuthenticated, redirect, self } from "../http"
import { proxy } from "../proxy"
import { Router as WsRouter } from "../wsRouter"
@@ -56,7 +55,7 @@ router.all("*", async (req, res, next) => {
return next()
}
// Redirect all other pages to the login.
const to = normalize(`${req.baseUrl}${req.path}`)
const to = self(req)
return redirect(req, res, "login", {
to: to !== "/" ? to : undefined,
})

View File

@@ -14,6 +14,8 @@ import { commit, rootPath } from "../constants"
import { Heart } from "../heart"
import { ensureAuthenticated, redirect } from "../http"
import { PluginAPI } from "../plugin"
import { CoderSettings, SettingsProvider } from "../settings"
import { UpdateProvider } from "../update"
import { getMediaMime, paths } from "../util"
import * as apps from "./apps"
import * as domainProxy from "./domainProxy"
@@ -47,6 +49,9 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
app.router.use(cookieParser())
app.wsRouter.use(cookieParser())
const settings = new SettingsProvider<CoderSettings>(path.join(args["user-data-dir"], "coder.json"))
const updater = new UpdateProvider("https://api.github.com/repos/coder/code-server/releases/latest", settings)
const common: express.RequestHandler = (req, _, next) => {
// /healthz|/healthz/ needs to be excluded otherwise health checks will make
// it look like code-server is always in use.
@@ -57,6 +62,8 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
// Add common variables routes can use.
req.args = args
req.heart = heart
req.settings = settings
req.updater = updater
next()
}

View File

@@ -3,8 +3,7 @@ import * as path from "path"
import * as qs from "qs"
import * as pluginapi from "../../../typings/pluginapi"
import { HttpCode, HttpError } from "../../common/http"
import { normalize } from "../../common/util"
import { authenticated, ensureAuthenticated, redirect } from "../http"
import { authenticated, ensureAuthenticated, redirect, self } from "../http"
import { proxy as _proxy } from "../proxy"
const getProxyTarget = (req: Request, passthroughPath?: boolean): string => {
@@ -25,7 +24,7 @@ export function proxy(
if (!authenticated(req)) {
// If visiting the root (/:port only) redirect to the login page.
if (!req.params[0] || req.params[0] === "/") {
const to = normalize(`${req.baseUrl}${req.path}`)
const to = self(req)
return redirect(req, res, "login", {
to: to !== "/" ? to : undefined,
})

View File

@@ -1,18 +1,15 @@
import { Router } from "express"
import { version } from "../constants"
import { ensureAuthenticated } from "../http"
import { UpdateProvider } from "../update"
export const router = Router()
const provider = new UpdateProvider()
router.get("/check", ensureAuthenticated, async (req, res) => {
const update = await provider.getUpdate(req.query.force === "true")
const update = await req.updater.getUpdate(req.query.force === "true")
res.json({
checked: update.checked,
latest: update.version,
current: version,
isLatest: provider.isLatestVersion(update),
isLatest: req.updater.isLatestVersion(update),
})
})

View File

@@ -1,11 +1,13 @@
import { logger } from "@coder/logger"
import * as express from "express"
import * as path from "path"
import { WebsocketRequest } from "../../../typings/pluginapi"
import { logError } from "../../common/util"
import { isDevMode } from "../constants"
import { toVsCodeArgs } from "../cli"
import { ensureAuthenticated, authenticated, redirect } from "../http"
import { loadAMDModule, readCompilationStats } from "../util"
import { isDevMode } from "../constants"
import { authenticated, ensureAuthenticated, redirect, self } from "../http"
import { SocketProxyProvider } from "../socket"
import { isFile, loadAMDModule } from "../util"
import { Router as WsRouter } from "../wsRouter"
import { errorHandler } from "./errors"
@@ -13,6 +15,7 @@ export class CodeServerRouteWrapper {
/** Assigned in `ensureCodeServerLoaded` */
private _codeServerMain!: CodeServerLib.IServerAPI
private _wsRouterWrapper = WsRouter()
private _socketProxyProvider = new SocketProxyProvider()
public router = express.Router()
public get wsRouter() {
@@ -23,14 +26,57 @@ export class CodeServerRouteWrapper {
private $root: express.Handler = async (req, res, next) => {
const isAuthenticated = await authenticated(req)
const NO_FOLDER_OR_WORKSPACE_QUERY = !req.query.folder && !req.query.workspace
// Ew means the workspace was closed so clear the last folder/workspace.
const FOLDER_OR_WORKSPACE_WAS_CLOSED = req.query.ew
if (!isAuthenticated) {
const to = self(req)
return redirect(req, res, "login", {
// req.baseUrl can be blank if already at the root.
to: req.baseUrl && req.baseUrl !== "/" ? req.baseUrl : undefined,
to: to !== "/" ? to : undefined,
})
}
if (NO_FOLDER_OR_WORKSPACE_QUERY && !FOLDER_OR_WORKSPACE_WAS_CLOSED) {
const settings = await req.settings.read()
const lastOpened = settings.query || {}
// This flag disables the last opened behavior
const IGNORE_LAST_OPENED = req.args["ignore-last-opened"]
const HAS_LAST_OPENED_FOLDER_OR_WORKSPACE = lastOpened.folder || lastOpened.workspace
const HAS_FOLDER_OR_WORKSPACE_FROM_CLI = req.args._.length > 0
const to = self(req)
let folder = undefined
let workspace = undefined
// Redirect to the last folder/workspace if nothing else is opened.
if (HAS_LAST_OPENED_FOLDER_OR_WORKSPACE && !IGNORE_LAST_OPENED) {
folder = lastOpened.folder
workspace = lastOpened.workspace
} else if (HAS_FOLDER_OR_WORKSPACE_FROM_CLI) {
const lastEntry = path.resolve(req.args._[req.args._.length - 1])
const entryIsFile = await isFile(lastEntry)
const IS_WORKSPACE_FILE = entryIsFile && path.extname(lastEntry) === ".code-workspace"
if (IS_WORKSPACE_FILE) {
workspace = lastEntry
} else if (!entryIsFile) {
folder = lastEntry
}
}
if (folder || workspace) {
return redirect(req, res, to, {
folder,
workspace,
})
}
}
// Store the query parameters so we can use them on the next load. This
// also allows users to create functionality around query parameters.
await req.settings.write({ query: req.query })
next()
}
@@ -50,9 +96,10 @@ export class CodeServerRouteWrapper {
}
private $proxyWebsocket = async (req: WebsocketRequest) => {
this._codeServerMain.handleUpgrade(req, req.socket)
const wrappedSocket = await this._socketProxyProvider.createProxy(req.ws)
this._codeServerMain.handleUpgrade(req, wrappedSocket)
req.socket.resume()
req.ws.resume()
}
//#endregion
@@ -66,15 +113,6 @@ export class CodeServerRouteWrapper {
return next()
}
if (isDevMode) {
// Is the development mode file watcher still busy?
const compileStats = await readCompilationStats()
if (!compileStats || !compileStats.lastCompiledAt) {
return next(new Error("VS Code may still be compiling..."))
}
}
// Create the server...
const { args } = req
@@ -88,10 +126,17 @@ export class CodeServerRouteWrapper {
)
try {
this._codeServerMain = await createVSServer(null, await toVsCodeArgs(args))
} catch (createServerError) {
logError(logger, "CodeServerRouteWrapper", createServerError)
return next(createServerError)
this._codeServerMain = await createVSServer(null, {
...(await toVsCodeArgs(args)),
// TODO: Make the browser helper script work.
"without-browser-env-var": true,
})
} catch (error) {
logError(logger, "CodeServerRouteWrapper", error)
if (isDevMode) {
return next(new Error((error instanceof Error ? error.message : error) + " (VS Code may still be compiling)"))
}
return next(error)
}
return next()
@@ -105,5 +150,6 @@ export class CodeServerRouteWrapper {
dispose() {
this._codeServerMain?.dispose()
this._socketProxyProvider.stop()
}
}

View File

@@ -1,8 +1,6 @@
import { logger } from "@coder/logger"
import { Query } from "express-serve-static-core"
import { promises as fs } from "fs"
import * as path from "path"
import { paths } from "./util"
export type Settings = { [key: string]: Settings | string | boolean | number }
@@ -54,14 +52,5 @@ export interface UpdateSettings {
* Global code-server settings.
*/
export interface CoderSettings extends UpdateSettings {
lastVisited: {
url: string
workspace: boolean
}
query: Query
query?: Query
}
/**
* Global code-server settings file.
*/
export const settings = new SettingsProvider<CoderSettings>(path.join(paths.data, "coder.json"))

View File

@@ -1,10 +1,11 @@
import { field, logger } from "@coder/logger"
import * as http from "http"
import * as https from "https"
import ProxyAgent from "proxy-agent"
import * as semver from "semver"
import * as url from "url"
import { version } from "./constants"
import { settings as globalSettings, SettingsProvider, UpdateSettings } from "./settings"
import { httpProxyUri, version } from "./constants"
import { SettingsProvider, UpdateSettings } from "./settings"
export interface Update {
checked: number
@@ -27,12 +28,11 @@ export class UpdateProvider {
* The URL for getting the latest version of code-server. Should return JSON
* that fulfills `LatestResponse`.
*/
private readonly latestUrl = "https://api.github.com/repos/cdr/code-server/releases/latest",
private readonly latestUrl: string,
/**
* Update information will be stored here. If not provided, the global
* settings will be used.
* Update information will be stored here.
*/
private readonly settings: SettingsProvider<UpdateSettings> = globalSettings,
private readonly settings: SettingsProvider<UpdateSettings>,
) {}
/**
@@ -103,8 +103,10 @@ export class UpdateProvider {
return new Promise((resolve, reject) => {
const request = (uri: string): void => {
logger.debug("Making request", field("uri", uri))
const httpx = uri.startsWith("https") ? https : http
const client = httpx.get(uri, { headers: { "User-Agent": "code-server" } }, (response) => {
const isHttps = uri.startsWith("https")
const agent = httpProxyUri ? new ProxyAgent(httpProxyUri) : undefined
const httpx = isHttps ? https : http
const client = httpx.get(uri, { headers: { "User-Agent": "code-server" }, agent }, (response) => {
if (!response.statusCode || response.statusCode < 200 || response.statusCode >= 400) {
response.destroy()
return reject(new Error(`${uri}: ${response.statusCode || "500"}`))

View File

@@ -1,17 +1,15 @@
import { logger } from "@coder/logger"
import * as argon2 from "argon2"
import * as cp from "child_process"
import * as crypto from "crypto"
import envPaths from "env-paths"
import { promises as fs, Stats } from "fs"
import { promises as fs } from "fs"
import * as net from "net"
import * as os from "os"
import * as path from "path"
import safeCompare from "safe-compare"
import * as util from "util"
import xdgBasedir from "xdg-basedir"
import { logError } from "../common/util"
import { isDevMode, rootPath, vsRootPath } from "./constants"
import { vsRootPath } from "./constants"
export interface Paths {
data: string
@@ -59,10 +57,10 @@ export const paths = getEnvPaths()
* On MacOS this function gets the standard XDG directories instead of using the native macOS
* ones. Most CLIs do this as in practice only GUI apps use the standard macOS directories.
*/
export function getEnvPaths(): Paths {
export function getEnvPaths(platform = process.platform): Paths {
const paths = envPaths("code-server", { suffix: "" })
const append = (p: string): string => path.join(p, "code-server")
switch (process.platform) {
switch (platform) {
case "darwin":
return {
// envPaths uses native directories so force Darwin to use the XDG spec
@@ -158,12 +156,7 @@ export const generatePassword = async (length = 24): Promise<string> => {
* Used to hash the password.
*/
export const hash = async (password: string): Promise<string> => {
try {
return await argon2.hash(password)
} catch (error: any) {
logger.error(error)
return ""
}
return await argon2.hash(password)
}
/**
@@ -173,11 +166,7 @@ export const isHashMatch = async (password: string, hash: string) => {
if (password === "" || hash === "" || !hash.startsWith("$")) {
return false
}
try {
return await argon2.verify(hash, password)
} catch (error: any) {
throw new Error(error)
}
return await argon2.verify(hash, password)
}
/**
@@ -523,34 +512,3 @@ export const loadAMDModule = async <T>(amdPath: string, exportName: string): Pro
return module[exportName] as T
}
export interface CompilationStats {
lastCompiledAt: Date
}
export const readCompilationStats = async (): Promise<null | CompilationStats> => {
if (!isDevMode) {
throw new Error("Compilation stats are only present in development")
}
const filePath = path.join(rootPath, "out/watcher.json")
let stat: Stats
try {
stat = await fs.stat(filePath)
} catch (error) {
return null
}
if (!stat.isFile()) {
return null
}
try {
const file = await fs.readFile(filePath)
return JSON.parse(file.toString("utf-8"))
} catch (error) {
logError(logger, "VS Code", error)
}
return null
}

View File

@@ -9,10 +9,16 @@ import { CodeServer, CodeServerPage } from "./models/CodeServer"
*
* If `includeCredentials` is `true` page requests will be authenticated.
*/
export const describe = (name: string, includeCredentials: boolean, fn: (codeServer: CodeServer) => void) => {
export const describe = (
name: string,
includeCredentials: boolean,
codeServerArgs: string[],
codeServerEnv: NodeJS.ProcessEnv,
fn: (codeServer: CodeServer) => void,
) => {
test.describe(name, () => {
// This will spawn on demand so nothing is necessary on before.
const codeServer = new CodeServer(name)
const codeServer = new CodeServer(name, codeServerArgs, codeServerEnv)
// Kill code-server after the suite has ended. This may happen even without
// doing it explicitly but it seems prudent to be sure.
@@ -36,6 +42,9 @@ export const describe = (name: string, includeCredentials: boolean, fn: (codeSer
authenticated: includeCredentials,
// This provides a cookie that authenticates with code-server.
storageState: includeCredentials ? storageState : {},
// NOTE@jsjoeio some tests use --cert which uses a self-signed certificate
// without this option, those tests will fail.
ignoreHTTPSErrors: true,
})
fn(codeServer)
@@ -61,8 +70,8 @@ export const test = base.extend<TestFixtures>({
// made too). In these cases just accept.
page.on("dialog", (d) => d.accept())
const codeServerPage = new CodeServerPage(codeServer, page)
await codeServerPage.setup(authenticated)
const codeServerPage = new CodeServerPage(codeServer, page, authenticated)
await codeServerPage.navigate()
await use(codeServerPage)
},
})

View File

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

View File

@@ -0,0 +1,23 @@
import * as path from "path"
import { describe, test } from "./baseFixture"
function runTestExtensionTests() {
// This will only work if the test extension is loaded into code-server.
test("should have access to VSCODE_PROXY_URI", async ({ codeServerPage }) => {
const address = await codeServerPage.address()
await codeServerPage.executeCommandViaMenus("code-server: Get proxy URI")
await codeServerPage.page.waitForSelector(`text=${address}/proxy/{{port}}`)
})
}
const flags = ["--extensions-dir", path.join(__dirname, "./extensions")]
describe("Extensions", true, flags, {}, () => {
runTestExtensionTests()
})
describe("Extensions with --cert", true, [...flags, "--cert"], {}, () => {
runTestExtensionTests()
})

View File

@@ -0,0 +1 @@
/extension.js

View File

@@ -0,0 +1,13 @@
import * as vscode from "vscode"
export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(
vscode.commands.registerCommand("codeServerTest.proxyUri", () => {
if (process.env.VSCODE_PROXY_URI) {
vscode.window.showInformationMessage(process.env.VSCODE_PROXY_URI)
} else {
vscode.window.showErrorMessage("No proxy URI was set")
}
}),
)
}

View File

@@ -0,0 +1,29 @@
{
"name": "code-server-extension",
"description": "code-server test extension",
"version": "0.0.1",
"publisher": "coder",
"activationEvents": [
"onCommand:codeServerTest.proxyUri"
],
"engines": {
"vscode": "^1.56.0"
},
"main": "./extension.js",
"contributes": {
"commands": [
{
"command": "codeServerTest.proxyUri",
"title": "Get proxy URI",
"category": "code-server"
}
]
},
"devDependencies": {
"@types/vscode": "^1.56.0",
"typescript": "^4.0.5"
},
"scripts": {
"build": "tsc"
}
}

View File

@@ -0,0 +1,12 @@
{
"compilerOptions": {
"target": "es2020",
"module": "commonjs",
"outDir": ".",
"strict": true,
"baseUrl": "./",
"skipLibCheck": true
},
"include": ["./extension.ts"],
"exclude": ["node_modules"]
}

View File

@@ -0,0 +1,13 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@types/vscode@^1.56.0":
version "1.57.0"
resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.57.0.tgz#cc648e0573b92f725cd1baf2621f8da9f8bc689f"
integrity sha512-FeznBFtIDCWRluojTsi9c3LLcCHOXP5etQfBK42+ixo1CoEAchkw39tuui9zomjZuKfUVL33KZUDIwHZ/xvOkQ==
typescript@^4.0.5:
version "4.3.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.2.tgz#399ab18aac45802d6f2498de5054fcbbe716a805"
integrity sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==

38
test/e2e/github.test.ts Normal file
View File

@@ -0,0 +1,38 @@
import { test as base } from "@playwright/test"
import { describe, expect, test } from "./baseFixture"
if (process.env.GITHUB_TOKEN) {
describe("GitHub token", true, [], {}, () => {
test("should be logged in to pull requests extension", async ({ codeServerPage }) => {
await codeServerPage.exec("git init")
await codeServerPage.exec("git remote add origin https://github.com/coder/code-server")
await codeServerPage.installExtension("GitHub.vscode-pull-request-github")
await codeServerPage.executeCommandViaMenus("View: Show Github")
await codeServerPage.page.click("text=Sign in")
await codeServerPage.page.click("text=Allow")
// It should ask to select an account, one of which will be the one we
// pre-injected.
expect(await codeServerPage.page.isVisible("text=Select an account")).toBe(false)
})
})
describe("No GitHub token", true, [], { GITHUB_TOKEN: "" }, () => {
test("should not be logged in to pull requests extension", async ({ codeServerPage }) => {
await codeServerPage.exec("git init")
await codeServerPage.exec("git remote add origin https://github.com/coder/code-server")
await codeServerPage.installExtension("GitHub.vscode-pull-request-github")
await codeServerPage.executeCommandViaMenus("View: Show Github")
await codeServerPage.page.click("text=Sign in")
await codeServerPage.page.click("text=Allow")
// Since there is no account it will ask directly for the token (because
// we are on localhost; otherwise it would initiate the oauth flow).
expect(await codeServerPage.page.isVisible("text=GitHub Personal Access Token")).toBe(false)
})
})
} else {
base.describe("GitHub token", () => {
base.skip("skipped because GITHUB_TOKEN is not set", () => {
// Playwright will not show this without a function.
})
})
}

View File

@@ -2,7 +2,7 @@ import { describe, test, expect } from "./baseFixture"
// This test is to make sure the globalSetup works as expected
// meaning globalSetup ran and stored the storageState
describe("globalSetup", true, () => {
describe("globalSetup", true, [], {}, () => {
test("should keep us logged in using the storageState", async ({ codeServerPage }) => {
// Make sure the editor actually loaded
expect(await codeServerPage.isEditorVisible()).toBe(true)

View File

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

View File

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

View File

@@ -3,7 +3,8 @@ import * as cp from "child_process"
import { promises as fs } from "fs"
import * as path from "path"
import { Page } from "playwright"
import { logError } from "../../../src/common/util"
import * as util from "util"
import { logError, plural } from "../../../src/common/util"
import { onLine } from "../../../src/node/util"
import { PASSWORD, workspaceDir } from "../../utils/constants"
import { idleTimer, tmpdir } from "../../utils/helpers"
@@ -13,14 +14,21 @@ interface CodeServerProcess {
address: string
}
class CancelToken {
class Context {
private _canceled = false
private _done = false
public canceled(): boolean {
return this._canceled
}
public done(): void {
this._done = true
}
public cancel(): void {
this._canceled = true
}
public finish(): boolean {
return this._done
}
}
/**
@@ -31,7 +39,13 @@ export class CodeServer {
public readonly logger: Logger
private closed = false
constructor(name: string) {
constructor(
name: string,
private readonly args: string[],
private readonly env: NodeJS.ProcessEnv,
private readonly _workspaceDir: Promise<string> | string | undefined,
private readonly entry = process.env.CODE_SERVER_TEST_ENTRY || ".",
) {
this.logger = logger.named(name)
}
@@ -47,12 +61,22 @@ export class CodeServer {
return address
}
/**
* The workspace directory code-server opens with.
*/
get workspaceDir(): Promise<string> {
if (!this._workspaceDir) {
this._workspaceDir = tmpdir(workspaceDir)
}
return this._workspaceDir
}
/**
* Create a random workspace and seed it with settings.
*/
private async createWorkspace(): Promise<string> {
const dir = await tmpdir(workspaceDir)
await fs.mkdir(path.join(dir, "User"))
const dir = await this.workspaceDir
await fs.mkdir(path.join(dir, "User"), { recursive: true })
await fs.writeFile(
path.join(dir, "User/settings.json"),
JSON.stringify({
@@ -73,32 +97,33 @@ export class CodeServer {
const dir = await this.createWorkspace()
return new Promise((resolve, reject) => {
this.logger.debug("spawning")
const proc = cp.spawn(
"node",
[
process.env.CODE_SERVER_TEST_ENTRY || ".",
// Using port zero will spawn on a random port.
"--bind-addr",
"127.0.0.1:0",
// Setting the XDG variables would be easier and more thorough but the
// modules we import ignores those variables for non-Linux operating
// systems so use these flags instead.
"--config",
path.join(dir, "config.yaml"),
"--user-data-dir",
dir,
// The last argument is the workspace to open.
dir,
],
{
cwd: path.join(__dirname, "../../.."),
env: {
...process.env,
PASSWORD,
},
const args = [
this.entry,
"--extensions-dir",
path.join(dir, "extensions"),
...this.args,
// Using port zero will spawn on a random port.
"--bind-addr",
"127.0.0.1:0",
// Setting the XDG variables would be easier and more thorough but the
// modules we import ignores those variables for non-Linux operating
// systems so use these flags instead.
"--config",
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, {
cwd: path.join(__dirname, "../../.."),
env: {
...process.env,
...this.env,
PASSWORD,
},
)
})
const timer = idleTimer("Failed to extract address; did the format change?", reject)
@@ -109,7 +134,7 @@ export class CodeServer {
})
proc.on("close", (code) => {
const error = new Error("closed unexpectedly")
const error = new Error("code-server closed unexpectedly")
if (!this.closed) {
this.logger.error(error.message, field("code", code))
}
@@ -126,7 +151,7 @@ export class CodeServer {
timer.reset()
// Log the line without the timestamp.
this.logger.trace(line.replace(/\[.+\]/, ""))
this.logger.debug(line.replace(/\[.+\]/, ""))
if (resolved) {
return
}
@@ -167,7 +192,11 @@ export class CodeServer {
export class CodeServerPage {
private readonly editorSelector = "div.monaco-workbench"
constructor(private readonly codeServer: CodeServer, public readonly page: Page) {
constructor(
private readonly codeServer: CodeServer,
public readonly page: Page,
private readonly authenticated: boolean,
) {
this.page.on("console", (message) => {
this.codeServer.logger.debug(message)
})
@@ -181,11 +210,25 @@ export class CodeServerPage {
}
/**
* Navigate to code-server.
* The workspace directory code-server opens with.
*/
async navigate() {
const address = await this.codeServer.address()
await this.page.goto(address, { waitUntil: "networkidle" })
get workspaceDir() {
return this.codeServer.workspaceDir
}
/**
* Navigate to a code-server endpoint (root by default). Then wait for the
* editor to become available.
*/
async navigate(endpoint = "/") {
const to = new URL(endpoint, await this.codeServer.address())
await this.page.goto(to.toString(), { waitUntil: "networkidle" })
// Only reload editor if authenticated. Otherwise we'll get stuck
// reloading the login page.
if (this.authenticated) {
await this.reloadUntilEditorIsReady()
}
}
/**
@@ -270,6 +313,29 @@ export class CodeServerPage {
await this.page.waitForSelector("textarea.xterm-helper-textarea")
}
/**
* Open a file by using menus.
*/
async openFile(file: string) {
await this.navigateMenus(["File", "Open File"])
await this.navigateQuickInput([path.basename(file)])
await this.waitForTab(file)
}
/**
* Wait for a tab to open for the specified file.
*/
async waitForTab(file: string): Promise<void> {
return this.page.waitForSelector(`.tab :text("${path.basename(file)}")`)
}
/**
* See if the specified tab is open.
*/
async tabIsVisible(file: string): Promise<void> {
return this.page.isVisible(`.tab :text("${path.basename(file)}")`)
}
/**
* Navigate to the command palette via menus then execute a command by typing
* it then clicking the match from the results.
@@ -284,13 +350,45 @@ export class CodeServerPage {
}
/**
* Navigate through the specified set of menus. If it fails it will keep
* trying.
* Navigate through the items in the selector. `open` is a function that will
* open the menu/popup containing the items through which to navigation.
*/
async navigateMenus(menus: string[]) {
const navigate = async (cancelToken: CancelToken) => {
const steps: Array<() => Promise<unknown>> = [() => this.page.waitForSelector(`${menuSelector}:focus-within`)]
for (const menu of menus) {
async navigateItems(items: string[], selector: string, open?: (selector: string) => void): Promise<void> {
const logger = this.codeServer.logger.named(selector)
/**
* If the selector loses focus or gets removed this will resolve with false,
* signaling we need to try again.
*/
const openThenWaitClose = async (ctx: Context) => {
if (open) {
await open(selector)
}
this.codeServer.logger.debug(`watching ${selector}`)
try {
await this.page.waitForSelector(`${selector}:not(:focus-within)`)
} catch (error) {
if (!ctx.done()) {
this.codeServer.logger.debug(`${selector} navigation: ${error.message || error}`)
}
}
return false
}
/**
* This will step through each item, aborting and returning false if
* canceled or if any navigation step has an error which signals we need to
* try again.
*/
const navigate = async (ctx: Context) => {
const steps: Array<{ fn: () => Promise<unknown>; name: string }> = [
{
fn: () => this.page.waitForSelector(`${selector}:focus-within`),
name: "focus",
},
]
for (const item of items) {
// Normally these will wait for the item to be visible and then execute
// the action. The problem is that if the menu closes these will still
// be waiting and continue to execute once the menu is visible again,
@@ -298,56 +396,102 @@ export class CodeServerPage {
// if the old promise clicks logout before the new one can). By
// splitting them into two steps each we can cancel before running the
// action.
steps.push(() => this.page.hover(`text=${menu}`, { trial: true }))
steps.push(() => this.page.hover(`text=${menu}`, { force: true }))
steps.push(() => this.page.click(`text=${menu}`, { trial: true }))
steps.push(() => this.page.click(`text=${menu}`, { force: true }))
steps.push({
fn: () => this.page.hover(`${selector} :text("${item}")`, { trial: true }),
name: `${item}:hover:trial`,
})
steps.push({
fn: () => this.page.hover(`${selector} :text("${item}")`, { force: true }),
name: `${item}:hover:force`,
})
steps.push({
fn: () => this.page.click(`${selector} :text("${item}")`, { trial: true }),
name: `${item}:click:trial`,
})
steps.push({
fn: () => this.page.click(`${selector} :text("${item}")`, { force: true }),
name: `${item}:click:force`,
})
}
for (const step of steps) {
await step()
if (cancelToken.canceled()) {
this.codeServer.logger.debug("menu navigation canceled")
try {
logger.debug(`navigation step: ${step.name}`)
await step.fn()
if (ctx.canceled()) {
logger.debug("navigation canceled")
return false
}
} catch (error) {
logger.debug(`navigation: ${error.message || error}`)
return false
}
}
return true
}
const menuSelector = '[aria-label="Application Menu"]'
const open = async () => {
await this.page.click(menuSelector)
await this.page.waitForSelector(`${menuSelector}:not(:focus-within)`)
return false
// We are seeing the menu closing after opening if we open it too soon and
// the picker getting recreated in the middle of trying to select an item.
// To counter this we will keep trying to navigate through the items every
// time we lose focus or there is an error.
let attempts = 1
let context = new Context()
while (!(await Promise.race([openThenWaitClose(), navigate(context)]))) {
++attempts
logger.debug("closed, retrying (${attempt}/∞)")
context.cancel()
context = new Context()
}
// TODO: Starting in 1.57 something closes the menu after opening it if we
// open it too soon. To counter that we'll watch for when the menu loses
// focus and when/if it does we'll try again.
// I tried using the classic menu but it doesn't show up at all for some
// reason. I also tried toggle but the menu disappears after toggling.
let retryCount = 0
let cancelToken = new CancelToken()
while (!(await Promise.race([open(), navigate(cancelToken)]))) {
this.codeServer.logger.debug("menu was closed, retrying")
++retryCount
cancelToken.cancel()
cancelToken = new CancelToken()
}
this.codeServer.logger.debug(`menu navigation retries: ${retryCount}`)
context.finish()
logger.debug(`navigation took ${attempts} ${plural(attempts, "attempt")}`)
}
/**
* Navigates to code-server then reloads until the editor is ready.
*
* It is recommended to run setup before using this model in any tests.
* Navigate through a currently opened "quick input" widget, retrying on
* failure.
*/
async setup(authenticated: boolean) {
await this.navigate()
// If we aren't authenticated we'll see a login page so we can't wait until
// the editor is ready.
if (authenticated) {
await this.reloadUntilEditorIsReady()
}
async navigateQuickInput(items: string[]): Promise<void> {
await this.navigateItems(items, ".quick-input-widget")
}
/**
* Navigate through the menu, retrying on failure.
*/
async navigateMenus(menus: string[]): Promise<void> {
await this.navigateItems(menus, '[aria-label="Application Menu"]', async (selector) => {
await this.page.click(selector)
})
}
/**
* Execute a command in the root of the instance's workspace directory.
*/
async exec(command: string): Promise<void> {
await util.promisify(cp.exec)(command, {
cwd: await this.workspaceDir,
})
}
/**
* Install an extension by ID to the instance's temporary extension
* directory.
*/
async installExtension(id: string): Promise<void> {
const dir = path.join(await this.workspaceDir, "extensions")
await util.promisify(cp.exec)(`node . --install-extension ${id} --extensions-dir ${dir}`, {
cwd: path.join(__dirname, "../../.."),
})
}
/**
* Wait for state to be flushed to the database.
*/
async stateFlush(): Promise<void> {
// If we reload too quickly VS Code will be unable to save the state changes
// so wait until those have been written to the database. It flushes every
// five seconds so we need to wait at least that long.
// TODO@asher: There must be a better way.
await this.page.waitForTimeout(5500)
}
}

View File

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

View File

@@ -1,29 +1,19 @@
import * as cp from "child_process"
import * as fs from "fs"
import * as path from "path"
import util from "util"
import { tmpdir } from "../utils/helpers"
import { clean, tmpdir } from "../utils/helpers"
import { describe, expect, test } from "./baseFixture"
describe("Integrated Terminal", true, () => {
// Create a new context with the saved storage state
// so we don't have to logged in
const testFileName = "pipe"
const testString = "new string test from e2e test"
let tmpFolderPath = ""
let tmpFile = ""
describe("Integrated Terminal", true, [], {}, () => {
const testName = "integrated-terminal"
test.beforeAll(async () => {
tmpFolderPath = await tmpdir("integrated-terminal")
tmpFile = path.join(tmpFolderPath, testFileName)
await clean(testName)
})
test.afterAll(async () => {
// Ensure directory was removed
await fs.promises.rmdir(tmpFolderPath, { recursive: true })
})
test("should have access to VSCODE_PROXY_URI", async ({ codeServerPage }) => {
const tmpFolderPath = await tmpdir(testName)
const tmpFile = path.join(tmpFolderPath, "pipe")
test("should echo a string to a file", async ({ codeServerPage }) => {
const command = `mkfifo '${tmpFile}' && cat '${tmpFile}'`
const exec = util.promisify(cp.exec)
const output = exec(command, { encoding: "utf8" })
@@ -32,12 +22,12 @@ describe("Integrated Terminal", true, () => {
await codeServerPage.focusTerminal()
await codeServerPage.page.waitForLoadState("load")
await codeServerPage.page.keyboard.type(`echo ${testString} > ${tmpFile}`)
await codeServerPage.page.keyboard.type(`printenv VSCODE_PROXY_URI > ${tmpFile}`)
await codeServerPage.page.keyboard.press("Enter")
// It may take a second to process
await codeServerPage.page.waitForTimeout(1000)
const { stdout } = await output
expect(stdout).toMatch(testString)
expect(stdout).toMatch(await codeServerPage.address())
})
})

View File

@@ -2,6 +2,7 @@
"license": "MIT",
"#": "We must put jest in a sub-directory otherwise VS Code somehow picks up the types and generates conflicts with mocha.",
"devDependencies": {
"@jest-mock/express": "^1.4.5",
"@playwright/test": "^1.16.3",
"@types/jest": "^27.0.2",
"@types/jsdom": "^16.2.13",

View File

@@ -12,7 +12,7 @@ const config: PlaywrightTestConfig = {
testDir: path.join(__dirname, "e2e"), // Search for tests in this directory.
timeout: 60000, // Each test is given 60 seconds.
retries: process.env.CI ? 2 : 1, // Retry in CI due to flakiness.
globalSetup: require.resolve("./utils/globalSetup.ts"),
globalSetup: require.resolve("./utils/globalE2eSetup.ts"),
reporter: "list",
// Put any shared options on the top level.
use: {
@@ -25,12 +25,10 @@ const config: PlaywrightTestConfig = {
name: "Chromium",
use: { browserName: "chromium" },
},
{
name: "Firefox",
use: { browserName: "firefox" },
},
{
name: "WebKit",
use: { browserName: "webkit" },

View File

@@ -1,24 +1,16 @@
// Note: we need to import logger from the root
// because this is the logger used in logError in ../src/common/util
import { logger } from "@coder/logger"
import { Emitter } from "../../../src/common/emitter"
import { mockLogger } from "../../utils/helpers"
describe("emitter", () => {
let spy: jest.SpyInstance
beforeEach(() => {
spy = jest.spyOn(logger, "error")
mockLogger()
})
afterEach(() => {
jest.clearAllMocks()
})
afterAll(() => {
jest.restoreAllMocks()
})
it("should run the correct callbacks", async () => {
const HELLO_WORLD = "HELLO_WORLD"
const GOODBYE_WORLD = "GOODBYE_WORLD"
@@ -85,8 +77,8 @@ describe("emitter", () => {
await emitter.emit({ event: HELLO_WORLD, callback: mockCallback })
// Check that error was called
expect(spy).toHaveBeenCalled()
expect(spy).toHaveBeenCalledTimes(1)
expect(spy).toHaveBeenCalledWith(message)
expect(logger.error).toHaveBeenCalled()
expect(logger.error).toHaveBeenCalledTimes(1)
expect(logger.error).toHaveBeenCalledWith(message)
})
})

View File

@@ -1,6 +1,7 @@
import { logger } from "@coder/logger"
import { JSDOM } from "jsdom"
import * as util from "../../../src/common/util"
import { createLoggerMock } from "../../utils/helpers"
import { mockLogger } from "../../utils/helpers"
const dom = new JSDOM()
global.document = dom.window.document
@@ -94,31 +95,29 @@ describe("util", () => {
})
describe("logError", () => {
beforeAll(() => {
mockLogger()
})
afterEach(() => {
jest.clearAllMocks()
})
afterAll(() => {
jest.restoreAllMocks()
})
const loggerModule = createLoggerMock()
it("should log an error with the message and stack trace", () => {
const message = "You don't have access to that folder."
const error = new Error(message)
util.logError(loggerModule.logger, "ui", error)
util.logError(logger, "ui", error)
expect(loggerModule.logger.error).toHaveBeenCalled()
expect(loggerModule.logger.error).toHaveBeenCalledWith(`ui: ${error.message} ${error.stack}`)
expect(logger.error).toHaveBeenCalled()
expect(logger.error).toHaveBeenCalledWith(`ui: ${error.message} ${error.stack}`)
})
it("should log an error, even if not an instance of error", () => {
util.logError(loggerModule.logger, "api", "oh no")
util.logError(logger, "api", "oh no")
expect(loggerModule.logger.error).toHaveBeenCalled()
expect(loggerModule.logger.error).toHaveBeenCalledWith("api: oh no")
expect(logger.error).toHaveBeenCalled()
expect(logger.error).toHaveBeenCalledWith("api: oh no")
})
})
})

View File

@@ -1,12 +1,16 @@
import { promises as fs } from "fs"
import { getAvailablePort, tmpdir, useEnv } from "../../test/utils/helpers"
import { clean, getAvailablePort, tmpdir, useEnv } from "../../test/utils/helpers"
/**
* This file is for testing test helpers (not core code).
*/
describe("test helpers", () => {
const testName = "temp-dir"
beforeAll(async () => {
await clean(testName)
})
it("should return a temp directory", async () => {
const testName = "temp-dir"
const pathToTempDir = await tmpdir(testName)
expect(pathToTempDir).toContain(testName)
expect(fs.access(pathToTempDir)).resolves.toStrictEqual(undefined)

View File

@@ -1,3 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`handleServerError should log an error if resolved is true 1`] = `"Cannot read property 'handle' of undefined"`;

View File

@@ -1,27 +1,29 @@
import { logger } from "@coder/logger"
import { promises, rmdirSync } from "fs"
import { promises } from "fs"
import * as http from "http"
import * as https from "https"
import * as path from "path"
import { createApp, ensureAddress, handleArgsSocketCatchError, handleServerError } from "../../../src/node/app"
import { OptionalString, setDefaults } from "../../../src/node/cli"
import { generateCertificate } from "../../../src/node/util"
import { getAvailablePort, tmpdir } from "../../utils/helpers"
import { clean, mockLogger, getAvailablePort, tmpdir } from "../../utils/helpers"
describe("createApp", () => {
let spy: jest.SpyInstance
let unlinkSpy: jest.SpyInstance
let port: number
let tmpDirPath: string
let tmpFilePath: string
beforeAll(async () => {
tmpDirPath = await tmpdir("unlink-socket")
mockLogger()
const testName = "unlink-socket"
await clean(testName)
tmpDirPath = await tmpdir(testName)
tmpFilePath = path.join(tmpDirPath, "unlink-socket-file")
})
beforeEach(async () => {
spy = jest.spyOn(logger, "error")
// NOTE:@jsjoeio
// Be mindful when spying.
// You can't spy on fs functions if you do import * as fs
@@ -36,12 +38,6 @@ describe("createApp", () => {
jest.clearAllMocks()
})
afterAll(() => {
jest.restoreAllMocks()
// Ensure directory was removed
rmdirSync(tmpDirPath, { recursive: true })
})
it("should return an Express app, a WebSockets Express app and an http server", async () => {
const defaultArgs = await setDefaults({
port,
@@ -70,8 +66,8 @@ describe("createApp", () => {
// By emitting an error event
// Ref: https://stackoverflow.com/a/33872506/3015595
app.server.emit("error", testError)
expect(spy).toHaveBeenCalledTimes(1)
expect(spy).toHaveBeenCalledWith(`http server error: ${testError.message} ${testError.stack}`)
expect(logger.error).toHaveBeenCalledTimes(1)
expect(logger.error).toHaveBeenCalledWith(`http server error: ${testError.message} ${testError.stack}`)
// Cleanup
app.dispose()
@@ -111,6 +107,18 @@ describe("createApp", () => {
app.dispose()
})
it("should change the file mode of a socket", async () => {
const defaultArgs = await setDefaults({
socket: tmpFilePath,
"socket-mode": "777",
})
const app = await createApp(defaultArgs)
expect((await promises.stat(tmpFilePath)).mode & 0o777).toBe(0o777)
app.dispose()
})
it("should create an https server if args.cert exists", async () => {
const testCertificate = await generateCertificate("localhost")
const cert = new OptionalString(testCertificate.cert)
@@ -152,20 +160,14 @@ describe("ensureAddress", () => {
})
describe("handleServerError", () => {
let spy: jest.SpyInstance
beforeEach(() => {
spy = jest.spyOn(logger, "error")
beforeAll(() => {
mockLogger()
})
afterEach(() => {
jest.clearAllMocks()
})
afterAll(() => {
jest.restoreAllMocks()
})
it("should call reject if resolved is false", async () => {
const resolved = false
const reject = jest.fn((err: Error) => undefined)
@@ -184,33 +186,27 @@ describe("handleServerError", () => {
handleServerError(resolved, error, reject)
expect(spy).toHaveBeenCalledTimes(1)
expect(spy).toThrowErrorMatchingSnapshot()
expect(logger.error).toHaveBeenCalledTimes(1)
expect(logger.error).toHaveBeenCalledWith(`http server error: ${error.message} ${error.stack}`)
})
})
describe("handleArgsSocketCatchError", () => {
let spy: jest.SpyInstance
beforeEach(() => {
spy = jest.spyOn(logger, "error")
beforeAll(() => {
mockLogger()
})
afterEach(() => {
jest.clearAllMocks()
})
afterAll(() => {
jest.restoreAllMocks()
})
it("should log an error if its not an NodeJS.ErrnoException", () => {
const error = new Error()
handleArgsSocketCatchError(error)
expect(spy).toHaveBeenCalledTimes(1)
expect(spy).toHaveBeenCalledWith(error)
expect(logger.error).toHaveBeenCalledTimes(1)
expect(logger.error).toHaveBeenCalledWith(error)
})
it("should log an error if its not an NodeJS.ErrnoException (and the error has a message)", () => {
@@ -219,8 +215,8 @@ describe("handleArgsSocketCatchError", () => {
handleArgsSocketCatchError(error)
expect(spy).toHaveBeenCalledTimes(1)
expect(spy).toHaveBeenCalledWith(errorMessage)
expect(logger.error).toHaveBeenCalledTimes(1)
expect(logger.error).toHaveBeenCalledWith(errorMessage)
})
it("should not log an error if its a iNodeJS.ErrnoException", () => {
@@ -229,7 +225,7 @@ describe("handleArgsSocketCatchError", () => {
handleArgsSocketCatchError(error)
expect(spy).toHaveBeenCalledTimes(0)
expect(logger.error).toHaveBeenCalledTimes(0)
})
it("should log an error if the code is not ENOENT (and the error has a message)", () => {
@@ -240,8 +236,8 @@ describe("handleArgsSocketCatchError", () => {
handleArgsSocketCatchError(error)
expect(spy).toHaveBeenCalledTimes(1)
expect(spy).toHaveBeenCalledWith(errorMessage)
expect(logger.error).toHaveBeenCalledTimes(1)
expect(logger.error).toHaveBeenCalledWith(errorMessage)
})
it("should log an error if the code is not ENOENT", () => {
@@ -250,7 +246,7 @@ describe("handleArgsSocketCatchError", () => {
handleArgsSocketCatchError(error)
expect(spy).toHaveBeenCalledTimes(1)
expect(spy).toHaveBeenCalledWith(error)
expect(logger.error).toHaveBeenCalledTimes(1)
expect(logger.error).toHaveBeenCalledWith(error)
})
})

View File

@@ -63,6 +63,8 @@ describe("parser", () => {
"--verbose",
"2",
["--locale", "ja"],
["--log", "error"],
"--help",
@@ -71,6 +73,8 @@ describe("parser", () => {
"--socket=mumble",
"--socket-mode=777",
"3",
["--user-data-dir", "path/to/user/dir"],
@@ -103,10 +107,12 @@ describe("parser", () => {
help: true,
host: "0.0.0.0",
json: true,
locale: "ja",
log: "error",
open: true,
port: 8081,
socket: path.resolve("mumble"),
"socket-mode": "777",
verbose: true,
version: true,
"bind-addr": "192.169.0.1:8080",
@@ -266,7 +272,9 @@ describe("parser", () => {
})
it("should override with --link", async () => {
const args = parse("--cert test --cert-key test --socket test --host 0.0.0.0 --port 8888 --link test".split(" "))
const args = parse(
"--cert test --cert-key test --socket test --socket-mode 777 --host 0.0.0.0 --port 8888 --link test".split(" "),
)
const defaultArgs = await setDefaults(args)
expect(defaultArgs).toEqual({
...defaults,
@@ -279,6 +287,7 @@ describe("parser", () => {
cert: undefined,
"cert-key": path.resolve("test"),
socket: undefined,
"socket-mode": undefined,
})
})
@@ -310,6 +319,19 @@ describe("parser", () => {
})
})
it("should use env var github token", async () => {
process.env.GITHUB_TOKEN = "ga-foo"
const args = parse([])
expect(args).toEqual({})
const defaultArgs = await setDefaults(args)
expect(defaultArgs).toEqual({
...defaults,
"github-auth": "ga-foo",
})
expect(process.env.GITHUB_TOKEN).toBe(undefined)
})
it("should error if password passed in", () => {
expect(() => parse(["--password", "supersecret123"])).toThrowError(
"--password can only be set in the config file or passed in via $PASSWORD",
@@ -322,6 +344,12 @@ describe("parser", () => {
)
})
it("should error if github-auth passed in", () => {
expect(() => parse(["--github-auth", "fdas423fs8a"])).toThrowError(
"--github-auth can only be set in the config file or passed in via $GITHUB_TOKEN",
)
})
it("should filter proxy domains", async () => {
const args = parse(["--proxy-domain", "*.coder.com", "--proxy-domain", "coder.com", "--proxy-domain", "coder.org"])
expect(args).toEqual({
@@ -358,16 +386,32 @@ describe("parser", () => {
"$argon2i$v=19$m=4096,t=3,p=1$0qr/o+0t00hsbjfqcksfdq$ofcm4rl6o+b7oxpua4qlxubypbbpsf+8l531u7p9hyy",
})
})
it("should throw an error for invalid config values", async () => {
const fakePath = "/fake-config-path"
const expectedErrMsg = `error reading ${fakePath}: `
expect(() =>
parse(["--foo"], {
configFile: fakePath,
}),
).toThrowError(expectedErrMsg)
})
it("should ignore optional strings set to false", async () => {
expect(parse(["--cert=false"])).toEqual({})
})
it("should use last flag", async () => {
expect(parse(["--port", "8081", "--port", "8082"])).toEqual({
port: 8082,
})
})
})
describe("cli", () => {
let testDir: string
const testName = "cli"
const vscodeIpcPath = path.join(os.tmpdir(), "vscode-ipc")
beforeAll(async () => {
testDir = await tmpdir("cli")
await fs.rmdir(testDir, { recursive: true })
await fs.mkdir(testDir, { recursive: true })
await clean(testName)
})
beforeEach(async () => {
@@ -416,6 +460,7 @@ describe("cli", () => {
args._ = ["./file"]
expect(await shouldOpenInExistingInstance(args)).toStrictEqual(undefined)
const testDir = await tmpdir(testName)
const socketPath = path.join(testDir, "socket")
await fs.writeFile(vscodeIpcPath, socketPath)
expect(await shouldOpenInExistingInstance(args)).toStrictEqual(undefined)
@@ -635,14 +680,15 @@ describe("readSocketPath", () => {
let tmpDirPath: string
let tmpFilePath: string
beforeEach(async () => {
tmpDirPath = await tmpdir("readSocketPath")
tmpFilePath = path.join(tmpDirPath, "readSocketPath.txt")
await fs.writeFile(tmpFilePath, fileContents)
const testName = "readSocketPath"
beforeAll(async () => {
await clean(testName)
})
afterEach(async () => {
await fs.rmdir(tmpDirPath, { recursive: true })
beforeEach(async () => {
tmpDirPath = await tmpdir(testName)
tmpFilePath = path.join(tmpDirPath, "readSocketPath.txt")
await fs.writeFile(tmpFilePath, fileContents)
})
it("should throw an error if it can't read the file", async () => {
@@ -677,47 +723,23 @@ describe("toVsCodeArgs", () => {
version: false,
}
const testName = "vscode-args"
beforeAll(async () => {
// Clean up temporary directories from the previous run.
await clean("vscode-args")
await clean(testName)
})
it("should convert empty args", async () => {
expect(await toVsCodeArgs(await setDefaults(parse([])))).toStrictEqual({
...vscodeDefaults,
folder: "",
workspace: "",
})
})
it("should convert with workspace", async () => {
const workspace = path.join(await tmpdir("vscode-args"), "test.code-workspace")
await fs.writeFile(workspace, "foobar")
expect(await toVsCodeArgs(await setDefaults(parse([workspace])))).toStrictEqual({
...vscodeDefaults,
workspace,
folder: "",
_: [workspace],
})
})
it("should convert with folder", async () => {
const folder = await tmpdir("vscode-args")
expect(await toVsCodeArgs(await setDefaults(parse([folder])))).toStrictEqual({
...vscodeDefaults,
folder,
workspace: "",
_: [folder],
})
})
it("should ignore regular file", async () => {
const file = path.join(await tmpdir("vscode-args"), "file")
const file = path.join(await tmpdir(testName), "file")
await fs.writeFile(file, "foobar")
expect(await toVsCodeArgs(await setDefaults(parse([file])))).toStrictEqual({
...vscodeDefaults,
folder: "",
workspace: "",
_: [file],
})
})

View File

@@ -1,21 +1,28 @@
import { createLoggerMock } from "../../utils/helpers"
import { logger } from "@coder/logger"
import { mockLogger } from "../../utils/helpers"
import * as semver from "semver"
describe("constants", () => {
let constants: typeof import("../../../src/node/constants")
describe("with package.json defined", () => {
const loggerModule = createLoggerMock()
const mockPackageJson = {
name: "mock-code-server",
description: "Run VS Code on a remote server.",
repository: "https://github.com/cdr/code-server",
repository: "https://github.com/coder/code-server",
version: "1.0.0",
commit: "f6b2be2838f4afb217c2fd8f03eafedd8d55ef9b",
}
const mockCodePackageJson = {
name: "mock-code-oss-dev",
version: "1.2.3",
}
beforeAll(() => {
jest.mock("@coder/logger", () => loggerModule)
mockLogger()
jest.mock("../../../package.json", () => mockPackageJson, { virtual: true })
jest.mock("../../../vendor/modules/code-oss-dev/package.json", () => mockCodePackageJson, { virtual: true })
constants = require("../../../src/node/constants")
})
@@ -24,12 +31,48 @@ describe("constants", () => {
jest.resetModules()
})
it("should provide the package name", () => {
expect(constants.pkgName).toBe(mockPackageJson.name)
})
it("should provide the commit", () => {
expect(constants.commit).toBe(mockPackageJson.commit)
})
it("should return the package.json version", () => {
expect(constants.version).toBe(mockPackageJson.version)
// Ensure the version is parseable as semver and equal
const actual = semver.parse(constants.version)
const expected = semver.parse(mockPackageJson.version)
expect(actual).toBeTruthy()
expect(actual).toStrictEqual(expected)
})
it("should include embedded Code version information", () => {
expect(constants.codeVersion).toBe(mockCodePackageJson.version)
// Ensure the version is parseable as semver and equal
const actual = semver.parse(constants.codeVersion)
const expected = semver.parse(mockCodePackageJson.version)
expect(actual).toBeTruthy()
expect(actual).toStrictEqual(expected)
})
it("should return a human-readable version string", () => {
expect(constants.getVersionString()).toStrictEqual(
`${mockPackageJson.version} ${mockPackageJson.commit} with Code ${mockCodePackageJson.version}`,
)
})
it("should return a machine-readable version string", () => {
expect(constants.getVersionJsonString()).toStrictEqual(
JSON.stringify({
codeServer: mockPackageJson.version,
commit: mockPackageJson.commit,
vscode: mockCodePackageJson.version,
}),
)
})
describe("getPackageJson", () => {
@@ -38,8 +81,8 @@ describe("constants", () => {
constants.getPackageJson("./package.json")
expect(loggerModule.logger.warn).toHaveBeenCalled()
expect(loggerModule.logger.warn).toHaveBeenCalledWith(expectedErrorMessage)
expect(logger.warn).toHaveBeenCalled()
expect(logger.warn).toHaveBeenCalledWith(expectedErrorMessage)
})
it("should find the package.json", () => {
@@ -47,6 +90,9 @@ describe("constants", () => {
// so to get the root package.json we need to use ../../
const packageJson = constants.getPackageJson("../../package.json")
expect(packageJson).toStrictEqual(mockPackageJson)
const codePackageJson = constants.getPackageJson("../../vendor/modules/code-oss-dev/package.json")
expect(codePackageJson).toStrictEqual(mockCodePackageJson)
})
})
})
@@ -55,9 +101,13 @@ describe("constants", () => {
const mockPackageJson = {
name: "mock-code-server",
}
const mockCodePackageJson = {
name: "mock-code-oss-dev",
}
beforeAll(() => {
jest.mock("../../../package.json", () => mockPackageJson, { virtual: true })
jest.mock("../../../vendor/modules/code-oss-dev/package.json", () => mockCodePackageJson, { virtual: true })
constants = require("../../../src/node/constants")
})
@@ -69,8 +119,24 @@ describe("constants", () => {
it("version should return 'development'", () => {
expect(constants.version).toBe("development")
})
it("commit should return 'development'", () => {
expect(constants.commit).toBe("development")
})
it("should return a human-readable version string", () => {
// this string is not super useful
expect(constants.getVersionString()).toStrictEqual("development development with Code development")
})
it("should return a machine-readable version string", () => {
expect(constants.getVersionJsonString()).toStrictEqual(
JSON.stringify({
codeServer: "development",
commit: "development",
vscode: "development",
}),
)
})
})
})

View File

@@ -1,4 +1,5 @@
import { relativeRoot } from "../../../src/node/http"
import { getMockReq } from "@jest-mock/express"
import { constructRedirectPath, relativeRoot } from "../../../src/node/http"
describe("http", () => {
it("should construct a relative path to the root", () => {
@@ -9,3 +10,46 @@ describe("http", () => {
expect(relativeRoot("/foo/bar/")).toStrictEqual("./../..")
})
})
describe("constructRedirectPath", () => {
it("should preserve slashes in queryString so they are human-readable", () => {
const mockReq = getMockReq({
originalUrl: "localhost:8080",
})
const mockQueryParams = { folder: "/Users/jp/dev/coder" }
const mockTo = ""
const actual = constructRedirectPath(mockReq, mockQueryParams, mockTo)
const expected = "./?folder=/Users/jp/dev/coder"
expect(actual).toBe(expected)
})
it("should use an empty string if no query params", () => {
const mockReq = getMockReq({
originalUrl: "localhost:8080",
})
const mockQueryParams = {}
const mockTo = ""
const actual = constructRedirectPath(mockReq, mockQueryParams, mockTo)
const expected = "./"
expect(actual).toBe(expected)
})
it("should append the 'to' path relative to the originalUrl", () => {
const mockReq = getMockReq({
originalUrl: "localhost:8080",
})
const mockQueryParams = {}
const mockTo = "vscode"
const actual = constructRedirectPath(mockReq, mockQueryParams, mockTo)
const expected = "./vscode"
expect(actual).toBe(expected)
})
it("should append append queryParams after 'to' path", () => {
const mockReq = getMockReq({
originalUrl: "localhost:8080",
})
const mockQueryParams = { folder: "/Users/jp/dev/coder" }
const mockTo = "vscode"
const actual = constructRedirectPath(mockReq, mockQueryParams, mockTo)
const expected = "./vscode?folder=/Users/jp/dev/coder"
expect(actual).toBe(expected)
})
})

View File

@@ -69,7 +69,7 @@ describe("plugin", () => {
expect(body).toStrictEqual([
{
name: "Test App",
version: "4.0.0",
version: "4.0.1",
description: "This app does XYZ.",
iconPath: "/test-plugin/test-app/icon.svg",

View File

@@ -1,39 +0,0 @@
import { shouldEnableProxy } from "../../../src/node/proxy_agent"
import { useEnv } from "../../utils/helpers"
describe("shouldEnableProxy", () => {
const [setHTTPProxy, resetHTTPProxy] = useEnv("HTTP_PROXY")
const [setHTTPSProxy, resetHTTPSProxy] = useEnv("HTTPS_PROXY")
const [setNoProxy, resetNoProxy] = useEnv("NO_PROXY")
beforeEach(() => {
jest.resetModules() // Most important - it clears the cache
resetHTTPProxy()
resetNoProxy()
resetHTTPSProxy()
})
it("returns true when HTTP_PROXY is set", () => {
setHTTPProxy("http://proxy.example.com")
expect(shouldEnableProxy()).toBe(true)
})
it("returns true when HTTPS_PROXY is set", () => {
setHTTPSProxy("https://proxy.example.com")
expect(shouldEnableProxy()).toBe(true)
})
it("returns false when NO_PROXY is set", () => {
setNoProxy("*")
expect(shouldEnableProxy()).toBe(false)
})
it("should return false when neither HTTP_PROXY nor HTTPS_PROXY is set", () => {
expect(shouldEnableProxy()).toBe(false)
})
it("should return false when NO_PROXY is set to https://example.com", () => {
setNoProxy("https://example.com")
expect(shouldEnableProxy()).toBe(false)
})
it("should return false when NO_PROXY is set to http://example.com", () => {
setNoProxy("http://example.com")
expect(shouldEnableProxy()).toBe(false)
})
})

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