.PHONY: build test test-race lint fmt clean run release version changelog help security-scan verify-reqs verify-docs BINARY := bin/orca GOFLAGS := -trimpath PKG := ./cmd/orca # Version is read from the latest git tag, with a `dev` fallback. # Override with `make build VERSION=v0.1.5` if needed. VERSION ?= $(shell git describe --tags --abbrev=0 2>/dev/null || echo "dev") GIT_COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown") BUILD_TIME ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ) # -ldflags injects version metadata into the binary. The variables live in # internal/cli/root.go, so we target git.cloudinit.dev/coreci/orca/internal/cli. LDFLAGS := -s -w \ -X git.cloudinit.dev/coreci/orca/internal/cli.version=$(VERSION) \ -X git.cloudinit.dev/coreci/orca/internal/cli.gitCommit=$(GIT_COMMIT) \ -X git.cloudinit.dev/coreci/orca/internal/cli.buildTime=$(BUILD_TIME) help: @echo "orca — make targets" @echo " build Build binary to $(BINARY) (injects version via -ldflags)" @echo " test Run tests" @echo " test-race Run tests with race detection (REQ-031)" @echo " lint Run gofmt + go vet" @echo " fmt Format code" @echo " clean Remove build artifacts" @echo " run Build and run with args (use: make run ARGS='version')" @echo " version Print the version string that would be injected" @echo " changelog Generate CHANGELOG.md from ---ci--- commit blocks" @echo " release Run scripts/release.sh [VERSION] — build, tar, publish" @echo " security-scan Run gosec+govulncheck+gitleaks (P03, REQ-014/027/039)" @echo " verify-reqs Assert ROADMAP COMPLETE ↔ REQUIREMENTS Complete (REQ-060)" @echo " verify-docs Assert docs/cli.md ↔ orca --help consistency (REQ-160)" build: @mkdir -p bin @echo " → building $(VERSION) ($(GIT_COMMIT))" go build $(GOFLAGS) -ldflags="$(LDFLAGS)" -o $(BINARY) $(PKG) test: go test -coverprofile=coverage.out ./... $(MAKE) test-bash # test-race runs the full test suite under the race detector (REQ-031). # Wired into the .coreci.yml `test` pipeline as well. test-race: go test -race -coverprofile=coverage.out ./... $(MAKE) test-bash lint: gofmt -l . go vet ./... $(MAKE) lint-bash fmt: gofmt -w . # test-bash runs bats tests for shell scripts (grill C-15). Skips gracefully # if bats is not installed. test-bash: @command -v bats >/dev/null 2>&1 && { \ echo "→ bats scripts/tests/*.bash"; \ bats scripts/tests/*.bash; \ } || echo "bats not installed; skipping bash tests (see scripts/tests/README.md)" # lint-bash runs shellcheck + shfmt on shell scripts (grill C-15). Skips # gracefully if the tools are not installed. lint-bash: @command -v shellcheck >/dev/null 2>&1 && { \ echo "→ shellcheck scripts/"; \ shellcheck scripts/*.sh scripts/lib/*.sh scripts/tests/*.bash || true; \ } || echo "shellcheck not installed; skipping (see scripts/tests/README.md)" @command -v shfmt >/dev/null 2>&1 && { \ echo "→ shfmt -d scripts/"; \ shfmt -d scripts/; \ } || echo "shfmt not installed; skipping (see scripts/tests/README.md)" clean: rm -rf bin coverage.out *.tar.gz run: build ./$(BINARY) $(ARGS) version: @echo "$(VERSION) (commit $(GIT_COMMIT), built $(BUILD_TIME))" # changelog aggregates the most recent ---ci--- tagged commit messages # into CHANGELOG.md. Idempotent; safe to run after every milestone. changelog: @echo "# Changelog" > CHANGELOG.md @echo "" >> CHANGELOG.md @echo "All notable changes to orca are documented in this file." >> CHANGELOG.md @echo "" >> CHANGELOG.md @echo "The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)," >> CHANGELOG.md @echo "and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html)." >> CHANGELOG.md @echo "" >> CHANGELOG.md @git log --pretty=format:'%H' --grep='^feat\|^fix\|^docs\|^ship\|^chore' 2>/dev/null | head -50 | while read sha; do \ msg=$$(git log -1 --pretty=format:'%s' "$$sha"); \ if echo "$$msg" | grep -qE -- '---ci---|phase:'; then \ phase=$$(echo "$$msg" | grep -oE 'phase: [0-9]+' | head -1 | awk '{print $$2}'); \ status=$$(echo "$$msg" | grep -oE 'status: [a-z]+' | head -1 | awk '{print $$2}'); \ echo "- \`$$sha\` (phase $$phase, $$status) — $$msg" >> CHANGELOG.md; \ else \ echo "- \`$$sha\` — $$msg" >> CHANGELOG.md; \ fi; \ done @echo "" >> CHANGELOG.md @echo "Generated by make changelog. Do not edit by hand." >> CHANGELOG.md @echo "✓ CHANGELOG.md updated" release: @if [ -z "$(VERSION)" ] || [ "$(VERSION)" = "dev" ]; then \ echo "release: no version tag found. Tag first: git tag v0.1.6"; \ exit 1; \ fi ./scripts/release.sh $(VERSION) # security-scan runs the three tools integrated in P03 (REQ-014, # REQ-027, REQ-039). Local equivalent of the .coreci.yml `validate` # security stages. Exits non-zero on any unsuppressed finding. # The script handles tool detection (silently skips tools not on PATH # in a developer's local environment; CI requires all three). security-scan: ./scripts/security_scan.sh # verify-reqs asserts ROADMAP milestone COMPLETE ↔ REQUIREMENTS row Complete # consistency (REQ-060). Catches doc-vs-doc drift; code-vs-doc drift is out # of scope (P04 audit). Exits 0 on consistency, 1 with a diff on drift. verify-reqs: go run ./cmd/verify-reqs .ciagent/ROADMAP.md .ciagent/REQUIREMENTS.md # verify-docs asserts that every top-level subcommand in docs/cli.md # exists in `orca --help` output (and vice versa). Catches doc drift # (REQ-160). Requires the binary to be built first (`make build`). verify-docs: build ./scripts/verify-docs.sh ./bin/orca docs/cli.md