mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-09-30 05:43:14 +00:00
* ci: re-home prod promotion into a gated promote-to-main workflow Migrate the prod-deploy gate to managed LangGraph Cloud (git-connected to `main`) + Vercel. Under managed, a push to `main` auto-deploys prod, so the dev -> main fast-forward IS the prod deploy trigger -- the bespoke AWS CD step is obsolete and already gone from this workflow. Re-home `promote-dev-to-prod.yml` -> `promote-to-main.yml`: - gate the promote job on the `prod` GitHub Environment (required reviewer amoussa1229), restoring the manual prod-approval that the retired AWS CD job used to carry; - drop the nightly auto-promote cron -- a scheduled auto-promotion conflicts with a manual approval gate now that the push deploys prod; promotion is workflow_dispatch only; - keep the dev-HEAD-fully-green precondition and the seahaven-promotion App fast-forward push (sole non-admin bypass actor on `main` ruleset 18238334). Update the companion check-dev-green.sh filename reference. * ci: refuse promote-to-main dispatch from any ref other than dev Defense-in-depth atop the already-pinned `ref: dev` checkout: workflow_dispatch runs the workflow definition from the launched ref, so reject a non-dev dispatch before the App token is minted. Surfaced by the GPT-4.1 cross-review of #63.
98 lines
5 KiB
YAML
98 lines
5 KiB
YAML
# Gated dev -> main promotion (the PROD deploy gate under managed LangGraph Cloud).
|
|
#
|
|
# PROD now runs on managed LangGraph Cloud (git-connected to `main`) + Vercel (UI).
|
|
# The platform AUTO-DEPLOYS prod on every push to `main`, so a fast-forward of `main`
|
|
# to `dev` IS the prod deploy trigger -- there is no separate AWS deploy step anymore
|
|
# (the bespoke S3/SSM/packer CD is retired). This workflow therefore carries the whole
|
|
# prod-promotion gate:
|
|
# 1. manual dispatch only (no scheduled auto-promote -- prod ships when a human asks),
|
|
# 2. the `prod` GitHub Environment approval (required reviewer: amoussa1229),
|
|
# 3. the dev-HEAD-fully-green precondition (check-dev-green.sh),
|
|
# 4. a fast-forward-only push of `main` -> `dev` via the seahaven-promotion App, the
|
|
# sole non-admin bypass actor on the `main` ruleset (id 18238334).
|
|
name: Promote to main (prod)
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
|
|
concurrency:
|
|
group: promote-dev-to-main
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
promote:
|
|
runs-on: ubuntu-latest
|
|
# The manual-approval gate. The `prod` Environment's required reviewer
|
|
# (amoussa1229) must approve before this job runs -- and because the FF push
|
|
# below auto-deploys managed prod, that approval IS the prod-deploy approval.
|
|
environment: prod
|
|
permissions:
|
|
contents: write
|
|
checks: read
|
|
steps:
|
|
# Defense-in-depth: the checkout below pins `ref: dev`, so this workflow only
|
|
# ever promotes dev's HEAD. But workflow_dispatch runs the workflow DEFINITION
|
|
# from whichever ref it was launched on, so a branch that edited this file could
|
|
# otherwise reach the privileged steps. Refuse any dispatch not from `dev`,
|
|
# before the App token is minted. (The `prod` Environment approval still gates
|
|
# everything after this regardless.)
|
|
- name: Guard — only promote from dev
|
|
env:
|
|
DISPATCH_REF: ${{ github.ref_name }}
|
|
run: |
|
|
if [ "${DISPATCH_REF}" != "dev" ]; then
|
|
echo "::error::promote-to-main must be dispatched from 'dev' (got '${DISPATCH_REF}')."
|
|
exit 1
|
|
fi
|
|
echo "Dispatch ref OK: ${DISPATCH_REF}"
|
|
# Mint a GitHub App installation token for the protected-branch push below.
|
|
# A plain ref push by github-actions[bot] is REJECTED by the `main` ruleset
|
|
# (PRs required + a required status check; the default token is not a bypass
|
|
# actor). The App behind these secrets MUST be added to the `main` ruleset's
|
|
# bypass actors; the push is then accepted and attributed to the App (not a
|
|
# human PAT). The promoted commit already passed every check on dev (gated
|
|
# below), so re-gating it via a PR on main would be redundant.
|
|
- name: Mint app token for the protected-branch push
|
|
id: app-token
|
|
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
|
|
with:
|
|
app-id: ${{ secrets.PROMOTE_APP_ID }}
|
|
private-key: ${{ secrets.PROMOTE_APP_PRIVATE_KEY }}
|
|
- uses: actions/checkout@v7
|
|
with:
|
|
ref: dev
|
|
fetch-depth: 0
|
|
# Persist the App token as the git credential so the fast-forward push uses
|
|
# the bypass-actor identity (not the default github-actions[bot]).
|
|
token: ${{ steps.app-token.outputs.token }}
|
|
- name: Require dev HEAD fully green
|
|
# Hard precondition: every check-run on the dev HEAD commit must be
|
|
# completed + passing before we let it become prod. A red OR still-pending
|
|
# check blocks the promotion. The promotion workflow's OWN check-runs are
|
|
# excluded by the gate (this run by id, plus any STALE prior promote runs by
|
|
# name + Actions URL) so the gate can't deadlock on itself.
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
# exclude THIS run's own check-run by its run id (not by name).
|
|
EXCLUDE_RUN_ID: ${{ github.run_id }}
|
|
run: |
|
|
SHA="$(git rev-parse HEAD)"
|
|
echo "dev HEAD = ${SHA}"
|
|
gh api --paginate "repos/${GITHUB_REPOSITORY}/commits/${SHA}/check-runs" \
|
|
-q '.check_runs[] | [.name, .status, (.conclusion // ""), (.details_url // "")] | join("\u001f")' \
|
|
| bash .github/scripts/check-dev-green.sh
|
|
- name: Fast-forward main (PROD) to dev
|
|
# main is the production branch: managed LangGraph Cloud is git-connected to it
|
|
# and auto-deploys prod on every push, so THIS push is the prod deploy trigger.
|
|
# A direct ref push is normally rejected by the `main` ruleset (PRs required),
|
|
# so it succeeds only because the App minted above is a bypass actor. The push
|
|
# is fast-forward-only, so a diverged main fails loudly rather than force-updating.
|
|
#
|
|
# SECURITY: this is the LAST step on purpose. The App token persists as the
|
|
# git credential after checkout — do not add steps after this push that run
|
|
# untrusted code or could echo the credential.
|
|
run: |
|
|
git push origin HEAD:refs/heads/main
|