mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 12:21:31 +00:00
02438ad9e1
Twelve findings from the architecture diligence audit's Phase 3 bundle
closed in one PR. All touch the CI workflows + small doc-drift fixes
across the production Go tree + migration headers.
CI workflow changes
====================
TEST-H1 — Race detection on ./... -short
.github/workflows/ci.yml:106 was a 9-package explicit list. Audit
finding TEST-H1 flagged that 25+ packages (internal/auth/*,
internal/repository/*, internal/mcp, internal/scep, internal/pkcs7,
internal/api/router, internal/api/acme, internal/cli, internal/cms,
internal/config, internal/deploy, internal/integration,
internal/ratelimit, internal/secret, internal/trustanchor, all of
cmd/) silently dropped off race coverage.
Post-fix: 'go test -race -short ./... -count=1 -timeout 600s'.
76 testing.Short() guards already cover testcontainers + live-DB
integration suites, so -short keeps the long-running tests out.
TEST-H2 — Cross-platform build matrix
New 'cross-platform-build' job in ci.yml. Matrix:
ubuntu-latest + windows-latest + macos-latest, fail-fast: false.
Builds cmd/server + cmd/agent + cmd/cli + cmd/mcp-server on each.
Catches Windows-specific regressions (path separators, file
permissions, exec.Command semantics) the pre-Phase-3 Ubuntu-only
CI missed.
TEST-L1 — actions/setup-go cache: true (explicit)
setup-go v5 defaults cache: true; making it explicit so a future
setup-go upgrade can't silently flip it. Re-runs hit the Go module
+ build cache instead of recompiling cold.
TEST-M1 — Mutation-testing floor at 55%
security-deep-scan.yml::go-mutesting step rewritten. Removed
continue-on-error + per-package '|| true'. New post-loop check
extracts every 'The mutation score is X.YZ' line and fails the
step if any package drops below 0.55. Floor rationale: starter
ratio catches major regressions without rejecting the audit's
'this is OK' steady state; raise quarterly.
TEST-M2 — 3 advisory deep-scan gates promoted to blocking
Removed continue-on-error: true from:
- gosec (filtered to G201/G202/G304/G108 high-signal rules:
SQL-injection + path-traversal + pprof-exposed)
- osv-scanner (multi-ecosystem CVE; complements govulncheck
which is already blocking in ci.yml)
- trivy image scan (--severity HIGH,CRITICAL --exit-code 1)
continue-on-error count: 15 → 11.
ZAP / schemathesis / nuclei / testssl stay advisory because their
false-positive rates on https://localhost:8443-targeted DAST runs
are high.
TEST-M3 — Playwright harness stub
web/package.json adds '@playwright/test' devDep + 'e2e' / 'e2e:install'
npm scripts. web/playwright.config.ts ships single chromium project
with webServer block pointing at 'npm run dev'. web/src/__tests__/
e2e/smoke.spec.ts proves the harness wires through. The full 15-flow
suite ships in frontend-design-audit Phase 8 (TEST-H1 in THAT audit);
this is the wiring + a single smoke test as the regression floor.
New Makefile target: 'make e2e-test'.
Doc/code drift fixes
====================
TEST-M4 + ARCH-L2 — Skip inventory artifact + CI guard
scripts/skip-inventory.sh walks every t.Skip site under cmd/ +
internal/ + deploy/test/ and emits docs/testing/skip-inventory.md
grouped by package with file:line:expression triples. Current
inventory: 142 t.Skip sites, 76 testing.Short() guards.
scripts/ci-guards/skip-inventory-drift.sh regenerates and fails on
diff (excluding the 'Last reviewed' timestamp line which drifts
daily). The Markdown is the canonical acquisition-diligence artifact
for 'what tests are being skipped and why.'
ARCH-H3 — MCP catalogue floor reconciliation
Audit framing was '121 vs floor 150 — doc/code drift.' Live count
via the test's actual regex over all 5 tool files (tools.go +
tools_audit_fix.go + tools_auth.go + tools_auth_bundle2.go +
tools_est.go): 155 unique 'Name: "certctl_*"' declarations.
Pre-Phase-3 audit measured tools.go in isolation (121) and missed
the other 4 files (+34 unique names). The test at
internal/ciparity/surface_parity_test.go::TestSurfaceParity_MCP
passes today (155 ≥ 150). Added a clarifying comment near
mcpBaselineFloor explaining the measurement scope so future
reviewers don't repeat the audit's framing error.
STATUS: stale — no code drift, just a measurement scoping error in
the audit.
ARCH-L1 — panic() rationale comments
5 panic sites in production Go (excluding _test.go):
- internal/repository/postgres/tx.go:84
- internal/service/issuer.go:861 (mustJSON)
- internal/service/est.go:728 (mustParseTime)
- internal/service/acme.go:1288 (rand source failure — already documented)
- internal/pkcs7/certrep.go:270 (OID marshal — already documented)
Added ARCH-L1 rationale comments to the 3 sites that didn't have
them. All 5 are defensible impossible-path / rethrow / hardcoded-
constant guards.
ARCH-L3 — Migration IF-NOT-EXISTS carve-outs
4 migrations skip the literal 'IF NOT EXISTS' token but ARE
idempotent via different Postgres patterns:
- 000014_policy_violation_severity_check.up.sql: ALTER TABLE
ADD CONSTRAINT CHECK doesn't accept IF NOT EXISTS; idempotency
via DROP CONSTRAINT IF EXISTS preamble.
- 000018_audit_events_worm.up.sql: CREATE OR REPLACE FUNCTION
+ DROP TRIGGER IF EXISTS + CREATE TRIGGER + DO $$ pg_roles
existence check. CREATE TRIGGER doesn't take IF NOT EXISTS.
- 000030_rbac_admin_perms.up.sql: INSERT ... ON CONFLICT DO NOTHING.
- 000039_audit_crit1_perms.up.sql: same INSERT + ON CONFLICT pattern.
Added ARCH-L3 header comments to each explaining the carve-out so
reviewers don't flag the missing literal token.
STATUS: largely stale — migrations are already idempotent.
ARCH-L4 — TODO/FIXME → see #<descriptor>
5 TODOs rewritten to the allowed 'see #<descriptor>' pattern:
- internal/repository/postgres/auth.go:220 → see #bundle-2-scope-fk
- internal/connector/discovery/gcpsm/gcpsm.go:547 → see #gcpsm-pagination
- internal/service/audit.go:244 → see #audit-pagination-count
- internal/service/job.go:295, 299 → see #validation-job-impl
New CI guard scripts/ci-guards/no-todo-in-prod.sh grep-fails any
new TODO/FIXME in cmd/ + internal/ (excluding _test.go); allows
'see #N' / 'see #<descriptor>' patterns.
Sandbox limitation
==================
The 6.1 GB certctl working tree fills the sandbox volume; go1.25.10
toolchain download fails with 'no space left on device' (sandbox has
1.25.9; go.mod requires 1.25.10). Local 'go test' / 'go build' NOT
run in this commit. Operator must run 'make verify' on their
workstation before push per CLAUDE.md operating rules.
The smoke.spec.ts NOT executed in the sandbox (no chromium installed).
Operator runs 'cd web && npm install && npx playwright install
--with-deps chromium && npm run e2e' on first wire-up.
All CI guards (no-todo-in-prod, skip-inventory-drift, G-3
env-docs-drift, doc-rot-detector, and every existing guard) verified
clean by running each individually.
Closes: cowork/certctl-architecture-diligence-audit.html#fix-TEST-H1,
cowork/certctl-architecture-diligence-audit.html#fix-TEST-H2,
cowork/certctl-architecture-diligence-audit.html#fix-TEST-M1,
cowork/certctl-architecture-diligence-audit.html#fix-TEST-M2,
cowork/certctl-architecture-diligence-audit.html#fix-TEST-M3,
cowork/certctl-architecture-diligence-audit.html#fix-TEST-M4,
cowork/certctl-architecture-diligence-audit.html#fix-TEST-L1,
cowork/certctl-architecture-diligence-audit.html#fix-ARCH-H3,
cowork/certctl-architecture-diligence-audit.html#fix-ARCH-L1,
cowork/certctl-architecture-diligence-audit.html#fix-ARCH-L2,
cowork/certctl-architecture-diligence-audit.html#fix-ARCH-L3,
cowork/certctl-architecture-diligence-audit.html#fix-ARCH-L4
347 lines
15 KiB
Makefile
347 lines
15 KiB
Makefile
.PHONY: help build run test lint verify verify-deploy loadtest acme-cert-manager-test acme-rfc-conformance-test keycloak-integration-test okta-smoke-test benchmark-auth benchmark-auth-coldcache clean docker-up docker-down migrate-up migrate-down generate test-cover frontend-build e2e-test qa-stats
|
|
|
|
# Default target - show help
|
|
help:
|
|
@echo "Certctl Development Commands"
|
|
@echo "============================="
|
|
@echo ""
|
|
@echo "Build & Run:"
|
|
@echo " make build Build server and agent binaries"
|
|
@echo " make run Run server locally (requires DB)"
|
|
@echo " make run-agent Run agent locally"
|
|
@echo ""
|
|
@echo "Testing & Quality:"
|
|
@echo " make test Run all tests"
|
|
@echo " make test-verbose Run tests with verbose output"
|
|
@echo " make lint Run linter (golangci-lint)"
|
|
@echo " make fmt Format code with gofmt"
|
|
@echo " make verify Pre-commit gate: fmt + vet + lint + test (CI-parity)"
|
|
@echo " make verify-deploy Pre-push gate: digest validity + OpenAPI parity + docker build smoke"
|
|
@echo " make loadtest k6 throughput run against postgres + certctl (NOT in verify; manual + cron only)"
|
|
@echo ""
|
|
@echo "Database:"
|
|
@echo " make migrate-up Run migrations (requires DB_URL)"
|
|
@echo " make migrate-down Rollback last migration"
|
|
@echo " make db-seed Seed database with test data"
|
|
@echo ""
|
|
@echo "Docker:"
|
|
@echo " make docker-build Build Docker images"
|
|
@echo " make docker-up Start Docker Compose stack"
|
|
@echo " make docker-down Stop Docker Compose stack"
|
|
@echo " make docker-logs View Docker logs"
|
|
@echo " make docker-clean Remove Docker resources"
|
|
@echo ""
|
|
@echo "Code Generation:"
|
|
@echo " make generate Run go generate"
|
|
@echo " make clean Clean build artifacts"
|
|
@echo ""
|
|
|
|
# Build targets
|
|
build:
|
|
@echo "Building server and agent..."
|
|
mkdir -p bin
|
|
CGO_ENABLED=0 go build -o bin/server ./cmd/server
|
|
CGO_ENABLED=0 go build -o bin/agent ./cmd/agent
|
|
@echo "Build complete: bin/server, bin/agent"
|
|
|
|
build-server:
|
|
@echo "Building server..."
|
|
mkdir -p bin
|
|
CGO_ENABLED=0 go build -o bin/server ./cmd/server
|
|
@echo "Server build complete"
|
|
|
|
build-agent:
|
|
@echo "Building agent..."
|
|
mkdir -p bin
|
|
CGO_ENABLED=0 go build -o bin/agent ./cmd/agent
|
|
@echo "Agent build complete"
|
|
|
|
# Run targets
|
|
run: build-server
|
|
@echo "Starting server (requires DATABASE_URL or DB_* env vars)..."
|
|
./bin/server
|
|
|
|
run-agent: build-agent
|
|
@echo "Starting agent (requires SERVER_URL and API_KEY env vars)..."
|
|
./bin/agent
|
|
|
|
# Testing targets
|
|
test:
|
|
@echo "Running tests..."
|
|
go test ./...
|
|
|
|
test-verbose:
|
|
@echo "Running tests with verbose output..."
|
|
go test -v ./...
|
|
|
|
test-coverage:
|
|
@echo "Running tests with coverage..."
|
|
go test -coverprofile=coverage.out ./...
|
|
go tool cover -html=coverage.out -o coverage.html
|
|
@echo "Coverage report: coverage.html"
|
|
|
|
test-cover:
|
|
@echo "Running tests with coverage..."
|
|
go test ./internal/service/... ./internal/api/handler/... ./internal/integration/... -count=1 -cover -coverprofile=coverage.out
|
|
@echo "Coverage report: coverage.out"
|
|
|
|
# Linting targets
|
|
lint:
|
|
@echo "Running golangci-lint..."
|
|
@which golangci-lint > /dev/null || (echo "Installing golangci-lint..." && go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest)
|
|
golangci-lint run ./...
|
|
|
|
fmt:
|
|
@echo "Formatting code..."
|
|
go fmt ./...
|
|
@echo "Code formatted"
|
|
|
|
vet:
|
|
@echo "Running go vet..."
|
|
go vet ./...
|
|
|
|
# verify: aggregate pre-commit gate. Mirrors what CI enforces, so
|
|
# running `make verify` locally before committing prevents the
|
|
# class of breakages that ship green-locally / red-on-CI (e.g.
|
|
# Bundle-9's ST1018 invisible-Unicode-literal hits, which `go vet`
|
|
# alone cannot catch — staticcheck under golangci-lint does).
|
|
verify:
|
|
@echo "==> fmt"
|
|
@go fmt ./... | { ! grep -q '.'; } || (echo "gofmt produced changes — commit them" && exit 1)
|
|
@echo "==> go vet ./..."
|
|
@go vet ./...
|
|
@echo "==> golangci-lint run ./... (incl. staticcheck ST*)"
|
|
@which golangci-lint > /dev/null || (echo "Installing golangci-lint..." && go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest)
|
|
@golangci-lint run ./... --timeout 5m
|
|
@echo "==> go test -short ./..."
|
|
@go test -short -count=1 ./...
|
|
@echo ""
|
|
@echo "verify: PASS — safe to commit"
|
|
|
|
# verify-deploy: optional pre-push gate. Runs the digest-validity check,
|
|
# the OpenAPI ↔ handler parity check, and a Docker build smoke for the
|
|
# production images (server + agent only — fast subset for local; CI
|
|
# builds all 4 Dockerfiles per ci-pipeline-cleanup Phase 8 / frozen
|
|
# decision 0.10).
|
|
#
|
|
# Per ci-pipeline-cleanup bundle Phase 11 / frozen decision 0.13.
|
|
verify-deploy:
|
|
@echo "==> Digest validity"
|
|
@bash scripts/ci-guards/digest-validity.sh
|
|
@echo "==> OpenAPI ↔ handler parity"
|
|
@bash scripts/ci-guards/openapi-handler-parity.sh
|
|
@echo "==> Docker build smoke (server + agent — fast subset)"
|
|
@docker build -f Dockerfile -t certctl:verify .
|
|
@docker build -f Dockerfile.agent -t certctl-agent:verify .
|
|
@echo ""
|
|
@echo "verify-deploy: PASS — safe to push"
|
|
|
|
# Load-test harness — closes the #8 acquisition-readiness blocker from
|
|
# the 2026-05-01 issuer coverage audit. Boots a minimal certctl stack
|
|
# (postgres + tls-init + certctl-server) and runs k6 against the API
|
|
# tier for ~5 minutes. Exits non-zero on any threshold breach.
|
|
#
|
|
# NOT in `make verify` — load tests take minutes, not seconds, and
|
|
# don't gate per-PR signal. CI gates this behind workflow_dispatch +
|
|
# weekly cron in .github/workflows/loadtest.yml. See
|
|
# deploy/test/loadtest/README.md for thresholds, baseline, and how to
|
|
# interpret a regression.
|
|
loadtest:
|
|
@echo "==> spinning up postgres + certctl + k6 driver (this takes ~7m)"
|
|
@cd deploy/test/loadtest && docker compose up --build --abort-on-container-exit --exit-code-from k6
|
|
@echo ""
|
|
@echo "==> results landed in deploy/test/loadtest/results/"
|
|
@if [ -f deploy/test/loadtest/results/summary.txt ]; then cat deploy/test/loadtest/results/summary.txt; fi
|
|
|
|
# Auth Bundle 2 Phase 10 — Keycloak end-to-end OIDC integration test.
|
|
# Boots a Keycloak container via testcontainers-go (quay.io/keycloak:25.0),
|
|
# imports a canned realm with two groups + two users, and drives the
|
|
# full OIDC flow against the certctl service: discovery + JWKS,
|
|
# auth-code login, group-claim parsing, group-role mapping, session
|
|
# mint, and JWKS rotation.
|
|
#
|
|
# Build-tag-gated under `integration` so `make verify` (which runs
|
|
# go test -short) NEVER pulls in the 60-90s Keycloak boot. Requires a
|
|
# local Docker daemon. Skips cleanly with t.Skip() when -short is set.
|
|
keycloak-integration-test:
|
|
@echo "==> running Keycloak OIDC integration test (requires Docker)"
|
|
@go test -tags=integration -count=1 -timeout=10m \
|
|
./internal/auth/oidc/...
|
|
|
|
# Auth Bundle 2 Phase 10 — optional Okta smoke test. Gated behind TWO
|
|
# build tags (integration + okta_smoke) so it only runs when invoked
|
|
# manually against the operator's own Okta dev tenant. Requires the
|
|
# OKTA_ISSUER + OKTA_CLIENT_ID + OKTA_CLIENT_SECRET env vars; the test
|
|
# t.Skip's with a clear message when any are missing. Documented in
|
|
# internal/auth/oidc/integration_okta_smoke_test.go.
|
|
okta-smoke-test:
|
|
@echo "==> running Okta smoke test (requires OKTA_ISSUER / _CLIENT_ID / _CLIENT_SECRET env vars)"
|
|
@go test -tags='integration okta_smoke' -count=1 -timeout=2m \
|
|
./internal/auth/oidc/...
|
|
|
|
# Auth Bundle 2 Phase 14 — auth performance benchmarks. Three default-
|
|
# tag benchmarks (session steady-state + session cold-process + oidc
|
|
# steady-state) producing p50/p95/p99/max numbers per the auth-
|
|
# benchmarks.md operator-doc table.
|
|
benchmark-auth:
|
|
@echo "==> running auth performance benchmarks (session + oidc steady-state)"
|
|
@go test -bench='BenchmarkSession_|BenchmarkOIDC_SteadyState' -benchmem \
|
|
-benchtime=2000x -run='^$$' \
|
|
./internal/auth/session/ ./internal/auth/oidc/
|
|
|
|
# Auth Bundle 2 Phase 14 — OIDC cold-cache benchmark against a live
|
|
# Keycloak container (requires Docker). Build-tag-gated so the
|
|
# default-tag benchmarks above never pull in the 60-90s container
|
|
# boot. Runs the integration test FIRST to populate the
|
|
# sharedKeycloak fixture, then runs the benchmark.
|
|
benchmark-auth-coldcache:
|
|
@echo "==> running OIDC cold-cache benchmark against live Keycloak (requires Docker)"
|
|
@go test -tags integration -count=1 -timeout=10m \
|
|
-run TestKeycloakIntegration_RefreshKeysFetchesDiscoveryAndJWKS \
|
|
-bench BenchmarkOIDC_ColdCache -benchmem -benchtime=10x \
|
|
./internal/auth/oidc/
|
|
|
|
# Phase 5 — kind-driven cert-manager integration test. Requires
|
|
# `kind`, `kubectl`, `helm`, and a local Docker daemon. Sets
|
|
# KIND_AVAILABLE=1 so the test runs (it skips cleanly when unset, which
|
|
# is the CI default — kind is too heavy for per-PR CI). The test
|
|
# brings up a fresh cluster, installs cert-manager 1.15, helm-installs
|
|
# certctl-test, applies a ClusterIssuer + Certificate, and asserts the
|
|
# Secret lands.
|
|
acme-cert-manager-test:
|
|
@echo "==> running cert-manager integration test (requires kind/kubectl/helm)"
|
|
@KIND_AVAILABLE=1 go test -tags=integration -count=1 -timeout=15m \
|
|
./deploy/test/acme-integration/...
|
|
|
|
# Phase 5 — RFC 8555 conformance against `lego` driving the certctl
|
|
# server. Hermetic: brings up a single certctl-server via docker
|
|
# compose, points lego at it, runs the conformance scenarios. Skips
|
|
# when the operator hasn't built the test image (`make docker-build`
|
|
# first).
|
|
acme-rfc-conformance-test:
|
|
@echo "==> running RFC 8555 conformance via lego"
|
|
@if ! command -v lego >/dev/null 2>&1; then \
|
|
echo "lego not installed — go install github.com/go-acme/lego/v4/cmd/lego@latest"; \
|
|
exit 1; \
|
|
fi
|
|
@cd deploy/test/loadtest && docker compose up -d certctl postgres
|
|
@sleep 8
|
|
@CERTCTL_ACME_DIR=https://localhost:8443/acme/profile/prof-test/directory \
|
|
bash deploy/test/acme-integration/conformance-lego.sh
|
|
@cd deploy/test/loadtest && docker compose down
|
|
|
|
# Database targets (requires migrate tool)
|
|
migrate-up:
|
|
@echo "Running migrations..."
|
|
@which migrate > /dev/null || (echo "Installing migrate CLI..." && go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest)
|
|
migrate -path migrations -database "${DB_URL:-postgres://certctl:certctl@localhost:5432/certctl?sslmode=disable}" up
|
|
|
|
migrate-down:
|
|
@echo "Rolling back last migration..."
|
|
@which migrate > /dev/null || (echo "Installing migrate CLI..." && go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest)
|
|
migrate -path migrations -database "${DB_URL:-postgres://certctl:certctl@localhost:5432/certctl?sslmode=disable}" down 1
|
|
|
|
migrate-status:
|
|
@echo "Checking migration status..."
|
|
@which migrate > /dev/null || (echo "Installing migrate CLI..." && go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest)
|
|
migrate -path migrations -database "${DB_URL:-postgres://certctl:certctl@localhost:5432/certctl?sslmode=disable}" version
|
|
|
|
db-seed:
|
|
@echo "Seeding database with test data..."
|
|
go run ./scripts/seed/main.go
|
|
|
|
# Docker targets
|
|
docker-build:
|
|
@echo "Building Docker images..."
|
|
docker-compose -f deploy/docker-compose.yml build
|
|
|
|
docker-up:
|
|
@echo "Starting Docker Compose stack..."
|
|
docker-compose -f deploy/docker-compose.yml up -d
|
|
@echo "Stack running. Access server at http://localhost:8443"
|
|
|
|
docker-up-dev:
|
|
@echo "Starting Docker Compose stack (dev mode)..."
|
|
docker-compose -f deploy/docker-compose.yml -f deploy/docker-compose.dev.yml up -d
|
|
@echo "Stack running. PgAdmin at http://localhost:5050"
|
|
|
|
docker-down:
|
|
@echo "Stopping Docker Compose stack..."
|
|
docker-compose -f deploy/docker-compose.yml down
|
|
|
|
docker-logs:
|
|
docker-compose -f deploy/docker-compose.yml logs -f
|
|
|
|
docker-logs-server:
|
|
docker-compose -f deploy/docker-compose.yml logs -f certctl-server
|
|
|
|
docker-logs-agent:
|
|
docker-compose -f deploy/docker-compose.yml logs -f certctl-agent
|
|
|
|
docker-clean:
|
|
@echo "Removing Docker resources..."
|
|
docker-compose -f deploy/docker-compose.yml down -v
|
|
@echo "Cleaned up"
|
|
|
|
# Code generation
|
|
generate:
|
|
@echo "Running go generate..."
|
|
go generate ./...
|
|
@echo "Code generation complete"
|
|
|
|
# Frontend build
|
|
frontend-build:
|
|
@echo "Building frontend..."
|
|
cd web && npm ci && npx vite build
|
|
@echo "Frontend build complete"
|
|
|
|
# Phase 3 TEST-M3 closure (2026-05-13): browser-driven E2E smoke
|
|
# target. The full 15-flow suite from web/src/__tests__/e2e/README.md
|
|
# ships in frontend-design-audit Phase 8; this target is the harness
|
|
# wiring that lets `make e2e-test` work today.
|
|
#
|
|
# First-time setup: `cd web && npm install && npx playwright install --with-deps chromium`.
|
|
# The webServer block in web/playwright.config.ts boots `npm run dev`
|
|
# automatically; no separate `make docker-up` needed.
|
|
e2e-test:
|
|
@echo "Running Playwright E2E (smoke + any *.spec.ts under web/src/__tests__/e2e/)..."
|
|
cd web && npx playwright test
|
|
@echo "E2E run complete"
|
|
|
|
# qa-stats: snapshot of the test-suite size at the current commit.
|
|
# Backend Go tests + subtests + fuzz targets + skipped sites, plus the
|
|
# seed-data counts in migrations/seed_demo.sql. Useful before a release
|
|
# to spot-check that no whole layer dropped off.
|
|
qa-stats:
|
|
@echo "=== certctl QA Suite Stats ==="
|
|
@echo "Date: $$(date +%Y-%m-%d)"
|
|
@echo "HEAD: $$(git rev-parse HEAD 2>/dev/null || echo 'not-a-git-repo')"
|
|
@echo ""
|
|
@echo "Backend test files: $$(find . -name '*_test.go' -not -path './web/*' 2>/dev/null | wc -l | tr -d ' ')"
|
|
@echo "Backend Test functions: $$(find . -name '*_test.go' -not -path './web/*' 2>/dev/null | xargs grep -c '^func Test' 2>/dev/null | awk -F: '{s+=$$2} END{print s+0}')"
|
|
@echo "Backend t.Run subtests: $$(find . -name '*_test.go' -not -path './web/*' 2>/dev/null | xargs grep -c 't\.Run(' 2>/dev/null | awk -F: '{s+=$$2} END{print s+0}')"
|
|
@echo "Frontend test files: $$(find web/src -name '*.test.ts' -o -name '*.test.tsx' 2>/dev/null | wc -l | tr -d ' ')"
|
|
@echo "Fuzz targets: $$(grep -rE 'func Fuzz[A-Z]' --include='*_test.go' . 2>/dev/null | wc -l | tr -d ' ')"
|
|
@echo "t.Skip sites: $$(grep -rE 't\.Skip(Now|f)?\(' --include='*_test.go' . 2>/dev/null | wc -l | tr -d ' ')"
|
|
@echo "qa_test.go Part_ subtests: $$(grep -cE 't\.Run\(\"Part[0-9]+_' deploy/test/qa_test.go 2>/dev/null || echo 0)"
|
|
@echo "Seed unique mc-* IDs: $$(grep -oE "mc-[a-z0-9_-]+" migrations/seed_demo.sql 2>/dev/null | sort -u | wc -l | tr -d ' ')"
|
|
@echo "Seed unique ag-* IDs: $$(grep -oE "ag-[a-z0-9_-]+" migrations/seed_demo.sql 2>/dev/null | sort -u | wc -l | tr -d ' ') (incl. agent_groups; agents-table count is 13 incl. agent-demo-1 + 3 cloud sentinels + server-scanner)"
|
|
@echo "Seed unique iss-* IDs: $$(grep -oE "iss-[a-z0-9_-]+" migrations/seed_demo.sql 2>/dev/null | sort -u | wc -l | tr -d ' ') (issuers table count is 13)"
|
|
@echo "Seed unique tgt-* IDs: $$(grep -oE "tgt-[a-z0-9_-]+" migrations/seed_demo.sql 2>/dev/null | sort -u | wc -l | tr -d ' ')"
|
|
@echo "Seed unique nst-* IDs: $$(grep -oE "nst-[a-z0-9_-]+" migrations/seed_demo.sql 2>/dev/null | sort -u | wc -l | tr -d ' ')"
|
|
|
|
# Cleanup
|
|
clean:
|
|
@echo "Cleaning build artifacts..."
|
|
rm -rf bin/ dist/ coverage.out coverage.html
|
|
go clean -testcache
|
|
cd web && rm -rf node_modules dist
|
|
@echo "Cleanup complete"
|
|
|
|
install-tools:
|
|
@echo "Installing development tools..."
|
|
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
|
go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
|
|
go install github.com/cosmtrek/air@latest
|
|
@echo "Tools installed"
|