apiVersion: tekton.dev/v1beta1 kind: Task metadata: name: go-ci annotations: tekton.dev/displayName: "go build + lint + race-test + vuln-scan" spec: params: - name: GO_IMAGE description: Container image carrying the Go toolchain. type: string default: docker.io/library/golang:1.25 - name: GOLANGCI_LINT_IMAGE description: | golangci-lint image (must be Go-version compatible with GO_IMAGE and a v2.x release — .golangci.yml uses the version "2" config schema). type: string default: docker.io/golangci/golangci-lint:v2.12.2-alpine - name: RELEASE_TOOLS_IMAGE description: | Pre-built release-tools image containing govulncheck (and other tools). Used only for the govulncheck step. type: string default: codeberg.org/operate-first/release-tools:latest - name: LINT_REQUIRED description: | If "true", lint findings fail the build. If "false", lint runs but its exit code is ignored (warn-only). Baseline was cleaned in dd9116f (0 findings), so lint is enforced by default now. type: string default: "true" workspaces: - name: source mountPath: /workspace/src stepTemplate: workingDir: $(workspaces.source.path) env: - name: GOFLAGS value: "-buildvcs=false" - name: GOCACHE value: /workspace/src/.gocache - name: GOMODCACHE value: /workspace/src/.gomodcache - name: GOTOOLCHAIN value: local steps: - name: build image: $(params.GO_IMAGE) script: | #!/usr/bin/env bash set -euo pipefail git config --global --add safe.directory "$(workspaces.source.path)" go version make build - name: vet image: $(params.GO_IMAGE) script: | #!/usr/bin/env bash set -euo pipefail git config --global --add safe.directory "$(workspaces.source.path)" go vet ./... - name: gofmt-check image: $(params.GO_IMAGE) script: | #!/usr/bin/env bash set -euo pipefail git config --global --add safe.directory "$(workspaces.source.path)" unformatted="$(gofmt -l . | grep -v '^\.gocache/' | grep -v '^\.gomodcache/' || true)" if [ -n "$unformatted" ]; then echo "Files not gofmt'd:" >&2 echo "$unformatted" >&2 exit 1 fi - name: mod-tidy-check image: $(params.GO_IMAGE) script: | #!/usr/bin/env bash set -euo pipefail git config --global --add safe.directory "$(workspaces.source.path)" cp go.mod go.mod.pre cp go.sum go.sum.pre go mod tidy if ! diff -u go.mod.pre go.mod || ! diff -u go.sum.pre go.sum; then echo "go.mod / go.sum drift detected. Run 'go mod tidy' locally." >&2 mv go.mod.pre go.mod mv go.sum.pre go.sum exit 1 fi rm -f go.mod.pre go.sum.pre - name: lint image: $(params.GOLANGCI_LINT_IMAGE) script: | #!/bin/sh set -eu git config --global --add safe.directory "$(workspaces.source.path)" golangci-lint version if [ "$(params.LINT_REQUIRED)" = "true" ]; then golangci-lint run --timeout=5m ./... else golangci-lint run --timeout=5m ./... || \ echo "::warning::golangci-lint findings present (LINT_REQUIRED=false)" fi - name: test-race image: $(params.GO_IMAGE) script: | #!/usr/bin/env bash set -euo pipefail git config --global --add safe.directory "$(workspaces.source.path)" go test -race -shuffle=on -count=1 ./... - name: govulncheck image: $(params.RELEASE_TOOLS_IMAGE) script: | #!/usr/bin/env bash set -euo pipefail git config --global --add safe.directory "$(workspaces.source.path)" govulncheck ./... - name: license-check image: $(params.GO_IMAGE) script: | #!/usr/bin/env bash # Fail build if any module in the dependency closure carries a # forbidden (GPL/AGPL) or restricted (LGPL/MPL/EPL) license. # Protects the Apache-2.0 binary from GPL contamination. # # Uses GO_IMAGE + go install rather than RELEASE_TOOLS_IMAGE to avoid # the circular bootstrap problem: release-tools:latest predates this # step, so go-licenses would not be present until after the image # rebuilds. GOMODCACHE is workspace-scoped, so the install is cached # across steps in the same PipelineRun. set -euo pipefail git config --global --add safe.directory "$(workspaces.source.path)" go install github.com/google/go-licenses@v1.6.0 go-licenses check ./... \ --disallowed_types=forbidden,restricted \ --ignore=codeberg.org/goern/forgejo-mcp