#!/usr/bin/env bash # Enable branch protection on main for home-network-k3s-impl. # # Sets enable_push:false -> no direct pushes to main; changes land only by merging a PR. # # enable_status_check is deliberately FALSE. There is currently NO Gitea Actions runner # registered (verified 2026-09-29: zero at repo, org and site level), so requiring the # gate context would deadlock EVERY PR permanently -- including the PR that fixes it. # Turn it on only after a runner is live and you have seen the gate actually report on # a real PR, using the context name CI itself produced. # # required_approvals is 0 for the same class of reason: jakman85 is a site admin but NOT # a repo collaborator, so requiring an approval now could leave nobody able to approve. # Add the collaborator first, then raise this to 1. set -euo pipefail HOST=gitea.home.keithjackson.dev OWNER=Home-Network REPO=home-network-k3s-impl creds="$(printf 'protocol=https\nhost=%s\n\n' "$HOST" | git credential fill)" U="$(sed -n 's/^username=//p' <<<"$creds")" P="$(sed -n 's/^password=//p' <<<"$creds")" [ -n "$U" ] && [ -n "$P" ] || { echo "no stored credential for $HOST" >&2; exit 1; } echo "authenticating as '${U}' (secret not shown)" echo "==> creating branch protection on 'main'" jq -n '{ branch_name: "main", enable_push: false, enable_status_check: false, status_check_contexts: [], required_approvals: 0, block_on_rejected_reviews: true, block_on_outdated_branch: false, dismiss_stale_approvals: true }' | curl -sS --config <(printf 'user = "%s:%s"\n' "$U" "$P") \ -X POST -H 'Content-Type: application/json' --data @- \ "https://${HOST}/api/v1/repos/${OWNER}/${REPO}/branch_protections" \ | jq -r 'if .branch_name then "created" else "API said: \(.message // tostring)" end' echo "==> verifying (this is the part that matters)" curl -sS --config <(printf 'user = "%s:%s"\n' "$U" "$P") \ "https://${HOST}/api/v1/repos/${OWNER}/${REPO}/branches/main" \ | jq -r '{protected, user_can_push, required_approvals, enable_status_check, status_check_contexts}' cat <<'NOTE' Now prove it actually blocks you -- do not take the API's word for it. From a clean checkout on main, with nothing to lose: git commit --allow-empty -m 'protection probe' git push origin main # EXPECT: rejected by the remote git reset --hard HEAD~1 # tidy up either way If that push SUCCEEDS, Gitea is letting site admins bypass protection and this is not yet doing what you want. NOTE