74 lines
1.7 KiB
Python
Executable File
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())
|