Skip to content

Give each signing certificate its own secret, and run the release on a pull request - #111

Open
agoodkind wants to merge 6 commits into
mainfrom
pr-name-the-ci-cert
Open

agoodkind wants to merge 6 commits into
mainfrom
pr-name-the-ci-cert

Conversation

@agoodkind

@agoodkind agoodkind commented Aug 9, 2026 •

Copy link
Copy Markdown
Owner

Proves both signing certificates work, and makes the release path testable before it publishes.

What was wrong

There was one certificate slot, APPLE_DEVELOPER_ID_P12_BASE64, shared by CI and the release. This repository put its Apple Distribution certificate in it so CI could sign at all, because the CI runner is not a registered device and only App Store profiles work there.

The cost was that a release could never be signed. The release build resolves a Developer ID identity, which was not in that secret, so it failed with Developer ID Application identity ... not found right after a successful import.

The two certificates are genuinely different, which is why one slot could not serve both. The Apple Distribution one is 85:D1:3A:F9:… and the Developer ID one is D5:C4:37:9A:….

The change

The shared workflow now takes each certificate as its own input and its own secret, and signing-identity-name selects which one signs (agoodkind/swift-makefile#206). This repository now holds both, so the CI comment that said the Developer-ID-named secret carries the distribution certificate is corrected here.

The release also now runs on a pull request. The shared pipeline executes every signed stage and stops before publishing, and this repository triggered releases only on a push to main, so the first thing to exercise the release path was the merge itself. A broken release was therefore discovered only once it could not be undone.

What this pull request verifies

Both certificates, on the paths that use them, without publishing anything:

  • Verify imports APPLE_DISTRIBUTION_P12_* and signs every product with Apple Distribution: Alex Goodkind (H3BMXM4W7H).
  • Release (dry run) imports APPLE_DEVELOPER_ID_P12_* and signs, notarizes and packages with Developer ID Application: Alex Goodkind (H3BMXM4W7H), then stops before publish.

A green run here is the first time this repository has signed with the correct certificate on both paths. Merging then publishes a pre-release, which is the downloadable build ICT-1 asks for.

The comment said the Developer-ID-named secret held the Apple Distribution certificate, which was true only because there was one certificate slot for both. Each certificate now has the secret named for it.
Copilot AI lite review requested due to automatic review settings August 9, 2026 00:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@agoodkind, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 30 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: QUIET

Plan: Pro Plus

Run ID: 39645bb2-076c-402a-bc84-86cf7016e691

📥 Commits

Reviewing files that changed from the base of the PR and between fc5d3ff and 5de7531.

📒 Files selected for processing (1)
  • Makefile
📝 Walkthrough

Walkthrough

The release workflow now runs for eligible pull requests, creates ephemeral prereleases, and cancels superseded runs. Release builds install Go, generate configuration, run the gate-proof probe, and use distinct CI and release signing certificates.

Changes

Pull-request release workflow

Layer / File(s) Summary
Pull-request release orchestration
.github/workflows/release.yml
The release workflow adds pull-request triggers, ref-scoped concurrency, fork exclusion, ephemeral prerelease settings, and Go installation.
Release signing and build preparation
.github/workflows/ci.yml, Makefile
The CI comments distinguish Apple Distribution and Developer ID certificates. The release command generates configuration and runs the gate-proof probe before building and archiving artifacts.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PullRequest
  participant release.yml
  participant ReusableReleaseWorkflow
  PullRequest->>release.yml: trigger release workflow
  release.yml->>ReusableReleaseWorkflow: pass ephemeral prerelease settings
  ReusableReleaseWorkflow->>ReusableReleaseWorkflow: install Go and build release artifacts
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the separate signing certificates and pull-request release validation changes.
Description check ✅ Passed The description directly explains the certificate configuration changes and release workflow validation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch pr-name-the-ci-cert

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

The shared pipeline builds, signs, notarizes and packages on a pull request and stops before publishing, but this repo triggered releases only on a push to main. The first thing to exercise the release path was therefore the merge, so a broken release was discovered only once it could not be undone.
Copilot AI review requested due to automatic review settings August 9, 2026 00:49

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@agoodkind agoodkind changed the title Name the certificate CI signs with, now that the release has its own Give each signing certificate its own secret, and run the release on a pull request Aug 9, 2026
The engine's release-build target carries no prerequisites, so nothing rendered Config.generated.swift and the dev tool the release command runs could not compile on a fresh CI checkout. Reproduced locally: with that gitignored directory absent, make generate recreates it. The dry-run gate job was copied from the engine and is redundant, because every job of the reusable workflow already reports as its own check.
Copilot AI review requested due to automatic review settings August 9, 2026 01:02

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

…ge as CI

The vendored WireGuardKitGo target prepares a Go goroot through its own Makefile and fails unless go env GOROOT resolves. CI installs Go for that reason; the release build links the same target and did not, so it failed at wireguard-go-bridge/goroot/.prepared.
Copilot AI review requested due to automatic review settings August 9, 2026 01:24

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

The release build on the runner takes the decoupled hard gate even though swift-mk build marks GateProof, while the same recipe takes the prologue path locally under the CI environment. The probe prints each authorization factor (freshness, ancestor, anchor, start time) in the job log, so the failing factor is named on the runner instead of guessed at.
Copilot AI review requested due to automatic review settings August 9, 2026 04:42

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/release.yml:
- Around line 29-35: Secure the reusable release workflow invocation by
replacing the mutable `@main` reference on _release.yml with its full commit SHA,
and replace secrets: inherit with explicit mappings for only the secrets
required by the release workflow. Preserve the existing pull-request condition
and inputs while limiting secret exposure.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: QUIET

Plan: Pro Plus

Run ID: a7dedc23-a3c7-48db-bf89-68d7e3c0c770

📥 Commits

Reviewing files that changed from the base of the PR and between b1283c3 and fc5d3ff.

📒 Files selected for processing (2)
  • .github/workflows/release.yml
  • Makefile

Comment on lines +29 to +35
# A fork pull request cannot read this repository's signing secrets, so the
# signed run would fail for a reason the contributor cannot fix.
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
uses: agoodkind/swift-makefile/.github/workflows/_release.yml@main
with:
ephemeral: ${{ github.event_name == 'pull_request' }}
release-track: ${{ github.event_name == 'pull_request' && 'prerelease' || '' }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Restrict secrets passed to the reusable release workflow.

The called workflow at Line [32] uses mutable @main, and Line [58] passes all available secrets with secrets: inherit. The new pull-request trigger makes this path run for same-repository pull requests. The fork check does not protect against a changed or compromised reusable workflow.

Pin agoodkind/swift-makefile/.github/workflows/_release.yml to a full commit SHA. Pass only the secrets required by the release workflow.

🧰 Tools
🪛 zizmor (1.29.0)

[warning] 32-32: secrets unconditionally inherited by called workflow (secrets-inherit): this reusable workflow

(secrets-inherit)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 29 - 35, Secure the reusable
release workflow invocation by replacing the mutable `@main` reference on
_release.yml with its full commit SHA, and replace secrets: inherit with
explicit mappings for only the secrets required by the release workflow.
Preserve the existing pull-request condition and inputs while limiting secret
exposure.

Source: Linters/SAST tools

The probe named .make/swift-mk literally, which does not exist on a runner: setup-build-env builds the engine into the toolchain cache and exports SWIFT_MK_BIN, so the release build stopped at exit 127 before reaching the dev tool. The command now expands SWIFT_MK_BIN at shell time, which resolves on a runner and locally.
Copilot AI review requested due to automatic review settings August 9, 2026 05:12

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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.

2 participants