diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 11a38e026654..b64c12359b4c 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -25,8 +25,8 @@ jobs: docs: ${{ steps.filter.outputs.docs }} helm: ${{ steps.filter.outputs.helm }} steps: - - uses: actions/checkout@v6 - - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 id: filter with: filters: | @@ -55,8 +55,8 @@ jobs: name: Run prettier check runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v6 - - uses: actions/setup-node@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: .node-version cache: npm @@ -72,8 +72,8 @@ jobs: needs: changes if: needs.changes.outputs.docs == 'true' steps: - - uses: actions/checkout@v6 - - uses: actions/setup-node@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: .node-version cache: npm @@ -89,10 +89,11 @@ jobs: needs: changes if: needs.changes.outputs.helm == 'true' steps: - - uses: actions/checkout@v6 - - uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: azure/setup-helm@dda3372f752e03dde6b3237bc9431cdc2f7a02a2 # v5.0.0 with: token: ${{ secrets.GITHUB_TOKEN }} + version: "v3.19.2" - run: helm plugin install https://github.com/instrumenta/helm-kubeval - run: helm kubeval ci/helm-chart @@ -102,8 +103,8 @@ jobs: needs: changes if: needs.changes.outputs.code == 'true' steps: - - uses: actions/checkout@v6 - - uses: actions/setup-node@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: .node-version cache: npm @@ -120,7 +121,7 @@ jobs: if: needs.changes.outputs.ci == 'true' steps: - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Check workflow files run: | bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) 1.7.9 @@ -133,8 +134,8 @@ jobs: needs: changes if: needs.changes.outputs.code == 'true' steps: - - uses: actions/checkout@v6 - - uses: actions/setup-node@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: .node-version cache: npm @@ -143,7 +144,7 @@ jobs: test/package-lock.json - run: SKIP_SUBMODULE_DEPS=1 npm ci - run: npm run test:unit - - uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5 + - uses: codecov/codecov-action@75cd11691c0faa626561e295848008c8a7dddffe # v5 if: success() with: token: ${{ secrets.CODECOV_TOKEN }} @@ -167,11 +168,11 @@ jobs: packages: quilt version: 1.0 - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: submodules: true - run: quilt push -a - - uses: actions/setup-node@v6 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: .node-version cache: npm @@ -190,7 +191,7 @@ jobs: # embedded into the code). Use VSCODE_CACHE_VERSION to force a rebuild. - name: Fetch prebuilt linux-x64 Code package from cache id: cache-vscode - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: lib/vscode-reh-web-linux-x64 key: vscode-linux-x64-package-${{ secrets.VSCODE_CACHE_VERSION }}-${{ steps.vscode-rev.outputs.rev }}-${{ hashFiles('patches/*.diff', 'ci/build/build-vscode.sh') }} @@ -204,7 +205,7 @@ jobs: # Push up an artifact containing the linux-x64 release. - run: KEEP_MODULES=1 npm run release - run: tar -czf package.tar.gz release - - uses: actions/upload-artifact@v7 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: linux-x64-package path: ./package.tar.gz @@ -212,12 +213,14 @@ jobs: test-e2e: name: Run e2e tests runs-on: ubuntu-22.04 + env: + LOG_LEVEL: debug needs: [changes, build] if: needs.changes.outputs.code == 'true' || needs.changes.outputs.deps == 'true' || needs.changes.outputs.ci == 'true' steps: - - uses: actions/checkout@v6 - - uses: actions/setup-node@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: .node-version cache: npm @@ -230,13 +233,13 @@ jobs: ./test/node_modules/.bin/playwright install-deps ./test/node_modules/.bin/playwright install - - uses: actions/download-artifact@v8 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: linux-x64-package - run: tar -xzf package.tar.gz - run: CODE_SERVER_TEST_ENTRY=./release npm run test:e2e - - uses: actions/upload-artifact@v7 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 if: always() with: name: failed-test-videos @@ -247,12 +250,13 @@ jobs: runs-on: ubuntu-22.04 env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + LOG_LEVEL: debug needs: [changes, build] if: needs.changes.outputs.code == 'true' || needs.changes.outputs.deps == 'true' || needs.changes.outputs.ci == 'true' steps: - name: Cache Caddy - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 id: caddy-cache with: path: | @@ -265,8 +269,8 @@ jobs: mkdir -p ~/.cache/caddy tar -xzf caddy_2.5.2_linux_amd64.tar.gz --directory ~/.cache/caddy - - uses: actions/checkout@v6 - - uses: actions/setup-node@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: .node-version cache: npm @@ -279,7 +283,7 @@ jobs: ./test/node_modules/.bin/playwright install-deps ./test/node_modules/.bin/playwright install - - uses: actions/download-artifact@v8 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: linux-x64-package - run: tar -xzf package.tar.gz @@ -288,7 +292,7 @@ jobs: - run: CODE_SERVER_TEST_ENTRY=./release npm run test:e2e:proxy - run: ~/.cache/caddy/caddy stop --config ./ci/Caddyfile if: always() - - uses: actions/upload-artifact@v7 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 if: always() with: name: failed-test-videos-proxy diff --git a/.github/workflows/installer.yaml b/.github/workflows/installer.yaml index f89c5b31de1b..a77a5fd61919 100644 --- a/.github/workflows/installer.yaml +++ b/.github/workflows/installer.yaml @@ -30,7 +30,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Install code-server run: ./install.sh @@ -44,7 +44,7 @@ jobs: container: "alpine:3.17" steps: - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Install curl run: apk add curl @@ -67,7 +67,7 @@ jobs: steps: - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Install code-server run: ./install.sh diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index eedd2e84c821..64355ee0dcd8 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -33,12 +33,12 @@ jobs: run: | echo "VERSION=${TAG#v}" >> $GITHUB_ENV - - uses: actions/checkout@v6 - - uses: actions/setup-node@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: .node-version - - uses: robinraju/release-downloader@daf26c55d821e836577a15f77d86ddc078948b05 # v1.12 + - uses: robinraju/release-downloader@28fc21f50d76778e7023361aa1f863e717d3d56f # v1.13 with: repository: "coder/code-server" tag: ${{ env.TAG }} @@ -64,23 +64,24 @@ jobs: echo "VERSION=${TAG#v}" >> $GITHUB_ENV - name: Checkout code-server-aur repo - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: repository: "cdrci/code-server-aur" token: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }} ref: "master" - - name: Merge in master - run: | - git remote add upstream https://github.com/coder/code-server-aur.git - git fetch upstream - git merge upstream/master - - name: Configure git run: | git config --global user.name cdrci git config --global user.email opensource@coder.com + - name: Fetch and reset master + run: | + git remote add upstream https://github.com/coder/code-server-aur.git + git fetch upstream + git reset --hard upstream/master + git push --force + - name: Validate package uses: heyhusen/archlinux-package-action@c9f94059ccbebe8710d31d582f33ef4e84fe575c # v3.0.0 with: @@ -107,27 +108,27 @@ jobs: run: | echo "VERSION=${TAG#v}" >> $GITHUB_ENV - - uses: actions/checkout@v6 - - uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3 - - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 + - uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 + - uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 + - uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - uses: robinraju/release-downloader@daf26c55d821e836577a15f77d86ddc078948b05 # v1.12 + - uses: robinraju/release-downloader@28fc21f50d76778e7023361aa1f863e717d3d56f # v1.13 with: repository: "coder/code-server" tag: v${{ env.VERSION }} fileName: "*.deb" out-file-path: "release-packages" - - uses: robinraju/release-downloader@daf26c55d821e836577a15f77d86ddc078948b05 # v1.12 + - uses: robinraju/release-downloader@28fc21f50d76778e7023361aa1f863e717d3d56f # v1.13 with: repository: "coder/code-server" tag: v${{ env.VERSION }} @@ -135,3 +136,32 @@ jobs: out-file-path: "release-packages" - run: npm run publish:docker + + repo: + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }} + TAG: ${{ inputs.version || github.ref_name }} + needs: docker + + steps: + - name: Set version to tag without leading v + run: | + echo "VERSION=${TAG#v}" >> $GITHUB_ENV + + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + + - run: ./ci/build/update-repo.sh + + - name: Open PR + run: | + git config --global user.name cdrci + git config --global user.email opensource@coder.com + git checkout -b "helm/$VERSION" + git add . + git commit -m "Update Helm chart and changelog with $VERSION" + git push -u origin "$(git branch --show)" + gh pr create \ + --repo coder/code-server \ + --body-file .cache/checklist \ + --title "Update to $VERSION" diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index fdce9e0604dd..8f2979e20ed3 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -6,6 +6,11 @@ on: version: type: string required: true + pull_request_target: + types: + - closed + branches: + - main permissions: contents: write # For creating releases. @@ -21,6 +26,9 @@ jobs: package-linux: name: ${{ format('linux-{0}', matrix.vscode_arch) }} runs-on: ubuntu-22.04 + if: >- + (github.event_name == 'workflow_dispatch') || + (github.event_name == 'pull_request_target' && github.event.pull_request.merged == true && startsWith(github.head_ref, 'update/')) strategy: matrix: @@ -39,7 +47,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - TAG: ${{ inputs.version || github.ref_name }} + TAG: ${{ inputs.version || github.event.pull_request.head.ref || github.ref_name }} # Set release package name. ARCH: ${{ matrix.package_arch }} # Cross-compile target. @@ -64,15 +72,16 @@ jobs: curl -sSfL https://github.com/goreleaser/nfpm/releases/download/v2.3.1/nfpm_2.3.1_`uname -s`_`uname -m`.tar.gz | tar -C ~/.local/bin -zxv nfpm echo "$HOME/.local/bin" >> $GITHUB_PATH - - name: Set version to tag without leading v + - name: Strip update/ and v from tag run: | - echo "VERSION=${TAG#v}" >> $GITHUB_ENV + version=${TAG#update/} + echo "VERSION=${version#v}" >> $GITHUB_ENV - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: submodules: true - run: quilt push -a - - uses: actions/setup-node@v6 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: .node-version cache: npm @@ -99,12 +108,18 @@ jobs: if: ${{ matrix.vscode_arch == 'x64' }} - run: tar -czf package.tar.gz release if: ${{ matrix.vscode_arch == 'x64' }} + - run: | + sed "/^## Unreleased/,/^## / ! d" CHANGELOG.md | head -n -2 | tail -n +3 > .cache/release-notes + if: ${{ matrix.vscode_arch == 'x64' }} - uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1 if: ${{ matrix.vscode_arch == 'x64' }} with: draft: true discussion_category_name: "📣 Announcements" files: package.tar.gz + tag_name: v${{ env.VERSION }} + name: v${{ env.VERSION }} + body_path: .cache/release-notes # Platform-specific release. - run: KEEP_MODULES=1 npm run release @@ -114,10 +129,15 @@ jobs: draft: true discussion_category_name: "📣 Announcements" files: ./release-packages/* + tag_name: v${{ env.VERSION }} + name: v${{ env.VERSION }} package-macos: name: ${{ matrix.vscode_target }} runs-on: ${{ matrix.os }} + if: >- + (github.event_name == 'workflow_dispatch') || + (github.event_name == 'pull_request_target' && github.event.pull_request.merged == true && startsWith(github.head_ref, 'update/')) strategy: matrix: include: @@ -128,7 +148,7 @@ jobs: env: VSCODE_TARGET: ${{ matrix.vscode_target }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - TAG: ${{ inputs.version || github.ref_name }} + TAG: ${{ inputs.version || github.event.pull_request.head.ref || github.ref_name }} # Ensure native modules are built from source to avoid prebuilds. npm_config_build_from_source: true @@ -144,15 +164,16 @@ jobs: curl -sSfL https://github.com/goreleaser/nfpm/releases/download/v2.3.1/nfpm_2.3.1_`uname -s`_`uname -m`.tar.gz | tar -C ~/.local/bin -zxv nfpm echo "$HOME/.local/bin" >> $GITHUB_PATH - - name: Set version to tag without leading v + - name: Strip update/ and v from tag run: | - echo "VERSION=${TAG#v}" >> $GITHUB_ENV + version=${TAG#update/} + echo "VERSION=${version#v}" >> $GITHUB_ENV - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: submodules: true - run: quilt push -a - - uses: actions/setup-node@v6 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: .node-version cache: npm @@ -172,3 +193,5 @@ jobs: draft: true discussion_category_name: "📣 Announcements" files: ./release-packages/* + tag_name: v${{ env.VERSION }} + name: v${{ env.VERSION }} diff --git a/.github/workflows/scripts.yaml b/.github/workflows/scripts.yaml index d6b2728ad66f..4ebef47ea875 100644 --- a/.github/workflows/scripts.yaml +++ b/.github/workflows/scripts.yaml @@ -41,7 +41,7 @@ jobs: container: "alpine:3.17" steps: - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Install test utilities run: apk add bats checkbashisms @@ -58,7 +58,7 @@ jobs: timeout-minutes: 5 steps: - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Install lint utilities run: sudo apt install shellcheck diff --git a/.github/workflows/security.yaml b/.github/workflows/security.yaml index 129ef3d174ed..ba4bcbba5da1 100644 --- a/.github/workflows/security.yaml +++ b/.github/workflows/security.yaml @@ -25,12 +25,12 @@ jobs: timeout-minutes: 15 steps: - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: fetch-depth: 0 - name: Install Node.js - uses: actions/setup-node@v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: .node-version @@ -46,12 +46,12 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: fetch-depth: 0 - name: Run Trivy vulnerability scanner in repo mode - uses: aquasecurity/trivy-action@97e0b3872f55f89b95b2f65b3dbab56962816478 + uses: aquasecurity/trivy-action@314ff8b43182423b84c50b1670b0e10f858f2d98 # latest with: scan-type: "fs" scan-ref: "." @@ -62,7 +62,7 @@ jobs: severity: "HIGH,CRITICAL" - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v4 + uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4 with: sarif_file: "trivy-repo-results.sarif" @@ -76,17 +76,17 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v4 + uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4 with: config-file: ./.github/codeql-config.yml languages: javascript - name: Autobuild - uses: github/codeql-action/autobuild@v4 + uses: github/codeql-action/autobuild@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v4 + uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4 diff --git a/.github/workflows/trivy-docker.yaml b/.github/workflows/trivy-docker.yaml index 350fe4a59989..98a8d8c4063f 100644 --- a/.github/workflows/trivy-docker.yaml +++ b/.github/workflows/trivy-docker.yaml @@ -18,8 +18,6 @@ on: - .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: @@ -48,10 +46,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Run Trivy vulnerability scanner in image mode - uses: aquasecurity/trivy-action@97e0b3872f55f89b95b2f65b3dbab56962816478 + uses: aquasecurity/trivy-action@314ff8b43182423b84c50b1670b0e10f858f2d98 # latest with: image-ref: "docker.io/codercom/code-server:latest" ignore-unfixed: true @@ -60,6 +58,6 @@ jobs: severity: "HIGH,CRITICAL" - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v4 + uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4 with: sarif_file: "trivy-image-results.sarif" diff --git a/.github/workflows/update.yaml b/.github/workflows/update.yaml new file mode 100644 index 000000000000..3ea12c5d9e07 --- /dev/null +++ b/.github/workflows/update.yaml @@ -0,0 +1,72 @@ +name: Update code-server + +on: + workflow_dispatch: + inputs: + version: + type: string + required: true + schedule: + - cron: "0 16,21 * * *" + +jobs: + update: + runs-on: ubuntu-latest + env: + TAG: ${{ inputs.version }} + GH_TOKEN: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }} + + steps: + - name: Fetch latest tag + if: env.TAG == '' + run: | + tag=$(curl -fsSLI -o /dev/null -w "%{url_effective}" https://github.com/microsoft/vscode/releases/latest) + tag="${tag#https://github.com/microsoft/vscode/releases/tag/}" + echo "TAG=$tag" >> $GITHUB_ENV + + - name: Remove leading v from tag + run: | + echo "VERSION=${TAG#v}" >> $GITHUB_ENV + + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + submodules: true + + - name: Check current version + id: check + run: | + commit="$(git -C lib/vscode rev-parse HEAD)" + if [[ $(git -C lib/vscode ls-remote --tags | grep "$commit") == */"$VERSION" ]] ; then + echo "$VERSION update has already been merged into $(git rev-parse --abbrev-ref HEAD)" + echo done=true >> $GITHUB_OUTPUT + elif git ls-remote --exit-code --heads origin "update/$VERSION" ; then + echo "There is already a PR for updating to $VERSION" + echo done=true >> $GITHUB_OUTPUT + else + echo "$VERSION update has not started yet" + echo done=false >> $GITHUB_OUTPUT + fi + + - uses: awalsh128/cache-apt-pkgs-action@2c09a5e66da6c8016428a2172bd76e5e4f14bb17 # latest + if: steps.check.outputs.done == 'false' + with: + packages: quilt + version: 1.0 + + - run: ./ci/build/update-vscode.sh + if: steps.check.outputs.done == 'false' + + - name: Open PR + if: steps.check.outputs.done == 'false' + run: | + git config --global user.name cdrci + git config --global user.email opensource@coder.com + git checkout -b "update/$VERSION" + git add . + git commit -m "Update Code to $VERSION" + git push -u origin "$(git branch --show)" + gh pr create \ + --repo coder/code-server \ + --title "Update Code to $VERSION" \ + --body-file .cache/checklist \ + --draft diff --git a/.gitignore b/.gitignore index ae15a5e43beb..7fea491b82ac 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ node_modules .home coverage **/.DS_Store +*.bak # Code packages itself here. /lib/vscode-reh-web-* diff --git a/CHANGELOG.md b/CHANGELOG.md index d2b4118bf239..4b5da51f146e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,64 @@ Code v99.99.999 ## Unreleased +## [4.122.0](https://github.com/coder/code-server/releases/tag/v4.122.0) - 2026-05-29 + +Code v1.122.0 + +### Changed + +- Update to Code 1.122.0 + +### Fixed + +- `--app-name` will now affect window titles within the editor (it is now used + as the value for `${appName}` in the title template) as well as some other + places like the help > about dialog. + +### Added + +- App name can now be set with the `CODE_SERVER_APP_NAME` environment variable. + +## [4.121.0](https://github.com/coder/code-server/releases/tag/v4.121.0) - 2026-05-20 + +Code v1.121.0 + +### Changed + +- Update to Code 1.121.0 + +## [4.118.0](https://github.com/coder/code-server/releases/tag/v4.118.0) - 2026-05-06 + +Code v1.118.0 + +### Changed + +- Update to Code 1.118.0 + +## [4.117.0](https://github.com/coder/code-server/releases/tag/v4.117.0) - 2026-04-22 + +Code v1.117.0 + +### Changed + +- Update to Code 1.117.0 + +## [4.116.0](https://github.com/coder/code-server/releases/tag/v4.116.0) - 2026-04-16 + +Code v1.116.0 + +### Changed + +- Update to Code 1.116.0 + +## [4.115.0](https://github.com/coder/code-server/releases/tag/v4.115.0) - 2026-04-08 + +Code v1.115.0 + +### Changed + +- Update to Code 1.115.0 + ## [4.114.1](https://github.com/coder/code-server/releases/tag/v4.114.1) - 2026-04-06 Code v1.114.0 diff --git a/ci/build/build-vscode.sh b/ci/build/build-vscode.sh index fba95b31f7ef..871a801aa30f 100755 --- a/ci/build/build-vscode.sh +++ b/ci/build/build-vscode.sh @@ -107,6 +107,9 @@ main() { EOF ) > product.json + + VSCODE_QUALITY=stable npm run gulp compile-copilot-extension-full-build + npm run gulp core-ci npm run gulp "vscode-reh-web-$VSCODE_TARGET${MINIFY:+-min}-ci" diff --git a/ci/build/update-repo.sh b/ci/build/update-repo.sh new file mode 100755 index 000000000000..e36afaf9daaf --- /dev/null +++ b/ci/build/update-repo.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +set -Eeuo pipefail + +function update_helm() { + local current + current=$(yq .version ci/helm-chart/Chart.yaml) + local next + next=$(semver "$current" -i minor) + echo "Bumping version from $current to $next..." + sed -i.bak "s/^version: $current\$/version: $next/" ci/helm-chart/Chart.yaml + + echo "Setting app version and image to $version..." + sed -i.bak "s/^appVersion: .\+\$/appVersion: $version/" ci/helm-chart/Chart.yaml + sed -i.bak "s/^ tag: .\+\$/ tag: '$version'/" ci/helm-chart/values.yaml +} + +function update_changelog() { + local date + date=$(printf '%(%Y-%m-%d)T\n' -1) + local link="https://github.com/coder/code-server/releases/tag/v$version" + sed -i.bak "s|## Unreleased|## Unreleased\n\n## [$version]($link) - $date|" CHANGELOG.md +} + +function main() { + cd "$(dirname "${0}")/../.." + + source ./ci/lib.sh + + local version=${VERSION:-$(git describe --tags)} + version="${version#v}" + + declare -a steps + + steps+=( + "Update Helm chart" "update_helm" + "Update changelog" "update_changelog" + ) + + # Even if a step failed, still output the last checkmark. + run-steps "${steps[@]}" || true + + # This step is always manual. + echo "- [ ] https://github.com/coder/code-server-aur/pulls" >> .cache/checklist +} + +main "$@" diff --git a/ci/build/update-vscode.sh b/ci/build/update-vscode.sh new file mode 100755 index 000000000000..26a43cd9b4cb --- /dev/null +++ b/ci/build/update-vscode.sh @@ -0,0 +1,156 @@ +#!/usr/bin/env bash + +set -Eeuo pipefail + +function unapply_patches() { + local -i exit_code=0 + quiet quilt pop -af || exit_code=$? + case $exit_code in + # Sucessfully unapplied. + 0) ;; + # No more patches to unapply. + 2) ;; + # Some error. + *) return $exit_code ;; + esac +} + +function update_vscode() { + pushd lib/vscode + if ! git checkout 2>&1 "$target_vscode_version" ; then + echo "$target_vscode_version does not exist locally, fetching..." + git fetch --all --prune --tags + echo "Checking out $target_vscode_version again..." + git checkout "$target_vscode_version" + fi + popd +} + +function refresh_patches() { + local -i exit_code=0 + while quiet quilt push ; ! (( exit_code=$? )) ; do + quilt refresh + done + case $exit_code in + # No more patches to apply. + 2) ;; + # Some error. + *) return $exit_code ;; + esac +} + +function update_node() { + local node_version + node_version=$(cat .node-version) + if [[ $node_version == "$target_node_version" ]] ; then + echo "Already set to $target_node_version" + else + echo "Updating from $node_version to $target_node_version..." + echo "$target_node_version" > .node-version + fi +} + +function get-webview-script-hash() { + local html + html=$(<"$1") + local start_tag='" + html=${html##*"$start_tag"} + html=${html%%"$end_tag"*} + echo -n "$html" | openssl sha256 -binary | openssl base64 +} + +function update_csp() { + local current + current=$(quilt top 2>/dev/null || echo "") + local patch_action="" + echo "Currently at ${current:-base}" + if [[ $current != */webview.diff ]] ; then + echo "Moving to patches/webview.diff..." + local -i exit_code=0 + if quilt applied 2>/dev/null | grep --quiet webview.diff ; then + quiet quilt pop webview || exit_code=$? + patch_action=pop + else + quiet quilt push webview || exit_code=$? + patch_action=push + fi + case $exit_code in + # Successfully moved. + 0) ;; + # Some error. + *) return $exit_code ;; + esac + fi + + local file=lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index.html + local hash + hash=$(get-webview-script-hash "$file") + echo "Calculated hash as $hash" + # Use octothorpe as a delimiter since the hash may contain a slash. + sed -i.bak "s#script-src 'sha256-[^']\+'#script-src 'sha256-$hash'#" "$file" + quilt refresh + + if [[ $patch_action != "" ]] ; then + echo "Moving back to ${current:-base}..." + case $patch_action in + pop) quiet quilt push "$current" ;; + push) quiet quilt pop "${current:--a}" ;; + esac + fi +} + +function add_changelog() { + local file=CHANGELOG.md + if grep --quiet "Code $target_vscode_version" "$file" ; then + echo "Changelog for $target_vscode_version already exists" + else + # TODO: This is not exactly robust. In particular, it needs to handle if + # there is already a "changed" section. + sed -i.bak "s/## Unreleased/## Unreleased\n\nCode v$target_vscode_version\n\n### Changed\n\n- Update to Code $target_vscode_version/" "$file" + fi +} + +function main() { + cd "$(dirname "${0}")/../.." + + source ./ci/lib.sh + + local target_node_version + target_node_version=$(grep target lib/vscode/remote/.npmrc | awk -F= '{print $2}' | tr -d '"') + + declare -a steps + + # If version is not set, assume we are already at the target version and the + # user is just trying to resolve conflics. + local target_vscode_version + if [[ ${VERSION-} ]] ; then + # Removing patches only needs to be done locally; in CI we start from a + # fresh clone each time. + if [[ ! ${CI-} ]] ; then + steps+=("Unapplying patches" "unapply_patches") + fi + target_vscode_version="${VERSION#v}" + steps+=( + "Update Code to $target_vscode_version" "update_vscode" + "Refresh Code patches" "refresh_patches" + ) + else + target_vscode_version="$(git -C lib/vscode describe --tags --exact-match)" + echo "Detected Code version $target_vscode_version" + fi + + steps+=( + "Set Node version to $target_node_version" "update_node" + "Update CSP webview hash" "update_csp" + "Add changelog note" "add_changelog" + ) + + # Even if a step failed, still output the last checkmark. + run-steps "${steps[@]}" || true + + # This step is always manual. + echo "- [ ] Verify changelog" >> .cache/checklist +} + +main "$@" diff --git a/ci/helm-chart/Chart.yaml b/ci/helm-chart/Chart.yaml index 155f4d880c5a..eeb2cf3f1836 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: 3.34.0 +version: 3.37.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.114.1 +appVersion: 4.122.0 diff --git a/ci/helm-chart/templates/deployment.yaml b/ci/helm-chart/templates/deployment.yaml index 38b855e83abd..18bece028fc6 100644 --- a/ci/helm-chart/templates/deployment.yaml +++ b/ci/helm-chart/templates/deployment.yaml @@ -8,7 +8,9 @@ metadata: annotations: {{- toYaml .Values.annotations | nindent 4 }} {{- end }} spec: - replicas: {{ .Values.replicaCount | default 1 }} + {{- if ne .Values.replicaCount nil }} + replicas: {{ .Values.replicaCount }} + {{- end }} strategy: type: Recreate selector: diff --git a/ci/helm-chart/values.yaml b/ci/helm-chart/values.yaml index 349ee431cff7..7406fa1ffb64 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.114.1' + tag: '4.122.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 71a875c6914b..df38a9552891 100755 --- a/ci/lib.sh +++ b/ci/lib.sh @@ -78,6 +78,43 @@ nodeArch() { echo "$cpu" } +run-steps() { + local -i failed=0 + mkdir -p .cache + rm -f .cache/checklist + while (( $# )) ; do + local name=$1 ; shift + local fn=$1 ; shift + # Only run if an earlier step has not failed. + if [[ $failed == 0 ]] ; then + echo "$name..." + if $fn | indent ; then + echo "- [X] $name" >> .cache/checklist + else + ((failed++)) + fi + fi + # For all failed steps, write out an empty checkbox. + if [[ $failed != 0 ]] ; then + echo "- [ ] $name" >> .cache/checklist + fi + done + if [[ $failed != 0 ]] ; then + return 1 + fi +} + +quiet() { + "$@" >/dev/null +} + +indent() { + local count=2 + local space + space=$(printf "%${count}s") + sed "s/^/$space| /g" +} + # See gulpfile.reh.ts for available targets. if [[ ! ${VSCODE_TARGET-} ]]; then VSCODE_TARGET="$(nodeOS)-$(nodeArch)" diff --git a/ci/release-image/docker-bake.hcl b/ci/release-image/docker-bake.hcl index 7ed867c28747..ecb0c313daed 100644 --- a/ci/release-image/docker-bake.hcl +++ b/ci/release-image/docker-bake.hcl @@ -20,6 +20,7 @@ group "default" { "code-server-debian-12", "code-server-ubuntu-focal", "code-server-ubuntu-noble", + "code-server-ubuntu-resolute", "code-server-fedora-39", "code-server-opensuse-tumbleweed", ] @@ -73,7 +74,6 @@ target "code-server-debian-12" { target "code-server-ubuntu-focal" { dockerfile = "ci/release-image/Dockerfile" tags = concat( - gen_tags_for_docker_and_ghcr("ubuntu"), gen_tags_for_docker_and_ghcr("focal"), ) args = { @@ -86,6 +86,7 @@ target "code-server-ubuntu-noble" { dockerfile = "ci/release-image/Dockerfile" tags = concat( gen_tags_for_docker_and_ghcr("noble"), + gen_tags_for_docker_and_ghcr("ubuntu"), ) args = { BASE = "ubuntu:noble" @@ -93,6 +94,17 @@ target "code-server-ubuntu-noble" { platforms = ["linux/amd64", "linux/arm64"] } +target "code-server-ubuntu-resolute" { + dockerfile = "ci/release-image/Dockerfile" + tags = concat( + gen_tags_for_docker_and_ghcr("resolute"), + ) + args = { + BASE = "ubuntu:resolute" + } + platforms = ["linux/amd64", "linux/arm64"] +} + target "code-server-fedora-39" { dockerfile = "ci/release-image/Dockerfile.fedora" tags = concat( diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 3a3705e6dc7b..a2087ff17672 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -93,17 +93,20 @@ commits first if you are doing this). ### Version updates to Code -1. Remove any patches with `quilt pop -a`. -2. Update the `lib/vscode` submodule to the desired upstream version branch. - 1. `cd lib/vscode && git checkout release/1.66 && cd ../..` - 2. `git add lib && git commit -m "chore: update to Code "` -3. Apply the patches one at a time (`quilt push`). If the application succeeds - but the lines changed, update the patch with `quilt refresh`. If there are - conflicts, then force apply with `quilt push -f`, manually add back the - rejected code, then run `quilt refresh`. -4. From the code-server **project root**, run `npm install`. -5. Check the Node.js version that's used by Electron (which is shipped with VS - Code. If necessary, update our version of Node.js to match. +PRs will be automatically created with updates to VS Code. If a patch cannot be +automatically resolved, it will be necessary to clone the branch, resolve the +conflicts manually, and finish the update. To do this: + +1. Apply as many patches as possible `quilt push -a`. +2. Once you hit a conflict, force apply with `quilt push -f`, manually add back + the rejected code, then run `quilt refresh`. +3. Once all patches have been resolved, run `./ci/build/update.sh` to finish the + update process. +4. Commit all changes, push them up to the branch, and update the checklist in + the PR description. + +Once the PR is ready, manually verify that the unreleased changelog section +contains all the changes going into this version before merging. ### Patching Code diff --git a/lib/vscode b/lib/vscode index e7fb5e96c073..6a49527b96e3 160000 --- a/lib/vscode +++ b/lib/vscode @@ -1 +1 @@ -Subproject commit e7fb5e96c0730b9deb70b33781f98e2f35975036 +Subproject commit 6a49527b96e326fe62fbdb56f60e16877c9aa724 diff --git a/package-lock.json b/package-lock.json index 29013575294f..07b9c058ec10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -58,7 +58,7 @@ "eslint-plugin-import": "^2.28.1", "eslint-plugin-prettier": "^5.0.0", "globals": "^16.1.0", - "prettier": "3.6.2", + "prettier": "3.8.3", "prettier-plugin-sh": "^0.18.0", "ts-node": "^10.9.1", "typescript": "^5.6.2", @@ -968,9 +968,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1639,9 +1639,9 @@ "license": "MIT" }, "node_modules/basic-ftp": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.2.0.tgz", - "integrity": "sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.0.tgz", + "integrity": "sha512-5K9eNNn7ywHPsYnFwjKgYH8Hf8B5emh7JKcPaVjjrMJFQQwGpwowEnZNEtHs7DfR7hCZsmaK3VA4HUK0YarT+w==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -1672,9 +1672,9 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dev": true, "license": "MIT", "dependencies": { @@ -3102,9 +3102,9 @@ "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", "funding": [ { "type": "individual", @@ -3637,9 +3637,9 @@ } }, "node_modules/ip-address": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", - "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", + "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", "license": "MIT", "engines": { "node": ">= 12" @@ -5042,9 +5042,9 @@ "license": "MIT" }, "node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", "license": "MIT", "funding": { "type": "opencollective", @@ -5100,9 +5100,9 @@ } }, "node_modules/prettier": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", - "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", + "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", "dev": true, "license": "MIT", "bin": { @@ -5197,9 +5197,9 @@ } }, "node_modules/qs": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", - "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", + "version": "6.15.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz", + "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -6613,9 +6613,9 @@ "license": "ISC" }, "node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "version": "8.20.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz", + "integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==", "license": "MIT", "engines": { "node": ">=10.0.0" diff --git a/package.json b/package.json index 4f01a218b2fa..b229efb3f5e5 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "eslint-plugin-import": "^2.28.1", "eslint-plugin-prettier": "^5.0.0", "globals": "^16.1.0", - "prettier": "3.6.2", + "prettier": "3.8.3", "prettier-plugin-sh": "^0.18.0", "ts-node": "^10.9.1", "typescript": "^5.6.2", diff --git a/patches/app-name.diff b/patches/app-name.diff new file mode 100644 index 000000000000..32cb90ed0c28 --- /dev/null +++ b/patches/app-name.diff @@ -0,0 +1,46 @@ +Apply --app-name to VS Code web page titles + +VS Code's `${appName}` title variable comes from `productService.nameLong` in the +web client. code-server already injects per-request product configuration into +VS Code's web bootstrap, so set `nameShort`/`nameLong` from the existing +`--app-name` CLI arg there. + +This keeps the patch minimal and makes browser tab titles honor `--app-name` +without changing unrelated product metadata. + +Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts ++++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts +@@ -24,6 +24,7 @@ export const serverOptions: OptionDescri + 'disable-getting-started-override': { type: 'boolean' }, + 'locale': { type: 'string' }, + 'link-protection-trusted-domains': { type: 'string[]' }, ++ 'app-name': { type: 'string' }, + + /* ----- server setup ----- */ + +@@ -124,6 +125,7 @@ export interface ServerParsedArgs { + 'disable-getting-started-override'?: boolean, + 'locale'?: string + 'link-protection-trusted-domains'?: string[], ++ 'app-name'?: string, + + /* ----- server setup ----- */ + +Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts ++++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts +@@ -366,8 +366,11 @@ export class WebClientServer { + linkProtectionTrustedDomains.push(...this._productService.linkProtectionTrustedDomains); + } + ++ const appName = this._environmentService.args['app-name']; + const productConfiguration: Partial> = { + codeServerVersion: this._productService.codeServerVersion, ++ nameShort: appName, ++ nameLong: appName, + rootEndpoint: rootBase, + updateEndpoint: !this._environmentService.args['disable-update-check'] ? rootBase + '/update/check' : undefined, + logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? rootBase + '/logout' : undefined, diff --git a/patches/clipboard.diff b/patches/clipboard.diff index 98af2bf73227..d4658b231494 100644 --- a/patches/clipboard.diff +++ b/patches/clipboard.diff @@ -78,7 +78,7 @@ Index: code-server/lib/vscode/src/vs/platform/environment/common/argv.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/platform/environment/common/argv.ts +++ code-server/lib/vscode/src/vs/platform/environment/common/argv.ts -@@ -144,6 +144,7 @@ export interface NativeParsedArgs { +@@ -146,6 +146,7 @@ export interface NativeParsedArgs { 'disable-chromium-sandbox'?: boolean; sandbox?: boolean; 'enable-coi'?: boolean; diff --git a/patches/copilot.diff b/patches/copilot.diff new file mode 100644 index 000000000000..c525d33a24fa --- /dev/null +++ b/patches/copilot.diff @@ -0,0 +1,163 @@ +Index: code-server/lib/vscode/build/gulpfile.extensions.ts +=================================================================== +--- code-server.orig/lib/vscode/build/gulpfile.extensions.ts ++++ code-server/lib/vscode/build/gulpfile.extensions.ts +@@ -291,6 +291,29 @@ export const compileCopilotExtensionBuil + task.task(compileCopilotExtensionBuildTask); + + /** ++ * Compiles the built-in copilot extension with proper `.vscodeignore` filtering ++ * and materializes native dependency shims (`node-pty`, `ripgrep`). ++ * Produces output equivalent to what CI ships from the pre-built VSIX. ++ * ++ * The result is placed in `.build/extensions/copilot/` and can be copied ++ * directly into a VS Code Insiders installation at: ++ * `/resources/app/extensions/copilot/` ++ */ ++export const compileCopilotExtensionFullBuildTask = task.define('compile-copilot-extension-full-build', task.series( ++ // Step 1: Clean previous copilot build output ++ task.define('clean-copilot-build', util.rimraf('.build/extensions/copilot')), ++ // Step 2: Build and package with proper `.vscodeignore` filtering ++ task.define('package-copilot-extension-full', () => ext.packageCopilotExtensionFullStream().pipe(gulp.dest('.build'))), ++ // Step 3: Materialize native dependency shims (`node-pty`, `ripgrep`) ++ task.define('copilot-extension-native-shims', () => { ++ const copilotExtDir = path.join(root, '.build', 'extensions', 'copilot'); ++ ext.prepareCopilotExtensionNativeShims(copilotExtDir); ++ return Promise.resolve(); ++ }) ++)); ++task.task(compileCopilotExtensionFullBuildTask); ++ ++/** + * Compiles the extensions for the build. + * This is essentially a helper task that combines {@link cleanExtensionsBuildTask}, {@link compileNonNativeExtensionsBuildTask} and {@link compileNativeExtensionsBuildTask} + */ +Index: code-server/lib/vscode/build/lib/extensions.ts +=================================================================== +--- code-server.orig/lib/vscode/build/lib/extensions.ts ++++ code-server/lib/vscode/build/lib/extensions.ts +@@ -21,6 +21,7 @@ import { getProductionDependencies } fro + import { type IExtensionDefinition, getExtensionStream } from './builtInExtensions.ts'; + import { fetchUrls, fetchGithub } from './fetch.ts'; + import { createTsgoStream, spawnTsgo } from './tsgo.ts'; ++import { prepareBuiltInCopilotRipgrepShim } from './copilot.ts'; + import watcher from './watch/index.ts'; + + import { createRequire } from 'module'; +@@ -483,6 +484,116 @@ export function packageCopilotExtensionS + ).pipe(util2.setExecutableBit(['**/*.sh'])); + } + ++/** ++ * Package the built-in copilot extension as a properly filtered VSIX-equivalent. ++ * Unlike {@link packageCopilotExtensionStream}, this uses vsce.listFiles with ++ * PackageManager.Npm so that .vscodeignore is respected for dependency filtering, ++ * producing output equivalent to what CI ships from the pre-built VSIX. ++ */ ++export function packageCopilotExtensionFullStream(): Stream { ++ const vsce = require('@vscode/vsce') as typeof import('@vscode/vsce'); ++ const extensionPath = path.join(root, 'extensions', 'copilot'); ++ if (!fs.existsSync(extensionPath)) { ++ return es.readArray([]); ++ } ++ ++ const esbuildConfigFileName = '.esbuild.mts'; ++ const esbuildScript = path.join(extensionPath, esbuildConfigFileName); ++ if (!fs.existsSync(esbuildScript)) { ++ throw new Error(`Copilot esbuild script not found at ${esbuildScript}`); ++ } ++ ++ const result = es.through(); ++ ++ // Step 1: Run esbuild to compile the extension ++ new Promise((resolve, reject) => { ++ const proc = cp.execFile(process.argv[0], [esbuildScript], { cwd: extensionPath }, (error, _stdout, stderr) => { ++ if (error) { ++ return reject(error); ++ } ++ const matches = (stderr || '').match(/\> (.+): error: (.+)?/g); ++ fancyLog(`Bundled extension: ${ansiColors.yellow(path.join('copilot', esbuildConfigFileName))} with ${matches ? matches.length : 0} errors.`); ++ for (const match of matches || []) { ++ fancyLog.error(match); ++ } ++ return resolve(); ++ }); ++ proc.stdout!.on('data', (data) => { ++ fancyLog(`${ansiColors.green('esbuilding copilot')}: ${data.toString('utf8')}`); ++ }); ++ }).then(() => { ++ // Step 2: Use `vsce.listFiles` with Npm package manager so `.vscodeignore` ++ // is applied to both source files AND `node_modules` dependencies. ++ // This is the key difference from `packageCopilotExtensionStream` which ++ // uses `PackageManager.None` and then blindly merges all production deps. ++ return vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Npm }); ++ }).then(fileNames => { ++ const files = fileNames ++ .map(fileName => path.join(extensionPath, fileName)) ++ .map(filePath => new File({ ++ path: filePath, ++ stat: fs.statSync(filePath), ++ base: extensionPath, ++ contents: fs.createReadStream(filePath) ++ })); ++ ++ es.readArray(files).pipe(result); ++ }).catch(err => { ++ console.error('Failed to package copilot extension:', err); ++ result.emit('error', err); ++ }); ++ ++ // Apply the same package.json cleanup as bundled extensions get ++ const cleaned = updateExtensionPackageJSON( ++ result.pipe(rename(p => p.dirname = `extensions/copilot/${p.dirname}`)), ++ (data: any) => { ++ delete data.scripts; ++ delete data.dependencies; ++ delete data.devDependencies; ++ if (data.main) { ++ data.main = data.main.replace('/out/', '/dist/'); ++ } ++ return data; ++ } ++ ); ++ ++ return minifyExtensionResources(cleaned) ++ .pipe(util2.setExecutableBit(['**/*.sh'])); ++} ++ ++/** ++ * Materializes native dependency shims (`node-pty`, `ripgrep`) into the copilot ++ * extension output at {@link outputDir}. Uses the root `node_modules` as the ++ * source for native binaries, targeting the current platform/arch. ++ * ++ * This is the equivalent of what {@link copyCopilotNativeDepsTask} in ++ * `gulpfile.vscode.ts` does during a full product build, but scoped to ++ * just the standalone copilot extension output. ++ * ++ * Failures are logged as warnings rather than throwing, since the copilot ++ * extension can still create shims at runtime if they are missing. ++ */ ++export function prepareCopilotExtensionNativeShims(outputDir: string): void { ++ const platform = process.platform; ++ const arch = process.arch; ++ const appNodeModulesDir = path.join(root, 'node_modules'); ++ ++ if (!fs.existsSync(outputDir)) { ++ fancyLog.warn('[prepareCopilotExtensionNativeShims] Copilot extension not found at', outputDir, '- skipping shims'); ++ return; ++ } ++ ++ try { ++ prepareBuiltInCopilotRipgrepShim(platform, arch, outputDir, appNodeModulesDir); ++ fancyLog(`[prepareCopilotExtensionNativeShims] Materialized native shims for ${platform}-${arch}`); ++ } catch (err) { ++ // Downgrade to a warning for local builds since the extension ++ // can still function without shims (it creates them at runtime). ++ fancyLog.warn(`[prepareCopilotExtensionNativeShims] Failed to materialize shims: ${err}`); ++ fancyLog.warn('[prepareCopilotExtensionNativeShims] The extension will still work but will create shims at runtime.'); ++ } ++} ++ + export function packageMarketplaceExtensionsStream(forWeb: boolean): Stream { + const marketplaceExtensionsDescriptions = [ + ...builtInExtensions.filter(({ name }) => (forWeb ? !marketplaceWebExtensionsExclude.has(name) : true)), diff --git a/patches/disable-builtin-ext-update.diff b/patches/disable-builtin-ext-update.diff index 3a4e21bb5c88..20af3023a47c 100644 --- a/patches/disable-builtin-ext-update.diff +++ b/patches/disable-builtin-ext-update.diff @@ -8,7 +8,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens --- code-server.orig/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -342,6 +342,10 @@ export class Extension implements IExten - if (this.type === ExtensionType.System && this.productService.quality === 'stable') { + if (this.type === ExtensionType.System && this.productService.quality === 'stable' && !this.productService.builtInExtensionsEnabledWithAutoUpdates?.some(id => id.toLowerCase() === this.identifier.id.toLowerCase())) { return false; } + // Do not update builtin extensions. diff --git a/patches/display-language.diff b/patches/display-language.diff index ea28cf3f2529..526272fe5775 100644 --- a/patches/display-language.diff +++ b/patches/display-language.diff @@ -18,7 +18,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts import { ProtocolConstants } from '../../base/parts/ipc/common/ipc.net.js'; import { IConfigurationService } from '../../platform/configuration/common/configuration.js'; import { ConfigurationService } from '../../platform/configuration/common/configurationService.js'; -@@ -301,6 +301,9 @@ export async function setupServerService +@@ -359,6 +359,9 @@ export async function setupServerService socketServer.registerChannel('mcpManagement', new McpManagementChannel(mcpManagementService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority))); @@ -198,7 +198,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts /* ----- server setup ----- */ -@@ -116,6 +117,7 @@ export interface ServerParsedArgs { +@@ -120,6 +121,7 @@ export interface ServerParsedArgs { 'disable-file-downloads'?: boolean; 'disable-file-uploads'?: boolean; 'disable-getting-started-override'?: boolean, @@ -291,7 +291,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens } // Prefers to run on UI -@@ -2072,17 +2069,6 @@ export class SetLanguageAction extends E +@@ -2284,17 +2281,6 @@ export class SetLanguageAction extends E update(): void { this.enabled = false; this.class = SetLanguageAction.DisabledClass; @@ -309,7 +309,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens } override async run(): Promise { -@@ -2099,7 +2085,6 @@ export class ClearLanguageAction extends +@@ -2311,7 +2297,6 @@ export class ClearLanguageAction extends private static readonly DisabledClass = `${this.EnabledClass} disabled`; constructor( @@ -317,7 +317,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens @ILocaleService private readonly localeService: ILocaleService, ) { super(ClearLanguageAction.ID, ClearLanguageAction.TITLE.value, ClearLanguageAction.DisabledClass, false); -@@ -2109,17 +2094,6 @@ export class ClearLanguageAction extends +@@ -2321,17 +2306,6 @@ export class ClearLanguageAction extends update(): void { this.enabled = false; this.class = ClearLanguageAction.DisabledClass; diff --git a/patches/external-file-actions.diff b/patches/external-file-actions.diff index 8cf16119155a..582384af6cee 100644 --- a/patches/external-file-actions.diff +++ b/patches/external-file-actions.diff @@ -27,7 +27,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts +++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts -@@ -303,6 +303,16 @@ export interface IWorkbenchConstructionO +@@ -312,6 +312,16 @@ export interface IWorkbenchConstructionO */ readonly userDataPath?: string @@ -99,7 +99,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts /* ----- server setup ----- */ -@@ -110,6 +112,8 @@ export interface ServerParsedArgs { +@@ -114,6 +116,8 @@ export interface ServerParsedArgs { /* ----- code-server ----- */ 'disable-update-check'?: boolean; 'auth'?: string; @@ -166,8 +166,8 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions import { AutoSaveAfterShortDelayContext } from '../../../services/filesConfiguration/common/filesConfigurationService.js'; import { WorkbenchListDoubleSelection } from '../../../../platform/list/browser/listService.js'; import { Schemas } from '../../../../base/common/network.js'; --import { DirtyWorkingCopiesContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, WorkbenchStateContext, WorkspaceFolderCountContext, SidebarFocusContext, ActiveEditorCanRevertContext, ActiveEditorContext, ResourceContextKey, ActiveEditorAvailableEditorIdsContext, MultipleEditorsSelectedInGroupContext, TwoEditorsSelectedInGroupContext, SelectedEditorsInGroupFileOrUntitledResourceContextKey } from '../../../common/contextkeys.js'; -+import { IsEnabledFileDownloads, IsEnabledFileUploads, DirtyWorkingCopiesContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, WorkbenchStateContext, WorkspaceFolderCountContext, SidebarFocusContext, ActiveEditorCanRevertContext, ActiveEditorContext, ResourceContextKey, ActiveEditorAvailableEditorIdsContext, MultipleEditorsSelectedInGroupContext, TwoEditorsSelectedInGroupContext, SelectedEditorsInGroupFileOrUntitledResourceContextKey } from '../../../common/contextkeys.js'; +-import { DirtyWorkingCopiesContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsSessionsWindowContext, WorkbenchStateContext, WorkspaceFolderCountContext, SidebarFocusContext, ActiveEditorCanRevertContext, ActiveEditorContext, ResourceContextKey, ActiveEditorAvailableEditorIdsContext, MultipleEditorsSelectedInGroupContext, TwoEditorsSelectedInGroupContext, SelectedEditorsInGroupFileOrUntitledResourceContextKey } from '../../../common/contextkeys.js'; ++import { IsEnabledFileDownloads, IsEnabledFileUploads, DirtyWorkingCopiesContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsSessionsWindowContext, WorkbenchStateContext, WorkspaceFolderCountContext, SidebarFocusContext, ActiveEditorCanRevertContext, ActiveEditorContext, ResourceContextKey, ActiveEditorAvailableEditorIdsContext, MultipleEditorsSelectedInGroupContext, TwoEditorsSelectedInGroupContext, SelectedEditorsInGroupFileOrUntitledResourceContextKey } from '../../../common/contextkeys.js'; import { IsWebContext } from '../../../../platform/contextkey/common/contextkeys.js'; import { ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js'; import { ThemeIcon } from '../../../../base/common/themables.js'; @@ -207,7 +207,7 @@ Index: code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts +++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts -@@ -41,6 +41,9 @@ export const EmbedderIdentifierContext = +@@ -40,6 +40,9 @@ export const EmbedderIdentifierContext = export const InAutomationContext = new RawContextKey('inAutomation', false, localize('inAutomation', "Whether VS Code is running under automation/smoke test")); diff --git a/patches/getting-started.diff b/patches/getting-started.diff index 79ecad219153..7135955f6efe 100644 --- a/patches/getting-started.diff +++ b/patches/getting-started.diff @@ -28,7 +28,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro import { IEditorOpenContext, IEditorSerializer } from '../../../common/editor.js'; import { IWebviewElement, IWebviewService } from '../../webview/browser/webview.js'; import './gettingStartedColors.js'; -@@ -924,6 +924,72 @@ export class GettingStartedPage extends +@@ -928,6 +928,72 @@ export class GettingStartedPage extends $('p.subtitle.description', {}, localize({ key: 'gettingStarted.editingEvolved', comment: ['Shown as subtitle on the Welcome page.'] }, "Editing evolved")) ); @@ -101,7 +101,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro const leftColumn = $('.categories-column.categories-column-left', {},); const rightColumn = $('.categories-column.categories-column-right', {},); -@@ -959,6 +1025,9 @@ export class GettingStartedPage extends +@@ -977,6 +1043,9 @@ export class GettingStartedPage extends recentList.setLimit(5); reset(leftColumn, startList.getDomElement(), recentList.getDomElement()); } @@ -135,7 +135,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts +++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts -@@ -313,6 +313,11 @@ export interface IWorkbenchConstructionO +@@ -322,6 +322,11 @@ export interface IWorkbenchConstructionO */ readonly isEnabledFileUploads?: boolean @@ -189,7 +189,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts /* ----- server setup ----- */ -@@ -114,6 +115,7 @@ export interface ServerParsedArgs { +@@ -118,6 +119,7 @@ export interface ServerParsedArgs { 'auth'?: string; 'disable-file-downloads'?: boolean; 'disable-file-uploads'?: boolean; @@ -234,7 +234,7 @@ Index: code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts +++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts -@@ -43,6 +43,7 @@ export const InAutomationContext = new R +@@ -42,6 +42,7 @@ export const InAutomationContext = new R export const IsEnabledFileDownloads = new RawContextKey('isEnabledFileDownloads', true, true); export const IsEnabledFileUploads = new RawContextKey('isEnabledFileUploads', true, true); diff --git a/patches/local-storage.diff b/patches/local-storage.diff index f633a1b80b84..986eb4dde3ba 100644 --- a/patches/local-storage.diff +++ b/patches/local-storage.diff @@ -30,7 +30,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts +++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts -@@ -298,6 +298,11 @@ export interface IWorkbenchConstructionO +@@ -307,6 +307,11 @@ export interface IWorkbenchConstructionO */ readonly configurationDefaults?: Record; diff --git a/patches/logout.diff b/patches/logout.diff index 0c1f281a21ff..c21be0de9115 100644 --- a/patches/logout.diff +++ b/patches/logout.diff @@ -28,7 +28,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts /* ----- server setup ----- */ -@@ -108,6 +109,7 @@ export const serverOptions: OptionDescri +@@ -112,6 +113,7 @@ export const serverOptions: OptionDescri export interface ServerParsedArgs { /* ----- code-server ----- */ 'disable-update-check'?: boolean; diff --git a/patches/series b/patches/series index ffc15fdd9d75..6f438da313bf 100644 --- a/patches/series +++ b/patches/series @@ -22,3 +22,5 @@ clipboard.diff display-language.diff trusted-domains.diff signature-verification.diff +copilot.diff +app-name.diff diff --git a/patches/sourcemaps.diff b/patches/sourcemaps.diff index d1f477dfdfbe..615edca9dad4 100644 --- a/patches/sourcemaps.diff +++ b/patches/sourcemaps.diff @@ -1,43 +1,25 @@ -Make sourcemaps self-hosted +Remove sourcemaps URL -Normally source maps get removed as part of the build process so prevent that -from happening. Also avoid using the windows.net host since obviously we can -not host our source maps there and want them to be self-hosted even if we could. - -To test try debugging/browsing the source of a build in a browser. +These will not work since we patch VS Code. Index: code-server/lib/vscode/build/gulpfile.reh.ts =================================================================== --- code-server.orig/lib/vscode/build/gulpfile.reh.ts +++ code-server/lib/vscode/build/gulpfile.reh.ts -@@ -263,8 +263,7 @@ function packageTask(type: string, platf +@@ -255,10 +255,15 @@ function packageTask(type: string, platf + const destination = path.join(BUILD_ROOT, destinationFolderName); + return () => { ++ const jsFilterMain = util.filter(data => !data.isDirectory() && /\.js$/.test(data.path)); ++ const src = gulp.src(sourceFolderName + '/**', { base: '.' }) .pipe(rename(function (path) { path.dirname = path.dirname!.replace(new RegExp('^' + sourceFolderName), 'out'); })) -- .pipe(util.setExecutableBit(['**/*.sh'])) + .pipe(util.setExecutableBit(['**/*.sh'])) - .pipe(filter(['**', '!**/*.{js,css}.map'])); -+ .pipe(util.setExecutableBit(['**/*.sh'])); ++ .pipe(filter(['**', '!**/*.{js,css}.map'])) ++ .pipe(jsFilterMain) ++ .pipe(util.stripSourceMappingURL()) ++ .pipe(jsFilterMain.restore); const workspaceExtensionPoints = ['debuggers', 'jsonValidation']; const isUIExtension = (manifest: { extensionKind?: string; main?: string; contributes?: Record }) => { -@@ -304,9 +303,9 @@ function packageTask(type: string, platf - .map(name => `.build/extensions/${name}/**`); - - const extensions = gulp.src(extensionPaths, { base: '.build', dot: true }); -- const extensionsCommonDependencies = gulp.src('.build/extensions/node_modules/**', { base: '.build', dot: true }); -- const sources = es.merge(src, extensions, extensionsCommonDependencies) -+ const extensionsCommonDependencies = gulp.src('.build/extensions/node_modules/**', { base: '.build', dot: true }) - .pipe(filter(['**', '!**/*.{js,css}.map'], { dot: true })); -+ const sources = es.merge(src, extensions, extensionsCommonDependencies); - - let version = packageJson.version; - const quality = (product as typeof product & { quality?: string }).quality; -@@ -501,7 +500,7 @@ function tweakProductForServerWeb(produc - const minifyTask = task.define(`minify-vscode-${type}`, task.series( - bundleTask, - util.rimraf(`out-vscode-${type}-min`), -- optimize.minifyTask(`out-vscode-${type}`, `https://main.vscode-cdn.net/sourcemaps/${commit}/core`) -+ optimize.minifyTask(`out-vscode-${type}`, ``) - )); - gulp.task(minifyTask); - diff --git a/patches/store-socket.diff b/patches/store-socket.diff index c2bca06c907f..ffbd9d15d37f 100644 --- a/patches/store-socket.diff +++ b/patches/store-socket.diff @@ -31,7 +31,7 @@ Index: code-server/lib/vscode/src/vs/workbench/api/node/extHostExtensionService. import { ExtHostDiskFileSystemProvider } from './extHostDiskFileSystemProvider.js'; import nodeModule from 'node:module'; import { assertType } from '../../../base/common/types.js'; -@@ -226,6 +228,52 @@ export class ExtHostExtensionService ext +@@ -175,6 +177,52 @@ export class ExtHostExtensionService ext performance.mark('code/extHost/didInitAPI'); diff --git a/patches/telemetry.diff b/patches/telemetry.diff index c830e09b0614..462d3ce01c77 100644 --- a/patches/telemetry.diff +++ b/patches/telemetry.diff @@ -28,7 +28,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts import { NullPolicyService } from '../../platform/policy/common/policy.js'; import { OneDataSystemAppender } from '../../platform/telemetry/node/1dsAppender.js'; import { LoggerService } from '../../platform/log/node/loggerService.js'; -@@ -174,11 +176,23 @@ export async function setupServerService +@@ -176,11 +178,23 @@ export async function setupServerService const requestService = new RequestService('remote', configurationService, environmentService, logService); services.set(IRequestService, requestService); diff --git a/patches/trusted-domains.diff b/patches/trusted-domains.diff index 0444cada7e9e..9d42246bda34 100644 --- a/patches/trusted-domains.diff +++ b/patches/trusted-domains.diff @@ -12,7 +12,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts /* ----- server setup ----- */ -@@ -118,6 +119,7 @@ export interface ServerParsedArgs { +@@ -122,6 +123,7 @@ export interface ServerParsedArgs { 'disable-file-uploads'?: boolean; 'disable-getting-started-override'?: boolean, 'locale'?: string diff --git a/patches/unique-db.diff b/patches/unique-db.diff index abe17ad75a95..9d4f2ae39913 100644 --- a/patches/unique-db.diff +++ b/patches/unique-db.diff @@ -21,7 +21,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/storage/browser/storageS export class BrowserStorageService extends AbstractStorageService { -@@ -300,7 +301,11 @@ export class IndexedDBStorageDatabase ex +@@ -328,7 +329,11 @@ export class IndexedDBStorageDatabase ex } static async createWorkspaceStorage(workspaceId: string, logService: ILogService): Promise { diff --git a/patches/update-check.diff b/patches/update-check.diff index 6f0de4ba9e84..d668e4254c9f 100644 --- a/patches/update-check.diff +++ b/patches/update-check.diff @@ -101,7 +101,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts readonly version: string; readonly date?: string; -@@ -115,6 +116,7 @@ export interface IProductConfiguration { +@@ -119,6 +120,7 @@ export interface IProductConfiguration { readonly resourceUrlTemplate: string; readonly nlsBaseUrl: string; readonly accessSKUs?: string[]; @@ -134,7 +134,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts /* ----- server setup ----- */ -@@ -104,6 +106,8 @@ export const serverOptions: OptionDescri +@@ -108,6 +110,8 @@ export const serverOptions: OptionDescri }; export interface ServerParsedArgs { diff --git a/patches/webview.diff b/patches/webview.diff index f3b825ed3dd8..a1ce247be496 100644 --- a/patches/webview.diff +++ b/patches/webview.diff @@ -41,7 +41,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts +++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts -@@ -223,7 +223,7 @@ export class BrowserWorkbenchEnvironment +@@ -226,7 +226,7 @@ export class BrowserWorkbenchEnvironment @memoize get webviewExternalEndpoint(): string { @@ -70,21 +70,21 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index -+ content="default-src 'none'; script-src 'sha256-nQZh+9dHKZP2cHbhYlCbWDtqxxJtGjRGBx57zNP2DZM=' 'self'; frame-src 'self'; style-src 'unsafe-inline';"> +- content="default-src 'none'; script-src 'sha256-q+WTr+fBXpLLE3++yWNaxT6BTWQtsKscoeIlynBRk4E=' 'self'; frame-src 'self'; style-src 'unsafe-inline';"> ++ content="default-src 'none'; script-src 'sha256-m1DlJtsIJd46QuWYNcsaYIG1xI+9FyjKQu+cfp+zq5Q=' 'self'; frame-src 'self'; style-src 'unsafe-inline';"> { - /** - * @param {MessageEvent} event -@@ -370,6 +370,12 @@ + if (navigator.serviceWorker.controller) { + // A previous SW is already controlling. Force an update +@@ -332,6 +332,12 @@ const hostname = location.hostname; diff --git a/src/node/cli.ts b/src/node/cli.ts index ac4ee32f0deb..0946c8e04344 100644 --- a/src/node/cli.ts +++ b/src/node/cli.ts @@ -677,9 +677,7 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config } args["proxy-domain"] = finalProxies - if (!args["app-name"]) { - args["app-name"] = "code-server" - } + args["app-name"] ??= process.env.CODE_SERVER_APP_NAME || "code-server" args._ = getResolvedPathsFromArgs(args) diff --git a/test/e2e/appName.test.ts b/test/e2e/appName.test.ts new file mode 100644 index 000000000000..a12795cb0b33 --- /dev/null +++ b/test/e2e/appName.test.ts @@ -0,0 +1,9 @@ +import { version } from "../../src/node/constants" +import { describe, test, expect } from "./baseFixture" + +const appName = "testnäme" +describe("--app-name", [`--app-name=${appName}`], {}, () => { + test("should use app-name for the title", async ({ codeServerPage }) => { + expect(await codeServerPage.page.title()).toContain(appName) + }) +}) diff --git a/test/e2e/models/CodeServer.ts b/test/e2e/models/CodeServer.ts index d7f9a176c94a..4017445db752 100644 --- a/test/e2e/models/CodeServer.ts +++ b/test/e2e/models/CodeServer.ts @@ -77,11 +77,14 @@ export class CodeServer { */ private async createWorkspace(): Promise { const dir = await this.workspaceDir - await fs.mkdir(path.join(dir, "Machine"), { recursive: true }) + await fs.mkdir(path.join(dir, "User"), { recursive: true }) await fs.writeFile( - path.join(dir, "Machine/settings.json"), + path.join(dir, "User/settings.json"), JSON.stringify({ "workbench.startupEditor": "none", + // Disable the welcome popup so we can avoid having to click through it + // on every test. + "workbench.welcomePage.experimentalOnboarding": false, }), "utf8", ) diff --git a/test/package-lock.json b/test/package-lock.json index 9945e42f474a..171c8d085db8 100644 --- a/test/package-lock.json +++ b/test/package-lock.json @@ -18,7 +18,7 @@ "jest-fetch-mock": "^3.0.3", "jsdom": "^16.4.0", "node-fetch": "^2.6.7", - "playwright": "^1.56.1", + "playwright": "^1.59.1", "ts-jest": "^27.0.7", "wtfnode": "^0.9.1" } @@ -1013,6 +1013,53 @@ "node": ">=18" } }, + "node_modules/@playwright/test/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/@playwright/test/node_modules/playwright": { + "version": "1.56.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.56.1.tgz", + "integrity": "sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.56.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/@playwright/test/node_modules/playwright-core": { + "version": "1.56.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.56.1.tgz", + "integrity": "sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@sinonjs/commons": { "version": "1.8.6", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", @@ -3645,9 +3692,9 @@ } }, "node_modules/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "dev": true, "license": "MIT" }, @@ -4067,13 +4114,13 @@ } }, "node_modules/playwright": { - "version": "1.56.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.56.1.tgz", - "integrity": "sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==", + "version": "1.59.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.59.1.tgz", + "integrity": "sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.56.1" + "playwright-core": "1.59.1" }, "bin": { "playwright": "cli.js" @@ -4086,9 +4133,9 @@ } }, "node_modules/playwright-core": { - "version": "1.56.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.56.1.tgz", - "integrity": "sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==", + "version": "1.59.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.59.1.tgz", + "integrity": "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/test/package.json b/test/package.json index 205d75a4e9f7..508876c785f2 100644 --- a/test/package.json +++ b/test/package.json @@ -14,7 +14,7 @@ "jest-fetch-mock": "^3.0.3", "jsdom": "^16.4.0", "node-fetch": "^2.6.7", - "playwright": "^1.56.1", + "playwright": "^1.59.1", "ts-jest": "^27.0.7", "wtfnode": "^0.9.1" }, diff --git a/test/playwright.config.ts b/test/playwright.config.ts index 3dea45370c58..1de4b92ca3b6 100644 --- a/test/playwright.config.ts +++ b/test/playwright.config.ts @@ -5,10 +5,10 @@ import path from "path" // The default configuration runs all tests in three browsers with workers equal // to half the available threads. See 'npm run test:e2e --help' to customize // from the command line. For example: -// npm run test:e2e --workers 1 # Run with one worker -// npm run test:e2e --project Chromium # Only run on Chromium -// npm run test:e2e --grep login # Run tests matching "login" -// PWDEBUG=1 npm run test:e2e # Run Playwright inspector +// npm run test:e2e -- --workers 1 # Run with one worker +// npm run test:e2e -- --project Chromium # Only run on Chromium +// npm run test:e2e -- --grep login # Run tests matching "login" +// PWDEBUG=1 npm run test:e2e # Run Playwright inspector const config: PlaywrightTestConfig = { testDir: path.join(__dirname, "e2e"), // Search for tests in this directory. timeout: 60000, // Each test is given 60 seconds. @@ -33,10 +33,12 @@ const config: PlaywrightTestConfig = { // name: "Firefox", // use: { browserName: "firefox" }, // }, - { - name: "WebKit", - use: { browserName: "webkit" }, - }, + // Keeps failing with "Underlying ArrayBuffer has been detached from the view or out-of-bounds" + // Not sure what we can do about it...so skip for now. + // { + // name: "WebKit", + // use: { browserName: "webkit" }, + // }, ], }