diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 35ba66e0..02400a35 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -10,6 +10,41 @@ permissions: contents: read jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + with: + persist-credentials: false + + - name: Set up Go + uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0 + with: + go-version-file: go.mod + cache: true + + - name: Verify vendor is up to date + run: | + go mod tidy + go mod vendor + git diff --exit-code -- go.mod go.sum vendor/ + + - name: Run golangci-lint + uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9 + with: + version: v2.8 + args: --timeout=5m ./... + + - name: Run golangci-lint formatter checks + run: go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.8.0 fmt --diff + + - name: Run govulncheck + uses: golang/govulncheck-action@b625fbe08f3bccbe446d94fbf87fcc875a4f50ee # v1 + with: + go-version-file: go.mod + go-package: ./... + test: runs-on: ubuntu-latest steps: @@ -68,7 +103,7 @@ jobs: publish-main: name: Publish GHCR :main - needs: [test, lint-actions] + needs: [test, lint, lint-actions] if: github.event_name == 'push' && github.ref == 'refs/heads/main' runs-on: ubuntu-latest permissions: diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..2d57f7a8 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,25 @@ +version: "2" + +run: + timeout: 5m + modules-download-mode: vendor + +linters: + enable: + - bodyclose + - errorlint + - gosec + - misspell + - nilerr + - revive + +formatters: + enable: + - gofumpt + settings: + gofumpt: + extra-rules: true + +issues: + max-issues-per-linter: 0 + max-same-issues: 0 diff --git a/Makefile b/Makefile index 1f23ef13..ee75ce71 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ GOFLAGS ?= -mod=vendor VENDOR_STAMP := vendor/.modules.stamp MODULE_FILES := go.mod $(wildcard go.sum) -.PHONY: vendor test build verify-vendor codegen +.PHONY: vendor test build lint vuln verify-vendor codegen $(VENDOR_STAMP): $(MODULE_FILES) go mod tidy @@ -18,6 +18,15 @@ test: $(VENDOR_STAMP) build: $(VENDOR_STAMP) GOFLAGS=$(GOFLAGS) go build ./... +lint: $(VENDOR_STAMP) + @command -v golangci-lint >/dev/null || (echo "golangci-lint not found; use nix develop" && exit 1) + GOFLAGS=$(GOFLAGS) golangci-lint run ./... + GOFLAGS=$(GOFLAGS) golangci-lint fmt --diff + +vuln: $(VENDOR_STAMP) + @command -v govulncheck >/dev/null || (echo "govulncheck not found; use nix develop" && exit 1) + GOFLAGS=$(GOFLAGS) govulncheck ./... + verify-vendor: go mod tidy go mod vendor diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..e5578c1f --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1770562336, + "narHash": "sha256-ub1gpAONMFsT/GU2hV6ZWJjur8rJ6kKxdm9IlCT0j84=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d6c71932130818840fc8fe9509cf50be8c64634f", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix index 15c0ca5d..d9367c6e 100644 --- a/flake.nix +++ b/flake.nix @@ -25,6 +25,8 @@ goreleaser actionlint zizmor + golangci-lint + govulncheck ]; }; } diff --git a/go.mod b/go.mod index 8cb51dd6..8986ddf6 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/coder/coder-k8s -go 1.25.6 +go 1.25.7 require ( k8s.io/apimachinery v0.35.0 diff --git a/internal/controller/codercontrolplane_controller.go b/internal/controller/codercontrolplane_controller.go index 1f2a7bfc..84940642 100644 --- a/internal/controller/codercontrolplane_controller.go +++ b/internal/controller/codercontrolplane_controller.go @@ -1,3 +1,4 @@ +// Package controller contains Kubernetes controllers for coder-k8s resources. package controller import ( diff --git a/internal/deps/deps.go b/internal/deps/deps.go index 37f614a6..e5cccdc5 100644 --- a/internal/deps/deps.go +++ b/internal/deps/deps.go @@ -5,8 +5,8 @@ package deps import ( - _ "k8s.io/apimachinery/pkg/runtime" - _ "k8s.io/client-go/kubernetes" - _ "k8s.io/code-generator" - _ "sigs.k8s.io/controller-runtime/pkg/client" + _ "k8s.io/apimachinery/pkg/runtime" // Keep apimachinery runtime dependency vendored. + _ "k8s.io/client-go/kubernetes" // Keep client-go kubernetes client vendored. + _ "k8s.io/code-generator" // Keep code-generator scripts vendored. + _ "sigs.k8s.io/controller-runtime/pkg/client" // Keep controller-runtime client vendored. ) diff --git a/main.go b/main.go index ee5b0aa2..81cd158e 100644 --- a/main.go +++ b/main.go @@ -1,3 +1,4 @@ +// Package main provides the entrypoint for the coder-k8s binary. package main import (