Skip to content

add buildkite pipeline for cli release#71

Draft
mokagio wants to merge 7 commits intoainfra-2351-sign-and-notarize-imessage-cli-in-ci-localfrom
ainfra-2351-add-buildkite-pipeline
Draft

add buildkite pipeline for cli release#71
mokagio wants to merge 7 commits intoainfra-2351-sign-and-notarize-imessage-cli-in-ci-localfrom
ainfra-2351-add-buildkite-pipeline

Conversation

@mokagio
Copy link
Copy Markdown

@mokagio mokagio commented May 6, 2026

Rationale

Stacked on top of #70 (the local sign+notarize automation).
Adds the .buildkite/ files that wire the new platform-imessage Buildkite pipeline (provisioned via Automattic/buildkite-ci#848) to actually do something — moving the macOS CLI release off GitHub Actions and onto Automattic Buildkite, so the Developer ID p12 and ASC API key live in a8c-secrets rather than as GitHub-side secrets.

image

Trigger model:

  • PR / main push → compile-check only (swift build -c release).
  • v* tag push → .buildkite/commands/release-cli.sh runs scripts/sign-and-notarize-cli (universal, hardened-runtime, notarized) and publishes the tarball + sha256 to a GitHub Release via gh.

Tradeoffs

  • The release script doesn't use Fastlane. For a single Mach-O CLI binary it would only add a Ruby toolchain dependency for what amounts to an xcrun notarytool submit --wait.
    Captured in #70.
  • Idempotent re-uploads via gh release upload --clobber so a Buildkite retry doesn't error if the release already has the asset.

Gotchas

  • Assumes gh is on the BK Mac agents and authenticated for beeper/platform-imessage. To be confirmed on the first run.
  • .github/workflows/release-imessage-cli.yml is intentionally left in place for now.
    Once a tag build proves green end to end on Buildkite, a follow-up PR should remove it so we don't have two workflows publishing to the same release.

How to test

  1. Land #70 (this PR's base).
  2. Rebase / re-target this PR to main.
  3. Open a non-tag PR and confirm the Build (compile check) step runs and goes green.
  4. Push a v0.x.y-test tag (or use the existing package.json version bump flow) and confirm the Sign, notarize, and publish CLI step:
    • Runs scripts/sign-and-notarize-cli.
    • Uploads imessage-cli-{version}-macos-universal.tar.gz (+ .sha256) to the matching GH Release.

Posted by Claude Code (Opus 4.7, 1M context) on behalf of @mokagio with approval.

Wires the `platform-imessage` Buildkite pipeline (provisioned via
[Automattic/buildkite-ci#848](Automattic/buildkite-ci#848))
to actually do something, so the macOS CLI release can move off
GitHub Actions and onto Automattic Buildkite — keeping the Developer
ID p12 and ASC API key alongside the rest of the org's Apple
distribution material in `a8c-secrets` rather than as GitHub-side
secrets.

Trigger model:

- PR / `main` push → compile-check only (`swift build -c release`).
- `v*` tag push → `.buildkite/commands/release-cli.sh` runs the local
  `scripts/sign-and-notarize-cli` (universal binary, hardened runtime,
  Apple-notarized) and publishes the tarball + sha256 to a GitHub
  Release via `gh`.

The release script is idempotent: if the release already exists for
the tag it just uploads with `--clobber`, so re-runs from a Buildkite
retry don't error.

`shared-pipeline-vars` mirrors the convention from
`pocket-casts-desktop` / `Automattic-Tracks-iOS`: pin the
`a8c-ci-toolkit` plugin and read the Xcode image id from
`.xcode-version`.

Follow-up: once a tag build proves green end-to-end on Buildkite,
remove `.github/workflows/release-imessage-cli.yml` so we don't have
two workflows publishing different assets to the same release.

---

Generated with the help of Claude Code, https://claude.ai/code

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mokagio mokagio self-assigned this May 6, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 6, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 46b264d7-5b64-4606-8f73-a6fb7053bb45

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ainfra-2351-add-buildkite-pipeline

Comment @coderabbitai help to get the list of available commands and usage tips.

mokagio and others added 6 commits May 6, 2026 14:39
`artifact_paths` runs at end-of-step regardless of step exit code, so
an explicit `buildkite-agent artifact upload` in the script only fires
on success — exactly when we need the artifact least. Switching to the
pipeline DSL means we still get the tarball + sha256 stashed even when
codesign, notarize, or `gh release` fails partway through.

The script now writes to `dist/` (already gitignored) instead of a
mktemp dir, so the glob in `artifact_paths` has a stable target.

---

Generated with the help of Claude Code, https://claude.ai/code

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Collapse the two pipeline steps into one that runs on every CI build
(PR, `main`, tag) and produces a signed+notarized universal-binary
tarball, uploaded as a Buildkite artifact via `artifact_paths`. Non-tag
builds skip the `gh release` step; tag builds do the full publish.

Lets reviewers grab a fully usable CLI from any PR's BK build instead
of having to clone and run the script themselves.

Non-tag asset names are versioned `${package.json version}-${shortsha}`
so each build's artifact is uniquely named, matching the BK artifact
naming convention.

Tradeoff: every PR/`main` push hits Apple's notary service (~30-90s
each). Well under the 75/hr/team cap, but worth knowing if traffic
spikes.

---

Generated with the help of Claude Code, https://claude.ai/code

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Buildkite Mac agent doesn't carry our Developer ID cert in its
keychain by default, so without this the script fails with `no
Developer ID Application identity for team PZYM8XX95Q in keychain`.

`set_up_signing` lane mirrors the `snelectron` / `matticspace-mobile`
pattern: `sync_code_signing(type: 'developer_id', ...)` against the
shared `a8c-fastlane-match` S3 bucket. Cert is already provisioned
there for our team. `app_identifier: []` works for `developer_id`
since the cert isn't tied to a specific app bundle.

Env-var presence is enforced via release-toolkit's `EnvManager` so we
fail fast with a clear message if `MATCH_S3_*` / `MATCH_PASSWORD` are
missing on the agent, rather than getting an opaque `match` error.

`Gemfile` carries only the two top-level gems (fastlane,
wpmreleasetoolkit); everything else is transitive.

---

Generated with the help of Claude Code, https://claude.ai/code

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CI expects it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant