AkurAI Build
Menu

Public repository / main

AkurAI-Build / deploy/hooks/pre-receive

Latest change cd8019fddc46769e797dc54194decfd9d4a98f2d - OLI-270: branch protection — rules per branch, pre-receive check, merge gate by Óli

#!/bin/sh
# Installed by AkurAI Build into every hosted repository (hooks/pre-receive).
# Asks the forge whether each ref update is allowed by the branch protection rules
# (OLI-270). Pushes only reach this hook through the forge's Smart HTTP endpoint,
# which passes AKURAI_FORGE_URL, AKURAI_FORGE_TOKEN and AKURAI_FORGE_REPO; without
# them (a local push by the forge user) nothing is checked.
[ -n "${AKURAI_FORGE_URL:-}" ] && [ -n "${AKURAI_FORGE_TOKEN:-}" ] && [ -n "${AKURAI_FORGE_REPO:-}" ] || exit 0
zero=0000000000000000000000000000000000000000
status=0
while read -r old new ref; do
  if [ "$old" = "$zero" ] || [ "$new" = "$zero" ]; then
    ff=true
  elif git merge-base --is-ancestor "$old" "$new" 2>/dev/null; then
    ff=true
  else
    ff=false
  fi
  body=$(printf '{"reference":"%s","old":"%s","new":"%s","fast_forward":%s}' "$ref" "$old" "$new" "$ff")
  reply=$(curl -s -m 10 -X POST "$AKURAI_FORGE_URL/api/repos/$AKURAI_FORGE_REPO/protection/check" \
    -H "Authorization: Bearer $AKURAI_FORGE_TOKEN" -H 'Content-Type: application/json' --data "$body") || reply=""
  if printf '%s' "$reply" | grep -Eq '"allowed":[[:space:]]*true'; then
    :
  elif printf '%s' "$reply" | grep -Eq '"allowed":[[:space:]]*false'; then
    reason=$(printf '%s' "$reply" | sed -n 's/.*"reason":[[:space:]]*"\([^"]*\)".*/\1/p')
    echo "akurai-build: rejected $ref: ${reason:-protected branch}" >&2
    status=1
  else
    echo "akurai-build: could not check branch protection for $ref (forge did not answer)" >&2
    status=1
  fi
done
exit $status