Repository navigation
ci: publish a linux/arm64 release binary and a multi-arch Docker image, run tests on PRs - #134
Open
Shashank Mittal (shashank-iitbhu) wants to merge 4 commits into
Open
Shashank Mittal (shashank-iitbhu) wants to merge 4 commits into
Shashank Mittal (shashank-iitbhu) wants to merge 4 commits into
Conversation
Tagged releases now also carry caterpillar-linux-arm64, built natively on the GitHub-hosted ubuntu-24.04-arm runner so cgo links the bundled glibc_linux_arm64 librdkafka without cross-compiling. The arm64 job hands the binary to the release job as a workflow artifact, and the existing softprops/action-gh-release step uploads both files in one call, before the Docker Hub steps run. Both build jobs check the binary's architecture with `file` and run test/pipelines/hello_name.yaml, so a wrong-arch or broken binary fails the run instead of being published. The existing `caterpillar` asset keeps its name and its x86-64 build. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Shashank Mittal (shashank-iitbhu)
requested a review
from a team
as a code owner
October 21, 2026 21:36
Go 1.25 is out of support; go-version-file: go.mod would install 1.25.0, and the x86-64 job pinned 1.24.7. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4 of 7 tasks
…lows release.yaml: - Remove the Docker Hub steps (buildx, login, metadata, build-push) and the DOCKERHUB_* secret references. The login has never succeeded and patternoss/caterpillar does not exist on Docker Hub; nothing else in the repo refers to that image. - Split the x86-64 build into its own build-linux-amd64 job. Both build jobs run on main and tags; the release job runs only on tags, downloads both binaries and uploads them in one softprops call with fail_on_unmatched_files. The caterpillar asset name is unchanged. - Least privilege: contents: read for the workflow, contents: write only for the release job, which runs no repository code. - Pin the x86-64 runner to ubuntu-24.04 (what ubuntu-latest is today) so the asset's glibc baseline doesn't move on its own. - Concurrency per ref; main runs cancel superseded runs, tag runs never cancel. ci.yaml: - Go 1.24.7 -> 1.27 (supported release). - Add go vet (copylocks disabled for three existing findings) and go test -race ./... (no external services needed). - contents: read permissions and per-PR concurrency. Both: actions/checkout v4 -> v7, actions/setup-go v5 -> v7, upload-artifact v4 -> v7, download-artifact v4 -> v8, and softprops/action-gh-release v2 -> v3.0.3 pinned to its commit. The old majors run on the deprecated Node 20 runtime. Checkout no longer persists the token. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ker Hub Build build/Dockerfile natively on ubuntu-24.04 (linux/amd64) and ubuntu-24.04-arm (linux/arm64), push each platform by digest, and merge the digests into one manifest list, following patterninc/heimdall's docker-image workflow. Tags: <version> for v* tags (v prefix stripped), dev for pushes to main, latest for the `latest` git tag. The merge job checks the published list has both platforms and that each platform's /caterpillar is an x86-64 or ARM aarch64 binary. Both Docker jobs fail early with a clear error when DOCKERHUB_USERNAME or DOCKERHUB_TOKEN is not set. The Docker jobs do not depend on the binary or release jobs, and the `latest` tag builds no binaries and creates no GitHub release. Document the image and its tags in the README. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Description
This PR changes four things in CI:
caterpillar-linux-arm64, for EKS nodes on AWS Graviton.patternoss/caterpillarimage, following the same pattern aspatterninc/heimdall'sdocker-image.yml.go vetandgo test.The existing
caterpillarasset does not change. It keeps the same name and is built by the same command on x86-64 glibc (ubuntu-24.04, which is whatubuntu-latestresolves to today). Images and tools that downloadreleases/download/<tag>/caterpillarkeep working.Merge order and prerequisites
build/Dockerfile, and onmainthat file still usesgolang:1.24.7-alpine, which can't build the module (go.modneeds a newer Go). build: require Go 1.27 (go.mod, Dockerfile builder, README) #133 moves it togolang:1.27-alpine. If this PR merges first, the Docker jobs fail on every push tomainuntil build: require Go 1.27 (go.mod, Dockerfile builder, README) #133 lands. The binary jobs and the GitHub release are not affected either way.DOCKERHUB_USERNAMEandDOCKERHUB_TOKEN(a Docker Hub access token that can push topatternoss/caterpillar). This repo has neither today, which is why the old login step always failed with "Username and password required". heimdall has them as repository secrets. Until they are added, both Docker jobs fail at their first step with an error naming the missing secret(s)..github/workflows/release.yamlTriggers. The workflow runs on pushes to
main,v*tags and thelatesttag (the same triggers as heimdall's image workflow).release(GitHub release)maindevv1.2.3tag1.2.3latesttaglatestJob graph. There are two independent chains with no
needsbetween them, so a Docker Hub failure can't block the release assets, and the other way round.build-linux-arm64job runs on the GitHub-hostedubuntu-24.04-armrunner, which is free for public repos. It uses the sameCGO_ENABLED=1 GOOS=linux go buildcommand as the x86-64 build and runs natively, so cgo needs no cross-compiling. confluent-kafka-go v2.15.0 ships a prebuiltlibrdkafka_glibc_linux_arm64.aand links it statically.build-linux-amd64andbuild-linux-arm64each build their binary, check thefileoutput (ELF 64-bit ... x86-64orELF 64-bit ... ARM aarch64) and runtest/pipelines/hello_name.yamlwith it. Onv*tags they also upload the binary as a workflow artifact. They don't run for thelatesttag.releaseruns onv*tags only, after both binary jobs succeed. It downloads both binaries, checks their architectures again and uploads both in onesoftprops/action-gh-releasecall withfail_on_unmatched_files: true. Two jobs never write the release at the same time, and a release can't be published with an asset missing. The conditions changed fromrefs/tags/torefs/tags/v, so pushing thelatesttag never creates a GitHub release.docker-buildis a matrix job. It buildsbuild/Dockerfile(default target, no changes to the Dockerfile) for linux/amd64 onubuntu-24.04(the same pinned runner as the binary job) and for linux/arm64 onubuntu-24.04-arm. Each platform builds on its own native runner, so no QEMU is needed. Each pushes its image to Docker Hub by digest (push-by-digest=true, untagged) and uploads the digest as adigest-<arch>artifact. It uses the GitHub Actions build cache, scoped per platform, and setsfail-fast: false, as heimdall does.docker-mergeruns after bothdocker-buildlegs succeed:<version>with thevstripped forv*tags,devformain, andlatestfor thelatesttag. It fails on any other ref, or if the result isn't a valid Docker tag.docker buildx imagetools createto push the manifest list.docker-merge):docker buildx imagetools inspectmust list bothlinux/amd64andlinux/arm64. Attestation entries (unknown/unknown) are ignored.docker create --platform <p>, thendocker cpto copy/caterpillarout of the container, and requiresfileto reportx86-64orARM aarch64respectively.createandcpdon't execute the image, so the arm64 check needs no QEMU on the x86-64 runner.DOCKERHUB_USERNAME/DOCKERHUB_TOKENthroughenv, checks each with-z, and fails with an::error::naming whichever is missing. This replaces the old, obscure login error, and the jobs never skip silently.ENTRYPOINT, as before. The binary is/caterpillar, so callers name it in the command:docker run patternoss/caterpillar:dev /caterpillar -conf ....contents: read, which covers every job exceptrelease. Onlyreleasegetscontents: write, and it doesn't check out or run any repository code. The Docker jobs push with the Docker Hub token, notGITHUB_TOKEN.run:scripts throughenv, not${{ }}interpolation.maincancels the supersededmainrun, but a tag run is never cancelled mid-publish.ubuntu-24.04instead ofubuntu-latest. This doesn't change the binary today. It means the asset's glibc baseline only moves when we decide to move it, not when GitHub movesubuntu-latest. GitHub's runner annotation on this PR's CI run saysubuntu-lateststarts moving to Ubuntu 26 on October 19, 2026.Tag scheme change. The old (never successful) step tagged
lateston every tag push andmainon pushes tomain. This PR uses heimdall's scheme instead:latestonly moves when thelatestgit tag is pushed, andmainpushes are taggeddev..github/workflows/ci.yaml(pull requests)1.24.7→1.27, the current supported release.go-version: '1.27', which installs the latest 1.27.x.go-version-file: go.modwould install the exact patch named ingo.modinstead.go vet -copylocks=false ./...step.go vet ./...fails onmaintoday with three existingcopylocksfindings:archive.go:81,compress.go:46andfile.go:223. All three copy a task struct that embedstask.Base.go test -race ./...step.internal/pkg/pipeline,.../ack,.../task) need no external services, so nothing is excluded.-race, which matters for the concurrency code inackandtask.permissions: contents: read, and a new push to a PR cancels the run for its previous commit.build, so any check names people rely on stay the same.README.mdA new "Docker Image" section describes
patternoss/caterpillar: its two platforms, the three tags (<version>,dev,latest) and when each is pushed. It also notes there is noENTRYPOINTand gives an exampledocker run. The section doesn't touch the Go-version line that #133 edits, so the two PRs merge without conflicts (checked withgit merge-tree).Both workflows
Actions updated. The old majors run on Node 20, and every run already logs a deprecation warning for it. All the majors below run on Node 24.
actions/checkoutactions/setup-goactions/upload-artifactactions/download-artifactsoftprops/action-gh-releasedocker/setup-buildx-actiondocker/login-actiondocker/build-push-actiondocker/metadata-actionsoftprops/action-gh-releaseis pinned to its v3.0.3 commit (efb3536…), because it is a third-party action that runs with a token that can write releases.persist-credentials: falseon checkout. No job pushes to git, so the token doesn't need to stay in.git/config.Validation done locally
rhysd/actionlintDocker image with shellcheck 0.11.0 enabled.build/Dockerfilebuilds for linux/arm64, with build: require Go 1.27 (go.mod, Dockerfile builder, README) #133's builder change applied in a scratch copy. I built it two ways: from this branch with only that one-line change, and from this branch merged with build: require Go 1.27 (go.mod, Dockerfile builder, README) #133. In both images,/caterpillar -conf test/pipelines/hello_name.yamlruns and prints its output. The image has no entrypoint, andfilereportsELF 64-bit LSB executable, ARM aarch64for/caterpillar.run:scripts fromdocker-mergeagainst a local registry. The inputs were two stand-in images pushed by digest with buildx (push-by-digest=true, default provenance attestations).imagetools createproduced a list with linux/amd64, linux/arm64 and two attestation entries.x86-64andARM aarch64for the two/caterpillarfiles.has no linux/amd64 image. With one digest file, create fails withExpected 2 platform digests.dev,2.3.4andlatestformain,v2.3.4andlatest. It rejectsrefs/tags/v, other branches, and a tag name containing$(...).golang:1.27-bookworm(go1.27.3, linux/arm64):go build,go vet -copylocks=false ./...andgo test -race ./...all pass.mainand build: require Go 1.27 (go.mod, Dockerfile builder, README) #133, and with-race -count=10to look for flaky tests.go vet ./...reports the same three copylocks findings onmain, so they aren't caused by this PR.golang:1.27-bookwormproducesELF 64-bit LSB executable, ARM aarch64 ... for GNU/Linux.lddshows only libc and libm, because librdkafka is linked statically. The binary runshello_name.yaml. When this job was first added, the same build also completed a Kafka write/read round trip against a local broker. The build command hasn't changed since, and I didn't repeat that test for this push.release.yamldoesn't run on pull requests, so the Docker jobs first run on the push tomainafter this merges. That run needs build: require Go 1.27 (go.mod, Dockerfile builder, README) #133 merged and the two secrets added.How to verify after merging
Types of changes
Checklist
🤖 Generated with Claude Code