Compare commits

..

6 Commits

Author SHA1 Message Date
Asher
1605d68709 Update contribution steps for updating
You can now more easily run the update script to finish out an update
and the documentation is updated to match.
2026-05-08 11:20:56 -08:00
Asher
93ce398e28 Make update cron run twice daily
Every hour seems aggressive, typically I will only check for PRs once a
day anyway.
2026-05-08 09:58:12 -08:00
Asher
62a552d896 Check for updates on a schedule 2026-05-07 15:20:49 -08:00
Asher
bd41dca064 Add 4.119.0 to the changelog 2026-05-07 12:10:55 -08:00
Asher
3dbddaaadf Ignore .bak files from sed operations 2026-05-07 12:10:55 -08:00
Asher
58491f317f Add workflow for updating VS Code
For now it is manually triggered.
2026-05-07 10:46:13 -08:00
7 changed files with 174 additions and 51 deletions

View File

@@ -51,7 +51,7 @@ jobs:
fetch-depth: 0
- name: Run Trivy vulnerability scanner in repo mode
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # latest
uses: aquasecurity/trivy-action@97e0b3872f55f89b95b2f65b3dbab56962816478 # latest
with:
scan-type: "fs"
scan-ref: "."

View File

@@ -51,7 +51,7 @@ jobs:
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Run Trivy vulnerability scanner in image mode
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # latest
uses: aquasecurity/trivy-action@97e0b3872f55f89b95b2f65b3dbab56962816478 # latest
with:
image-ref: "docker.io/codercom/code-server:latest"
ignore-unfixed: true

72
.github/workflows/update.yaml vendored Normal file
View File

@@ -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 VS Code to $VERSION"
git push -u origin "$(git branch --show)"
gh pr create \
--repo coder/code-server \
--title "Update VS Code to $VERSION" \
--body-file .cache/checklist \
--draft

1
.gitignore vendored
View File

@@ -11,6 +11,7 @@ node_modules
.home
coverage
**/.DS_Store
*.bak
# Code packages itself here.
/lib/vscode-reh-web-*

View File

@@ -22,6 +22,14 @@ Code v99.99.999
## Unreleased
## [4.119.0](https://github.com/coder/code-server/releases/tag/v4.119.0) - 2026-05-07
Code v1.119.0
### Changed
- Update to Code 1.119.0
## [4.118.0](https://github.com/coder/code-server/releases/tag/v4.118.0) - 2026-05-06
Code v1.118.0

View File

@@ -2,13 +2,24 @@
set -Eeuo pipefail
function remove_patches() {
function quiet() {
"$@" >/dev/null
}
function indent() {
local count=2
local space
space=$(printf "%${count}s")
sed "s/^/$space| /g"
}
function unapply_patches() {
local -i exit_code=0
quilt pop -af || exit_code=$?
quiet quilt pop -af || exit_code=$?
case $exit_code in
# Sucessfully removed.
# Sucessfully unapplied.
0) ;;
# No more patches to remove.
# No more patches to unapply.
2) ;;
# Some error.
*) return $exit_code ;;
@@ -17,19 +28,18 @@ function remove_patches() {
function update_vscode() {
pushd lib/vscode
if ! git checkout "$VERSION" ; then
echo "$VERSION does not exist locally, fetching..."
if ! git checkout 2>&1 "$target_vscode_version" ; then
echo "$target_vscode_version does not exist locally, fetching..."
git fetch --all --prune
git checkout "$VERSION"
git checkout "$target_vscode_version"
fi
popd
}
function refresh_patches() {
local -i exit_code=0
while quilt push ; ! (( exit_code=$? )) ; do
while quiet quilt push ; ! (( exit_code=$? )) ; do
quilt refresh
echo # Extra new line for separation.
done
case $exit_code in
# No more patches to apply.
@@ -42,8 +52,8 @@ function refresh_patches() {
function update_node() {
local node_version
node_version=$(cat .node-version)
if [[ $node_version == $target_node_version ]] ; then
echo "$node_version already matches $target_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
@@ -52,26 +62,37 @@ function update_node() {
function get-webview-script-hash() {
local html
html=$(<$1)
html=$(<"$1")
local start_tag='<script async type="module">'
local end_tag="</script>"
html=${html##*$start_tag}
html=${html%%$end_tag*}
html=${html##*"$start_tag"}
html=${html%%"$end_tag"*}
echo -n "$html" | openssl sha256 -binary | openssl base64
}
function update_csp() {
local -i exit_code=0
# Move back to the webview patch so it can be refreshed.
quilt pop webview || exit_code=$?
case $exit_code in
# Successfully moved.
0) ;;
# Already at the patch.
2) ;;
# Some error.
*) return $exit_code ;;
esac
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")
@@ -79,8 +100,14 @@ function update_csp() {
# 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
# Get patched back up.
quilt push -a
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 run() {
@@ -91,8 +118,8 @@ function run() {
local fn=$1 ; shift
# Only run if an earlier step has not failed.
if [[ $failed == 0 ]] ; then
echo "[+] $name..."
if $fn ; then
echo "$name..."
if $fn | indent ; then
echo "- [X] $name" >> .cache/checklist
else
((failed++))
@@ -110,12 +137,12 @@ function run() {
function add_changelog() {
local file=CHANGELOG.md
if grep "Code $VERSION" "$file" ; then
echo "Changelog for $VERSION already exists"
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$VERSION\n\n### Changed\n\n- Update to Code $VERSION/" "$file"
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
}
@@ -128,15 +155,27 @@ function main() {
target_node_version=$(grep target lib/vscode/remote/.npmrc | awk -F= '{print $2}' | tr -d '"')
declare -a steps
# Removing patches only needs to be done locally; in CI we start from a fresh
# clone each time.
if [[ ! ${CI-} ]] ; then
steps+=("Remove patches" "remove_patches")
# 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 VS Code to $target_vscode_version" "update_vscode"
"Refresh VS Code patches" "refresh_patches"
)
else
target_vscode_version="$(git -C lib/vscode describe --tags --exact-match)"
echo "Detected VS Code version $target_vscode_version"
fi
steps+=(
"Update VS Code to $VERSION" "update_vscode"
"Refresh VS Code patches" "refresh_patches"
"Set Node version to $target_node_version" "update_node"
"Update CSP webview hash" "update_csp"
"Add changelog note" "add_changelog"

View File

@@ -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 <version>"`
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