Skip to content

feat(workflow): add event-driven CI-ready gate for publish#7664

Merged
BYK merged 10 commits intomainfrom
feat/ci-ready-signal
Apr 1, 2026
Merged

feat(workflow): add event-driven CI-ready gate for publish#7664
BYK merged 10 commits intomainfrom
feat/ci-ready-signal

Conversation

@BYK
Copy link
Copy Markdown
Member

@BYK BYK commented Apr 1, 2026

Summary

  • New ci-ready.yml workflow that handles repository_dispatch events from target repos when CI passes
  • Modified publish.yml with a gate step that checks label state before publishing
  • Added concurrency control to prevent duplicate publish runs
  • Created ci-pending and ci-ready labels

Context

craft publish currently polls GitHub's commit status API every 30 seconds for up to 60 minutes. This polling time is billed as GitHub Actions minutes and steals from our available capacity — a publish job that waits 45 minutes for CI burns 45 minutes of runner time doing nothing but sleep 30 in a loop. For repos like sentry-native (~1h 23m CI), this also exhausts the 1-hour GitHub App token lifetime, causing expired-token failures.

This PR replaces the polling wait with an event-driven label state machine. Instead of starting the publish runner and idling until CI passes, the job doesn't start at all until CI signals readiness — zero wasted runner minutes.

Label Meaning
ci-pending CI signal expected but not yet received
ci-ready CI passed, ready to publish
accepted Approved for publishing (unchanged)

Gate Decision Matrix

accepted ci-pending ci-ready Action
yes no no Old repo: publish with polling (unchanged)
yes yes no Waiting for CI: comment on issue, skip
yes yes Ready: publish immediately
no yes CI ready, waiting for approval: skip

Cross-Repo Dependency

This is Phase 1 of a three-phase rollout:

  1. Phase 1 (this PR): Gate logic + ci-ready.yml workflow — safe to deploy, no impact on existing repos
  2. Phase 2 (getsentry/craft#789): ci_ready input + signal-ready action
  3. Phase 3 (target repos): Opt-in one repo at a time

Old repos (without ci_ready: true) are completely unaffected — they keep the existing polling behavior.

Add a ci-ready.yml workflow that handles repository_dispatch events from
target repos when their CI passes. It adds a "ci-ready" label to the
publish issue, replacing the "ci-pending" label set at issue creation.

Modify publish.yml with a gate step that checks label state:
- Old repos (no ci-pending/ci-ready): publish with polling (unchanged)
- New repos with both accepted + ci-ready: publish with --no-status-check
- New repos with accepted but no ci-ready: comment and wait for CI
- ci-ready without accepted: wait for approval

Add concurrency control to prevent duplicate publish runs when both
labels arrive near-simultaneously.

This is Phase 1 of a cross-repo change. Phase 2 (getsentry/craft#789)
adds the ci_ready input and signal-ready action.
@BYK BYK marked this pull request as ready for review April 1, 2026 13:32
@BYK BYK requested a review from a team as a code owner April 1, 2026 13:32
BYK added 3 commits April 1, 2026 13:33
Use contains(labels, accepted) so the job only runs when accepted is
present. The || still allows ci-ready to trigger the job, but only
when accepted is already on the issue — preventing wasted runs.
All label state is available in github.event.issue.labels at event time.
The publish job if-condition now directly encodes the decision matrix:
- accepted + no ci-pending → run
- accepted + ci-ready → run (with --no-status-check)
- accepted + ci-pending → skip (waiting-for-ci job comments instead)
- anything without accepted → skip

This removes the gate step that was re-fetching labels via gh issue view
and all the step-level should_publish guards.
…imit

GITHUB_TOKEN events are suppressed by GitHub and would not trigger
publish.yml. Use the sentry-internal-app token (same pattern as
auto-approve.yml) so the ci-ready label addition fires the labeled
event that publish.yml listens for.

Also add --limit 200 to gh issue list to handle repos with many open
issues (default is 30).
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

BYK added 4 commits April 1, 2026 14:30
- ci-ready.yml: add issues:read permission and explicit GH_TOKEN for
  the find-issue step (repository_dispatch does not auto-expose the
  token to gh CLI)
- publish.yml: add GH_TOKEN to waiting-for-ci job comment step
gh CLI auto-reads GITHUB_TOKEN in GitHub Actions. Only override with
GH_TOKEN when we need a different token (the GitHub App token for
label changes that must trigger downstream workflows).
Issue numbers are unique but do not prevent parallel publishes when
duplicate issues exist for the same repo@version. The title
("publish: getsentry/foo@1.2.3") is the natural identity of the
release and ensures only one publish runs per repo@version.
The ci-ready signal is tied to a specific SHA but someone could push
to the release branch after CI passes. Letting craft poll the status
is safer — and since CI is already done by the time publish starts,
the first poll iteration returns immediately anyway.
@BYK BYK enabled auto-merge (squash) April 1, 2026 14:58
@Jeffreyhung Jeffreyhung disabled auto-merge April 1, 2026 16:34
Comment on lines +81 to +82
app-id: ${{ vars.SENTRY_INTERNAL_APP_ID }}
private-key: ${{ secrets.SENTRY_INTERNAL_APP_PRIVATE_KEY }}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

niche: probably better to use release-bot here to unify the app usage, release bot is also managed more tightly and less likely to break or affected by other changes

@BYK BYK merged commit a81365e into main Apr 1, 2026
10 checks passed
@BYK BYK deleted the feat/ci-ready-signal branch April 1, 2026 18:47
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