fluxer/scripts/ci/workflows/promote_canary_to_main.py
2026-02-17 12:22:36 +00:00

74 lines
1.7 KiB
Python
Executable File

#!/usr/bin/env python3
import pathlib
import sys
sys.path.append(str(pathlib.Path(__file__).resolve().parents[1]))
from ci_workflow import EnvArg, parse_step_env_args
from ci_utils import run_step
STEPS: dict[str, str] = {
"verify": """
set -euo pipefail
src="${SRC}"
dst="${DST}"
git fetch origin "${dst}" "${src}" --prune
# Ensure HEAD is exactly origin/src
git reset --hard "origin/${src}"
# FF-only requirement: dst must be an ancestor of src
if ! git merge-base --is-ancestor "origin/${dst}" "origin/${src}"; then
echo "::error::Cannot fast-forward: origin/${dst} is not an ancestor of origin/${src} (branches diverged)."
exit 1
fi
ahead="$(git rev-list --count "origin/${dst}..origin/${src}")"
echo "ahead=$ahead" >> "$GITHUB_OUTPUT"
{
echo "## Promote \`${src}\` → \`${dst}\` (ff-only)"
echo ""
echo "- \`${dst}\`: \`$(git rev-parse "origin/${dst}")\`"
echo "- \`${src}\`: \`$(git rev-parse "origin/${src}")\`"
echo "- Commits to promote: **${ahead}**"
echo ""
echo "### Commits"
if [ "$ahead" -eq 0 ]; then
echo "_Nothing to promote._"
else
git log --oneline --decorate "origin/${dst}..origin/${src}"
fi
} >> "$GITHUB_STEP_SUMMARY"
""",
"push": """
set -euo pipefail
dst="${DST}"
# Push src HEAD to dst (no merge commit, same SHAs)
git push origin "HEAD:refs/heads/${dst}"
""",
"dry_run": """
echo "No push performed (dry_run=${DRY_RUN}, ahead=${AHEAD})."
""",
}
def main() -> int:
args = parse_step_env_args(
[
EnvArg("--src", "SRC"),
EnvArg("--dst", "DST"),
EnvArg("--dry-run", "DRY_RUN"),
EnvArg("--ahead", "AHEAD"),
]
)
run_step(STEPS, args.step)
return 0
if __name__ == "__main__":
raise SystemExit(main())