Previously, when Gitea is installed with DISABLE_GIT_HOOKS=true (the
default), every git-hook API call returned 403 and the script:
- marked every repository as FAILED, and
- never counted the hook step at all.
This change detects the disabled state up front with a single probe
against the first editable repo:
- If hooks are disabled, it prints a clear notice, skips the pre-receive
step for every repo (branch/tag protection still runs normally), and
exits non-zero (2) so automation notices the run is partial.
- A per-repo 403 on the hook step is isolated (HookNotWritable) so it no
longer clobbers the whole repo into FAILED -- branch/tag still apply,
and the hook reports 'SKIPPED (git hooks not writable)'.
- Adds a Hooks skipped counter and distinguishes 'disabled' vs
'not writable' in the summary.
- Fixes an UnboundLocalError on the 'no editable repos' path by
initializing hooks_enabled before the probe.
Verified end-to-end against a mock Gitea API for both scenarios (hooks
disabled -> skip + exit 2; hooks enabled -> exact/stale/missing handled
correctly, exit 0).
Adds pre-receive hook management to the existing hardening script:
- Defines GIT_HOOKS with the canonical guard content (rejects workflow
changes arriving via untrusted branches) from pre-receive-guard.sh.
- Reads the current hook via the git-hook API; treats is_active=false
as not set.
- Sets/updates the hook via PATCH only when the content differs, using
exact-match comparison (Gitea stores hook content verbatim).
- Mirrors the existing branch/tag protection reporting (dry-run vs
--apply) and adds hooks to the summary counters.
- Skips archived repos and surfaces API failures like the rest of the
script.