#!/usr/bin/env bash # Apply branch protection rules to Furtka's main branch on Forgejo. # Idempotent — re-runs safely (creates on first call, patches thereafter). # # Requires: jq, curl, and a Forgejo personal access token with repo write # scope. Token is read from $FORGEJO_TOKEN, or extracted from the local # git remote URL as a fallback. # # Usage: # FORGEJO_TOKEN=... ./ops/forgejo/apply-branch-protection.sh set -euo pipefail HOST="${FORGEJO_HOST:-forgejo.sourcegate.online}" REPO="${FORGEJO_REPO:-daniel/furtka}" BRANCH="${FORGEJO_BRANCH:-main}" if [ -z "${FORGEJO_TOKEN:-}" ]; then FORGEJO_TOKEN=$(git config --get remote.origin.url \ | sed -nE 's|https://[^:]+:([^@]+)@.*|\1|p') fi if [ -z "${FORGEJO_TOKEN:-}" ]; then echo "error: set FORGEJO_TOKEN or configure a token in remote.origin.url" >&2 exit 1 fi here=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) config="$here/branch-protection.json" base="https://${HOST}/api/v1/repos/${REPO}/branch_protections" api() { curl --silent --show-error --fail-with-body \ --header "Authorization: token ${FORGEJO_TOKEN}" \ --header "Content-Type: application/json" \ "$@" } code=$(curl --silent --output /dev/null --write-out '%{http_code}' \ --header "Authorization: token ${FORGEJO_TOKEN}" \ "${base}/${BRANCH}") case "$code" in 200) echo "Updating existing protection on ${BRANCH}…" api --request PATCH "${base}/${BRANCH}" --data @"$config" | jq . ;; 404) echo "Creating protection on ${BRANCH}…" body=$(jq --arg b "$BRANCH" '. + {branch_name: $b}' "$config") api --request POST "${base}" --data "$body" | jq . ;; *) echo "unexpected HTTP ${code} from ${base}/${BRANCH}" >&2 exit 1 ;; esac