ci: build on native arm64 runners, pin actions to SHAs#10
Conversation
Use ubuntu-24.04-arm runners for arm64 builds (and tests) instead of QEMU emulation, mirroring appwrite/docker-base. Each arch is built and pushed separately, then a manifest job assembles the multi-arch tag. Pin all third-party actions to commit SHAs with version comments. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Greptile SummaryThis PR replaces the single QEMU-based build-and-push workflow with a four-workflow pipeline:
Confidence Score: 5/5Safe to merge — the CI/CD redesign is structurally sound and the only finding is a defensive edge-case guard in the cleanup script. All four new workflows follow correct patterns: native arm64 runners replace QEMU, artifacts are exchanged by name with matching upload/download keys, the promote-not-rebuild release flow correctly shares the concurrency group, and fail-fast: false is applied throughout. The one finding is a null-guard in the daily cleanup loop that would only fire if Docker Hub returned an unexpected null for a CI tag — an unlikely edge case that does not affect builds or releases. No files require special attention. Important Files Changed
Reviews (10): Last reviewed commit: "ci: point --ci-config at the real filena..." | Re-trigger Greptile |
Trivy scans built images for CRITICAL/HIGH CVEs and uploads SARIF to the GitHub Security tab. Runs on push, PR, and a weekly cron so newly-disclosed CVEs in already-shipped base images get flagged. Dive enforces layer-efficiency thresholds via .dive-ci.yml to catch Dockerfile regressions (e.g. uncleared apt caches). Both workflows fan out per PHP version. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
PHP 8.2 reaches end-of-life on 2026-12-31; drop it now to focus on 8.3/8.4/8.5. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Three separate workflow files each created their own check rows and the push+pull_request triggers fired duplicate runs on every PR commit. Merge into one workflow with three jobs and limit triggers to push-on-main plus PRs (cron retained for Trivy CVE refresh). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Trigger is `release: published`; matching the filename to the trigger makes intent obvious at a glance. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Previously each of structure-test/dive/trivy rebuilt the same Dockerfile, amounting to 12 builds per CI run for 3 Dockerfiles. Split into a single build job per (php, arch) that saves the image as an artifact; downstream jobs load it instead of rebuilding (3 amd64 builds reused twice each, plus the 3 arm64 builds for structure-test). Add concurrency group keyed on ref so superseded commits' runs cancel instead of stacking up. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
CI now pushes per-commit images on main (php-X.Y-<sha>[-arch]) after tests pass and assembles the multi-arch manifest with buildx imagetools create. Tagging is driven by docker/metadata-action. Release workflow drops its build/push matrix entirely — it just calls buildx imagetools create to retag the already-tested per-commit manifest to the release tag. Server-side, no rebuild, takes seconds. Add cleanup.yml: daily scheduled job that deletes CI tags matching php-X.Y-<sha>[-arch] older than TTL_DAYS via the Docker Hub API. Released semver tags don't match the regex and are never touched. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
If a release is cut before CI finishes pushing the per-commit image, buildx imagetools create would fail with manifest-not-found. Add a wait-for-ci job that polls the CI run for github.sha until it succeeds (or times out at 30min), then runs the promote matrix. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace the polling wait-for-ci job with a shared per-commit concurrency
group ('build-<sha>'). CI and release on the same commit can't run
concurrently; release queues until CI's group slot is free.
PR runs use a separate group keyed on ref so superseded PR commits keep
cancelling earlier runs as before.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Audit pass on workflow names: unify 'Checkout the repo' / 'Checkout code' to 'Checkout', shorten verbose Trivy/manifest/promote step names, and rename 'Cleanup stale CI tags' workflow to 'Cleanup' for consistency with 'CI' / 'Release'. Standardize on 'Docker Hub' (two words). Replace plexsystems/container-structure-test-action with a direct binary install: the action is a Docker action that hardcodes the amd64 binary, so it fails with 'exec format error' on the ubuntu-24.04-arm runners. Install the matching linux-<arch> binary instead. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Job-level 'if' on a matrix job displays the unrendered '\${{ matrix.* }}'
string in skipped check rows. Move push/manifest into a separate
publish-sha workflow that triggers via workflow_run on CI success on
main, so PRs no longer see skipped placeholder rows.
The new workflow downloads CI's image artifact by run-id and pushes
per-arch tags + assembles the multi-arch manifest. Concurrency group is
still 'build-<sha>', shared with ci.yml and release.yml.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Pipeline reads as CI -> publish -> release; -sha suffix leaked the tag format into the filename. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The 'deleted' counter in cleanup.yml was incremented inside a piped subshell so the outer scope never saw it — pure dead code; remove it and use a process substitution loop instead so the body runs in the parent shell. While here, switch all curl invocations (cleanup HTTP calls + structure-test binary download) to '-fsS' / '-fsSL' so HTTP errors surface as a non-zero exit instead of being silently saved as the response body. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Floating on 'latest' makes builds non-reproducible — pin the version so upgrades are explicit. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
…ADME The storage.googleapis.com bucket only hosts a 'latest/' path, not versioned ones — pinned URL 404'd. Switch to the GitHub release asset URL which exposes per-version downloads. Expand README with supported PHP versions, tag scheme, and a description of the four workflows. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Download checksums.txt from the same release and run sha256sum -c against the per-arch asset. Catches a corrupted download or a tampered mirror. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The yuichielectric/dive-action wraps dive v0.9, which doesn't yet support --ci-config — invocation failed with 'unknown flag: --ci-config'. Install dive v0.13.1 directly with checksum verification. Capture the dive report to the GitHub Actions step summary so the layer breakdown and efficiency metrics are visible on every run instead of buried in raw step logs. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
dive's --ci-config is passed verbatim to viper.SetConfigFile, so it needs the literal path including extension. The committed file is .dive-ci.yml. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Summary
ubuntu-24.04-armrunners by matrixing on arch and runner OS, mirroring appwrite/docker-base.…-amd64/…-arm64tag, then amanifestjob assembles the multi-arch tag per PHP version.actions/checkout,docker/login-action, andplexsystems/container-structure-test-actionto commit SHAs with version comments.Test plan
test.ymlruns the matrix on bothubuntu-24.04andubuntu-24.04-armand all PHP versions pass structure tests.docker buildx imagetools inspect appwrite/utopia-base:php-<ver>-<tag>.🤖 Generated with Claude Code