Skip to content

ci(release): build darwin/amd64 on macos-14, not the starved macos-13 - #285

Merged
adnaan merged 2 commits into
mainfrom
release-runner-fix
Jun 5, 2026
Merged

ci(release): build darwin/amd64 on macos-14, not the starved macos-13#285
adnaan merged 2 commits into
mainfrom
release-runner-fix

Conversation

@adnaan

@adnaan adnaan commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Problem

The CLI release workflow's darwin/amd64 build runs on macos-13. GitHub is winding down Intel macOS runners, so that job sits queued indefinitely — and since the Create Release job needs all three builds, no release ever publishes its assets. That's why livetemplate/homebrew-tap's formula has been stuck on a placeholder version: there were never any release artifacts to point it at. (Observed live on the v0.3.3 release: darwin-arm64 + linux-amd64 finished in seconds, darwin-amd64 queued 30+ min on macos-13.)

Fix

  • Build darwin/amd64 on macos-14 (Apple Silicon). The build is pure Go with CGO_ENABLED=0, so it cross-compiles cleanly; the smoke test runs the amd64 binary under Rosetta, which is preinstalled on the macos-14 image.
  • Make the smoke test arch-aware so the release can never again be blocked by a runner/emulation gap: if the built binary can't execute on the runner, it confirms the build produced an executable and skips the run instead of failing.

No release behaviour changes for the platforms that already worked; this only removes the dependency on the deprecated runner.

🤖 Generated with Claude Code

GitHub is winding down macos-13 (Intel) runners; the darwin/amd64 build
job queued indefinitely on them, so the Create Release job never ran and
no release ever published its assets (the Homebrew formula was stuck on a
placeholder version as a result).

The build is pure-Go with CGO disabled, so it cross-compiles on the
Apple-Silicon runner; the smoke test runs the amd64 binary under Rosetta.
Make the smoke test arch-aware so a future runner/emulation gap degrades
to "verify the build, skip the run" instead of blocking the release.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Jun 5, 2026

Copy link
Copy Markdown

Code Review

Overview

This PR fixes a legitimate production blocker: macos-13 (Intel) runners are being retired by GitHub, causing the darwin/amd64 build to queue indefinitely and preventing any releases from publishing. The fix switches to macos-14 (Apple Silicon) and adds an arch-aware smoke test so a future runner/emulation gap degrades gracefully rather than blocking the release entirely. The motivation is clearly documented and the scope is appropriately narrow.


What works well

  • Minimal blast radius: single file, 28 lines changed, no logic changes outside the CI definition.
  • Env vars over inline interpolation: using EXPECTED_VERSION and TARGET_ARCH env vars in the smoke test (instead of ${{ }} directly inside the shell script) is the correct pattern — it avoids shell injection risk and keeps the script readable.
  • Good comments: both inline (the matrix comment) and the commit message clearly explain why macos-13 was abandoned, which will save future maintainers from re-litigating this.

Concerns

1. The fallback silently swallows real binary failures

if VERSION_OUT=$(./tinkerdown version 2>/dev/null); then
  ...
elif [ -x ./tinkerdown ]; then
  echo "Built tinkerdown ($TARGET_ARCH) is not runnable on this runner; skipping execution smoke test."
else
  exit 1
fi

The elif branch fires whenever ./tinkerdown version exits non-zero — including crashes, panics, missing config, or a genuinely broken binary. The intent is to catch the arch-incompatible case (e.g. Rosetta not available), but the guard is too broad. A darwin/amd64 binary that panics on startup would pass this smoke test with a note that says "skipping execution".

Suggestion: distinguish the two failure modes explicitly. On macos-14, Rosetta 2 is preinstalled; the amd64 binary should run. If it doesn't, that is worth surfacing as a warning at minimum:

HOST_ARCH=$(uname -m)   # arm64 on macos-14
if [ "$HOST_ARCH" = "$TARGET_ARCH" ] || [ "$TARGET_ARCH" = "amd64" -a "$HOST_ARCH" = "arm64" ]; then
  # Native run, or amd64 under Rosetta on Apple Silicon — should work.
  VERSION_OUT=$(./tinkerdown version)
  echo "$VERSION_OUT"
  echo "$VERSION_OUT" | grep -Fq "$EXPECTED_VERSION"
  ./tinkerdown help
else
  echo "Runner arch ($HOST_ARCH) cannot execute $TARGET_ARCH binary; confirming executable bit and skipping run."
  [ -x ./tinkerdown ]
fi

This makes the fallback path intentional rather than a catch-all for any failure.

2. 2>/dev/null hides startup errors

The 2>/dev/null suppresses stderr from the first tinkerdown version call. If the binary crashes with a Go panic or an OS error, the CI log will show nothing — just the silent skip. Consider at least capturing stderr to a temp file and printing it when the fallback fires, so there is a debugging trail.

3. No explicit Rosetta availability check

The PR description says "Rosetta is preinstalled on the macos-14 image" — but this is relied on implicitly. If GitHub ever changes that image without announcement, the fallback would silently degrade the smoke test. A quick explicit check would make the assumption auditable:

if [ "$TARGET_ARCH" = "amd64" ]; then
  /usr/bin/arch -x86_64 true 2>/dev/null || echo "::warning::Rosetta not available; amd64 smoke test will be skipped."
fi

Minor notes

  • The new inline comment on the matrix entry is long (4 lines). That context is already well-captured in the PR description and commit message; a shorter one-liner referencing the issue/PR would be lighter for anyone reading the YAML day-to-day.
  • No test changes needed — this is purely infrastructure.

Summary

The core fix (macos-13macos-14) is correct and should be merged as a production fix. The main risk is concern #1: the fallback condition is too broad and could silently skip the smoke test for a genuinely broken binary. I'd suggest tightening that guard before merging, or at least adding a ::warning:: annotation so the skip is visible in the GitHub Actions UI rather than buried in log output.

The earlier arch-aware fallback skipped on any non-zero exit, which would
also swallow a crash or wrong-version binary. Every matrix target is
runnable on its runner (arm64 native, amd64 via Rosetta on macos-14, linux
native), so require the binary to run and match the expected version — a
failure is a real problem and should fail loudly, not publish silently.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@adnaan
adnaan merged commit c6c0945 into main Jun 5, 2026
3 of 4 checks passed
@adnaan
adnaan deleted the release-runner-fix branch June 5, 2026 22:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant