diff --git a/.github/workflows/golangci_lint.yml b/.github/workflows/golangci_lint.yml index 84b8e44f7f..b090bff250 100644 --- a/.github/workflows/golangci_lint.yml +++ b/.github/workflows/golangci_lint.yml @@ -10,8 +10,21 @@ jobs: contents: read actions: read steps: + - name: Checkout code + uses: actions/checkout@v5 + with: + persist-credentials: false + + - name: Get golangci-lint version from asdf + id: get-version + run: | + version=$(grep '^golangci-lint ' .tool-versions | awk '{print $2}') + echo "version=${version}" | tee -a "$GITHUB_OUTPUT" + - name: golangci-lint if: ${{ always() && !contains(join(github.event.pull_request.labels.*.name, ' '), 'allow-lint-issues') }} - uses: smartcontractkit/.github/actions/ci-lint-go@ci-lint-go/v2 + # NOTE: Keep this version in sync with ACTION_CI_LINT_GO_GIT_TAG in ./script/lint.sh + uses: smartcontractkit/.github/actions/ci-lint-go@ci-lint-go/3.0.0 with: - golangci-lint-version: v2.2.2 + checkout-repo: false + golangci-lint-version: v${{ steps.get-version.outputs.version }} diff --git a/.golangci.yml b/.golangci.yml deleted file mode 100644 index 47aff6198c..0000000000 --- a/.golangci.yml +++ /dev/null @@ -1,162 +0,0 @@ -version: "2" -linters: - enable: - - containedctx - - copyloopvar - - depguard - - errname - - errorlint - - exhaustive - - fatcontext - - ginkgolinter - - gomoddirectives - - gosec - - loggercheck - - mirror - - misspell - - noctx - - perfsprint - - prealloc - - revive - - rowserrcheck - - spancheck - - sqlclosecheck - - testifylint - - unconvert - - whitespace - settings: - depguard: - rules: - main: - list-mode: lax - deny: - - pkg: cosmossdk.io/errors - desc: Use the standard library instead - - pkg: github.com/ethereum/go-ethereum - desc: This is a chain-agnostic repo - - pkg: github.com/gagliardetto/solana-go - desc: This is a chain-agnostic repo - - pkg: github.com/go-gorm/gorm - desc: Use github.com/jmoiron/sqlx directly instead - - pkg: github.com/gofrs/uuid - desc: Use github.com/google/uuid instead - - pkg: github.com/pkg/errors - desc: Use the standard library instead, for example https://pkg.go.dev/errors#Join - - pkg: github.com/satori/go.uuid - desc: Use github.com/google/uuid instead - - pkg: github.com/test-go/testify/assert - desc: Use github.com/stretchr/testify/assert instead - - pkg: github.com/test-go/testify/mock - desc: Use github.com/stretchr/testify/mock instead - - pkg: github.com/test-go/testify/require - desc: Use github.com/stretchr/testify/require instead - - pkg: go.uber.org/multierr - desc: Use the standard library instead, for example https://pkg.go.dev/errors#Join - - pkg: gopkg.in/guregu/null.v1 - desc: Use gopkg.in/guregu/null.v4 instead - - pkg: gopkg.in/guregu/null.v2 - desc: Use gopkg.in/guregu/null.v4 instead - - pkg: gopkg.in/guregu/null.v3 - desc: Use gopkg.in/guregu/null.v4 instead - exhaustive: - default-signifies-exhaustive: true - gosec: - excludes: - - G101 - - G104 - govet: - enable: - - shadow - settings: - printf: - funcs: - - (github.com/smartcontractkit/chainlink-common/pkg/logger.Logger).Debugf - - (github.com/smartcontractkit/chainlink-common/pkg/logger.Logger).Infof - - (github.com/smartcontractkit/chainlink-common/pkg/logger.Logger).Warnf - - (github.com/smartcontractkit/chainlink-common/pkg/logger.Logger).Errorf - - (github.com/smartcontractkit/chainlink-common/pkg/logger.Logger).Panicf - - (github.com/smartcontractkit/chainlink-common/pkg/logger.Logger).Fatalf - - (github.com/smartcontractkit/chainlink-common/pkg/logger.SugaredLogger).AssumptionViolationf - - (github.com/smartcontractkit/chainlink-common/pkg/logger.SugaredLogger).Tracef - - (github.com/smartcontractkit/chainlink-common/pkg/logger.SugaredLogger).Criticalf - loggercheck: - rules: - - (github.com/smartcontractkit/chainlink-common/pkg/logger.Logger).Debugw - - (github.com/smartcontractkit/chainlink-common/pkg/logger.Logger).Infow - - (github.com/smartcontractkit/chainlink-common/pkg/logger.Logger).Warnw - - (github.com/smartcontractkit/chainlink-common/pkg/logger.Logger).Errorw - - (github.com/smartcontractkit/chainlink-common/pkg/logger.Logger).Panicw - - (github.com/smartcontractkit/chainlink-common/pkg/logger.Logger).Fatalw - - (github.com/smartcontractkit/chainlink-common/pkg/logger.SugaredLogger).AssumptionViolationw - - (github.com/smartcontractkit/chainlink-common/pkg/logger.SugaredLogger).Tracew - - (github.com/smartcontractkit/chainlink-common/pkg/logger.SugaredLogger).Criticalw - - (github.com/smartcontractkit/chainlink-common/pkg/logger.SugaredLogger).With - revive: - confidence: 0.8 - rules: - - name: blank-imports - - name: context-as-argument - - name: context-keys-type - - name: dot-imports - - name: error-return - - name: error-strings - - name: error-naming - - name: exported - - name: if-return - - name: increment-decrement - - name: var-naming - - name: var-declaration - - name: package-comments - - name: range - - name: receiver-naming - - name: time-naming - - name: indent-error-flow - - name: errorf - - name: empty-block - - name: superfluous-else - - name: unreachable-code - - name: redefines-builtin-id - - name: waitgroup-by-value - - name: unconditional-recursion - - name: struct-tag - - name: string-of-int - - name: range-val-address - - name: range-val-in-closure - - name: modifies-value-receiver - - name: modifies-parameter - - name: identical-branches - - name: get-return - - name: early-return - - name: defer - - name: constant-logical-expr - - name: bool-literal-in-expr - - name: atomic - exclusions: - generated: lax - presets: - - comments - - common-false-positives - - legacy - - std-error-handling - rules: - - linters: - - gosec - path: test - text: '^G404:' - paths: - - third_party$ - - builtin$ - - examples$ -formatters: - enable: - - goimports - settings: - goimports: - local-prefixes: - - github.com/smartcontractkit/chainlink - exclusions: - generated: lax - paths: - - third_party$ - - builtin$ - - examples$ diff --git a/Makefile b/Makefile index 9cc251ea08..b959417606 100644 --- a/Makefile +++ b/Makefile @@ -42,8 +42,12 @@ generate: mockery install-protoc gomods cre-protoc modgraph cre-protoc: cd pkg/capabilities/v2/protoc && go build -o protoc-gen-cre . + .PHONY: lint-workspace lint -GOLANGCI_LINT_VERSION := 1.64.8 +# If GOLANGCI_LINT_VERSION is not set, extract it from .tool-versions +ifndef GOLANGCI_LINT_VERSION +GOLANGCI_LINT_VERSION := $(shell grep '^golangci-lint ' .tool-versions | awk '{print $$2}') +endif GOLANGCI_LINT_COMMON_OPTS := --max-issues-per-linter 0 --max-same-issues 0 GOLANGCI_LINT_DIRECTORY := ./golangci-lint diff --git a/script/lint.sh b/script/lint.sh index c1be92a10d..da256f38ab 100755 --- a/script/lint.sh +++ b/script/lint.sh @@ -1,7 +1,8 @@ -#!/bin/bash +#!/usr/bin/env bash # run_linter.sh # This script runs golangci-lint either locally or in a Docker container based on version matching. + # Parameters GOLANGCI_LINT_VERSION="$1" COMMON_OPTS="$2" @@ -9,9 +10,34 @@ DIRECTORY="$3" EXTRA_OPTS="$4" OUTPUT_FILE="$DIRECTORY/$(date +%Y-%m-%d_%H:%M:%S).txt" +# Require GOLANGCI_LINT_VERSION as first argument +if [[ -z "${GOLANGCI_LINT_VERSION:-}" ]]; then + echo "Error: GOLANGCI_LINT_VERSION env var is required." >&2 + echo "Usage: $0 [extra-opts]" >&2 + exit 1 +fi + + # Prepare the lint directory mkdir -p "$DIRECTORY" +# Check if user provided a local config path via env var +if [[ -n "${GOLANGCI_LINT_CONFIG:-}" ]]; then + CONFIG_FILE="$GOLANGCI_LINT_CONFIG" + echo "Using user-provided config: $CONFIG_FILE" +else + # NOTE: Keep this version in sync with the action tag in /.github/workflows/golangci_lint.yml + ACTION_CI_LINT_GO_GIT_TAG="${CI_LINT_GO_VERSION:-ci-lint-go/3.0.0}" + # Download remote golangci-lint config to gitignored directory + REMOTE_CONFIG_URL="https://raw.githubusercontent.com/smartcontractkit/.github/refs/tags/${ACTION_CI_LINT_GO_GIT_TAG}/actions/ci-lint-go/files/golangci-default.yml" + CONFIG_FILE="$DIRECTORY/golangci.remote.yml" + echo "Downloading remote config from: $REMOTE_CONFIG_URL" + curl -sfL "$REMOTE_CONFIG_URL" -o "$CONFIG_FILE" +fi + +# Always use the selected config +COMMON_OPTS="$COMMON_OPTS --config $CONFIG_FILE" + DOCKER_CMD="docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:v$GOLANGCI_LINT_VERSION golangci-lint run $COMMON_OPTS $EXTRA_OPTS" if command -v golangci-lint >/dev/null 2>&1; then