Skip to content

ci: Gate push-triggered publish and cancel on release-stamping commits#1901

Merged
hatayama merged 6 commits into
v3-betafrom
ci/gate-publish-on-release-stamping-commit
Jul 21, 2026
Merged

ci: Gate push-triggered publish and cancel on release-stamping commits#1901
hatayama merged 6 commits into
v3-betafrom
ci/gate-publish-on-release-stamping-commit

Conversation

@hatayama

@hatayama hatayama commented Jul 21, 2026

Copy link
Copy Markdown
Owner

Summary

native-cli-publish and dispatcher-publish both fire on every push to
main/v3-beta, and their resolver scripts decide publish/release purely
from release/asset state. That means an ordinary feature-PR merge push gets
evaluated the same way as a release retry, and — because their
Cancel superseded approval-waiting runs step runs whenever
publish == 'true' || release == 'true' — an ordinary push run can cancel a
legitimate release run that is still waiting on the cli-release environment
approval.

This PR adds a push-event gate to both resolvers: on push, publish/release
are only allowed when HEAD's diff actually stamps the resolved version (the
release-please manifest/contract entry, or the component's CHANGELOG.md
heading) via a new/reused release_commit_updates_*_version predicate.
Everything else on push resolves to publish=false/release=false, so the
cancel step no longer fires for it either. workflow_dispatch bypasses the
gate and keeps the previous state-based evaluation, so retrying an
incomplete release is still possible — just not automatic on every push.

  • scripts/resolve-native-cli-release-target.sh: collapse the old two-block
    publish/release evaluation into one gate, reusing
    release_commit_updates_cli_version; remove now-dead
    CLI_RELEASE_INPUT_PATHS / latest_cli_asset_release_tag /
    cli_release_inputs_changed.
  • scripts/resolve-dispatcher-release-target.sh: add
    release_commit_updates_dispatcher_version and the same push gate.
  • Remove the unreferenced BEFORE_SHA env from native-cli-publish.yml.
  • Update docs/version-series-realignment.md and
    docs/release-recovery-runbook.md to describe the new gate and the
    workflow_dispatch-only retry path.

No cli/release-automation or shared-release-input files changed, so
scripts/stamp-release-inputs.sh / scripts/check-go-cli.sh are not
required for this PR.

Test plan

  • sh -n scripts/resolve-native-cli-release-target.sh
  • sh -n scripts/resolve-dispatcher-release-target.sh
  • scripts/test-resolve-native-cli-release-target.sh
  • scripts/test-resolve-dispatcher-release-target.sh
  • scripts/test-native-cli-publish-workflow.sh
  • scripts/test-dispatcher-publish-workflow.sh
  • Real-repo smoke test (read-only): ran both resolver scripts against the
    actual current HEAD (a non-stamping commit) with EVENT_NAME=push EVENT_REF_NAME=v3-beta — both report publish=false/release=false
    with the expected skip message pointing at workflow_dispatch.

Review in cubic

hatayama added 4 commits July 21, 2026 10:57
Normal feature-PR pushes to main/v3-beta were being evaluated as
release retries because the resolver only checked release/asset
state. Add a push-event gate that requires HEAD to actually stamp
the project runner version (diff-based check reusing
release_commit_updates_cli_version) before allowing publish/release;
workflow_dispatch keeps the old state-based evaluation for retries.
Also drop the now-unused CLI_RELEASE_INPUT_PATHS/
latest_cli_asset_release_tag/cli_release_inputs_changed dead code and
rewrite the test suite for the new gate behavior.
Mirror the native CLI resolver's push gate: add
release_commit_updates_dispatcher_version to check whether HEAD's
diff stamps the dispatcher contract or CHANGELOG, and require it on
push events before allowing publish/release. workflow_dispatch keeps
the state-based evaluation for retrying an incomplete release.
Update the test suite to cover stamped/unstamped push and
workflow_dispatch cases.
BEFORE_SHA (github.event.before) was never referenced by
scripts/resolve-native-cli-release-target.sh; the new push gate uses
the checked-out HEAD commit instead.
version-series-realignment.md described dispatcher-publish as reacting
to every push regardless of commit content; that's no longer true now
that push only evaluates when HEAD stamps the resolved version.
release-recovery-runbook.md's operational notes still implied later
push builds could retry recreating a deleted broken release. Update
both to describe the new gate and the workflow_dispatch-only retry
path.
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

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

Next review available in: 40 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 47a043b0-ba44-4b26-b903-0da882797c12

📥 Commits

Reviewing files that changed from the base of the PR and between ddc653c and cbe9fac.

📒 Files selected for processing (1)
  • scripts/test-resolve-native-cli-release-target.sh
📝 Walkthrough

Walkthrough

Push-based dispatcher and native CLI release resolution now require the HEAD commit to stamp the resolved version. Native CLI decisions use current release and asset state, while tests and recovery documentation cover stamped pushes, skipped pushes, reruns, and manual dispatch.

Changes

Release gating and recovery

Layer / File(s) Summary
Dispatcher stamping gate
scripts/resolve-dispatcher-release-target.sh, scripts/test-resolve-dispatcher-release-target.sh
Dispatcher push runs inspect HEAD diffs for contract or changelog version stamps; tests cover stamped, unstamped, changelog-only, published, and dispatched scenarios.
Native CLI state-based resolution
scripts/resolve-native-cli-release-target.sh, scripts/test-resolve-native-cli-release-target.sh
Previous-release and input-diff checks are removed; publishing now uses HEAD stamping plus target release and asset state, with updated test fixtures and scenarios.
Workflow recovery guidance
.github/workflows/native-cli-publish.yml, docs/release-recovery-runbook.md, docs/version-series-realignment.md
The native CLI workflow stops passing BEFORE_SHA, and documentation describes push gates, reruns, and workflow_dispatch recovery.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Push or dispatcher
  participant Release workflow
  participant Release resolver
  participant Git
  participant GitHub Releases
  Push or dispatcher->>Release workflow: Start publish evaluation
  Release workflow->>Release resolver: Pass event and target version
  Release resolver->>Git: Inspect HEAD version stamp
  Git-->>Release resolver: Return contract or changelog diff
  Release resolver->>GitHub Releases: Query release and assets
  GitHub Releases-->>Release resolver: Return release state
  Release resolver-->>Release workflow: Set publish and release decisions
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.61% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: gating push-triggered publish/cancel behavior on release-stamping commits.
Description check ✅ Passed The description matches the changeset and accurately describes the new push gate, workflow_dispatch retry path, and related cleanup.
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 ci/gate-publish-on-release-stamping-commit

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.

@hatayama hatayama changed the title Gate push-triggered publish and cancel on release-stamping commits ci: Gate push-triggered publish and cancel on release-stamping commits Jul 21, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/resolve-dispatcher-release-target.sh (1)

184-196: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Push-gate wiring looks correct given the intended stamping semantics.

BUILD_SHA capture and the push+unstamped short-circuit correctly force both outputs to false and point at workflow_dispatch, matching the PR's stated behavior and the downstream workflow's steps.release.outputs.publish/release gating. See the related comment on lines 126-143 regarding the merge-commit diff caveat that this branch depends on.

🤖 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 `@scripts/resolve-dispatcher-release-target.sh` around lines 184 - 196,
Preserve the existing push-gate wiring in the dispatcher release evaluation:
capture BUILD_SHA, and when CAN_EVALUATE_DISPATCHER_RELEASE is true but the push
HEAD does not satisfy release_commit_updates_dispatcher_version for VERSION, set
both SHOULD_PUBLISH and SHOULD_RELEASE to false and direct retries to
workflow_dispatch. Do not alter the established prerelease or downstream
output-gating behavior.
🤖 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 `@scripts/test-resolve-native-cli-release-target.sh`:
- Around line 260-261: Update the INPUT_RELEASE_TAG assignment in the test
invocation to use an explicit empty-string literal rather than a space after the
equals sign, while preserving the existing empty release-tag behavior.

---

Outside diff comments:
In `@scripts/resolve-dispatcher-release-target.sh`:
- Around line 184-196: Preserve the existing push-gate wiring in the dispatcher
release evaluation: capture BUILD_SHA, and when CAN_EVALUATE_DISPATCHER_RELEASE
is true but the push HEAD does not satisfy
release_commit_updates_dispatcher_version for VERSION, set both SHOULD_PUBLISH
and SHOULD_RELEASE to false and direct retries to workflow_dispatch. Do not
alter the established prerelease or downstream output-gating behavior.
🪄 Autofix (Beta)

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 919a9583-0278-4040-96c0-f170b61fe403

📥 Commits

Reviewing files that changed from the base of the PR and between 9b02fb5 and 0c3abfd.

📒 Files selected for processing (7)
  • .github/workflows/native-cli-publish.yml
  • docs/release-recovery-runbook.md
  • docs/version-series-realignment.md
  • scripts/resolve-dispatcher-release-target.sh
  • scripts/resolve-native-cli-release-target.sh
  • scripts/test-resolve-dispatcher-release-target.sh
  • scripts/test-resolve-native-cli-release-target.sh
💤 Files with no reviewable changes (1)
  • .github/workflows/native-cli-publish.yml

Comment thread scripts/test-resolve-native-cli-release-target.sh Outdated
hatayama added 2 commits July 21, 2026 11:12
The single retry paragraph conflated two different failure modes: an
unstamped/cancelled dispatcher-publish push run, and a failed
release-please workflow run. Its trailing "once the release exists
with all assets" precondition only applied to the release-please
retry case, but read as applying to the unstamped-push case too,
which can never satisfy it. Split into two separate paragraphs, one
per failure mode.
CodeRabbit flagged INPUT_RELEASE_TAG= \ (shellcheck SC1007: space
after = looks like a typo for ==). Use an explicit empty-string
literal instead.
@hatayama

Copy link
Copy Markdown
Owner Author

@coderabbitai Thanks for the confirmation on the dispatcher push-gate wiring (lines 184-196).

Re: the merge-commit diff caveat you flagged (a true merge commit would make git show render a combined diff, potentially hiding the stamp) — this repo enforces squash merges via the check-pr-title CI gate (conventional-commit PR titles are only meaningful under squash), so HEAD on main/v3-beta is always a single-parent squash commit, never a multi-parent merge commit. The existing release_commit_updates_cli_version predicate in resolve-native-cli-release-target.sh has run under this same assumption in production, so release_commit_updates_dispatcher_version mirroring it is consistent with established behavior. No code change needed here.

Fixed the shellcheck SC1007 nit in cbe9fac.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@hatayama Thanks for the detailed clarification. Given the enforced squash-merge invariant on main and v3-beta, the combined-diff caveat does not apply. Mirroring the established release_commit_updates_cli_version behavior in the dispatcher resolver is appropriate.

Noted the SC1007 fix in cbe9fac6 as well. 🐇


✏️ Learnings added
Learnt from: hatayama
URL: https://github.com/hatayama/unity-cli-loop/pull/1901

Timestamp: 2026-07-21T02:19:50.449Z
Learning: On this repository, `main` and `v3-beta` are enforced to contain single-parent squash commits; the `check-pr-title` CI gate and conventional-commit PR-title workflow rely on squash merging. Release-stamping predicates in `scripts/resolve-native-cli-release-target.sh` and `scripts/resolve-dispatcher-release-target.sh` may therefore rely on ordinary single-parent `git show` diffs rather than handling combined merge diffs.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

@hatayama
hatayama merged commit 2f98ed6 into v3-beta Jul 21, 2026
11 checks passed
@hatayama
hatayama deleted the ci/gate-publish-on-release-stamping-commit branch July 21, 2026 02:23
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