From 6749f899e88c2c2ba2324e224e9d9bac4a835bca Mon Sep 17 00:00:00 2001 From: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com> Date: Fri, 24 Jul 2026 11:08:53 -0700 Subject: [PATCH] Warn when local golangci-lint version differs from CI (#1052) Motivation: `make lint` runs the locally installed `golangci-lint` binary, but nothing checks that its version matches the one pinned for the `golangci-lint-action` step in .github/workflows/dapr_cli.yaml (GOLANG_CI_LINT_VER). A version drift between a contributor's local lint and CI's lint can produce different results locally vs. in the pipeline, which is confusing to debug. This mirrors the approach already adopted in dapr/components-contrib (PR #1861), which the issue explicitly links as a reference solution. Approach: Add two new Makefile targets, wired as prerequisites of `lint`: - `verify-linter-installed`: fails with exit 1 and an install command if `golangci-lint` is not found on PATH. - `verify-linter-version`: compares the installed version (parsed from `golangci-lint --version`) against GOLANG_CI_LINT_VER (parsed from .github/workflows/dapr_cli.yaml) and prints a warning with an upgrade command if they differ. This check is non-fatal (it does not fail the build) since a version mismatch doesn't prevent linting from running, it just risks different results than CI. This is a Makefile-only, developer-tooling change; it does not touch Go source and does not affect CI itself, since CI's lint step invokes golangci-lint-action directly rather than `make lint`. Validation: - `go build ./...` and `go test ./pkg/...` both pass (no Go source was changed). - Manually exercised all three code paths of the new targets: - golangci-lint not on PATH: `make verify-linter-installed` exits 1 with a helpful install command. - golangci-lint v2.10.1 installed (matches GOLANG_CI_LINT_VER): `make verify-linter-installed verify-linter-version` exits 0 silently. - golangci-lint v2.5.0 installed (mismatch): prints a Yours/Theirs warning with an upgrade command and exits 0 (non-fatal). Fixes #1052 Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com> --- Makefile | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c6b853a233..9105a2b2de 100644 --- a/Makefile +++ b/Makefile @@ -55,21 +55,33 @@ LOCAL_OS := $(shell uname) ifeq ($(LOCAL_OS),Linux) TARGET_OS_LOCAL = linux GOLANGCI_LINT:=golangci-lint + FINDBIN := which export ARCHIVE_EXT = .tar.gz else ifeq ($(LOCAL_OS),Darwin) TARGET_OS_LOCAL = darwin GOLANGCI_LINT:=golangci-lint + FINDBIN := which PATH := $(PATH):$(HOME)/go/bin/darwin_$(GOARCH) export ARCHIVE_EXT = .tar.gz else TARGET_OS_LOCAL ?= windows BINARY_EXT_LOCAL = .exe GOLANGCI_LINT:=golangci-lint.exe + FINDBIN := where export ARCHIVE_EXT = .zip endif export GOOS ?= $(TARGET_OS_LOCAL) export BINARY_EXT ?= $(BINARY_EXT_LOCAL) +# Version of golangci-lint used by the GitHub Actions pipeline (.github/workflows/dapr_cli.yaml). +GH_LINT_VERSION := $(shell grep 'GOLANG_CI_LINT_VER:' .github/workflows/dapr_cli.yaml | xargs | cut -d' ' -f2) +LINTER_BINARY := $(shell $(FINDBIN) $(GOLANGCI_LINT) 2>/dev/null) +ifeq (,$(LINTER_BINARY)) + INSTALLED_LINT_VERSION := v0.0.0 +else + INSTALLED_LINT_VERSION := v$(shell $(GOLANGCI_LINT) --version | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+' | head -1) +endif + TEST_OUTPUT_FILE ?= test_output.json # Set the default timeout for tests to 10 minutes @@ -110,11 +122,38 @@ $(CLI_BINARY): CGO_ENABLED=$(CGO) GOOS=$(GOOS) GOARCH=$(GOARCH) go build $(GCFLAGS) -ldflags $(LDFLAGS) \ -o $(BINS_OUT_DIR)/$(CLI_BINARY)$(BINARY_EXT); +################################################################################ +# Target: verify-linter-installed # +################################################################################ +.PHONY: verify-linter-installed +verify-linter-installed: + @if [ -z "$(LINTER_BINARY)" ]; then \ + echo "[!] golangci-lint is not installed"; \ + echo "[!] You can install it from https://golangci-lint.run/usage/install/"; \ + echo "[!] or by running"; \ + echo "[!] curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $$(go env GOPATH)/bin $(GH_LINT_VERSION)"; \ + exit 1; \ + fi + +################################################################################ +# Target: verify-linter-version # +################################################################################ +.PHONY: verify-linter-version +verify-linter-version: + @if [ "$(GH_LINT_VERSION)" != "$(INSTALLED_LINT_VERSION)" ]; then \ + echo "[!] Your locally installed version of golangci-lint is different from the pipeline"; \ + echo "[!] This will likely cause linting issues for you locally"; \ + echo "[!] Yours: $(INSTALLED_LINT_VERSION)"; \ + echo "[!] Theirs: $(GH_LINT_VERSION)"; \ + echo "[!] Upgrade: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $$(go env GOPATH)/bin $(GH_LINT_VERSION)"; \ + sleep 3; \ + fi + ################################################################################ # Target: lint # ################################################################################ .PHONY: lint -lint: +lint: verify-linter-installed verify-linter-version $(GOLANGCI_LINT) run --timeout=20m ################################################################################