From 68b4df9ae5abe462629846718545a660d9fb67b0 Mon Sep 17 00:00:00 2001 From: across Date: Sun, 27 Sep 2026 04:37:42 +0530 Subject: [PATCH 1/2] build: require Go 1.26.6 and add Makefile quality targets govulncheck v1.8.0 (the version @latest resolves to) refuses to run on Go 1.24, and Go 1.24 is outside the upstream support window; the reachable stdlib fixes the security job needs ship in Go 1.26.6, the toolchain the rest of the GrayCode ecosystem already uses. - go.mod: go 1.26.6 (go mod tidy -diff is clean) - Makefile: add fmt-check, test-e2e, coverage, cross-check and vulncheck (govulncheck pinned to v1.8.0); make check now runs the gofmt gate; fuzz no longer swallows failures with || true - fmt-check escapes its command substitution: the unescaped $(gofmt -l .) was expanded by make to an empty string, so the gate could never fail - AGENTS.md, README.md, CONTRIBUTING.md: document the targets, the Go version, and the cgo requirement --- AGENTS.md | 12 ++++++++---- CONTRIBUTING.md | 7 ++++--- Makefile | 27 ++++++++++++++++++++++----- README.md | 10 +++++++--- go.mod | 2 +- 5 files changed, 42 insertions(+), 16 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index effd417..8b6fa68 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -17,17 +17,21 @@ One concern per commit. Keep PRs focused — one feature or fix each. Describe t ## Build & Test ```bash -make build # across + all cmd/across-agent-* binaries into bin/ +make build # core CLI + cmd/across-agent-* binaries into bin/ make test # go test -count=1 ./... +make test-e2e # dedicated E2E suite make test-race # go test -race -count=1 ./... make vet # go vet ./... -make e2e # go test -count=1 -run E2E ./... +make e2e # alias for test-e2e make fuzz # FuzzAcrossJSONL, 15s -make check # vet + test-race — run this before opening a PR +make coverage # coverage profile (coverage.out) +make cross-check # windows/amd64 vet + build (compile-only, CGO disabled) +make vulncheck # govulncheck at the pinned version +make check # gofmt check + vet + test-race — run before opening a PR make fmt # gofmt -w . ``` -CI runs `go mod tidy`, `go build ./...`, `make vet`, `make test`, `make test-race`. Go 1.24. +Go 1.26.6 (`go.mod`) with cgo enabled (SQLite driver). CI pins the same toolchain with `GOTOOLCHAIN=local` and runs `go mod tidy -diff`, gofmt, build/vet/test on Linux and macOS, a Windows compile-only check, race, dedicated E2E, coverage, and govulncheck. Windows is not runtime-tested. ## Structure diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 90784df..94d920b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,19 +11,20 @@ Thanks for your interest. Across is in local alpha — contributions should be s ## Getting started +Requires Go 1.26.6 or newer (see `go.mod`), `git`, and a C compiler for cgo (the SQLite driver). + ```bash git clone https://github.com/GrayCodeAI/across.git cd across -go mod tidy make build make test -make test-race +make check ``` ## Making changes - One concern per commit. Write a concise commit message explaining *why*. -- Run `make check` (vet + test-race) before opening a PR. +- Run `make check` (gofmt check + vet + test-race) before opening a PR. - Add tests for new behavior. A feature without a test is not implemented. - Update docs in the same commit if behavior changes. diff --git a/Makefile b/Makefile index 43ec6a3..e6a3c9f 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,13 @@ -.PHONY: build test test-race vet e2e fuzz fmt clean check install-local uninstall-local +.PHONY: build test test-e2e test-race vet e2e fuzz fmt fmt-check coverage cross-check vulncheck clean check install-local uninstall-local + +GOVULNCHECK_VERSION ?= v1.8.0 fmt: gofmt -w . +fmt-check: + @unformatted="$$(gofmt -l .)"; if [ -n "$$unformatted" ]; then echo "gofmt required for:"; echo "$$unformatted"; exit 1; fi + build: go build -o bin/across ./cmd/across go build -o bin/across-agent-claude-code ./cmd/across-agent-claude-code @@ -18,22 +23,34 @@ build: test: go test -count=1 ./... +test-e2e: + go test -count=1 -run E2E ./... + test-race: go test -race -count=1 ./... vet: go vet ./... -e2e: - go test -count=1 -run E2E ./... +e2e: test-e2e fuzz: - go test -fuzz=FuzzAcrossJSONL -fuzztime=15s ./internal/event/ || true + go test -fuzz=FuzzAcrossJSONL -fuzztime=15s ./internal/event/ + +coverage: + go test -count=1 -coverprofile=coverage.out ./... + +cross-check: + GOOS=windows GOARCH=amd64 go vet ./... + GOOS=windows GOARCH=amd64 go build ./... + +vulncheck: + go run golang.org/x/vuln/cmd/govulncheck@$(GOVULNCHECK_VERSION) ./... clean: rm -rf bin/ -check: vet test-race +check: fmt-check vet test-race install-local: mkdir -p $(HOME)/.local/bin diff --git a/README.md b/README.md index cd7b989..0e6c372 100644 --- a/README.md +++ b/README.md @@ -346,15 +346,19 @@ Qualification: `UNIMPLEMENTED` · `SYNTHETIC_TESTED` · `LIVE_TESTED` · `LIVE_Q ```bash make build # Build all binaries to bin/ -make test # Unit tests +make test # All tests, including E2E +make test-e2e # End-to-end tests only (alias: make e2e) make test-race # Race detector -make e2e # End-to-end tests make vet # go vet -make check # vet + test-race +make check # gofmt check + vet + test-race +make cross-check # Windows compile-only check (CGO disabled) +make vulncheck # govulncheck at the pinned version make install-local # Copy binaries to ~/.local/bin/ make uninstall-local ``` +Requires Go 1.26.6 or newer (see `go.mod`), `git`, and a C compiler for cgo (the SQLite driver). + ### Contributing See [CONTRIBUTING.md](CONTRIBUTING.md). One concern per commit. Evidence over confidence. `make check` before opening a PR. diff --git a/go.mod b/go.mod index b5a82e2..1cf155c 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/graycodeai/across -go 1.24 +go 1.26.6 require ( github.com/mattn/go-sqlite3 v1.14.32 From 6964567ca71e4039605471334b1427793726773d Mon Sep 17 00:00:00 2001 From: across Date: Sun, 27 Sep 2026 04:37:50 +0530 Subject: [PATCH 2/2] ci: pin actions by SHA, run on Go 1.26.6, and make Windows compile-only - Pin every action to a full commit SHA with a version comment (same pins as rho/flux), check out without persisted credentials, and keep the workflow token read-only. - Use Go 1.26.6 with GOTOOLCHAIN=local so the job runs the toolchain it names instead of silently switching. - Split quality (tidy -diff, gofmt, build, vet, test on Linux and macOS), race, E2E, coverage and govulncheck (pinned) jobs; each runs the Makefile target a contributor runs locally. - Windows was added to the test matrix without qualification: the E2E and unit suites exec sh/python3, create symlinks and rely on cgo, and no test is gated by GOOS. Keep Windows as a compile-only check until it is qualified; README already lists it as untested. - Add .gitattributes (eol=lf) so a Windows checkout cannot turn every file into a gofmt failure. --- .gitattributes | 1 + .github/workflows/ci.yml | 103 +++++++++++++++++++++++++++++++++++---- 2 files changed, 95 insertions(+), 9 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6313b56 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0a4ad1b..7449d15 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,19 +6,104 @@ on: pull_request: branches: [main] +permissions: + contents: read + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + GO_VERSION: "1.26.6" + GOTOOLCHAIN: local + GOWORK: "off" + jobs: - build: - runs-on: ubuntu-latest + quality: strategy: + fail-fast: false matrix: - go: ['1.24'] + os: [ubuntu-latest, macos-latest] + runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: - go-version: ${{ matrix.go }} - - run: go mod tidy + persist-credentials: false + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version: ${{ env.GO_VERSION }} + cache: true + - name: go.mod and go.sum are tidy + run: go mod tidy -diff + - name: gofmt + run: make fmt-check - run: go build ./... - - run: make vet - - run: make test + - run: go vet ./... + - run: go test -count=1 ./... + + cross-compile: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version: ${{ env.GO_VERSION }} + cache: true + - name: Windows compile check (CGO disabled; not a runtime qualification) + run: make cross-check + + race: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version: ${{ env.GO_VERSION }} + cache: true - run: make test-race + + e2e: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version: ${{ env.GO_VERSION }} + cache: true + - run: make test-e2e + + coverage: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version: ${{ env.GO_VERSION }} + cache: true + - run: make coverage + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: coverage + path: coverage.out + if-no-files-found: error + + security: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version: ${{ env.GO_VERSION }} + cache: true + - name: govulncheck + run: make vulncheck