Repository navigation
ci(build): build release images natively per arch and merge manifests - #1705
Merged
Merged
Conversation
Release (v*) images built linux/arm64 under QEMU on amd64 runners. Emulated arm64 npm ci hangs or dies with 'qemu: uncaught target signal 4 (Illegal instruction)': in the v0.9.1 tag build (run 37678912473) MCP Docs Image hung >1.5h in arm64 'npm ci' on attempts 1 and 2 before attempt 3 got through. Each image now goes through a reusable docker-image.yml: branch builds keep one amd64 job pushing their tags directly; release builds run amd64 on ubuntu-latest and arm64 on ubuntu-24.04-arm, push by digest with SBOM + provenance, and a merge job assembles the index with the unchanged metadata-action tags and asserts it holds exactly amd64 and arm64. The backend import smoke now runs natively on every built arch against the pushed digest. arm64 gets its own registry cache ref. workflow_dispatch gains 'tag' (rebuild an existing release tag from any branch without moving it; latest only if it is the newest stable tag) and 'images' (subset to build).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Why. Release (
v*) images builtlinux/arm64under QEMU on amd64 runners. Emulated arm64npm ciis unreliable. In the v0.9.1 tag build (run 37678912473),MCP Docs Imagehung for more than 1.5 h in#30 [linux/arm64 builder 4/7] RUN npm ci --ignore-scriptson attempt 1 (cancelled 21:39Z) and again on attempt 2 (cancelled 22:31Z). Attempt 3 (22:33–22:35Z) eventually got through. EE hits the same failure asqemu: uncaught target signal 4 (Illegal instruction). Run alone, the samenpm cisucceeds, so the problem is the emulation, not a dependency.What. The workflow now follows Docker's "Distribute build across multiple runners" pattern: each architecture builds natively, pushes by digest, and a merge job combines the digests into one manifest.
.github/workflows/docker-image.yml. Each of the four image jobs indocker-build.ymlcalls it, which removes about 240 lines of duplicated steps.ubuntu-latestamd64 job pushes the metadata tags directly, with the same cache ref (:buildcache) and the same attestation flags (verified from the buildx command lines). The merge job is skipped.ubuntu-latestand arm64 onubuntu-24.04-arm.outputs: type=image,push-by-digest=true,name-canonical=true,push=trueand uploads its digest as an artifact.merge manifestjob runsdocker buildx imagetools createwith the same metadata-action tags as before ({{version}},{{major}}.{{minor}}, pluslatestvialatest=auto).linux/amd64+linux/arm64(attestation manifests excluded).sbom: true+provenance: mode=maxon releases. SearXNG keeps the buildx defaults. Each per-arch digest is an index (image + attestation manifest), andimagetools createkeeps both platforms' SBOM and provenance (verified below).:buildcache, so branch builds stay warm; arm64 uses:buildcache-arm64.build-info.jsonstamping is unchanged.changesjob: tag builds and plainworkflow_dispatchstill build all four images, and push path filtering is unchanged (it now also watchesdocker-image.yml). It also resolvesrelease_tag, the checkoutref, and thelatestflavor.workflow_dispatchinputstag(e.g.v0.9.1): checks outrefs/tags/<tag>and computes metadata as if building that tag (type=semver,…,value=<tag>; the revision label is the tag's commit). It builds both arches natively and pushes, without moving the git tag, and works when dispatched fromdev/main. A rebuild only takeslatestif<tag>is the newest stablev*tag, so rebuilding an old release can't rolllatestback. The concurrency group includes the tag, so a rebuild doesn't cancel the branch's pushes and isn't cancelled by them.images(defaultall): a comma-separated subset ofbackend, frontend, searxng, mcp-docs.docs/architecture/05-deployment.md, CHANGELOG.backend/src/dockerfile-prod-modules.test.tsnow finds the smoke script in the backend job'ssmoke_test:input. It still requirescollab-schemaand@tiptap/extension-code-block.Rebuild a release after merge
Use
images=allto republish all four images. Note:compendiq-ce-mcp-docs:0.9.1is already published (indexsha256:b19c26b2…, amd64 + arm64 + attestations), from attempt 3 of run 37678912473. A rebuild is optional; see Risks for what it re-tags.Verification
actionlint1.7.12 (rhysd/actionlintimage): 0 errors on both workflows. Both files also pass a YAML parse.changesjob scripts ran inubuntu:24.04against a scratch repo with tagsv0.9.0,v0.9.1,v0.10.0-rc.1:latest=true; older and prerelease tags givefalse.v9.9.9,0.9.1,v0.9.1;id) fail.latest=auto.imagessubsets work and unknown names fail.beforebuilds all four.dockerfile-prod-modules.test.ts: 8/8 pass.scratch_taginput that only replaced the final tags with:nativearm-test/:nativearm-test-branch. That hook commit was dropped before this head, and the runs were deleted afterwards.-f tag=v0.9.1 -f images=all), release path: success, all 13 jobs.ubuntu-24.04-arm(Architecture: aarch64); amd64 legs onubuntu-latest.[builder 4/7] RUN npm ci --ignore-scriptsfinished in 4.7 s natively on arm64 for mcp-docs.runtime require smoke okpassed on both amd64 and arm64.:0.9.1 :0.9 :latestfor every image, the same as the published v0.9.1 output (:latest==:0.9.1digest today).Index platforms: ["linux/amd64","linux/arm64"]for all four.org.opencontainers.image.revision=ce05906b…(the v0.9.1 commit, not the branch head), version0.9.1.images=all), branch path: success. It ran 4 amd64 jobs, and the merge jobs were skipped.build-info.jsonwas stamped.:0.9.1tags were left untouched. Both test runs were deleted. Nov*tag was created, moved or deleted.Risks
createdlabel, the frontendbuiltAt, and SBOM/provenance timestamps all change. Rebuilding an existing tag movesX.Y.Z,X.Y(andlatestif it is the newest tag) to new, functionally equivalent digests. The previous digests stay pullable by@sha256. Useimages=to limit what gets re-tagged.ubuntu-24.04-armrunner availability. If that label stops working, the arm64 leg queues or fails and the merge doesn't run, so nothing is tagged. It does not publish an amd64-only release.:buildcache-arm64. The test run already warmed it with v0.9.1 sources, and that cache tag was kept on purpose.<Image> / build (amd64|arm64)and<Image> / merge manifest. None of these are PR status checks (the workflow runs on push and dispatch only).