From 3f974f77da80c5c4d5beab700986fca6b4ac5b3f Mon Sep 17 00:00:00 2001 From: lex0c Date: Sat, 27 Jun 2026 23:46:44 -0300 Subject: [PATCH] ci: add security pipeline and harden prod build - govulncheck job in CI (reachability-based, blocking gate) - single-source Go version via go-version-file: go.mod (drops the stale '1.21' pin that silently auto-downloaded the real toolchain) - least-privilege permissions: contents: read on the CI workflow - dependabot for gomod + github-actions (weekly) - release: static + stripped binaries (CGO_ENABLED=0, -ldflags -s -w, ~32% smaller), publish SHA256SUMS, add go vet Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/dependabot.yml | 17 +++++++++++++++++ .github/workflows/ci.yml | 26 ++++++++++++++++++++++++-- .github/workflows/pages.yml | 2 +- .github/workflows/release.yml | 19 +++++++++++++++++-- 4 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..8009aae --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,17 @@ +version: 2 +updates: + # Go module dependencies. Keeps cobra/pflag and their transitive deps + # patched; pairs with the govulncheck gate in ci.yml. + - package-ecosystem: gomod + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 5 + + # GitHub Actions versions. When the actions are later SHA-pinned, this + # is what bumps the pinned SHAs (and annotates them with the version). + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 5 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dfd4b11..a9fc8f7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,9 @@ on: pull_request: branches: [main] +permissions: + contents: read + jobs: # Cross-platform verification. The project cross-compiles cleanly to # all three OSes via the release workflow, but "compiles" ≠ "runtime- @@ -27,7 +30,7 @@ jobs: - uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version-file: go.mod - name: Vet run: go vet ./... @@ -50,7 +53,7 @@ jobs: - uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version-file: go.mod - name: Build run: make build @@ -61,3 +64,22 @@ jobs: - name: Quality gates run: ./gitcortex ci --fail-on-churn-risk 5500 --format github-actions # Add --fail-on-busfactor 1 when team grows + + # Vulnerability scan against the Go vulnerability database. govulncheck + # does reachability analysis, so it only fails when vulnerable code is + # actually reachable from this module — low false-positive, safe as a + # blocking gate. Covers both our deps and the stdlib we call. + vulncheck: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + + - name: Install govulncheck + run: go install golang.org/x/vuln/cmd/govulncheck@latest + + - name: Run govulncheck + run: govulncheck ./... diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index e3cc08f..e0f88bc 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version-file: go.mod - name: Build gitcortex run: make build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c47aad3..6e96056 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,15 +18,25 @@ jobs: - uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version-file: go.mod + + - name: Vet + run: go vet ./... - name: Test run: go test ./... -count=1 + # CGO_ENABLED=0 -> fully static binaries (no libc dependency, run on + # any Linux). -s -w strips the symbol table and DWARF: ~25-30% + # smaller artifacts. Go panic stack traces survive (they use the + # embedded pclntab, not ELF/DWARF) — only interactive debuggers + # (delve/gdb) lose symbols, which we never run against a release. - name: Build binaries + env: + CGO_ENABLED: 0 run: | VERSION=${GITHUB_REF#refs/tags/} - LDFLAGS="-X main.version=$VERSION" + LDFLAGS="-s -w -X main.version=$VERSION" GOOS=linux GOARCH=amd64 go build -trimpath -ldflags "$LDFLAGS" -o dist/gitcortex-linux-amd64 ./cmd/gitcortex/ GOOS=linux GOARCH=arm64 go build -trimpath -ldflags "$LDFLAGS" -o dist/gitcortex-linux-arm64 ./cmd/gitcortex/ @@ -34,6 +44,11 @@ jobs: GOOS=darwin GOARCH=arm64 go build -trimpath -ldflags "$LDFLAGS" -o dist/gitcortex-darwin-arm64 ./cmd/gitcortex/ GOOS=windows GOARCH=amd64 go build -trimpath -ldflags "$LDFLAGS" -o dist/gitcortex-windows-amd64.exe ./cmd/gitcortex/ + # Publish checksums so downloads can be verified: + # sha256sum -c SHA256SUMS + - name: Checksums + run: cd dist && sha256sum gitcortex-* > SHA256SUMS + - name: Create release uses: softprops/action-gh-release@v2 with: