Files
gitea-actions/git/promotion-gate/action.yml
T
deac 4e765e5c64
publish.yaml / publish (push) Successful in 4s
add-promotion-gate-action: Add git/promotion-gate composite action
Enforces which source branches may merge into which target branches, configured via a rules input (one target:allowed,allowed per line, glob-capable). Empty rules (default) skips enforcement entirely, so repos can adopt it without immediately gating on rules they have not configured. Extracted for reuse across repos moving to a gitflow-style branch promotion model, starting with stat-tackler-api.
2026-08-21 14:57:03 -04:00

76 lines
1.9 KiB
YAML

name: Promotion Gate
description: Enforce which source branches may merge into which target branches
inputs:
rules:
description: |
One rule per line: "target:allowed1,allowed2,...". Targets not
listed are unrestricted. Allowed entries may use a trailing glob,
e.g. `hotfix-*`. Leave empty (default) to skip entirely.
default: ""
runs:
using: composite
steps:
- name: Check merge source is allowed for target branch
shell: sh
env:
BASE: ${{ gitea.event.pull_request.base.ref }}
HEAD: ${{ gitea.event.pull_request.head.ref }}
RULES: ${{ inputs.rules }}
run: |
if [ -z "$RULES" ]; then
echo "No promotion rules configured — skipping."
exit 0
fi
rc=0
found=0
oldIFS=$IFS
IFS='
'
set -f
set -- $RULES
set +f
IFS=$oldIFS
for line in "$@"; do
if [ -z "$line" ]; then
continue
fi
target=${line%%:*}
allowed=${line#*:}
if [ "$target" = "$line" ]; then
continue
fi
if [ "$BASE" = "$target" ]; then
found=1
matched=0
innerIFS=$IFS
IFS=','
for pat in $allowed; do
IFS=$innerIFS
case "$HEAD" in
$pat)
matched=1
;;
esac
IFS=','
done
IFS=$innerIFS
if [ "$matched" -eq 1 ]; then
echo "Allowed: '$HEAD' -> '$BASE' (matches: $allowed)"
else
echo "::error::$BASE only accepts merges from: $allowed — got '$HEAD'"
rc=1
fi
fi
done
if [ "$found" -eq 0 ]; then
echo "No promotion-source restriction configured for base '$BASE'"
fi
exit $rc