build: staging moves itself every Friday after the full check, and stageaf installs it - #1438
Merged
Merged
Conversation
Accept a required ref from reusable callers and an optional ref from a manual dispatch. Check out that ref in every job and give it a separate concurrency group. Keep the nightly issue job off a called check so a promotion failure cannot page with the caller's SHA. The runbook's by-hand step, which passed a sha to --ref and was refused, becomes --ref dev -f ref=$SHA. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Choose the latest first-parent dev commit at the Toronto Friday 17:00 committer-time cutoff, run the reusable Full check on it, and fast-forward staging only after a successful result. Recheck both refs immediately before the token-backed push, wait for the release run created by this push, and send every outcome to the run summary and the configured Slack webhook. Report a failed plan and unexpected finish errors even when the release tool fails. Send a separate production signal for the staging pointer captured before the promotion. Keep main manual, and document the retry, dry-run, fine-grained token, bypass, and fallback roads. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Route update and failed-install guidance for a stageaf executable through the staging proxy (agentfield.ai/get/stageaf). Name the stageaf install line in staging release notes, the terminal manual, and the guide. Cover the named installer, update failure, release notes, and manual retrieval with focused tests. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…#1438) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The plan-failed job ran scripts/slack-post.sh without checking the repository out, and every job starts in an empty workspace, so a failed plan reported nothing to the run summary or to Slack. Its shell-block test copied the script into its own directory and could not see the gap. A new law test walks every job in promote-staging.yml and fails when a step runs a repository script or command before any checkout. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A plan is current when staging already holds the cutoff commit, which includes staging having moved past it; the message said "Nothing new on dev" in both cases, though dev can carry commits after the cutoff. It now says staging is already past the commit when the two differ. An empty push, fetch or recheck log made the error reader print an empty line, which the message quoted as "was refused: ." The reader now refuses an empty log, and the message names a missing reason instead of drawing a bare colon. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Promote to staging, runs every Friday. It picks the newest first-parentdevcommit whose committer time is at or before 17:00 America/Toronto and runs the Full check on that exact commit. If the check passes, it fast-forwardsstagingto the commit and waits for the staging build to publish. Every outcome is posted to Slack and to the run summary.stagingheld before its own move as the candidate formain, with the exact push command.mainstays manual and runs one week behindstaging.stageaf.curl -fsSL https://agentfield.ai/get/stageaf | bashinstalls the staging build asstageafbesidecodeaf, the staging twin ofdevaf. The proxy row is website2.0 PR multi-attach R1 / L2: home's held row opens through the host instead of being refused #64; this PR makes codeaf spell that address (a stageaf's own reinstall line, staging release notes, the manual, and GUIDE).Why the cutoff is a commit time
Scheduled runs here start hours late: the nightly
0 9 * * *started between 12:59Z and 15:46Z this week. The cron (30 22 * * 5, which is 18:30 EDT / 17:30 EST) only has to fire some time after the cutoff. A law test checks that relation in both UTC offsets.devonly moves by squash merges that GitHub makes, so a commit's committer time is the moment it landed ondev.Changes
ci-full.yml: takesworkflow_callwith a requiredref, plus an optionalrefon dispatch. Every checkout uses that ref, the concurrency group is keyed by it, and the nightly-issuepagejob ignores called runs. Push, pull-request and nightly behavior are unchanged. This also repairs the runbook's by-hand step:gh workflow run ci-full.yml --ref $SHAis refused for a sha, so it becomes--ref dev -f ref=$SHA.promote-staging.yml(jobsplan,plan-failed,signal,full_check,finish) plus newcmd/codeaf-release promotion-*subcommands. The branching logic (cutoff math, candidate choice, outcome, release-run matching, Slack text and escaping) is in Go and tested with injected clocks and throwaway git repositories. The push is fast-forward only, rechecked immediately before it happens, and never touchesmain. If anything fails unexpectedly, an error trap still posts a message saying whetherstagingmoved.scripts/slack-post.sh: posts toSLACK_RELEASE_WEBHOOK. If the secret is missing, the message still lands in the run summary and the run only warns.stageafadded toupdate.CurlLine, the staging release notes,running-from-the-terminal.md(new section + probes), anddocs/GUIDE.md.docs/rules/promotion.md(the weekly road, every message and what to do next, retry and dry run, one-time setup),docs/rules/ci.md,.github/rulesets/README.md, andCLAUDE.mdBranches.One-time setup (owner, before the first Friday that should push)
PROMOTION_TOKEN: a fine-grained personal access token scoped to this repository, with Contents: read and write and Workflows: read and write, owned by an account that can bypass the liveprotectionruleset (check withgh api repos/Agent-Field/codeaf/rulesets/<id> --jq .current_user_can_bypass→always).GITHUB_TOKENcan't do this job: its pushes start no other workflow, soReleasewould never publish, and GitHub refuses its pushes when the commits touch.github/workflows/.SLACK_RELEASE_WEBHOOK: a Slack incoming webhook. The webhook's own configuration picks the channel.Without the token, a Friday run still runs the check. It then reports that
stagingdid not move, gives the exact by-hand push, and ends red.Test plan
make pr-ready BASE=c26ea9c98: light gate plus freshcmd/codeaf,cmd/codeaf-release,internal/manual,internal/release,internal/update, all ok.actionlintv1.7.7 on every workflow;make test-laws;make test-packed-manual.needsedge, a Full check checkout or its ref, orpersist-credentials: falseturns them red.dev/staging/mainwith--now 2026-09-25T22:30:00Z. It picksc26ea9c98(6 changes over5ba989468), and every message renders as intended (moved, check failed or cancelled, token missing, build did not publish, current, dry run, and both production-signal shapes).gh workflow run promote-staging.yml --ref dev -f dry_run=true -f signal=trueproves the reusable call, the permissions and the messages on GitHub without movingstaging.Rollout order
Merge website2.0 PR #64 first, so
/get/stageafanswers before any staging release notes or Slack message hand it out.🤖 Generated with Claude Code