Skip to content

fix: port promotion script fixes from infra-central - #163

Merged
bajtos merged 5 commits into
mainfrom
claude/clever-saha-3936a3
Oct 15, 2026
Merged

bajtos merged 5 commits into
mainfrom
claude/clever-saha-3936a3

Conversation

@bajtos

@bajtos bajtos commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

Written by Claude.

Port the improvements fil-forge/infra-central#245 made while porting #136's change-list format to infra-central's scripts/promote.sh.

  • Page the compare API. Unpaged, it stops at 250 commits without saying so. gh api --paginate --slurp hands jq every page as one array, so the identical, behind, diverged and cut-short notes are written once. jq is now a prerequisite; ubuntu-latest ships it.
  • Run under bash 3.2, so --dry-run works with macOS's /bin/bash. VERSIONS is a plain string that load_versions sets for the service being described, and digest_link takes only the digest.
  • Derive the ghcr.io org and package from the service's repository.
  • Delete the remote-tracking ref when bot/promote-staging is gone from origin, so old_head never names a commit the force-with-lease cannot match.
  • Treat a head the bot authored but did not commit as hand-pushed, since an amended bot commit keeps the bot as author.
  • Check for a hand-pushed head before the close path too, so a held-back branch is no longer deleted once staging matches dev. The runbook says so.
  • Build the promotion commit in a temporary worktree detached at origin/main, removed on exit, so neither a dry run nor a real one touches the calling checkout, its index or its branches.

infra-central's SOURCE/TARGET stages, BASE and SMOKE_RUN_URL stay out.

Verification

  • make check-shell passes.
  • changes against fil-forge/ingot 6071feb...7b28323 lists all 8 commits ahead; swapped, it prints only the "8 commits behind" note; the same commit twice prints only the "same commit" note. With per_page=5 the API returns two pages (5 + 3) and the output matches per_page=100 exactly.
  • APP_SLUG=fil-forge-bot /bin/bash scripts/ci/promote-staging.sh --dry-run (bash 3.2.57) exits 0, lists ingot's 9 commits with both digests linked to ghcr.io.
  • The same dry run in a clone with origin/main at e7c8906, started with an unstaged edit, an untracked file, a staged file, a staged edit to staging's versions.env and an existing dry-run/promote-staging, lists ingot's 8 commits, commits only the one-line pin change, and leaves HEAD, the index, every probe and the branch as they were, with no worktree left behind.

infra-central's port of the change-list format (fil-forge/infra-central
PR 245) improved on it in places that matter here too:

- Page the compare API. Unpaged, it stops at 250 commits without saying
  so. The pages are read as one array with jq, so the notes about an
  identical, behind or diverged pin are written once, not per page.
- Run under bash 3.2, so --dry-run works with macOS's /bin/bash:
  VERSIONS is a plain string set for the service being described.
- Name the ghcr.io package after the repository it publishes from.
- Drop a stale remote-tracking ref when bot/promote-staging is gone
  from origin, so the force-with-lease matches the real branch.
- Treat a head the bot authored but did not commit as hand-pushed: an
  amended bot commit keeps the bot as author.
- Check for a hand-pushed head before closing, so a held-back branch is
  not deleted once staging catches up with dev.
- Build a dry run on a scratch branch and switch back afterwards, so
  the local bot/promote-staging is never touched.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Miroslav Bajtoš <oss@bajtos.net>
Copilot AI balanced review requested due to automatic review settings October 14, 2026 16:40
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-14T16:45:13.562283Z bbaa2a4 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bbaa2a4c13

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/ci/promote-staging.sh Outdated
Comment thread scripts/ci/promote-staging.sh Outdated

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.

🔵 Needs a closer look

The script performs force-pushes, remote branch deletions, and PR open/close operations with subtle git ref/lease semantics that warrant human verification before approval.

1 open finding
What changed in this PR

This PR ports a set of fixes to scripts/ci/promote-staging.sh (which keeps the "Promote dev's images to staging" pull request) from the equivalent script in infra-central. The changes harden the script's compare-API handling, git-ref bookkeeping, and dry-run isolation, and follow up #136's change-list formatting work. It fits into the automated promotion pipeline run by promote-staging.yml on every push to main.

Changes:

  • Page the compare API with gh api --paginate --slurp and process all pages as one array in a standalone jq, so the identical/behind/diverged/cut-short notes are written once and the list is not silently capped at 250 commits.
  • Make the script bash 3.2 compatible (VERSIONS as a plain string instead of an associative array) and derive the ghcr.io org/package from each service's repository; digest_link now takes only the digest.
  • Fix git-ref handling: delete stale remote-tracking refs for a branch gone from origin, treat an app-authored-but-not-committed head as hand-pushed (and check this before the close path), build dry runs on a scratch branch, and push via HEAD:refs/heads/$BRANCH.
File Description
scripts/​ci/​promote-staging.sh Paginated compare API, bash 3.2-safe VERSIONS/digest_link refactor, stale-ref cleanup, author+committer hand-push check moved earlier, dry-run scratch branch, and updated header/usage docs.
docs/​RUNBOOK.md Updates the hold-a-service-back guidance to match the new author+committer detection (an amended bot commit counts as a hand-push).

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread scripts/ci/promote-staging.sh Outdated
The dry run committed on dry-run/promote-staging, switched back and
deleted that branch. Anything staged went into the commit and was lost
with it, and an existing branch of that name was reset to main.

- Commit on a detached HEAD, which needs no branch name.
- Refuse to run with staged changes or an edit to staging's
  versions.env, which the promotion commit would take in.
- List the jq variables the SC2016 comment covers.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Miroslav Bajtoš <oss@bajtos.net>
Every run now builds the commit in a worktree detached at main and
removed on exit, as infra-central's promote.sh does. The worktree's
index starts clean, so nothing staged in the checkout the script runs
in can reach the commit, and the checkout's branches are never moved.

This replaces the detached checkout and the refusal to run with a
dirty index, which only guarded the dry run.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Miroslav Bajtoš <oss@bajtos.net>
Set the trap that removes the worktree where the worktree is made, and
fall back to deleting its directory, so a failed git worktree add
leaves no empty temporary directory behind. This and the comments now
match infra-central's promote.sh (fil-forge/infra-central#251).

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Miroslav Bajtoš <oss@bajtos.net>
@bajtos bajtos changed the title Port promotion script fixes from infra-central fix: port promotion script fixes from infra-central Oct 15, 2026
@bajtos
bajtos enabled auto-merge (squash) October 15, 2026 09:52
@bajtos
bajtos merged commit 2b956c2 into main Oct 15, 2026
4 checks passed
@bajtos
bajtos deleted the claude/clever-saha-3936a3 branch October 15, 2026 09:53
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