Gitea repo settings live in its own database, not in a manifest Flux reconciles, so they are drift-prone and invisible to the conformance gate -- which is how main came to accept direct pushes while the log recorded it as protected. Adds infra/gitea/branch-protection.sh (blocks direct pushes to main) and a README carrying the measured before-state and the ORDER the remaining steps must happen in. The script deliberately leaves enable_status_check:false and required_approvals:0. Both would deadlock today: there is no runner to satisfy a required context, and the only human account is not yet a repo collaborator, so no one could supply an approval. The README sequences both. It prints a push probe to run afterwards. The API response is not proof -- Gitea may let site admins bypass protection, and that has to be observed, not assumed. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
58 lines
2.4 KiB
Bash
Executable File
58 lines
2.4 KiB
Bash
Executable File
#!/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
|