mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
build: add pre-commit/push hooks mirroring CI checks (#22705)
This change adds git hooks and Makefile targets that mirror CI required checks locally, catching issues before they reach CI. This is for use by AI agents (documented in AGENTS.md). - **pre-commit** (every commit): gen, fmt, lint, typos, slim binary build. Fast checks without Docker or Playwright. - **pre-push** (before push): full CI suite including site build, tests, sqlc-vet, offlinedocs. To use: ```sh git config core.hooksPath scripts/githooks ``` Works in worktrees (where `.git` is a file). Bypass with `--no-verify`.
This commit is contained in:
committed by
GitHub
parent
d06bf5c75f
commit
752e6ecc16
@@ -116,7 +116,7 @@ endif
|
||||
# Note, all find statements should be written with `.` or `./path` as
|
||||
# the search path so that these exclusions match.
|
||||
FIND_EXCLUSIONS= \
|
||||
-not \( \( -path '*/.git/*' -o -path './build/*' -o -path './vendor/*' -o -path './.coderv2/*' -o -path '*/node_modules/*' -o -path '*/out/*' -o -path './coderd/apidoc/*' -o -path '*/.next/*' -o -path '*/.terraform/*' \) -prune \)
|
||||
-not \( \( -path '*/.git/*' -o -path './build/*' -o -path './vendor/*' -o -path './.coderv2/*' -o -path '*/node_modules/*' -o -path '*/out/*' -o -path './coderd/apidoc/*' -o -path '*/.next/*' -o -path '*/.terraform/*' -o -path './_gen/*' \) -prune \)
|
||||
# Source files used for make targets, evaluated on use.
|
||||
GO_SRC_FILES := $(shell find . $(FIND_EXCLUSIONS) -type f -name '*.go' -not -name '*_test.go')
|
||||
# Same as GO_SRC_FILES but excluding certain files that have problematic
|
||||
@@ -675,6 +675,108 @@ lint/migrations:
|
||||
./scripts/check_pg_schema.sh "Fixtures" $(FIXTURE_FILES)
|
||||
.PHONY: lint/migrations
|
||||
|
||||
TYPOS_VERSION := $(shell grep -oP 'crate-ci/typos@\S+\s+\#\s+v\K[0-9.]+' .github/workflows/ci.yaml)
|
||||
|
||||
# Map uname values to typos release asset names.
|
||||
TYPOS_ARCH := $(shell uname -m)
|
||||
ifeq ($(shell uname -s),Darwin)
|
||||
TYPOS_OS := apple-darwin
|
||||
else
|
||||
TYPOS_OS := unknown-linux-musl
|
||||
endif
|
||||
|
||||
build/typos-$(TYPOS_VERSION):
|
||||
mkdir -p build/
|
||||
curl -sSfL "https://github.com/crate-ci/typos/releases/download/v$(TYPOS_VERSION)/typos-v$(TYPOS_VERSION)-$(TYPOS_ARCH)-$(TYPOS_OS).tar.gz" \
|
||||
| tar -xzf - -C build/ ./typos
|
||||
mv build/typos "$@"
|
||||
|
||||
lint/typos: build/typos-$(TYPOS_VERSION)
|
||||
build/typos-$(TYPOS_VERSION) --config .github/workflows/typos.toml
|
||||
.PHONY: lint/typos
|
||||
|
||||
# pre-commit and pre-push mirror CI "required" jobs locally.
|
||||
# See the "required" job's needs list in .github/workflows/ci.yaml.
|
||||
#
|
||||
# pre-commit runs checks that don't need external services (Docker,
|
||||
# Playwright). This is the git pre-commit hook default since test
|
||||
# and Docker failures in the local environment would otherwise block
|
||||
# all commits.
|
||||
#
|
||||
# pre-push runs the full CI suite including tests. This is the git
|
||||
# pre-push hook default, catching everything CI would before pushing.
|
||||
#
|
||||
# Both use two-phase execution: gen+fmt first (writes files), then
|
||||
# lint+build (reads files). This avoids races where gen's `go run`
|
||||
# creates temporary .go files that lint's find-based checks pick up.
|
||||
# Within each phase, targets run in parallel via -j. Both fail if
|
||||
# any tracked files have unstaged changes afterward.
|
||||
#
|
||||
# Both pre-commit and pre-push:
|
||||
# gen, fmt, lint, lint/typos, slim binary (local arch)
|
||||
#
|
||||
# pre-push only (need external services or are slow):
|
||||
# site/out/index.html (pnpm build)
|
||||
# test-postgres (needs Docker)
|
||||
# test-js, test-e2e (needs Playwright)
|
||||
# sqlc-vet (needs Docker)
|
||||
# offlinedocs/check
|
||||
#
|
||||
# Omitted:
|
||||
# test-go-pg-17 (same tests, different PG version)
|
||||
|
||||
define check-unstaged
|
||||
unstaged="$$(git diff --name-only)"
|
||||
if [[ -n $$unstaged ]]; then
|
||||
echo "ERROR: unstaged changes in tracked files:"
|
||||
echo "$$unstaged"
|
||||
echo
|
||||
echo "Review each change (git diff), verify correctness, then stage:"
|
||||
echo " git add -u && git commit"
|
||||
exit 1
|
||||
fi
|
||||
untracked=$$(git ls-files --other --exclude-standard)
|
||||
if [[ -n $$untracked ]]; then
|
||||
echo "WARNING: untracked files (not in this commit, won't be in CI):"
|
||||
echo "$$untracked"
|
||||
echo
|
||||
fi
|
||||
endef
|
||||
|
||||
pre-commit:
|
||||
$(MAKE) -j --output-sync=target gen fmt
|
||||
$(check-unstaged)
|
||||
$(MAKE) -j --output-sync=target \
|
||||
lint \
|
||||
lint/typos \
|
||||
build/coder-slim_$(GOOS)_$(GOARCH)$(GOOS_BIN_EXT)
|
||||
$(check-unstaged)
|
||||
.PHONY: pre-commit
|
||||
|
||||
pre-push:
|
||||
$(MAKE) -j --output-sync=target gen fmt
|
||||
$(check-unstaged)
|
||||
$(MAKE) -j --output-sync=target \
|
||||
lint \
|
||||
lint/typos \
|
||||
build/coder-slim_$(GOOS)_$(GOARCH)$(GOOS_BIN_EXT) \
|
||||
site/out/index.html \
|
||||
test-postgres \
|
||||
test-js \
|
||||
test-e2e \
|
||||
test-race \
|
||||
sqlc-vet \
|
||||
offlinedocs/check
|
||||
$(check-unstaged)
|
||||
.PHONY: pre-push
|
||||
|
||||
offlinedocs/check: offlinedocs/node_modules/.installed
|
||||
cd offlinedocs/
|
||||
pnpm format:check
|
||||
pnpm lint
|
||||
pnpm export
|
||||
.PHONY: offlinedocs/check
|
||||
|
||||
# All files generated by the database should be added here, and this can be used
|
||||
# as a target for jobs that need to run after the database is generated.
|
||||
DB_GEN_FILES := \
|
||||
@@ -1041,8 +1143,7 @@ docs/manifest.json: site/node_modules/.installed coderd/apidoc/.gen docs/referen
|
||||
tmpdir=$$(mktemp -d -p _gen) && tmpfile=$$(realpath "$$tmpdir")/$(notdir $@) && \
|
||||
cp _gen/manifest-staging.json "$$tmpfile" && \
|
||||
./scripts/biome_format.sh "$$tmpfile" && \
|
||||
mv "$$tmpfile" "$@" && rm -rf "$$tmpdir" && \
|
||||
rm -f _gen/manifest-staging.json
|
||||
mv "$$tmpfile" "$@" && rm -rf "$$tmpdir"
|
||||
|
||||
coderd/apidoc/swagger.json: site/node_modules/.installed coderd/apidoc/.gen
|
||||
touch "$@"
|
||||
@@ -1165,6 +1266,11 @@ test-cli:
|
||||
$(MAKE) test TEST_PACKAGES="./cli..."
|
||||
.PHONY: test-cli
|
||||
|
||||
test-js: site/node_modules/.installed
|
||||
cd site/
|
||||
pnpm test:ci
|
||||
.PHONY: test-js
|
||||
|
||||
# sqlc-cloud-is-setup will fail if no SQLc auth token is set. Use this as a
|
||||
# dependency for any sqlc-cloud related targets.
|
||||
sqlc-cloud-is-setup:
|
||||
|
||||
Reference in New Issue
Block a user