ci: add main CI checks staging-release promotion - #5639
think-in-universe wants to merge 9 commits into
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Note Gemini is unable to generate a review for this pull request due to the file types involved not being currently supported. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughSummary by CodeRabbit
WalkthroughAdds ChangesMain CI checks and staging promotion
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant MainWorkflow
participant MainCIChecks
participant GitHubAPI
participant Slack
participant GitRepository
MainWorkflow->>MainCIChecks: completed workflow_run on main
MainCIChecks->>GitHubAPI: inspect jobs and workflow runs
GitHubAPI-->>MainCIChecks: failure details and workflow statuses
MainCIChecks->>Slack: post failure alert when applicable
MainCIChecks->>GitRepository: fast-forward staging-release after required checks succeed
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
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. Comment |
There was a problem hiding this comment.
Pull request overview
Adds a new GitHub Actions workflow to promote main → staging by fast-forwarding staging only when the latest main commit has a fully green status-check rollup, and refusing to sync if staging has diverged.
Changes:
- Introduces a scheduled / workflow_run-triggered
Sync main to stagingworkflow. - Adds a guard job that queries GitHub’s
statusCheckRollupto ensure the currentmainHEAD is green before syncing. - Fast-forwards
stagingvia GitHub API (no merge commits; refuses ifstaginghas staging-only commits).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| permissions: | ||
| contents: write | ||
|
|
| sync-staging: | ||
| name: Fast-forward staging | ||
| needs: check-main | ||
| if: needs.check-main.outputs.green == 'true' | ||
| runs-on: ubuntu-latest | ||
| steps: |
| git fetch origin main staging | ||
|
|
||
| if git merge-base --is-ancestor "origin/main" "origin/staging"; then |
There was a problem hiding this comment.
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/sync-main-to-staging.yml:
- Around line 192-208: The ancestry checks in the sync-main-to-staging workflow
are using the moving `origin/main` ref, which can drift after `check-main` has
selected the commit to apply. Update the merge-base guards in the sync step to
compare against `MAIN_SHA` consistently, so the safety check and the later `gh
api` PATCH both use the same fixed commit. This keeps the fast-forward decision
aligned with the exact SHA being promoted and avoids rejecting a valid sync when
main advances.
🪄 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: ASSERTIVE
Plan: Pro Plus
Run ID: b2873a15-8dc8-4df1-a370-56221d6bf5d0
📒 Files selected for processing (1)
.github/workflows/sync-main-to-staging.yml
| git fetch origin main staging | ||
|
|
||
| if git merge-base --is-ancestor "origin/main" "origin/staging"; then | ||
| echo "::notice::staging already contains main ${MAIN_SHA}; nothing to sync." | ||
| exit 0 | ||
| fi | ||
|
|
||
| if ! git merge-base --is-ancestor "origin/staging" "origin/main"; then | ||
| echo "::error::staging has commits that are not in main; refusing to overwrite or merge automatically." | ||
| exit 1 | ||
| fi | ||
|
|
||
| gh api \ | ||
| -X PATCH \ | ||
| "repos/${GITHUB_REPOSITORY}/git/refs/heads/staging" \ | ||
| -f "sha=${MAIN_SHA}" \ | ||
| -F "force=false" >/dev/null |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the workflow and inspect the relevant sections with line numbers.
file=".github/workflows/sync-main-to-staging.yml"
wc -l "$file"
sed -n '1,260p' "$file" | cat -nRepository: nearai/ironclaw
Length of output: 8642
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate repository review-rule files and any workflow-specific guidance.
git ls-files | rg '(^|/)(CLAUDE\.md|AGENTS\.md|\.claude/|rules)' || true
# If present, show the relevant guidance files.
for f in CLAUDE.md AGENTS.md .claude/rules.md .claude/rules/*.md; do
if [[ -f "$f" ]]; then
echo "===== $f ====="
sed -n '1,220p' "$f"
fi
doneRepository: nearai/ironclaw
Length of output: 50374
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the workflow file for any nearby references to the target ref/update logic.
sed -n '174,210p' .github/workflows/sync-main-to-staging.yml | cat -nRepository: nearai/ironclaw
Length of output: 1662
Use MAIN_SHA for both merge-base guards. sync-staging re-fetches origin/main after check-main has already captured the commit to apply, so the branch tip can move between jobs. That makes the ancestry check and the PATCH target diverge; a safe fast-forward to MAIN_SHA can be rejected because origin/main advanced.
🤖 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/sync-main-to-staging.yml around lines 192 - 208, The
ancestry checks in the sync-main-to-staging workflow are using the moving
`origin/main` ref, which can drift after `check-main` has selected the commit to
apply. Update the merge-base guards in the sync step to compare against
`MAIN_SHA` consistently, so the safety check and the later `gh api` PATCH both
use the same fixed commit. This keeps the fast-forward decision aligned with the
exact SHA being promoted and avoids rejecting a valid sync when main advances.
Reborn integration-tier coverageLine coverage (Reborn crates): 17.19% — 11063 / 64362 lines Per-crate breakdown (11 crates, lowest-covered first)
This signal is informational: coverage never gates the PR — not the percentage, not the per-crate holes, not the 0-coverage callout. |
|
🚅 Deployed to the ironclaw-pr-5639 environment in ironclaw-ci-preview
|
…sync-main-to-staging-on-green
🔎 IronLoop Review StatusHead: Current reviewers:
Reviewer summaries
Recent activity
Available commands
Run metadataAdmission: webhook accepted the request and IronLoop persisted reviewer state before this projection. |
|
@claude review |
| run: | | ||
| set -euo pipefail | ||
| git push origin "HEAD:refs/heads/${STAGING_BRANCH}" |
| staging-release update is a normal `git push` to | ||
| `refs/heads/staging-release`, so it fails instead of forcing when | ||
| `staging-release` is not a fast-forward from `main`. |
Code Review: PR #5639Found 5 issues: HIGH SEVERITY
MEDIUM SEVERITY
Recommendations
No security vulnerabilities found. Permission scoping is correct (global read-only, job-specific write). Fast-forward-only git behavior preserves branch safety. Secrets handling is secure. |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/main-ci-checks.yml:
- Around line 230-238: Reorder the checks in the workflow so the divergence
validation runs before the “already contains main” early exit. In the merge-base
logic around the `HEAD_SHA` and `origin/${STAGING_BRANCH}` checks, first reject
staging commits absent from `origin/main`, then report success only when staging
contains the promoted main commit.
In @.github/workflows/README.md:
- Around line 121-124: Update the staging-release promotion documentation to
scope the “fails only” statement specifically to the ancestry guard, while also
noting that required CI, pending runs, push permissions, and concurrent updates
may independently block or fail the workflow. Preserve the existing SHA-skip and
non-ancestor behavior description.
🪄 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: ASSERTIVE
Plan: Pro Plus
Run ID: 5982226d-2319-4462-94e6-3bb586650c8c
📒 Files selected for processing (2)
.github/workflows/README.md.github/workflows/main-ci-checks.yml
| if git merge-base --is-ancestor "$HEAD_SHA" "origin/${STAGING_BRANCH}"; then | ||
| echo "::notice::${STAGING_BRANCH} already contains main ${HEAD_SHA}; nothing to sync." | ||
| exit 0 | ||
| fi | ||
|
|
||
| if ! git merge-base --is-ancestor "origin/${STAGING_BRANCH}" "origin/main"; then | ||
| echo "::error::${STAGING_BRANCH} has commits that are not in main; refusing to overwrite or merge automatically." | ||
| exit 1 | ||
| fi |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Check divergence before treating staging as already promoted.
Line 230 also succeeds for HEAD_SHA -> staging-only commit, returning before Lines 235-238 can reject divergence. This violates the documented requirement to fail when staging-release contains commits absent from main.
Proposed fix
- if git merge-base --is-ancestor "$HEAD_SHA" "origin/${STAGING_BRANCH}"; then
- echo "::notice::${STAGING_BRANCH} already contains main ${HEAD_SHA}; nothing to sync."
- exit 0
- fi
-
if ! git merge-base --is-ancestor "origin/${STAGING_BRANCH}" "origin/main"; then
echo "::error::${STAGING_BRANCH} has commits that are not in main; refusing to overwrite or merge automatically."
exit 1
fi
+
+ if git merge-base --is-ancestor "$HEAD_SHA" "origin/${STAGING_BRANCH}"; then
+ echo "::notice::${STAGING_BRANCH} already contains main ${HEAD_SHA}; nothing to sync."
+ exit 0
+ fi📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if git merge-base --is-ancestor "$HEAD_SHA" "origin/${STAGING_BRANCH}"; then | |
| echo "::notice::${STAGING_BRANCH} already contains main ${HEAD_SHA}; nothing to sync." | |
| exit 0 | |
| fi | |
| if ! git merge-base --is-ancestor "origin/${STAGING_BRANCH}" "origin/main"; then | |
| echo "::error::${STAGING_BRANCH} has commits that are not in main; refusing to overwrite or merge automatically." | |
| exit 1 | |
| fi | |
| if ! git merge-base --is-ancestor "origin/${STAGING_BRANCH}" "origin/main"; then | |
| echo "::error::${STAGING_BRANCH} has commits that are not in main; refusing to overwrite or merge automatically." | |
| exit 1 | |
| fi | |
| if git merge-base --is-ancestor "$HEAD_SHA" "origin/${STAGING_BRANCH}"; then | |
| echo "::notice::${STAGING_BRANCH} already contains main ${HEAD_SHA}; nothing to sync." | |
| exit 0 | |
| fi |
🤖 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/main-ci-checks.yml around lines 230 - 238, Reorder the
checks in the workflow so the divergence validation runs before the “already
contains main” early exit. In the merge-base logic around the `HEAD_SHA` and
`origin/${STAGING_BRANCH}` checks, first reject staging commits absent from
`origin/main`, then report success only when staging contains the promoted main
commit.
| if [ "${#missing[@]}" -gt 0 ] || [ "${#pending[@]}" -gt 0 ]; then | ||
| echo "ready=false" >> "$GITHUB_OUTPUT" | ||
| if [ "${#missing[@]}" -gt 0 ]; then | ||
| printf 'Required workflow has not appeared yet: %s\n' "${missing[@]}" | ||
| fi | ||
| if [ "${#pending[@]}" -gt 0 ]; then | ||
| printf 'Workflow is still pending: %s\n' "${pending[@]}" | ||
| fi | ||
| exit 0 | ||
| fi |
|
I pushed fixes for the open actionable review items in this PR on commit What changed:
If you want, I can follow up with one short comment per unresolved thread and explicitly cite the exact file/line changes. |
There was a problem hiding this comment.
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/main-ci-checks.yml:
- Around line 110-113: Remove the github.event.workflow_run.name == 'Code Style'
condition from the job-level if expression in the workflow, while retaining the
push-event and successful-conclusion checks. Rely on the existing concurrency
group and SHA validation to prevent duplicate processing.
🪄 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: ASSERTIVE
Plan: Pro Plus
Run ID: c83cedd1-cd30-4028-9adf-1a27ecff1e42
📒 Files selected for processing (1)
.github/workflows/main-ci-checks.yml
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/main-ci-checks.yml (1)
160-172: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winDo not treat workflow-query failures as skipped optional checks.
When
gh run listfails, this replaces the result with{}. Lines 177-182 then classify every optional query failure as “did not run,” allowing promotion without confirming that the optional workflow passed. Track query failures as pending/retryable for both required and optional workflows instead.Proposed fix
if ! run_json="$(gh run list \ --repo "$GITHUB_REPOSITORY" \ --workflow "$workflow" \ --branch main \ --event push \ --commit "$HEAD_SHA" \ --limit 1 \ --json conclusion,status,url \ --jq '.[0] // {}' \ 2>/dev/null)"; then echo "::warning::Failed to query workflow status for ${workflow}; treating as missing." - run_json='{}' + pending+=("${workflow} (status query failed)") + return fi🤖 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/main-ci-checks.yml around lines 160 - 172, Update the workflow-status polling logic around the gh run list query and its run_json='{}' fallback so query failures are tracked as pending/retryable rather than classified as missing or skipped. Ensure this behavior applies equally to required and optional workflows, preventing promotion until each query succeeds and confirms the workflow result.
🤖 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.
Outside diff comments:
In @.github/workflows/main-ci-checks.yml:
- Around line 160-172: Update the workflow-status polling logic around the gh
run list query and its run_json='{}' fallback so query failures are tracked as
pending/retryable rather than classified as missing or skipped. Ensure this
behavior applies equally to required and optional workflows, preventing
promotion until each query succeeds and confirms the workflow result.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: a2bf1e21-535d-4354-8e73-896cc9e8d2af
📒 Files selected for processing (1)
.github/workflows/main-ci-checks.yml
Summary
Main CI Checksworkflow.MAIN_CI_SLACK_WEBHOOK_URLS.staging-releaseto a greenmaincommit after required push-to-main CI workflows pass for that SHA.staging-releasealready contains the SHA and fails rather than overwriting staging-release-only commits.Change Type
Linked Issue
None.
Validation
origin/staging-releasefrom currentorigin/mainwith a normal push..github/workflows/main-ci-checks.ymlas YAML locally.bash -n.git diff --checkfor the workflow changes.actionlintwas not available locally.Security Impact
This workflow uses the dedicated
MAIN_CI_SLACK_WEBHOOK_URLSsecret for Slack alert delivery and does not print webhook values. The staging-release promotion job grantscontents: writeonly to the job that updatesrefs/heads/staging-release, and it performs a normal non-force push. It does not run untrusted PR code; it reacts to completed push-to-main workflow runs.Reborn Trust-Boundary Checklist
N/A: GitHub Actions automation only; no Reborn runtime, trust-bearing type, prompt ingress, policy, sandbox, DB, or host-boundary behavior is changed.
Database Impact
None.
Blast Radius
Touches GitHub Actions automation for main CI alerting and branch promotion from
maintostaging-release. Possible breakage is limited to Slack alert delivery and the workflow's ability to fast-forward the staging-release ref.Rollback Plan
Revert this PR to restore the Slack-only main CI alert workflow and remove automatic staging-release promotion. If promotion must be paused without reverting, protect
staging-releaseagainst direct pushes or disable theMain CI Checksworkflow.Review Follow-Through
Reviewer should confirm the required workflow list and whether
staging-releaseshould stay fast-forward-only frommain.Review track: C (CI)
Note: This workflow targets
staging-release(notstaging) for automated main→staging release fast-forwarding.