pulumi up can be dispatched from any branch (PR or main). Without coordination, two concurrent PRs could race — each uping over the other, or a stale branch could revert a newer deployment.
The reusable workflow gets a new optional live-branch input. When set and cmd == "up":
- Pre-step: verify HEAD descends from the current
live-branchpointer - Run:
pulumi upas normal - Post-step (on success only): fast-forward
live-branchto HEAD
git fetch origin "$LIVE_BRANCH" || {
echo "::notice::live-branch '$LIVE_BRANCH' does not exist yet, skipping ancestry check"
exit 0
}
LIVE_SHA=$(git rev-parse "origin/$LIVE_BRANCH")
if ! git merge-base --is-ancestor "$LIVE_SHA" HEAD; then
echo "::error::Cannot up: HEAD is not a descendant of $LIVE_BRANCH ($LIVE_SHA). Rebase onto $LIVE_BRANCH first."
exit 1
figit push origin "HEAD:refs/heads/$LIVE_BRANCH"Fast-forward by construction (ancestry verified above). If two concurrent ups race, the second push fails (non-fast-forward) — desired behavior.
Unrestricted — no ancestry check, no pointer update. Any branch can preview.
inputs:
live-branch:
description: 'Branch to track last successful `up`. If set, enforces monotonic ancestry for `up` commands.'
required: false
type: string
default: ''permissions:
contents: write # needed to push live-branch pointer (upgrade from read)Note: this is only needed when live-branch is set. The workflow already has contents: read. The caller must also grant contents: write.
Add two steps around the existing "Run Pulumi" step:
- Before "Run Pulumi": ancestry check (conditional on
inputs.cmd == 'up' && inputs.live-branch != '') - After "Run Pulumi": update pointer (conditional on same + success)
jobs:
pulumi:
uses: Open-Athena/pulumi/.github/workflows/pulumi.yml@v1
with:
cmd: ${{ inputs.cmd }}
stack: ${{ inputs.stack }}
project: ${{ inputs.project }}
working-directory: aws/${{ inputs.project }}
deps-directory: aws
live-branch: aws-live
permissions:
contents: write
id-token: write# In Open-Athena/ops: point aws-live at the last successfully up'd commit
# (currently HEAD of rw/pulumi-test-role, which was the last `up`)
git push o <last-up-sha>:refs/heads/aws-live- Per-stack branches (
aws-live/oa-ci/dev) vs singleaws-live? Start with single, split later if needed. - Add
concurrencykey to serializeupinvocations? Push-time rejection is probably sufficient.