Run the macOS binaries job on a larger Apple Silicon runner - #117
Draft
Bencheng21 wants to merge 1 commit into
Draft
Bencheng21 wants to merge 1 commit into
Bencheng21 wants to merge 1 commit into
Conversation
**Why**
The release critical path is goreleaser-binaries, and its dominant cost is Go
compilation. macos-latest has 3 vCPUs and GoReleaser builds one target per core,
so with four targets the fourth queues behind the first three.
This is measurable and universal. Across the most recent successful release of
nine connectors, exactly three targets start together and macos-arm64 waits:
connector 4th target starts macos-amd64 post-hook delta
baton-hubspot 108s 108s 0.1s
baton-snowflake 117s 118s 0.8s
baton-slack 160s 162s 2.9s
baton-salesforce 162s 165s 2.4s
baton-zoom 169s 170s 1.0s
baton-github 176s 177s 0.9s
baton-jira 192s 194s 1.9s
baton-aws 200s 201s 1.1s
baton-okta 331s 335s 3.7s
The gon post-hook fires the instant a build finishes, so the fourth target
provably starts when the first frees its slot rather than running concurrently.
**What this changes**
- Adds a macos_runner input, defaulting to macos-latest-xlarge (Apple Silicon M2,
5 vCPU). Five slots for four targets removes the queueing entirely.
- validate-inputs restricts the value to GitHub-hosted Apple Silicon labels. This
job holds the Apple signing certificate and assumes the artifacts AWS role, so
the runner it lands on is a trust decision; a free-form label would let a caller
point it at a runner they control.
Intel labels are deliberately excluded. macos-latest-large is the 12 vCPU option,
but it would change the codesigning host architecture and move the Homebrew prefix
from /opt/homebrew to /usr/local, which the gon install step depends on.
**What this does not claim**
The saving is not predicted here. The logs show when each build starts but not when
the two linux builds finish, so per-core scaling cannot be derived from them; the
only defensible claim is that the queueing is real and five slots removes it.
Treat this as the experiment that measures it.
Larger runners bill at a higher per-minute rate, and this job runs on every
connector release, so the default should be reviewed against actual spend once the
compile phase has been measured on the new runner.
**Validation**
- Parsed .github/workflows/release.yaml with PyYAML; confirmed the input default
and that the job resolves runs-on from it.
- Exercised the allowlist against macos-latest, macos-latest-xlarge,
macos-15-xlarge (accepted) and macos-latest-large, macos-13, self-hosted, and a
shell-injection attempt (rejected).
- scripts/test-normalize-release-options.sh, scripts/test-derive-iam-role-name.sh,
scripts/test-release-config-templates.py, go build ./...
Not validated: no release has been run on the new runner.
Co-Authored-By: Claude Opus 5 (1M context) <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.
Why
The release critical path is
goreleaser-binaries, and its dominant cost is Go compilation.macos-latesthas 3 vCPUs and GoReleaser builds one target per core, so with four targets the fourth queues behind the first three.This is measurable and universal. Across the most recent successful release of nine connectors, exactly three targets start together and
macos-arm64waits:macos-amd64post-hook firesThe
gonpost-hook fires the instant a build finishes, so the fourth target provably starts when the first frees its slot — it is queued, not running concurrently with delayed logging.For scale: on
baton-githubthe compile phase was 3m49s of a 9m27s release (~40%).What this changes
macos_runnerinput, defaulting tomacos-latest-xlarge(Apple Silicon M2, 5 vCPU, 14 GB). Five slots for four targets removes the queueing entirely.validate-inputsrestricts the value to GitHub-hosted Apple Silicon labels. This job holdsAPPLE_SIGNING_KEY_P12and assumes the artifacts AWS role, so the runner it lands on is a trust decision — a free-form label would let a caller point it at a runner they control.Intel labels are deliberately excluded.
macos-latest-largeis the 12-vCPU option, but it would change the codesigning host architecture and move the Homebrew prefix from/opt/homebrewto/usr/local, which thebrew install conductorone/gon/gonstep depends on. If the 12-core throughput turns out to be worth chasing, that should be its own change with the Homebrew prefix handled explicitly.What this does not claim
The saving is not predicted here. The logs show when each build starts but not when the two linux builds finish, so per-core scaling cannot be derived from them. The only defensible claim is that the queueing is real and that five slots removes it. This PR is the experiment that measures the rest.
Suggested rollout: point one connector at this branch, cut a prerelease tag, and compare the
building binariesphase duration against its current baseline (the table above gives you nine baselines to pick from). If the gain is small, the 5 vCPU ceiling is the reason and the structural fix in #116 is the better lever.Cost
Larger runners bill at a higher per-minute rate, and this job runs on every connector release. The job should get shorter, but shorter × pricier is not automatically cheaper. The default should be reviewed against actual spend once the compile phase has been measured — if it is not clearly worth it, flip the default back to
macos-latestand let individual connectors opt in.Validation
.github/workflows/release.yamlwith PyYAML; confirmed the input default and that the job resolvesruns-onfrom it.macos-latest,macos-latest-xlarge,macos-15-xlargeaccepted;macos-latest-large,macos-13,self-hosted, and a shell-injection attempt rejected.scripts/test-normalize-release-options.sh,scripts/test-derive-iam-role-name.sh,scripts/test-release-config-templates.py,go build ./....Not validated: no release has been run on the new runner. Hence draft.
Relationship to #116
Independent and complementary. #116 removes two of the four targets from the macOS runner entirely; this widens the runner. Either alone helps; together the macOS job would build 2 targets with 5 slots. I would land this one first — it is one input and a validation check, versus #116's 850 lines.
🤖 Generated with Claude Code