-
Notifications
You must be signed in to change notification settings - Fork 0
224 lines (204 loc) · 10.2 KB
/
Copy pathauto-update.yml
File metadata and controls
224 lines (204 loc) · 10.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
name: auto-update
# Daily check against Microsoft's stable channel for a new VSCode
# release. If the SHA on the latest-redirect doesn't match what the
# recipe pins, open a PR that bumps the recipe (per-arch SRCREVs,
# tarball timestamps, sha256 checksums, and the LICENSES.chromium.html
# md5) and renames the file to vscode_<new-version>.bb.
#
# The PR is left for human review before merging -- automated bumps
# of opaque binary blobs are exactly the case where a human eye on
# the diff is valuable.
on:
schedule:
# 10:42 UTC daily. Microsoft typically publishes stable releases
# mid-month around 17:00-22:00 UTC; a morning-UTC poll picks them
# up the next day reliably without piling on right after release.
- cron: '42 10 * * *'
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
check-and-update:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
# Need full history so we can detect whether an auto-update
# branch with the new version already exists.
fetch-depth: 0
- name: Resolve Microsoft's latest stable URLs
id: resolve
run: |
set -eo pipefail
for arch in x64 arm64 armhf; do
url=$(curl -sLI "https://update.code.visualstudio.com/latest/linux-$arch/stable" \
| awk 'BEGIN{IGNORECASE=1} /^location:/{print $2}' \
| tr -d '\r' | tail -1)
if [ -z "$url" ]; then
echo "::error::failed to resolve URL for $arch"
exit 1
fi
# URL pattern: .../stable/<sha>/code-stable-<arch>-<timestamp>.tar.gz
sha=$(echo "$url" | awk -F/ '{print $(NF-1)}')
ts=$(echo "$url" | awk -F/ '{print $NF}' | sed -E "s/code-stable-${arch}-([0-9]+)\.tar\.gz/\1/")
echo "$arch url: $url"
echo "$arch sha: $sha"
echo "$arch ts: $ts"
echo "url_$arch=$url" >> "$GITHUB_OUTPUT"
echo "sha_$arch=$sha" >> "$GITHUB_OUTPUT"
echo "ts_$arch=$ts" >> "$GITHUB_OUTPUT"
done
- name: Read current recipe state
id: current
run: |
set -eo pipefail
recipe=$(ls recipes-devtools/vscode/vscode_*.bb)
ver=$(basename "$recipe" .bb | sed 's/^vscode_//')
cur_sha=$(awk -F'"' '/^GIT_SHA[[:space:]]*=/ { print $2; exit }' "$recipe")
echo "recipe=$recipe" >> "$GITHUB_OUTPUT"
echo "version=$ver" >> "$GITHUB_OUTPUT"
echo "git_sha=$cur_sha" >> "$GITHUB_OUTPUT"
echo "Current: $recipe / version=$ver / GIT_SHA=$cur_sha"
- name: Skip if upstream SHA matches current recipe
id: gate
run: |
set -eo pipefail
# All three arches publish in lockstep under the same SHA;
# if any of them diverge the recipe layout doesn't support
# it anyway, so use x64 as the canonical signal.
if [ "${{ steps.resolve.outputs.sha_x64 }}" = "${{ steps.current.outputs.git_sha }}" ]; then
echo "Already at latest stable SHA ${{ steps.current.outputs.git_sha }}; nothing to do."
echo "needs_update=false" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "Upstream has new SHA: ${{ steps.resolve.outputs.sha_x64 }} (recipe pins ${{ steps.current.outputs.git_sha }})"
echo "needs_update=true" >> "$GITHUB_OUTPUT"
- name: Fetch tarballs and compute checksums + license md5
if: steps.gate.outputs.needs_update == 'true'
id: checksums
run: |
set -eo pipefail
mkdir -p /tmp/vscode-tarballs
for arch in x64 arm64 armhf; do
url_var="url_$arch"
url="${{ steps.resolve.outputs.url_x64 }}"
# Re-resolve per-arch URL via output (matrix-style)
case $arch in
x64) url="${{ steps.resolve.outputs.url_x64 }}" ;;
arm64) url="${{ steps.resolve.outputs.url_arm64 }}" ;;
armhf) url="${{ steps.resolve.outputs.url_armhf }}" ;;
esac
echo "Downloading $arch from $url"
curl -sLo "/tmp/vscode-tarballs/$arch.tgz" "$url"
sum=$(sha256sum "/tmp/vscode-tarballs/$arch.tgz" | cut -d' ' -f1)
echo "sha256_$arch=$sum" >> "$GITHUB_OUTPUT"
echo "$arch: $sum"
done
# All three tarballs ship the same LICENSES.chromium.html;
# extract from x64 (cheapest) and md5 it.
mkdir -p /tmp/vscode-extract
tar xzf /tmp/vscode-tarballs/x64.tgz -C /tmp/vscode-extract \
VSCode-linux-x64/LICENSES.chromium.html
lic_md5=$(md5sum /tmp/vscode-extract/VSCode-linux-x64/LICENSES.chromium.html \
| cut -d' ' -f1)
echo "license_md5=$lic_md5" >> "$GITHUB_OUTPUT"
echo "LICENSES.chromium.html md5: $lic_md5"
- name: Discover new version string
if: steps.gate.outputs.needs_update == 'true'
id: version
run: |
set -eo pipefail
# Microsoft's `/api/update/.../stable/VERSION/.../release-notes` is one
# source of the human-readable version. Simpler: parse the binary's
# ProductDevelopment from package.json inside the tarball.
mkdir -p /tmp/vscode-extract-meta
tar xzf /tmp/vscode-tarballs/x64.tgz -C /tmp/vscode-extract-meta \
VSCode-linux-x64/resources/app/package.json
ver=$(python3 -c "import json; print(json.load(open('/tmp/vscode-extract-meta/VSCode-linux-x64/resources/app/package.json'))['version'])")
echo "Detected version: $ver"
echo "version=$ver" >> "$GITHUB_OUTPUT"
- name: Bail if a branch for this version already exists
if: steps.gate.outputs.needs_update == 'true'
id: branch_check
run: |
set -eo pipefail
branch="auto-update/vscode-${{ steps.version.outputs.version }}"
if git ls-remote --heads origin "$branch" | grep -q "$branch"; then
echo "::warning::branch $branch already exists upstream; skipping (assume PR already pending)"
echo "skip=true" >> "$GITHUB_OUTPUT"
else
echo "skip=false" >> "$GITHUB_OUTPUT"
echo "branch=$branch" >> "$GITHUB_OUTPUT"
fi
- name: Update recipe in-place
if: steps.gate.outputs.needs_update == 'true' && steps.branch_check.outputs.skip != 'true'
run: |
set -eo pipefail
old_recipe="${{ steps.current.outputs.recipe }}"
new_recipe="recipes-devtools/vscode/vscode_${{ steps.version.outputs.version }}.bb"
git mv "$old_recipe" "$new_recipe"
# In-place value substitutions. Avoid sed -i's BSD/GNU split
# by using Python.
python3 - <<PYEOF
import re, pathlib
p = pathlib.Path("$new_recipe")
s = p.read_text()
subs = [
(r'^GIT_SHA = "[^"]*"',
'GIT_SHA = "${{ steps.resolve.outputs.sha_x64 }}"'),
(r'^TIMESTAMP-x64 = "[^"]*"',
'TIMESTAMP-x64 = "${{ steps.resolve.outputs.ts_x64 }}"'),
(r'^TIMESTAMP-arm64 = "[^"]*"',
'TIMESTAMP-arm64 = "${{ steps.resolve.outputs.ts_arm64 }}"'),
(r'^TIMESTAMP-armhf = "[^"]*"',
'TIMESTAMP-armhf = "${{ steps.resolve.outputs.ts_armhf }}"'),
(r'^SRC_URI\[vscode-x64\.sha256sum\][^=]*=\s*"[^"]*"',
'SRC_URI[vscode-x64.sha256sum] = "${{ steps.checksums.outputs.sha256_x64 }}"'),
(r'^SRC_URI\[vscode-arm64\.sha256sum\][^=]*=\s*"[^"]*"',
'SRC_URI[vscode-arm64.sha256sum] = "${{ steps.checksums.outputs.sha256_arm64 }}"'),
(r'^SRC_URI\[vscode-armhf\.sha256sum\][^=]*=\s*"[^"]*"',
'SRC_URI[vscode-armhf.sha256sum] = "${{ steps.checksums.outputs.sha256_armhf }}"'),
(r'LICENSES\.chromium\.html;md5=[0-9a-f]+',
'LICENSES.chromium.html;md5=${{ steps.checksums.outputs.license_md5 }}'),
]
for pat, repl in subs:
s, n = re.subn(pat, repl, s, count=1, flags=re.MULTILINE)
if n == 0:
raise SystemExit(f"pattern not matched: {pat}")
p.write_text(s)
PYEOF
echo "--- diff ---"
git diff -- "$new_recipe" || true
- name: Commit + push branch + open PR
if: steps.gate.outputs.needs_update == 'true' && steps.branch_check.outputs.skip != 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -eo pipefail
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
branch="${{ steps.branch_check.outputs.branch }}"
git checkout -b "$branch"
git add -A
git commit -m "vscode: bump to ${{ steps.version.outputs.version }}
Microsoft released VSCode ${{ steps.version.outputs.version }} (SHA
${{ steps.resolve.outputs.sha_x64 }}). Per-arch tarball timestamps:
x64 ${{ steps.resolve.outputs.ts_x64 }}
arm64 ${{ steps.resolve.outputs.ts_arm64 }}
armhf ${{ steps.resolve.outputs.ts_armhf }}
sha256 checksums and LICENSES.chromium.html md5 refreshed."
git push -u origin "$branch"
gh pr create \
--base main --head "$branch" \
--title "vscode: bump to ${{ steps.version.outputs.version }}" \
--body "Automated bump generated by .github/workflows/auto-update.yml.
Upstream details:
- SHA: \`${{ steps.resolve.outputs.sha_x64 }}\`
- Version: \`${{ steps.version.outputs.version }}\`
Per-arch tarballs:
- x64: \`${{ steps.resolve.outputs.url_x64 }}\`
- arm64: \`${{ steps.resolve.outputs.url_arm64 }}\`
- armhf: \`${{ steps.resolve.outputs.url_armhf }}\`
sha256 checksums refreshed; LICENSES.chromium.html md5 re-extracted from the new x64 tarball.
CI will run the multi-arch parse + fetch matrix and the end-to-end scarthgap build. Eyeball the diff before merging since this is a proprietary binary bump."