diff --git a/.github/semantic.yaml b/.github/semantic.yaml index 27a663ed5662..55d345cc2ac9 100644 --- a/.github/semantic.yaml +++ b/.github/semantic.yaml @@ -61,3 +61,6 @@ types: # 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 diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 6906cc145647..cb7a4e87e1a7 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -29,6 +29,9 @@ jobs: steps: - name: Checkout repo uses: actions/checkout@v3 + with: + fetch-depth: 0 + submodules: true - name: Install Node.js v14 uses: actions/setup-node@v3 @@ -38,21 +41,17 @@ jobs: - name: Install helm uses: azure/setup-helm@v1.1 - # NOTE@jsjoeio - # disabling this until we can audit the build process - # and the usefulness of this step - # See: https://github.com/coder/code-server/issues/4287 - # - name: Fetch dependencies from cache - # id: cache-yarn - # uses: actions/cache@v2 - # with: - # path: "**/node_modules" - # key: yarn-build-${{ hashFiles('**/yarn.lock') }} - # restore-keys: | - # yarn-build- + - name: Fetch dependencies from cache + id: cache-yarn + uses: actions/cache@v3 + with: + path: "**/node_modules" + key: yarn-build-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + yarn-build- - name: Install dependencies - # if: steps.cache-yarn.outputs.cache-hit != 'true' + if: steps.cache-yarn.outputs.cache-hit != 'true' run: yarn --frozen-lockfile - name: Run yarn fmt @@ -71,6 +70,9 @@ jobs: steps: - name: Checkout repo uses: actions/checkout@v3 + with: + fetch-depth: 0 + submodules: true - name: Install Node.js v14 uses: actions/setup-node@v3 @@ -79,7 +81,7 @@ jobs: - name: Fetch dependencies from cache id: cache-yarn - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: "**/node_modules" key: yarn-build-${{ hashFiles('**/yarn.lock') }} @@ -102,56 +104,53 @@ jobs: env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} steps: - - uses: actions/checkout@v3 + - name: Checkout repo + uses: actions/checkout@v3 with: fetch-depth: 0 + submodules: true + + - name: Install quilt + run: sudo apt update && sudo apt install quilt + + - name: Patch Code + run: quilt push -a - name: Install Node.js v14 uses: actions/setup-node@v3 with: node-version: "14" - # TODO@Teffen investigate why this omits code-oss-dev/node_modules - # - name: Fetch dependencies from cache - # id: cache-yarn - # uses: actions/cache@v2 - # with: - # path: | - # "**/node_modules" - # "**/vendor/modules" - # "**/vendor/modules/code-oss-dev/node_modules" - # key: yarn-build-${{ hashFiles('**/yarn.lock') }}-${{ hashFiles('**/vendor/yarn.lock') }} - # restore-keys: | - # yarn-build- + - name: Fetch dependencies from cache + id: cache-yarn + uses: actions/cache@v3 + with: + path: "**/node_modules" + key: yarn-build-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + yarn-build- - name: Install dependencies - # if: steps.cache-yarn.outputs.cache-hit != 'true' + if: steps.cache-yarn.outputs.cache-hit != 'true' run: yarn --frozen-lockfile - name: Build code-server run: yarn build - # Parse the hash of the latest commit inside vendor/modules/code-oss-dev - # use this to avoid rebuilding it if nothing changed - # How it works: the `git log` command fetches the hash of the last commit - # that changed a file inside `vendor/modules/code-oss-dev`. If a commit changes any file in there, - # the hash returned will change, and we rebuild vscode. If the hash did not change, - # (for example, a change to `src/` or `docs/`), we reuse the same build as last time. - # This saves a lot of time in CI, as compiling VSCode can take anywhere from 5-10 minutes. - - name: Get latest vendor/modules/code-oss-dev rev + # Get Code's git hash. When this changes it means the content is + # different and we need to rebuild. + - name: Get latest lib/vscode rev id: vscode-rev - run: echo "::set-output name=rev::$(jq -r '.devDependencies["code-oss-dev"]' vendor/package.json | sed -r 's|.*#(.*)$|\1|')" + run: echo "::set-output name=rev::$(git rev-parse HEAD:./lib/vscode)" - - name: Attempt to fetch vscode build from cache + # We need to rebuild when we have a new version of Code or when any of + # the patches changed. Use VSCODE_CACHE_VERSION to force a rebuild. + - name: Fetch prebuilt Code package from cache id: cache-vscode - uses: actions/cache@v2 + uses: actions/cache@v3 with: - path: | - vendor/modules/code-oss-dev/.build - vendor/modules/code-oss-dev/out-build - vendor/modules/code-oss-dev/out-vscode-reh-web - vendor/modules/code-oss-dev/out-vscode-reh-web-min - key: vscode-reh-build-${{ steps.vscode-rev.outputs.rev }} + path: lib/vscode-reh-web-* + key: vscode-reh-package-${{ secrets.VSCODE_CACHE_VERSION }}-${{ steps.vscode-rev.outputs.rev }}-${{ hashFiles('patches/*.diff') }} - name: Build vscode if: steps.cache-vscode.outputs.cache-hit != 'true' @@ -179,7 +178,7 @@ jobs: run: tar -czf package.tar.gz release - name: Upload npm package artifact - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: npm-package path: ./package.tar.gz @@ -196,9 +195,13 @@ jobs: if: github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - name: Checkout repo + uses: actions/checkout@v3 + with: + fetch-depth: 0 - - uses: actions/download-artifact@v3 + - name: Download artifact + uses: actions/download-artifact@v3 id: download with: name: "npm-package" @@ -225,7 +228,10 @@ jobs: container: "centos:7" steps: - - uses: actions/checkout@v3 + - name: Checkout repo + uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Install Node.js v14 uses: actions/setup-node@v3 @@ -268,7 +274,7 @@ jobs: run: yarn package - name: Upload release artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: release-packages path: ./release-packages @@ -314,7 +320,10 @@ jobs: NODE_VERSION: v14.17.4 steps: - - uses: actions/checkout@v3 + - name: Checkout repo + uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Install Node.js v14 uses: actions/setup-node@v3 @@ -352,7 +361,7 @@ jobs: run: yarn package ${NPM_CONFIG_ARCH} - name: Upload release artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: release-packages path: ./release-packages @@ -363,7 +372,10 @@ jobs: runs-on: macos-latest timeout-minutes: 15 steps: - - uses: actions/checkout@v3 + - name: Checkout repo + uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Install Node.js v14 uses: actions/setup-node@v3 @@ -393,7 +405,7 @@ jobs: run: yarn package - name: Upload release artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: release-packages path: ./release-packages @@ -408,7 +420,11 @@ 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@v3 + - name: Checkout repo + uses: actions/checkout@v3 + with: + fetch-depth: 0 + submodules: true - name: Install Node.js v14 uses: actions/setup-node@v3 @@ -417,7 +433,7 @@ jobs: - name: Fetch dependencies from cache id: cache-yarn - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: "**/node_modules" key: yarn-build-${{ hashFiles('**/yarn.lock') }} @@ -450,7 +466,7 @@ jobs: - name: Upload test artifacts if: always() - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: failed-test-videos path: ./test/test-results @@ -461,10 +477,12 @@ jobs: trivy-scan-repo: runs-on: ubuntu-20.04 steps: - - name: Checkout code + - name: Checkout repo uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Run Trivy vulnerability scanner in repo mode - #Commit SHA for v0.0.17 uses: aquasecurity/trivy-action@296212627a1e693efa09c00adc3e03b2ba8edf18 with: scan-type: "fs" @@ -474,6 +492,7 @@ jobs: template: "@/contrib/sarif.tpl" output: "trivy-repo-results.sarif" severity: "HIGH,CRITICAL" + - name: Upload Trivy scan results to GitHub Security tab uses: github/codeql-action/upload-sarif@v1 with: diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 7cc0c1e27e11..d622e2c73fae 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -35,6 +35,19 @@ jobs: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} + - name: Get version + id: version + run: echo "::set-output name=version::$(jq .version package.json)" + + - name: Download artifact + uses: dawidd6/action-download-artifact@v2 + id: download + with: + branch: v${{ steps.version.outputs.version }} + workflow_conclusion: completed + name: "release-packages" + path: release-packages + - name: Run ./ci/steps/docker-buildx-push.sh run: ./ci/steps/docker-buildx-push.sh env: diff --git a/.github/workflows/docs-preview.yaml b/.github/workflows/docs-preview.yaml index df149117578d..42021b5400ae 100644 --- a/.github/workflows/docs-preview.yaml +++ b/.github/workflows/docs-preview.yaml @@ -17,89 +17,24 @@ 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@v3 - with: - repository: coder/m - ref: refs/heads/master - ssh-key: ${{ secrets.READONLY_M_DEPLOY_KEY }} - submodules: true - fetch-depth: 0 - - - name: Install Node.js - uses: actions/setup-node@v3 - with: - node-version: 14 - - - name: Cache Node Modules - uses: actions/cache@v2 - with: - path: "/node_modules" - key: node-${{ hashFiles('yarn.lock') }} - - - name: Create Deployment - id: deployment - run: ./ci/scripts/github_deployment.sh create - env: - GITHUB_TOKEN: ${{ github.token }} - DEPLOY_ENVIRONMENT: codercom-preview-docs - - - name: Deploy Preview to Vercel - id: preview - run: ./ci/scripts/deploy_vercel.sh - env: - VERCEL_ORG_ID: team_tGkWfhEGGelkkqUUm9nXq17r - VERCEL_PROJECT_ID: QmZRucMRh3GFk1817ZgXjRVuw5fhTspHPHKct3JNQDEPGd - VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} - CODE_SERVER_DOCS_MAIN_BRANCH: ${{ github.event.pull_request.head.sha }} + - uses: actions/checkout@v3 - - name: Install node_modules - run: yarn install - - - name: Check docs - run: yarn ts-node ./product/coder.com/site/scripts/checkDocs.ts - env: - BASE_URL: ${{ steps.preview.outputs.url }} - - - name: Update Deployment - # If we don't specify always, it won't run this check if failed. - # This means the deployment would be stuck pending. - if: always() - run: ./ci/scripts/github_deployment.sh update - env: - GITHUB_DEPLOYMENT: ${{ steps.deployment.outputs.id }} - GITHUB_TOKEN: ${{ github.token }} - DEPLOY_STATUS: ${{ steps.preview.outcome }} - DEPLOY_URL: ${{ steps.preview.outputs.url }} + - name: Set outputs + id: vars + run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" - name: Comment Credentials uses: marocchino/sticky-pull-request-comment@v2 - if: always() with: header: codercom-preview-docs message: | - ✨ Coder.com for PR #${{ github.event.number }} deployed! It will be updated on every commit. - - * _Host_: ${{ steps.preview.outputs.url }}/docs/code-server - * _Last deploy status_: ${{ steps.preview.outcome }} + ✨ code-server docs for PR #${{ github.event.number }} is ready! It will be updated on every commit. + * _Host_: https://coder.com/docs/code-server/${{ steps.vars.outputs.sha_short }} + * _Last deploy status_: success * _Commit_: ${{ github.event.pull_request.head.sha }} * _Workflow status_: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} diff --git a/.github/workflows/npm-brew.yaml b/.github/workflows/npm-brew.yaml index 8c8b84fe2c38..60b3208b5ff3 100644 --- a/.github/workflows/npm-brew.yaml +++ b/.github/workflows/npm-brew.yaml @@ -23,9 +23,16 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: actions/download-artifact@v3 + - name: Get version + id: version + run: echo "::set-output name=version::$(jq .version package.json)" + + - name: Download artifact + uses: dawidd6/action-download-artifact@v2 id: download with: + branch: v${{ steps.version.outputs.version }} + workflow_conclusion: completed name: "npm-package" path: release-npm-package @@ -49,11 +56,20 @@ jobs: id: set-up-homebrew uses: Homebrew/actions/setup-homebrew@master - - uses: actions/checkout@v3 + - name: Checkout code-server + uses: actions/checkout@v3 + + - name: Checkout cdrci/homebrew-core + uses: actions/checkout@v3 + with: + repository: cdrci/homebrew-core + path: homebrew-core + - name: Configure git run: | git config user.name github-actions git config user.email github-actions@github.com + - name: Bump code-server homebrew version env: HOMEBREW_GITHUB_API_TOKEN: ${{secrets.HOMEBREW_GITHUB_API_TOKEN}} diff --git a/.github/workflows/trivy-docker.yaml b/.github/workflows/trivy-docker.yaml new file mode 100644 index 000000000000..827a9905ab2f --- /dev/null +++ b/.github/workflows/trivy-docker.yaml @@ -0,0 +1,65 @@ +name: Trivy Nightly Docker Scan + +on: + # Run scans if the workflow is modified, in order to test the + # workflow itself. This results in some spurious notifications, + # but seems okay for testing. + pull_request: + branches: + - main + paths: + - .github/workflows/trivy-docker.yaml + + # Run scans against master whenever changes are merged. + push: + branches: + - main + paths: + - .github/workflows/trivy-docker.yaml + + schedule: + # Run at 10:15 am UTC (3:15am PT/5:15am CT) + # Run at 0 minutes 0 hours of every day. + - cron: "15 10 * * *" + + workflow_dispatch: + +permissions: + actions: none + checks: none + contents: read + deployments: none + issues: none + packages: none + pull-requests: none + repository-projects: none + security-events: write + 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 }} + +jobs: + trivy-scan-image: + runs-on: ubuntu-20.04 + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Run Trivy vulnerability scanner in image mode + uses: aquasecurity/trivy-action@296212627a1e693efa09c00adc3e03b2ba8edf18 + with: + image-ref: "docker.io/codercom/code-server:latest" + ignore-unfixed: true + format: "sarif" + output: "trivy-image-results.sarif" + severity: "HIGH,CRITICAL" + + - name: Upload Trivy scan results to GitHub Security tab + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: "trivy-image-results.sarif" diff --git a/.gitignore b/.gitignore index 3cc6e31d7af3..e615ec464617 100644 --- a/.gitignore +++ b/.gitignore @@ -8,12 +8,17 @@ release-packages/ release-gcp/ release-images/ node_modules -vendor/modules -node-* /plugins /lib/coder-cloud-agent .home coverage **/.DS_Store + +# Code packages itself here. +/lib/vscode-reh-web-* + # Failed e2e test videos are saved here test/test-results + +# Quilt's internal data. +/.pc diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000000..9854a1b1dd30 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/vscode"] + path = lib/vscode + url = https://github.com/microsoft/vscode diff --git a/.prettierrc.yaml b/.prettierrc.yaml index bf4b4a7d239b..a58621d69ead 100644 --- a/.prettierrc.yaml +++ b/.prettierrc.yaml @@ -7,7 +7,7 @@ useTabs: false overrides: # Attempt to keep VScode's existing code style intact. - - files: "vendor/modules/code-oss-dev/**/*.ts" + - files: "lib/vscode/**/*.ts" options: # No limit defined upstream. printWidth: 10000 diff --git a/.tours/contributing.tour b/.tours/contributing.tour index 95799b6abb7e..970543343632 100644 --- a/.tours/contributing.tour +++ b/.tours/contributing.tour @@ -143,7 +143,7 @@ "description": "Static images and the manifest live here in `src/browser/media` (see the explorer)." }, { - "directory": "vendor/modules/code-oss-dev", + "directory": "lib/vscode", "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/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." } diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c4d25b71382..4b6b5f4ca65e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,17 +20,77 @@ VS Code v99.99.999 --> -## [Unreleased](https://github.com/coder/code-server/releases) +## [4.2.0](https://github.com/coder/code-server/releases/tag/v4.2.0) - 2022-03-22 -VS Code v0.00.0 +Code v1.64.2 + +### Added + +- Added tests for `handleArgsSocketCatchError`, `setDefaults` and + `optionDescriptions`. + +### Changed + +- We switched from using the fork `coder/vscode` to a submodule of + `microsoft/vscode` + patches managed by `quilt` for how Code sits inside the + code-server codebase. +- Upgraded to Code 1.64.2. + +### Fixed + +- Update popup notification through `--disable-update-check` is now fixed. +- Fixed PWA icons not loading on iPad +- Fixed the homebrew release process. Our `cdrci` bot should now automatically + update the version as part of the release pipeline. +- Fixed titleBar color setting being ignored in PWA. + +### Security + +- Updated to `minimist-list`. +- Updated `cloud-agent` to `v0.2.4` which uses `nhooyr.io/webscoket` `v1.8.7`. + +## [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 -- Add here +- 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 -VS Code v1.63.0 +Code v1.63.0 ### Fixed @@ -41,7 +101,7 @@ VS Code v1.63.0 ## [4.0.1](https://github.com/coder/code-server/releases/tag/v4.0.1) - 2022-01-04 -VS Code v1.63.0 +Code v1.63.0 code-server has been rebased on upstream's newly open-sourced server implementation (#4414). @@ -57,7 +117,7 @@ implementation (#4414). 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 VS Code's `product.json`. + corresponds to `extensionsGallery` in Code's `product.json`. ### Added @@ -79,11 +139,11 @@ implementation (#4414). ## [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 @@ -99,7 +159,7 @@ Undocumented (see releases page). ## [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 @@ -115,7 +175,7 @@ VS Code v1.56.1 ## [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 @@ -129,13 +189,13 @@ VS Code v1.56.1 ## [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 diff --git a/ci/build/build-packages.sh b/ci/build/build-packages.sh index 8da6aec38332..6c85ccd33cde 100755 --- a/ci/build/build-packages.sh +++ b/ci/build/build-packages.sh @@ -50,6 +50,11 @@ release_nfpm() { export NFPM_ARCH + # Code deletes some files from the extension node_modules directory which + # leaves broken symlinks in the corresponding .bin directory. nfpm will fail + # on these broken symlinks so clean them up. + rm -fr "./release-standalone/lib/vscode/extensions/node_modules/.bin" + PKG_FORMAT="deb" NFPM_ARCH="$(get_nfpm_arch $PKG_FORMAT "$ARCH")" nfpm_config="$(envsubst < ./ci/build/nfpm.yaml)" diff --git a/ci/build/build-release.sh b/ci/build/build-release.sh index 7f152e1701f9..88dc26febb63 100755 --- a/ci/build/build-release.sh +++ b/ci/build/build-release.sh @@ -15,8 +15,8 @@ main() { source ./ci/lib.sh - VSCODE_SRC_PATH="vendor/modules/code-oss-dev" - VSCODE_OUT_PATH="$RELEASE_PATH/vendor/modules/code-oss-dev" + VSCODE_SRC_PATH="lib/vscode" + VSCODE_OUT_PATH="$RELEASE_PATH/lib/vscode" mkdir -p "$RELEASE_PATH" @@ -25,7 +25,7 @@ main() { rsync ./docs/README.md "$RELEASE_PATH" rsync LICENSE.txt "$RELEASE_PATH" - rsync ./vendor/modules/code-oss-dev/ThirdPartyNotices.txt "$RELEASE_PATH" + rsync ./lib/vscode/ThirdPartyNotices.txt "$RELEASE_PATH" } bundle_code_server() { @@ -66,31 +66,10 @@ EOF bundle_vscode() { mkdir -p "$VSCODE_OUT_PATH" - rsync "$VSCODE_SRC_PATH/yarn.lock" "$VSCODE_OUT_PATH" - rsync "$VSCODE_SRC_PATH/out-vscode-reh-web${MINIFY:+-min}/" "$VSCODE_OUT_PATH/out" + rsync ./lib/vscode-reh-web-*/ "$VSCODE_OUT_PATH" - rsync "$VSCODE_SRC_PATH/.build/extensions/" "$VSCODE_OUT_PATH/extensions" - if [ "$KEEP_MODULES" = 0 ]; then - rm -Rf "$VSCODE_OUT_PATH/extensions/node_modules" - else - rsync "$VSCODE_SRC_PATH/node_modules/" "$VSCODE_OUT_PATH/node_modules" - fi - rsync "$VSCODE_SRC_PATH/extensions/package.json" "$VSCODE_OUT_PATH/extensions" - rsync "$VSCODE_SRC_PATH/extensions/yarn.lock" "$VSCODE_OUT_PATH/extensions" - rsync "$VSCODE_SRC_PATH/extensions/postinstall.js" "$VSCODE_OUT_PATH/extensions" - - 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. + # Add the commit, date, our name, links, 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" <( cat << EOF { @@ -98,15 +77,48 @@ bundle_vscode() { "commit": "$(cd "$VSCODE_SRC_PATH" && git rev-parse HEAD)", "quality": "stable", "date": $(jq -n 'now | todate'), - "codeServerVersion": "$VERSION" + "codeServerVersion": "$VERSION", + "nameShort": "code-server", + "nameLong": "code-server", + "applicationName": "code-server", + "dataFolderName": ".code-server", + "win32MutexName": "codeserver", + "licenseUrl": "https://github.com/coder/code-server/blob/main/LICENSE.txt", + "win32DirName": "code-server", + "win32NameVersion": "code-server", + "win32AppUserModelId": "coder.code-server", + "win32ShellNameShort": "c&ode-server", + "darwinBundleIdentifier": "com.coder.code.server", + "linuxIconName": "com.coder.code.server", + "reportIssueUrl": "https://github.com/coder/code-server/issues/new", + "documentationUrl": "https://go.microsoft.com/fwlink/?LinkID=533484#vscode", + "keyboardShortcutsUrlMac": "https://go.microsoft.com/fwlink/?linkid=832143", + "keyboardShortcutsUrlLinux": "https://go.microsoft.com/fwlink/?linkid=832144", + "keyboardShortcutsUrlWin": "https://go.microsoft.com/fwlink/?linkid=832145", + "introductoryVideosUrl": "https://go.microsoft.com/fwlink/?linkid=832146", + "tipsAndTricksUrl": "https://go.microsoft.com/fwlink/?linkid=852118", + "newsletterSignupUrl": "https://www.research.net/r/vsc-newsletter", + "linkProtectionTrustedDomains": [ + "https://open-vsx.org" + ] } EOF ) > "$VSCODE_OUT_PATH/product.json" - # We remove the scripts field so that later on we can run - # yarn to fetch node_modules if necessary without build scripts running. - # We cannot use --no-scripts because we still want dependent package scripts to run. - jq 'del(.scripts)' < "$VSCODE_SRC_PATH/package.json" > "$VSCODE_OUT_PATH/package.json" + # Use the package.json for the web/remote server. It does not have the right + # version though so pull that from the main package.json. Also remove keytar + # since the web does not rely on it and that removes the dependency on + # libsecret. + jq --slurp '.[0] * {version: .[1].version} | del(.dependencies.keytar)' \ + "$VSCODE_SRC_PATH/remote/package.json" \ + "$VSCODE_SRC_PATH/package.json" > "$VSCODE_OUT_PATH/package.json" + + rsync "$VSCODE_SRC_PATH/remote/yarn.lock" "$VSCODE_OUT_PATH/yarn.lock" + + if [ "$KEEP_MODULES" = 0 ]; then + rm -Rf "$VSCODE_OUT_PATH/extensions/node_modules" + rm -Rf "$VSCODE_OUT_PATH/node_modules" + fi pushd "$VSCODE_OUT_PATH" symlink_asar diff --git a/ci/build/build-standalone-release.sh b/ci/build/build-standalone-release.sh index 481110b47b39..2bc553a619ce 100755 --- a/ci/build/build-standalone-release.sh +++ b/ci/build/build-standalone-release.sh @@ -29,12 +29,6 @@ main() { cd "$RELEASE_PATH" yarn --production --frozen-lockfile - - # HACK: the version of Typescript vscode 1.57 uses in extensions/ - # leaves a few stray symlinks. Clean them up so nfpm does not fail. - # Remove this line when its no longer needed. - - rm -fr "$RELEASE_PATH/vendor/modules/code-oss-dev/extensions/node_modules/.bin" } main "$@" diff --git a/ci/build/build-vscode.sh b/ci/build/build-vscode.sh index be996fceef56..bb3225a2b517 100755 --- a/ci/build/build-vscode.sh +++ b/ci/build/build-vscode.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -euo pipefail -# Builds vscode into vendor/modules/code-oss-dev/out-vscode. +# Builds vscode into lib/vscode/out-vscode. # MINIFY controls whether a minified version of vscode is built. MINIFY=${MINIFY-true} @@ -9,7 +9,7 @@ MINIFY=${MINIFY-true} main() { cd "$(dirname "${0}")/../.." - cd vendor/modules/code-oss-dev + cd lib/vscode # Any platform works since we have our own packaging step (for now). yarn gulp "vscode-reh-web-linux-x64${MINIFY:+-min}" diff --git a/ci/build/npm-postinstall.sh b/ci/build/npm-postinstall.sh index 43c3262ec341..123b56dfbb48 100755 --- a/ci/build/npm-postinstall.sh +++ b/ci/build/npm-postinstall.sh @@ -90,8 +90,8 @@ symlink_asar() { } vscode_yarn() { - echo 'Installing vendor dependencies...' - cd vendor/modules/code-oss-dev + echo 'Installing Code dependencies...' + cd lib/vscode yarn --production --frozen-lockfile symlink_asar diff --git a/ci/build/release-github-assets.sh b/ci/build/release-github-assets.sh index 29f27566816a..6395adcb7eec 100755 --- a/ci/build/release-github-assets.sh +++ b/ci/build/release-github-assets.sh @@ -9,6 +9,15 @@ set -euo pipefail main() { cd "$(dirname "$0")/../.." source ./ci/lib.sh + source ./ci/steps/steps-lib.sh + + # 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-packages without GitHub credentials." + exit 1 + fi download_artifact release-packages ./release-packages local assets=(./release-packages/code-server*"$VERSION"*{.tar.gz,.deb,.rpm}) diff --git a/ci/dev/fmt.sh b/ci/dev/fmt.sh index d5d7ffeed9c7..447186212d2f 100755 --- a/ci/dev/fmt.sh +++ b/ci/dev/fmt.sh @@ -19,7 +19,7 @@ main() { "*.sh" ) prettier --write --loglevel=warn $( - git ls-files "${prettierExts[@]}" | grep -v "lib/vscode" | grep -v "vendor/modules/code-oss-dev" | grep -v 'helm-chart' + git ls-files "${prettierExts[@]}" | grep -v "lib/vscode" | grep -v 'helm-chart' ) doctoc --title '# FAQ' docs/FAQ.md > /dev/null diff --git a/ci/dev/lint.sh b/ci/dev/lint.sh index 34b2e8f78fd9..58a999c4f2f0 100755 --- a/ci/dev/lint.sh +++ b/ci/dev/lint.sh @@ -4,10 +4,10 @@ set -euo pipefail main() { cd "$(dirname "$0")/../.." - eslint --max-warnings=0 --fix $(git ls-files "*.ts" "*.tsx" "*.js" | grep -v "vendor/modules/code-oss-dev" | grep -v "lib/vscode") - stylelint $(git ls-files "*.css" | grep -v "vendor/modules/code-oss-dev" | grep -v "lib/vscode") + eslint --max-warnings=0 --fix $(git ls-files "*.ts" "*.tsx" "*.js" | grep -v "lib/vscode") + stylelint $(git ls-files "*.css" | grep -v "lib/vscode") tsc --noEmit --skipLibCheck - shellcheck -e SC2046,SC2164,SC2154,SC1091,SC1090,SC2002 $(git ls-files "*.sh" | grep -v "vendor/modules/code-oss-dev" | grep -v "lib/vscode") + shellcheck -e SC2046,SC2164,SC2154,SC1091,SC1090,SC2002 $(git ls-files "*.sh" | grep -v "lib/vscode") if command -v helm && helm kubeval --help > /dev/null; then helm kubeval ci/helm-chart fi diff --git a/ci/dev/postinstall.sh b/ci/dev/postinstall.sh index 78f26cc631bd..170cdb46fd66 100755 --- a/ci/dev/postinstall.sh +++ b/ci/dev/postinstall.sh @@ -1,50 +1,32 @@ #!/usr/bin/env bash set -euo pipefail -main() { - cd "$(dirname "$0")/../.." - source ./ci/lib.sh - - pushd test - echo "Installing dependencies for $PWD" - yarn install - popd - +# Install dependencies in $1. +install-deps() { local args=(install) if [[ ${CI-} ]]; then args+=(--frozen-lockfile) fi - - pushd test - echo "Installing dependencies for $PWD" - yarn "${args[@]}" - popd - - pushd test/e2e/extensions/test-extension + # If there is no package.json then yarn will look upward and end up installing + # from the root resulting in an infinite loop (this can happen if you have not + # checked out the submodule yet for example). + if [[ ! -f "$1/package.json" ]]; then + echo "$1/package.json is missing; did you run git submodule update --init?" + exit 1 + fi + pushd "$1" 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 - # node_modules and itself being in a directory with the same name. - args+=(--modules-folder modules) - - # We ignore scripts because NPM/Yarn's default behavior is to assume that - # devDependencies are not needed, and that even git repo based packages are - # assumed to be compiled. Because the default behavior for VS Code's - # `postinstall` assumes we're also compiled, this needs to be ignored. - args+=(--ignore-scripts) - - yarn "${args[@]}" - - # Finally, run the vendor `postinstall` - yarn run postinstall +main() { + cd "$(dirname "$0")/../.." + source ./ci/lib.sh - popd + install-deps test + install-deps test/e2e/extensions/test-extension + install-deps lib/vscode } main "$@" diff --git a/ci/dev/test-e2e.sh b/ci/dev/test-e2e.sh index cf3e53d118e9..00724ac2b5f2 100755 --- a/ci/dev/test-e2e.sh +++ b/ci/dev/test-e2e.sh @@ -37,7 +37,7 @@ main() { exit 1 fi - if [[ ! -d $dir/vendor/modules/code-oss-dev/out ]]; then + if [[ ! -d $dir/lib/vscode/out ]]; then echo >&2 "No VS Code build detected" help exit 1 diff --git a/ci/dev/test-unit.sh b/ci/dev/test-unit.sh index 3578d87e647d..f2dbf41b5159 100755 --- a/ci/dev/test-unit.sh +++ b/ci/dev/test-unit.sh @@ -14,11 +14,17 @@ main() { # Our code imports from `out` in order to work during development but if you # have only built for production you will have not have this directory. In # that case symlink `out` to a production build directory. - local vscode="vendor/modules/code-oss-dev" - local link="$vscode/out" - local target="out-build" - if [[ ! -e $link ]] && [[ -d $vscode/$target ]]; then - ln -s "$target" "$link" + if [[ ! -e lib/vscode/out ]]; then + pushd lib + local out=(vscode-reh-web-*) + if [[ -d "${out[0]}" ]]; then + ln -s "../${out[0]}/out" ./vscode/out + else + echo "Could not find lib/vscode/out or lib/vscode-reh-web-*" + echo "Code must be built before running unit tests" + exit 1 + fi + popd fi # We must keep jest in a sub-directory. See ../../test/package.json for more diff --git a/ci/dev/watch.ts b/ci/dev/watch.ts index 55a5b14d1f4c..66480b29e7e5 100644 --- a/ci/dev/watch.ts +++ b/ci/dev/watch.ts @@ -14,7 +14,7 @@ class Watcher { private rootPath = path.resolve(process.cwd()) private readonly paths = { /** Path to uncompiled VS Code source. */ - vscodeDir: path.join(this.rootPath, "vendor", "modules", "code-oss-dev"), + vscodeDir: path.join(this.rootPath, "lib/vscode"), pluginDir: process.env.PLUGIN_DIR, } diff --git a/ci/helm-chart/Chart.yaml b/ci/helm-chart/Chart.yaml index c68fb2b20c4e..5b525226360f 100644 --- a/ci/helm-chart/Chart.yaml +++ b/ci/helm-chart/Chart.yaml @@ -15,9 +15,9 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 2.1.0 +version: 2.3.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.2 +appVersion: 4.2.0 diff --git a/ci/helm-chart/values.yaml b/ci/helm-chart/values.yaml index f37771999fe2..a0c2f134f2d7 100644 --- a/ci/helm-chart/values.yaml +++ b/ci/helm-chart/values.yaml @@ -6,7 +6,7 @@ replicaCount: 1 image: repository: codercom/code-server - tag: '4.0.2' + tag: '4.2.0' pullPolicy: Always # Specifies one or more secrets to be used when pulling images from a diff --git a/ci/lib.sh b/ci/lib.sh index 0e357986153f..c7b5a420aca6 100755 --- a/ci/lib.sh +++ b/ci/lib.sh @@ -14,7 +14,7 @@ pkg_json_version() { } vscode_version() { - jq -r .version vendor/modules/code-oss-dev/package.json + jq -r .version lib/vscode/package.json } os() { diff --git a/ci/steps/brew-bump.sh b/ci/steps/brew-bump.sh index 7df17da92431..68ae26de2ef7 100755 --- a/ci/steps/brew-bump.sh +++ b/ci/steps/brew-bump.sh @@ -2,7 +2,9 @@ set -euo pipefail main() { - cd "$(dirname "$0")/../.." + REPO="homebrew-core" + GITHUB_USERNAME="cdrci" + UPSTREAM_USERNAME_AND_REPO="Homebrew/$REPO" # Only sourcing this so we get access to $VERSION source ./ci/lib.sh source ./ci/steps/steps-lib.sh @@ -21,25 +23,18 @@ main() { exit 1 fi - # 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 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 - echo "git clone failed. Cannot find homebrew-core directory." + if ! directory_exists "$REPO"; then + echo "git clone failed. Cannot find $REPO directory." ls -la exit 1 fi - echo "Changing into homebrew-core directory" - pushd homebrew-core && pwd + echo "Changing into $REPO directory" + pushd "$REPO" && pwd - echo "Adding Homebrew/homebrew-core" - git remote add upstream https://github.com/Homebrew/homebrew-core.git + echo "Adding $UPSTREAM_USERNAME_AND_REPO" + git remote add upstream "https://github.com/$UPSTREAM_USERNAME_AND_REPO.git" # Make sure the git remote step is successful if ! git config remote.upstream.url > /dev/null; then @@ -50,24 +45,22 @@ main() { fi # TODO@jsjoeio - can I somehow check that this succeeded? - echo "Fetching upstream Homebrew/hombrew-core commits" - git fetch upstream + echo "Fetching upstream $UPSTREAM_USERNAME_AND_REPO commits" + git fetch upstream master # TODO@jsjoeio - can I somehow check that this succeeded? - echo "Merging in latest Homebrew/homebrew-core changes" + echo "Merging in latest $UPSTREAM_USERNAME_AND_REPO changes branch master" git merge upstream/master - 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 PATH_TO_GIT_ASKPASS="$HOME/git-askpass.sh" # Source: https://serverfault.com/a/912788 # shellcheck disable=SC2016,SC2028 - echo 'echo $HOMEBREW_GITHUB_API_TOKEN' > "$PATH_TO_ASKPASS" + echo 'echo $HOMEBREW_GITHUB_API_TOKEN' > "$PATH_TO_GIT_ASKPASS" # Make sure the git-askpass.sh file creation is successful - if file_exists "$PATH_TO_GIT_ASKPASS"; then + if ! file_exists "$PATH_TO_GIT_ASKPASS"; then echo "git-askpass.sh not found in $HOME." ls -la "$HOME" exit 1 @@ -77,16 +70,20 @@ main() { chmod +x "$PATH_TO_GIT_ASKPASS" # Make sure the git-askpass.sh file is executable - if is_executable "$PATH_TO_GIT_ASKPASS"; then + if ! is_executable "$PATH_TO_GIT_ASKPASS"; then echo "$PATH_TO_GIT_ASKPASS is not executable." ls -la "$PATH_TO_GIT_ASKPASS" exit 1 fi + # NOTE: we need to make sure our fork is up-to-date + # otherwise, brew bump-formula-pr will use an + # outdated base + echo "Pushing changes to $GITHUB_USERNAME/$REPO fork on GitHub" # 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://coder-oss@github.com/coder-oss/homebrew-core.git --all + export GIT_ASKPASS="$PATH_TO_GIT_ASKPASS" + git push "https://$GITHUB_USERNAME@github.com/$GITHUB_USERNAME/$REPO.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 @@ -94,21 +91,12 @@ main() { if ! output=$(brew bump-formula-pr --version="${VERSION}" code-server --no-browse --no-audit 2>&1); then if [[ $output == *"Duplicate PRs should not be opened"* ]]; then echo "$VERSION is already submitted" + exit 0 else echo "$output" exit 1 fi fi - - # Clean up and remove homebrew-core - popd - rm -rf homebrew-core - - # Make sure homebrew-core is removed - if directory_exists "homebrew-core"; then - echo "rm -rf homebrew-core failed." - ls -la - fi } main "$@" diff --git a/ci/steps/docker-buildx-push.sh b/ci/steps/docker-buildx-push.sh index c3bb0579635a..ba09cd76a115 100755 --- a/ci/steps/docker-buildx-push.sh +++ b/ci/steps/docker-buildx-push.sh @@ -4,12 +4,9 @@ set -euo pipefail main() { cd "$(dirname "$0")/../.." - # ci/lib.sh sets VERSION and provides download_artifact here - source ./ci/lib.sh - - # Download the release-packages artifact - download_artifact release-packages ./release-packages - + # NOTE@jsjoeio - this script assumes that you've downloaded + # the release-packages artifact to ./release-packages before + # running this docker buildx step docker buildx bake -f ci/release-image/docker-bake.hcl --push } diff --git a/ci/steps/publish-npm.sh b/ci/steps/publish-npm.sh index 7ba3a0f97d2f..36ca0773b3f5 100755 --- a/ci/steps/publish-npm.sh +++ b/ci/steps/publish-npm.sh @@ -13,14 +13,6 @@ main() { 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. @@ -51,6 +43,13 @@ main() { exit 1 fi + # Check that we're using at least v7 of npm CLI + if ! command -v jq &> /dev/null; then + echo "Couldn't find jq" + echo "We need this in order to modify the package.json for dev builds." + exit 1 + fi + # This allows us to publish to npm in CI workflows if [[ ${CI-} ]]; then echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc @@ -86,6 +85,10 @@ main() { # See: https://github.com/coder/code-server/pull/3935 echo "node_modules.asar" > release/.npmignore + # We use this to set the name of the package in the + # package.json + PACKAGE_NAME="code-server" + # NOTES:@jsjoeio # We only need to run npm version for "development" and "staging". # This is because our release:prep script automatically bumps the version @@ -112,12 +115,14 @@ main() { # 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" + PACKAGE_NAME="@coder/code-server-pr" # This means the npm version will be tagged with "" # and installed when a user runs `yarn install code-server@` NPM_TAG="$PR_NUMBER" fi echo "using tag: $NPM_TAG" + echo "using package name: $PACKAGE_NAME" # We modify the version in the package.json # to be the current version + the PR number + commit SHA @@ -125,9 +130,14 @@ main() { # Example: "version": "4.0.1-4769-ad7b23cfe6ffd72914e34781ef7721b129a23040" # Example: "version": "4.0.1-beta-ad7b23cfe6ffd72914e34781ef7721b129a23040" pushd release - # NOTE:@jsjoeio + # NOTE@jsjoeio # I originally tried to use `yarn version` but ran into issues and abandoned it. npm version "$NPM_VERSION" + # NOTE@jsjoeio + # Use the development package name + # This is so we don't clutter the code-server versions on npm + # with development versions. + jq ".name |= \"$PACKAGE_NAME\"" package.json popd fi @@ -141,7 +151,10 @@ main() { return fi - yarn publish --non-interactive release --tag "$NPM_TAG" + # NOTE@jsjoeio + # Since the dev builds are scoped to @coder + # We pass --access public to ensure npm knows it's not private. + yarn publish --non-interactive release --tag "$NPM_TAG" --access public } main "$@" diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 3e01c6d0a67a..205311558019 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -7,7 +7,8 @@ - [Creating pull requests](#creating-pull-requests) - [Commits and commit history](#commits-and-commit-history) - [Development workflow](#development-workflow) - - [Updates to VS Code](#updates-to-vs-code) + - [Version updates to Code](#version-updates-to-code) + - [Patching Code](#patching-code) - [Build](#build) - [Help](#help) - [Test](#test) @@ -16,7 +17,7 @@ - [Integration tests](#integration-tests) - [End-to-end tests](#end-to-end-tests) - [Structure](#structure) - - [Modifications to VS Code](#modifications-to-vs-code) + - [Modifications to Code](#modifications-to-code) - [Currently Known Issues](#currently-known-issues) @@ -44,6 +45,8 @@ Here is what is needed: signature verification](https://docs.github.com/en/github/authenticating-to-github/managing-commit-signature-verification) or follow [this tutorial](https://joeprevite.com/verify-commits-on-github) +- `quilt` + - Used to manage patches to Code - `rsync` and `unzip` - Used for code-server releases - `bats` @@ -57,7 +60,7 @@ If you're developing code-server on Linux, make sure you have installed or insta sudo apt-get install build-essential g++ libx11-dev libxkbfile-dev libsecret-1-dev python-is-python3 ``` -These are required by VS Code. See [their Wiki](https://github.com/microsoft/vscode/wiki/How-to-Contribute#prerequisites) for more information. +These are required by Code. See [their Wiki](https://github.com/microsoft/vscode/wiki/How-to-Contribute#prerequisites) for more information. ## Creating pull requests @@ -78,41 +81,44 @@ we'll guide you. ## Development workflow -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/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) -6. `cd code-server && yarn link code-oss-dev --modules-folder vendor/modules` - links your local `vscode` repo (`code-oss-dev` package) inside your local version of code-server -7. `cd code-server && yarn watch` - this will spin up code-server on localhost:8080 which you can start developing. It will live reload changes to the source. - -### Updates to VS Code +2. `git submodule update --init` - Clone `vscode` submodule +3. `quilt push -a` - Apply patches to the `vscode` submodule. +4. `yarn` - Install dependencies +5. `yarn watch` - Launch code-server localhost:8080. code-server will be live + reloaded when changes are made; the browser needs to be refreshed manually. -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: +When pulling down changes that include modifications to the patches you will +need to apply them with `quilt`. If you pull down changes that update the +`vscode` submodule you will need to run `git submodule update --init` and +re-apply the patches. -1. Update the package tag listed in `vendor/package.json`: - -```json -{ - "devDependencies": { - "vscode": "coder/vscode#" - } -} -``` +### Version updates to Code +1. Update the `lib/vscode` submodule to the desired upstream version branch. 2. From the code-server **project root**, run `yarn install`. - Then, test code-server locally to make sure everything works. -3. Check the Node.js version that's used by Electron (which is shipped with VS +3. Apply the patches (`quilt push -a`) or restore your stashed changes. At this + stage you may need to resolve conflicts. For example use `quilt push -f`, + manually apply the rejected portions, then `quilt refresh`. +4. Test code-server locally to make sure everything works. +5. Check the Node.js version that's used by Electron (which is shipped with VS Code. If necessary, update your version of Node.js to match. -4. Open a PR - -> Watch for updates to -> `vendor/modules/code-oss-dev/src/vs/code/browser/workbench/workbench.html`. You may need to -> make changes to `src/browser/pages/vscode.html`. +6. Commit the updated submodule and patches to `code-server`. +7. Open a PR. + +### Patching Code + +0. You can go through the patch stack with `quilt push` and `quilt pop`. +1. Create a new patch (`quilt new {name}.diff`) or use an existing patch. +2. Add the file(s) you are patching (`quilt add [-P patch] {file}`). A file + **must** be added before you make changes to it. +3. Make your changes. Patches do not need to be independent of each other but + each patch must result in a working code-server without any broken in-between + states otherwise they are difficult to test and modify. +4. Add your changes to the patch (`quilt refresh`) +5. Add a comment in the patch about the reason for the patch and how to + reproduce the behavior it fixes or adds. Every patch should have an e2e test + as well. ### Build @@ -208,99 +214,46 @@ code-server running locally. In CI, this is taken care of for you. ## Structure -The `code-server` script serves as an HTTP API for login and starting a remote VS +The `code-server` script serves as an HTTP API for login and starting a remote Code process. The CLI code is in [src/node](../src/node) and the HTTP routes are implemented in [src/node/routes](../src/node/routes). -Most of the meaty parts are in the VS Code portion of the codebase under -[vendor/modules/code-oss-dev](../vendor/modules/code-oss-dev), which we describe next. - -### Modifications to VS Code - -In v1 of code-server, we had a patch of VS Code that split the codebase into a -front-end and a server. The front-end consisted of the UI code, while the server -ran the extensions and exposed an API to the front-end for file access and all -UI needs. - -Over time, Microsoft added support to VS Code to run it on the web. They have -made the front-end open source, but not the server. As such, code-server v2 (and -later) uses the VS Code front-end and implements the server. We do this by using -a Git subtree to fork and modify VS Code. This code lives under -[vendor/modules/code-oss-dev](../vendor/modules/code-oss-dev). - -Some noteworthy changes in our version of VS Code include: - -- Adding our build file, [`vendor/modules/code-oss-dev/coder.js`](../vendor/modules/code-oss-dev/coder.js), which includes build steps specific to code-server -- Node.js version detection changes in [`build/lib/node.ts`](../vendor/modules/code-oss-dev/build/lib/node.ts) and [`build/lib/util.ts`](../vendor/modules/code-oss-dev/build/lib/util.ts) -- Allowing extra extension directories - - Added extra arguments to [`src/vs/platform/environment/common/argv.ts`](../vendor/modules/code-oss-dev/src/vs/platform/environment/common/argv.ts) and to [`src/vs/platform/environment/node/argv.ts`](../vendor/modules/code-oss-dev/src/vs/platform/environment/node/argv.ts) - - Added extra environment state to [`src/vs/platform/environment/common/environment.ts`](../vendor/modules/code-oss-dev/src/vs/platform/environment/common/environment.ts); - - Added extra getters to [`src/vs/platform/environment/common/environmentService.ts`](../vendor/modules/code-oss-dev/src/vs/platform/environment/common/environmentService.ts) - - Added extra scanning paths to [`src/vs/platform/extensionManagement/node/extensionsScanner.ts`](../vendor/modules/code-oss-dev/src/vs/platform/extensionManagement/node/extensionsScanner.ts) -- Additions/removals from [`package.json`](../vendor/modules/code-oss-dev/package.json): - - Removing `electron`, `keytar` and `native-keymap` to avoid pulling in desktop dependencies during build on Linux - - Removing `gulp-azure-storage` and `gulp-tar` (unsued in our build process, may pull in outdated dependencies) - - Adding `proxy-agent`, `proxy-from-env` (for proxying) and `rimraf` (used during build/install steps) -- Adding our branding/custom URLs/version: - - [`product.json`](../vendor/modules/code-oss-dev/product.json) - - [`src/vs/base/common/product.ts`](../vendor/modules/code-oss-dev/src/vs/base/common/product.ts) - - [`src/vs/workbench/browser/parts/dialogs/dialogHandler.ts`](../vendor/modules/code-oss-dev/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts) - - [`src/vs/workbench/contrib/welcome/page/browser/vs_code_welcome_page.ts`](../vendor/modules/code-oss-dev/src/vs/workbench/contrib/welcome/page/browser/vs_code_welcome_page.ts) - - [`src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts`](../vendor/modules/code-oss-dev/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts) -- Removing azure/macOS signing related dependencies from [`build/package.json`](../vendor/modules/code-oss-dev/build/package.json) -- Modifying `.gitignore` to allow us to add files to `src/vs/server` and modifying `.eslintignore` to ignore lint on the shared files below (we use different formatter settings than VS Code). -- Sharing some files with our codebase via symlinks: - - [`src/vs/base/common/ipc.d.ts`](../vendor/modules/code-oss-dev/src/vs/base/common/ipc.d.ts) points to [`typings/ipc.d.ts`](../typings/ipc.d.ts) - - [`src/vs/base/common/util.ts`](../vendor/modules/code-oss-dev/src/vs/base/common/util.ts) points to [`src/common/util.ts`](../src/common/util.ts) - - [`src/vs/base/node/proxy_agent.ts`](../vendor/modules/code-oss-dev/src/vs/base/node/proxy_agent.ts) points to [`src/node/proxy_agent.ts`](../src/node/proxy_agent.ts) -- Allowing socket changes by adding `setSocket` in [`src/vs/base/parts/ipc/common/ipc.net.ts`](../vendor/modules/code-oss-dev/src/vs/base/parts/ipc/common/ipc.net.ts) - - We use this for connection persistence in our server-side code. -- Added our server-side Node.JS code to `src/vs/server`. - - This code includes the logic to spawn the various services (extension host, terminal, etc.) and some glue -- Added [`src/vs/workbench/browser/client.ts`](../vendor/modules/code-oss-dev/src/vs/workbench/browser/client.ts) to hold some server customizations. - - Includes the functionality for the Log Out command and menu item - - Also, imported and called `initialize` from the main web file, [`src/vs/workbench/browser/web.main.ts`](../vendor/modules/code-oss-dev/src/vs/workbench/browser/web.main.ts) -- Added a (hopefully temporary) hotfix to [`src/vs/workbench/common/resources.ts`](../vendor/modules/code-oss-dev/src/vs/workbench/common/resources.ts) to get context menu actions working for the Git integration. -- Added connection type to WebSocket query parameters in [`src/vs/platform/remote/common/remoteAgentConnection.ts`](../vendor/modules/code-oss-dev/src/vs/platform/remote/common/remoteAgentConnection.ts) -- Added `CODE_SERVER*` variables to the sanitization list in [`src/vs/base/common/processes.ts`](../vendor/modules/code-oss-dev/src/vs/base/common/processes.ts) -- Fix localization support: - - Added file [`src/vs/workbench/services/localizations/browser/localizationsService.ts`](../vendor/modules/code-oss-dev/src/vs/workbench/services/localizations/browser/localizationsService.ts). - - Modified file [`src/vs/base/common/platform.ts`](../vendor/modules/code-oss-dev/src/vs/base/common/platform.ts) - - Modified file [`src/vs/base/node/languagePacks.js`](../vendor/modules/code-oss-dev/src/vs/base/node/languagePacks.js) -- Added code to allow server to inject settings to [`src/vs/platform/product/common/product.ts`](../vendor/modules/code-oss-dev/src/vs/platform/product/common/product.ts) -- Extension fixes: - - Avoid disabling extensions by extensionKind in [`src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts`](../vendor/modules/code-oss-dev/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts) (Needed for vscode-icons) - - Remove broken symlinks in [`extensions/postinstall.js`](../vendor/modules/code-oss-dev/extensions/postinstall.js) - - Add tip about extension gallery in [`src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts`](../vendor/modules/code-oss-dev/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts) - - Use our own server for GitHub authentication in [`extensions/github-authentication/src/githubServer.ts`](../vendor/modules/code-oss-dev/extensions/github-authentication/src/githubServer.ts) - - Settings persistence on the server in [`src/vs/workbench/services/environment/browser/environmentService.ts`](../vendor/modules/code-oss-dev/src/vs/workbench/services/environment/browser/environmentService.ts) - - Add extension install fallback in [`src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts`](../vendor/modules/code-oss-dev/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts) - - Add proxy-agent monkeypatch and keep extension host indefinitely running in [`src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts`](../vendor/modules/code-oss-dev/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts) - - Patch build system to avoid removing extension dependencies for `yarn global add` users in [`build/lib/extensions.ts`](../vendor/modules/code-oss-dev/build/lib/extensions.ts) - - Allow all extensions to use proposed APIs in [`src/vs/workbench/services/environment/browser/environmentService.ts`](../vendor/modules/code-oss-dev/src/vs/workbench/services/environment/browser/environmentService.ts) - - Make storage writes async to allow extensions to wait for them to complete in [`src/vs/platform/storage/common/storage.ts`](../vendor/modules/code-oss-dev/src/vs/platform/storage/common/storage.ts) -- Specify webview path in [`src/vs/code/browser/workbench/workbench.ts`](../vendor/modules/code-oss-dev/src/vs/code/browser/workbench/workbench.ts) -- URL readability improvements for folder/workspace in [`src/vs/code/browser/workbench/workbench.ts`](../vendor/modules/code-oss-dev/src/vs/code/browser/workbench/workbench.ts) -- Socket/Authority-related fixes (for remote proxying etc.): - - [`src/vs/code/browser/workbench/workbench.ts`](../vendor/modules/code-oss-dev/src/vs/code/browser/workbench/workbench.ts) - - [`src/vs/platform/remote/browser/browserSocketFactory.ts`](../vendor/modules/code-oss-dev/src/vs/platform/remote/browser/browserSocketFactory.ts) - - [`src/vs/base/common/network.ts`](../vendor/modules/code-oss-dev/src/vs/base/common/network.ts) -- Added code to write out IPC path in [`src/vs/workbench/api/node/extHostCLIServer.ts`](../vendor/modules/code-oss-dev/src/vs/workbench/api/node/extHostCLIServer.ts) - -As the web portion of VS Code matures, we'll be able to shrink and possibly -eliminate our modifications. In the meantime, upgrading the VS Code version requires -us to ensure that our changes are still applied and work as intended. In the future, -we'd like to run VS Code unit tests against our builds to ensure that features -work as expected. +Most of the meaty parts are in the Code portion of the codebase under +[lib/vscode](../lib/vscode), which we describe next. + +### Modifications to Code + +Our modifications to Code can be found in the [patches](../patches) directory. +We pull in Code as a submodule pointing to an upstream release branch. + +In v1 of code-server, we had Code as a submodule and used a single massive patch +that split the codebase into a front-end and a server. The front-end consisted +of the UI code, while the server ran the extensions and exposed an API to the +front-end for file access and all UI needs. + +Over time, Microsoft added support to Code to run it on the web. They had made +the front-end open source, but not the server. As such, code-server v2 (and +later) uses the Code front-end and implements the server. We did this by using a +Git subtree to fork and modify Code. + +Microsoft eventually made the server open source and we were able to reduce our +changes significantly. Some time later we moved back to a submodule and patches +(managed by `quilt` this time instead of the mega-patch). + +As the web portion of Code continues to mature, we'll be able to shrink and +possibly eliminate our patches. In the meantime, upgrading the Code version +requires us to ensure that our changes are still applied correctly and work as +intended. In the future, we'd like to run Code unit tests against our builds to +ensure that features work as expected. > We have [extension docs](../ci/README.md) on the CI and build system. -If the functionality you're working on does NOT depend on code from VS Code, please +If the functionality you're working on does NOT depend on code from Code, please move it out and into code-server. ### Currently Known Issues -- Creating custom VS Code extensions and debugging them doesn't work +- Creating custom Code extensions and debugging them doesn't work - Extension profiling and tips are currently disabled diff --git a/docs/MAINTAINING.md b/docs/MAINTAINING.md index 8bec1e9c4d7f..7281f02a923e 100644 --- a/docs/MAINTAINING.md +++ b/docs/MAINTAINING.md @@ -34,7 +34,6 @@ as well as share our workflow for maintaining the project. Current maintainers: - @code-asher -- @TeffenEllis - @jsjoeio Occasionally, other Coder employees may step in time to time to assist with code-server. @@ -165,7 +164,7 @@ If you're the current release manager, follow these steps: ### Publishing a release -1. Create a release branch called `v0.0.0` but replace with new version +1. Create a new branch called `v0.0.0` (replace 0s with actual version aka v4.2.0) 1. Run `yarn release:prep` and type in the new version (e.g., `3.8.1`) 1. GitHub Actions will generate the `npm-package`, `release-packages` and `release-images` artifacts. You do not have to wait for this step to complete diff --git a/docs/README.md b/docs/README.md index f02649af76c6..c028d281bae3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -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/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.0.2 docs](https://img.shields.io/static/v1?label=Docs&message=see%20v4.0.2%20&color=blue)](https://github.com/coder/code-server/tree/v4.0.2/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.2.0 docs](https://img.shields.io/static/v1?label=Docs&message=see%20v4.2.0%20&color=blue)](https://github.com/coder/code-server/tree/v4.2.0/docs) Run [VS Code](https://github.com/Microsoft/vscode) on any machine anywhere and access it in the browser. diff --git a/docs/collaboration.md b/docs/collaboration.md index 5ae803d5b937..52b1c87d2783 100644 --- a/docs/collaboration.md +++ b/docs/collaboration.md @@ -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.2/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.2.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. diff --git a/docs/guide.md b/docs/guide.md index 81e37d7d148d..b08a3ed17208 100644 --- a/docs/guide.md +++ b/docs/guide.md @@ -52,7 +52,7 @@ There are several approaches to operating and exposing code-server securely: We highly recommend using [port forwarding via SSH](https://help.ubuntu.com/community/SSH/OpenSSH/PortForwarding) to access code-server. If you have an SSH server on your remote machine, this approach -doesn't required additional setup. +doesn't require any additional setup at all. The downside to SSH forwarding, however, is that you can't access code-server when using machines without SSH clients (such as iPads). If this applies to you, diff --git a/docs/helm.md b/docs/helm.md index b404919c5917..2282ae964924 100644 --- a/docs/helm.md +++ b/docs/helm.md @@ -1,6 +1,6 @@ # 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.2](https://img.shields.io/badge/AppVersion-4.0.2-informational?style=flat-square)](https://img.shields.io/badge/AppVersion-4.0.2-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.2.0](https://img.shields.io/badge/AppVersion-4.2.0-informational?style=flat-square)](https://img.shields.io/badge/AppVersion-4.2.0-informational?style=flat-square) [code-server](https://github.com/coder/code-server) code-server is VS Code running on a remote server, accessible through the browser. @@ -73,7 +73,7 @@ and their default values. | hostnameOverride | string | `""` | | image.pullPolicy | string | `"Always"` | | image.repository | string | `"codercom/code-server"` | -| image.tag | string | `"4.0.2"` | +| image.tag | string | `"4.2.0"` | | imagePullSecrets | list | `[]` | | ingress.enabled | bool | `false` | | nameOverride | string | `""` | diff --git a/docs/manifest.json b/docs/manifest.json index 8f0265078ddd..a637b72b61b7 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -1,5 +1,5 @@ { - "versions": ["v4.0.2"], + "versions": ["v4.2.0"], "routes": [ { "title": "Home", diff --git a/lib/vscode b/lib/vscode new file mode 160000 index 000000000000..f80445acd5a3 --- /dev/null +++ b/lib/vscode @@ -0,0 +1 @@ +Subproject commit f80445acd5a3dadef24aa209168452a3d97cc326 diff --git a/package.json b/package.json index 759cfe0236f9..bf5ae282fc6f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-server", "license": "MIT", - "version": "4.0.2", + "version": "4.2.0", "description": "Run VS Code on a remote server.", "homepage": "https://github.com/coder/code-server", "bugs": { @@ -51,7 +51,7 @@ "@types/ws": "^8.0.0", "@typescript-eslint/eslint-plugin": "^5.0.0", "@typescript-eslint/parser": "^5.0.0", - "audit-ci": "^5.0.0", + "audit-ci": "^6.0.0", "codecov": "^3.8.3", "doctoc": "^2.0.0", "eslint": "^7.7.0", @@ -69,7 +69,7 @@ }, "resolutions": { "ansi-regex": "^5.0.1", - "normalize-package-data": "^3.0.0", + "normalize-package-data": "^4.0.0", "doctoc/underscore": "^1.13.1", "doctoc/**/trim": "^1.0.0", "postcss": "^8.2.1", @@ -81,7 +81,8 @@ "vm2": "^3.9.6", "follow-redirects": "^1.14.8", "node-fetch": "^2.6.7", - "nanoid": "^3.1.31" + "nanoid": "^3.1.31", + "minimist": "npm:minimist-lite@2.2.0" }, "dependencies": { "@coder/logger": "1.1.16", @@ -127,7 +128,6 @@ "testEnvironment": "node", "testPathIgnorePatterns": [ "/node_modules/", - "/vendor/", "/lib/", "/out/", "test/e2e" @@ -158,7 +158,7 @@ "/release-npm-package", "/release-gcp", "/release-images", - "/vendor" + "/lib" ], "moduleNameMapper": { "^.+\\.(css|less)$": "/test/utils/cssStub.ts" diff --git a/patches/base-path.diff b/patches/base-path.diff new file mode 100644 index 000000000000..715f8a2150a9 --- /dev/null +++ b/patches/base-path.diff @@ -0,0 +1,305 @@ +Add base path support + +Some users will host code-server behind a path-rewriting reverse proxy, for +example domain.tld/my/base/path. This patch adds support for that since Code +assumes everything is on / by default. + +To test this serve code-server behind a reverse proxy with a path like /code. + +Index: code-server/lib/vscode/src/vs/base/common/network.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/base/common/network.ts ++++ code-server/lib/vscode/src/vs/base/common/network.ts +@@ -151,8 +151,10 @@ class RemoteAuthoritiesImpl { + } + return URI.from({ + scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource, +- authority: `${host}:${port}`, +- path: `/vscode-remote-resource`, ++ authority: platform.isWeb ? window.location.host : `${host}:${port}`, ++ path: platform.isWeb ++ ? URI.joinPath(URI.parse(window.location.href), `/vscode-remote-resource`).path ++ : `/vscode-remote-resource`, + query + }); + } +Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench-dev.html +=================================================================== +--- code-server.orig/lib/vscode/src/vs/code/browser/workbench/workbench-dev.html ++++ code-server/lib/vscode/src/vs/code/browser/workbench/workbench-dev.html +@@ -11,8 +11,8 @@ + + + +- +- ++ ++ + + + +@@ -27,23 +27,26 @@ + + + +- +- +- ++ ++ ++ + + + + + + +- +- ++ ++ + +- ++ ++ + +- +- +- ++ ++ ++ + +Index: code-server/lib/vscode/src/vs/platform/remote/browser/browserSocketFactory.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/platform/remote/browser/browserSocketFactory.ts ++++ code-server/lib/vscode/src/vs/platform/remote/browser/browserSocketFactory.ts +@@ -274,7 +274,7 @@ export class BrowserSocketFactory implem + + connect(host: string, port: number, query: string, debugLabel: string, callback: IConnectCallback): void { + const webSocketSchema = (/^https:/.test(window.location.href) ? 'wss' : 'ws'); +- const socket = this._webSocketFactory.create(`${webSocketSchema}://${/:/.test(host) ? `[${host}]` : host}:${port}/?${query}&skipWebSocketFrames=false`, debugLabel); ++ const socket = this._webSocketFactory.create(`${webSocketSchema}://${window.location.host}${window.location.pathname}?${query}&skipWebSocketFrames=false`, debugLabel); + const errorListener = socket.onError((err) => callback(err, undefined)); + socket.onOpen(() => { + errorListener.dispose(); +@@ -282,6 +282,3 @@ export class BrowserSocketFactory implem + }); + } + } +- +- +- +Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts ++++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts +@@ -252,7 +252,10 @@ export class WebClientServer { + return res.end(); + } + +- const remoteAuthority = req.headers.host; ++ // It is not possible to reliably detect the remote authority on the server ++ // in all cases. Set this to something invalid to make sure we catch code ++ // that is using this when it should not. ++ const remoteAuthority = 'remote'; + + function escapeAttribute(value: string): string { + return value.replace(/"/g, '"'); +@@ -272,6 +275,8 @@ export class WebClientServer { + accessToken: this._environmentService.args['github-auth'], + scopes: [['user:email'], ['repo']] + } : undefined; ++ const base = relativeRoot(getOriginalUrl(req)) ++ const vscodeBase = relativePath(getOriginalUrl(req)) + const data = (await util.promisify(fs.readFile)(filePath)).toString() + .replace('{{WORKBENCH_WEB_CONFIGURATION}}', escapeAttribute(JSON.stringify({ + remoteAuthority, +@@ -279,6 +284,7 @@ export class WebClientServer { + developmentOptions: { enableSmokeTestDriver: this._environmentService.driverHandle === 'web' ? true : undefined }, + settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, + productConfiguration: >{ ++ rootEndpoint: base, + extensionsGallery: this._webExtensionResourceUrlTemplate ? { + ...this._productService.extensionsGallery, + 'resourceUrlTemplate': this._webExtensionResourceUrlTemplate.with({ +@@ -289,7 +295,9 @@ export class WebClientServer { + } : undefined + } + }))) +- .replace('{{WORKBENCH_AUTH_SESSION}}', () => authSessionInfo ? escapeAttribute(JSON.stringify(authSessionInfo)) : ''); ++ .replace('{{WORKBENCH_AUTH_SESSION}}', () => authSessionInfo ? escapeAttribute(JSON.stringify(authSessionInfo)) : '') ++ .replace(/{{BASE}}/g, base) ++ .replace(/{{VS_BASE}}/g, vscodeBase); + + const cspDirectives = [ + 'default-src \'self\';', +@@ -368,3 +376,70 @@ export class WebClientServer { + return res.end(data); + } + } ++ ++/** ++ * Remove extra slashes in a URL. ++ * ++ * This is meant to fill the job of `path.join` so you can concatenate paths and ++ * then normalize out any extra slashes. ++ * ++ * If you are using `path.join` you do not need this but note that `path` is for ++ * file system paths, not URLs. ++ */ ++export const normalizeUrlPath = (url: string, keepTrailing = false): string => { ++ return url.replace(/\/\/+/g, "/").replace(/\/+$/, keepTrailing ? "/" : "") ++} ++ ++/** ++ * Get the relative path that will get us to the root of the page. For each ++ * slash we need to go up a directory. Will not have a trailing slash. ++ * ++ * For example: ++ * ++ * / => . ++ * /foo => . ++ * /foo/ => ./.. ++ * /foo/bar => ./.. ++ * /foo/bar/ => ./../.. ++ * ++ * All paths must be relative in order to work behind a reverse proxy since we ++ * we do not know the base path. Anything that needs to be absolute (for ++ * example cookies) must get the base path from the frontend. ++ * ++ * All relative paths must be prefixed with the relative root to ensure they ++ * work no matter the depth at which they happen to appear. ++ * ++ * For Express `req.originalUrl` should be used as they remove the base from the ++ * standard `url` property making it impossible to get the true depth. ++ */ ++export const relativeRoot = (originalUrl: string): string => { ++ const depth = (originalUrl.split("?", 1)[0].match(/\//g) || []).length ++ return normalizeUrlPath("./" + (depth > 1 ? "../".repeat(depth - 1) : "")) ++} ++ ++/** ++ * Get the relative path to the current resource. ++ * ++ * For example: ++ * ++ * / => . ++ * /foo => ./foo ++ * /foo/ => . ++ * /foo/bar => ./bar ++ * /foo/bar/ => . ++ */ ++export const relativePath = (originalUrl: string): string => { ++ const parts = originalUrl.split("?", 1)[0].split("/") ++ return normalizeUrlPath("./" + parts[parts.length - 1]) ++} ++ ++/** ++ * code-server serves Code using Express. Express removes the base from the url ++ * and puts the original in `originalUrl` so we must use this to get the correct ++ * depth. Code is not aware it is behind Express so the types do not match. We ++ * may want to continue moving code into Code and eventually remove the Express ++ * wrapper or move the web server back into code-server. ++ */ ++export const getOriginalUrl = (req: http.IncomingMessage): string => { ++ return (req as any).originalUrl || req.url ++} +Index: code-server/lib/vscode/src/vs/base/common/product.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/base/common/product.ts ++++ code-server/lib/vscode/src/vs/base/common/product.ts +@@ -32,6 +32,7 @@ export type ExtensionVirtualWorkspaceSup + + export interface IProductConfiguration { + readonly codeServerVersion?: string ++ readonly rootEndpoint?: string + + readonly version: string; + readonly date?: string; +Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/code/browser/workbench/workbench.ts ++++ code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts +@@ -504,6 +504,7 @@ function doCreateUri(path: string, query + }); + } + ++ path = (window.location.pathname + "/" + path).replace(/\/\/+/g, "/") + return URI.parse(window.location.href).with({ path, query }); + } + +@@ -515,7 +516,7 @@ function doCreateUri(path: string, query + if (!configElement || !configElementAttribute) { + throw new Error('Missing web configuration element'); + } +- const config: IWorkbenchConstructionOptions & { folderUri?: UriComponents, workspaceUri?: UriComponents } = JSON.parse(configElementAttribute); ++ const config: IWorkbenchConstructionOptions & { folderUri?: UriComponents, workspaceUri?: UriComponents } = { ...JSON.parse(configElementAttribute), remoteAuthority: location.host } + + // Create workbench + create(document.body, { diff --git a/patches/connection-type.diff b/patches/connection-type.diff new file mode 100644 index 000000000000..9f04bc29918d --- /dev/null +++ b/patches/connection-type.diff @@ -0,0 +1,19 @@ +Add connection type to web sockets + +This allows the backend to distinguish them. In our case we use them to count a +single "open" of Code so we need to be able to distinguish between web sockets +from two instances and two web sockets used in a single instance. + +Index: code-server/lib/vscode/src/vs/platform/remote/common/remoteAgentConnection.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/platform/remote/common/remoteAgentConnection.ts ++++ code-server/lib/vscode/src/vs/platform/remote/common/remoteAgentConnection.ts +@@ -231,7 +231,7 @@ async function connectToRemoteExtensionH + + let socket: ISocket; + try { +- socket = await createSocket(options.logService, options.socketFactory, options.host, options.port, `reconnectionToken=${options.reconnectionToken}&reconnection=${options.reconnectionProtocol ? 'true' : 'false'}`, `renderer-${connectionTypeToString(connectionType)}-${options.reconnectionToken}`, timeoutCancellationToken); ++ socket = await createSocket(options.logService, options.socketFactory, options.host, options.port, `type=${connectionTypeToString(connectionType)}&reconnectionToken=${options.reconnectionToken}&reconnection=${options.reconnectionProtocol ? 'true' : 'false'}`, `renderer-${connectionTypeToString(connectionType)}-${options.reconnectionToken}`, timeoutCancellationToken); + } catch (error) { + options.logService.error(`${logPrefix} socketFactory.connect() failed or timed out. Error:`); + options.logService.error(error); diff --git a/patches/display-language.diff b/patches/display-language.diff new file mode 100644 index 000000000000..d5ddfa785a52 --- /dev/null +++ b/patches/display-language.diff @@ -0,0 +1,265 @@ +Add display language support + +This likely needs tweaking if we want to upstream. + +Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/server/node/serverServices.ts ++++ code-server/lib/vscode/src/vs/server/node/serverServices.ts +@@ -198,6 +198,9 @@ export async function setupServerService + const channel = new ExtensionManagementChannel(extensionManagementService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority)); + socketServer.registerChannel('extensions', channel); + ++ const localizationsChannel = ProxyChannel.fromService(accessor.get(ILocalizationsService)); ++ socketServer.registerChannel('localizations', localizationsChannel); ++ + const encryptionChannel = ProxyChannel.fromService(accessor.get(IEncryptionMainService)); + socketServer.registerChannel('encryption', encryptionChannel); + +Index: code-server/lib/vscode/src/vs/base/common/platform.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/base/common/platform.ts ++++ code-server/lib/vscode/src/vs/base/common/platform.ts +@@ -83,6 +83,17 @@ if (typeof navigator === 'object' && !is + _isWeb = true; + _locale = navigator.language; + _language = _locale; ++ ++ const el = typeof document !== 'undefined' && document.getElementById('vscode-remote-nls-configuration'); ++ const rawNlsConfig = el && el.getAttribute('data-settings'); ++ if (rawNlsConfig) { ++ try { ++ const nlsConfig: NLSConfig = JSON.parse(rawNlsConfig); ++ _locale = nlsConfig.locale; ++ _translationsConfigFile = nlsConfig._translationsConfigFile; ++ _language = nlsConfig.availableLanguages['*'] || LANGUAGE_DEFAULT; ++ } catch (error) { /* Oh well. */ } ++ } + } + + // Native environment +Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html +=================================================================== +--- code-server.orig/lib/vscode/src/vs/code/browser/workbench/workbench.html ++++ code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html +@@ -23,6 +23,9 @@ + + + ++ ++ ++ + + + +@@ -38,6 +41,27 @@ + + + +