mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
fix(scripts/githooks): prevent agents from bypassing git hooks (#22825)
Agents hit short shell timeouts on `git commit` (~13s) before `make pre-commit` finishes (~20s warm), then disable hooks via `git config core.hooksPath /dev/null`. This bypasses all local checks and, because it writes to shared `.git/config`, silently disables hooks for every other worktree too. Add explicit timing guidance to AGENTS.md, and write worktree-scoped `core.hooksPath` in post-checkout, pre-commit, and pre-push hooks to make the bypass ineffective.
This commit is contained in:
committed by
GitHub
parent
a48e4a43e2
commit
dd34e3d3c2
@@ -105,22 +105,37 @@ app, err := api.Database.GetOAuth2ProviderAppByClientID(ctx, clientID)
|
||||
|
||||
### Full workflows available in imported WORKFLOWS.md
|
||||
|
||||
### Git Hooks (MANDATORY)
|
||||
### Git Hooks (MANDATORY - DO NOT SKIP)
|
||||
|
||||
Before your first commit, ensure the git hooks are installed.
|
||||
Two hooks run automatically:
|
||||
**You MUST install and use the git hooks. NEVER bypass them with
|
||||
`--no-verify`. Skipping hooks wastes CI cycles and is unacceptable.**
|
||||
|
||||
- **pre-commit**: `make pre-commit` (gen, fmt, lint, typos, build).
|
||||
Fast checks that catch most CI failures.
|
||||
- **pre-push**: `make pre-push` (full CI suite including tests).
|
||||
Runs before pushing to catch everything CI would.
|
||||
|
||||
Wait for them to complete, do not skip or bypass them.
|
||||
The first run will be slow as caches warm up. Consecutive runs are
|
||||
**significantly faster** (often 10x) thanks to Go build cache,
|
||||
generated file timestamps, and warm node_modules. This is NOT a
|
||||
reason to skip them. Wait for hooks to complete before proceeding,
|
||||
no matter how long they take.
|
||||
|
||||
```sh
|
||||
git config core.hooksPath scripts/githooks
|
||||
```
|
||||
|
||||
Two hooks run automatically:
|
||||
|
||||
- **pre-commit**: `make pre-commit` (gen, fmt, lint, typos, build).
|
||||
Fast checks that catch most CI failures. Allow at least 5 minutes.
|
||||
- **pre-push**: `make pre-push` (full CI suite including tests).
|
||||
Runs before pushing to catch everything CI would. Allow at least
|
||||
15 minutes (race tests are slow without cache).
|
||||
|
||||
`git commit` and `git push` will appear to hang while hooks run.
|
||||
This is normal. Do not interrupt, retry, or reduce the timeout.
|
||||
|
||||
NEVER run `git config core.hooksPath` to change or disable hooks.
|
||||
|
||||
If a hook fails, fix the issue and retry. Do not work around the
|
||||
failure by skipping the hook.
|
||||
|
||||
### Git Workflow
|
||||
|
||||
When working on existing PRs, check out the branch first:
|
||||
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
# Shield this worktree against shared config hooksPath poisoning.
|
||||
# Worktree-scoped config overrides the shared .git/config, so even if
|
||||
# another worktree runs `git config core.hooksPath /dev/null`, this
|
||||
# worktree continues to use the correct hooks.
|
||||
#
|
||||
# This hook runs on `git worktree add` and `git checkout`/`git switch`.
|
||||
# Only needed in linked worktrees where shared config can be poisoned
|
||||
# by another worktree. Skipped in the main checkout to avoid errors
|
||||
# when extensions.worktreeConfig is not set (e.g. fresh clones).
|
||||
if [[ "$(git rev-parse --git-dir)" != "$(git rev-parse --git-common-dir)" ]]; then
|
||||
git config --worktree core.hooksPath scripts/githooks
|
||||
fi
|
||||
@@ -16,4 +16,8 @@ set -euo pipefail
|
||||
cd "$(git rev-parse --show-toplevel)"
|
||||
unset GIT_DIR
|
||||
|
||||
# In linked worktrees, set worktree-scoped hooksPath to override shared config.
|
||||
if [[ "$(git rev-parse --git-dir)" != "$(git rev-parse --git-common-dir)" ]]; then
|
||||
git config --worktree core.hooksPath scripts/githooks
|
||||
fi
|
||||
exec make pre-commit
|
||||
|
||||
@@ -19,4 +19,8 @@ set -euo pipefail
|
||||
cd "$(git rev-parse --show-toplevel)"
|
||||
unset GIT_DIR
|
||||
|
||||
# In linked worktrees, set worktree-scoped hooksPath to override shared config.
|
||||
if [[ "$(git rev-parse --git-dir)" != "$(git rev-parse --git-common-dir)" ]]; then
|
||||
git config --worktree core.hooksPath scripts/githooks
|
||||
fi
|
||||
exec make pre-push
|
||||
|
||||
Reference in New Issue
Block a user