mirror of
https://github.com/boshu2/agentops.git
synced 2026-09-14 15:08:13 +08:00
5d61bf8a3f
Fixes the three gremlins observed 2026-07-18 (bead age-gate-scripts-worktree-gitdir-p62wo): 1. **Gate scripts broke under hook env from linked worktrees** (#919 regression): new scripts/lib/repo-root.sh (GIT_*-scrubbed resolution, BASH_SOURCE anchor, worktree-correct) swept across 32 scripts. Proof: this PR's own push ran the pre-push gates from a linked worktree and passed. 2. **core.bare=true recurrence**: mechanism proven (leaked GIT_DIR + no-arg git init --bare rewrites the SHARED config); writer traced with high confidence to a live Gas City city process (concrete suspect: gascity cmd_rig_test.go runGitInTest, unscrubbed env + no-arg init --bare — fork-side fix filed separately). Defense: new always.git-config-hygiene gate fails fast on core.bare/test identities with the repair command inline (--self-test proves fail-closed). 3. **Test/test@test.com identity leak**: writer convicted — our own pre-push chain leaked GIT_DIR into go test, whose helpers wrote the shared config via git -C (mechanism proven). Cut at both ends: validate-go-fast scrubs env for children; every test git-helper set-site scrubs; check-test-isolation gains a WARN-ratchet rule (baseline 3 → FAIL at 0). Gates: shellcheck rc=0 across 36 scripts; go build/vet clean; 655+379+149 tests; hygiene self-test; both originally-failing validators pass under the repro env.
64 lines
2.2 KiB
Bash
Executable File
64 lines
2.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# restore-branch-protection.sh — re-apply the pre-collapse branch protection on
|
|
# main (ag-qidx.1 rollback). Reconstructs the PUT body from the captured GET in
|
|
# docs/runbooks/branch-protection-backup.json. This is the one-command revert for
|
|
# the push-to-main collapse.
|
|
#
|
|
# scripts/restore-branch-protection.sh # apply
|
|
# scripts/restore-branch-protection.sh --dry-run # print PUT body, do not apply
|
|
set -euo pipefail
|
|
|
|
# shellcheck disable=SC1007,SC1091
|
|
. "$(CDPATH= cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib/repo-root.sh"
|
|
repo_root="$(resolve_repo_root)"
|
|
backup="${repo_root}/scripts/branch-protection-backup.json"
|
|
dry_run=false
|
|
[[ "${1:-}" == "--dry-run" ]] && dry_run=true
|
|
|
|
if [[ ! -f "$backup" ]]; then
|
|
echo "ERROR: backup ${backup} not found — cannot restore" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# The GET schema is richer than PUT accepts; build the exact PUT body from it.
|
|
put_body="$(python3 - "$backup" <<'PY'
|
|
import json, sys
|
|
g = json.load(open(sys.argv[1]))
|
|
|
|
def rsc(g):
|
|
s = g.get("required_status_checks")
|
|
if not s:
|
|
return None
|
|
return {"strict": s.get("strict", False),
|
|
"contexts": s.get("contexts", [])}
|
|
|
|
def rpr(g):
|
|
r = g.get("required_pull_request_reviews")
|
|
if not r:
|
|
return None
|
|
return {"dismiss_stale_reviews": r.get("dismiss_stale_reviews", False),
|
|
"require_code_owner_reviews": r.get("require_code_owner_reviews", False),
|
|
"required_approving_review_count": r.get("required_approving_review_count", 0)}
|
|
|
|
body = {
|
|
"required_status_checks": rsc(g),
|
|
"enforce_admins": g.get("enforce_admins", {}).get("enabled", False),
|
|
"required_pull_request_reviews": rpr(g),
|
|
"restrictions": None,
|
|
"required_linear_history": g.get("required_linear_history", {}).get("enabled", False),
|
|
"allow_force_pushes": g.get("allow_force_pushes", {}).get("enabled", False),
|
|
"allow_deletions": g.get("allow_deletions", {}).get("enabled", False),
|
|
}
|
|
print(json.dumps(body))
|
|
PY
|
|
)"
|
|
|
|
if $dry_run; then
|
|
echo "PUT repos/:owner/:repo/branches/main/protection"
|
|
echo "$put_body" | python3 -m json.tool
|
|
exit 0
|
|
fi
|
|
|
|
echo "$put_body" | gh api --method PUT repos/:owner/:repo/branches/main/protection --input - >/dev/null
|
|
echo "✓ branch protection on main restored from ${backup}"
|