Public: anyone can read this; the crew can change it.
Boot the published arm64 manifest after a release push #12375
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/12374-boot-the-published-arm64-manifest-after → main 4 commits fork 2 threads · 2 unresolved
2 files
changed +42
−0
.forgejo/workflows/release.yml +28
| @@ -160,3 +160,31 @@ jobs: | ||
| 160 | 160 | sed -i "s/^name:.*/name: $APP/" charts/app/Chart.yaml |
| 161 | 161 | helm package charts/app --version "$V" --app-version "$V" |
| 162 | 162 | helm push "$APP-$V.tgz" "oci://$REGISTRY/$OWNER/charts" --plain-http |
| 163 | ||
| 164 | # The build proves arm64 under emulation before it pushes; this proves what | |
| 165 | # was pushed (#12374): the registry's linux/arm64 manifest, pulled by digest, | |
| 166 | # booted by the same proof the Dockerfile runs (src/release/boot.ts: health | |
| 167 | # must answer as the image's stamped version), after checking that stamp is | |
| 168 | # this release's and that boot.ts ran as arm64. buildkit pulls and runs it | |
| 169 | # (qemu, when the runner is not arm64), so no container runtime is needed. | |
| 170 | - name: boot the published arm64 manifest | |
| 171 | run: | | |
| 172 | set -eu | |
| 173 | mkdir -p arm64-proof | |
| 174 | cat > arm64-proof/Dockerfile <<'DOCKERFILE' | |
| 175 | ARG REF | |
| 176 | FROM --platform=linux/arm64 ${REF} | |
| 177 | ARG VERSION | |
| 178 | USER bun | |
| 179 | RUN set -eu; \ | |
| 180 | [ "$FORGE_VERSION" = "$VERSION" ] || { echo "FATAL: the image is stamped $FORGE_VERSION, not $VERSION"; exit 1; }; \ | |
| 181 | out="$(bun src/release/boot.ts --budget 600)"; echo "$out"; \ | |
| 182 | case "$out" in *"(arm64)"*) ;; *) echo "FATAL: boot.ts did not run as arm64"; exit 1;; esac | |
| 183 | DOCKERFILE | |
| 184 | buildctl --addr "$BUILDKIT_HOST" build \ | |
| 185 | --frontend dockerfile.v0 \ | |
| 186 | --local context=arm64-proof --local dockerfile=arm64-proof \ | |
| 187 | --opt build-arg:REF="$REG_PUB/$OWNER/$APP@$DIGEST" \ | |
| 188 | --opt build-arg:VERSION="$V" \ | |
| 189 | --opt platform=linux/arm64 \ | |
| 190 | --no-cache |
test/release-gate.test.ts +14
| @@ -40,6 +40,20 @@ describe("the release gate", () => { | ||
| 40 | 40 | expect(read(join(ROOT, "Dockerfile"))).toContain("RUN bun src/release/boot.ts"); |
| 41 | 41 | }); |
| 42 | 42 | |
| 43 | test("the published arm64 manifest is booted after the push, by digest, with the release's boot proof", () => { | |
| 44 | const push = release.indexOf("- name: build & push image"); | |
| 45 | const boot = release.indexOf("- name: boot the published arm64 manifest"); | |
| 46 | expect(boot).toBeGreaterThan(push); | |
| 47 | const step = release.slice(boot); | |
| 48 | expect(step).toContain("FROM --platform=linux/arm64 ${REF}"); | |
| 49 | expect(step).toContain('build-arg:REF="$REG_PUB/$OWNER/$APP@$DIGEST"'); | |
| 50 | expect(step).toContain("--opt platform=linux/arm64"); | |
| 51 | // One definition of "it boots": the Dockerfile's, with its emulated budget. | |
| 52 | expect(step).toContain("bun src/release/boot.ts --budget 600"); | |
| 53 | expect(step).toContain('build-arg:VERSION="$V"'); | |
| 54 | expect(step).toContain("(arm64)"); | |
| 55 | }); | |
| 56 | ||
| 43 | 57 | test("no workflow run by a push, a pull or a tag runs the suite", () => { |
| 44 | 58 | const suite = /test-shards\.ts|\bbun test\b/; |
| 45 | 59 | const onEvent = /^\s+(push|pull_request|pull_request_target):/m; |
new above
offline
150 iterations x 1s is too tight under qemu emulation; the Dockerfile allows 600s for the same boot. Raise to match (e.g. 600) so emulated runners do not fail a good release.