Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ GO_TEST_FLAGS :=-race
GO_LD_FLAGS:=

verify-gocilint:
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.64.6
${GOPATH}/bin/golangci-lint run --timeout=3m ./...
@./ci/lint/run-lint.sh

verify-govet:
go vet -mod=vendor ./...
Expand Down
111 changes: 111 additions & 0 deletions ci/lint/README-golangci-lint.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# golangci-lint Management for sdk-go

This directory contains scripts and configurations for golangci-lint v2 version management. All builds require **Go 1.23+**.

## Quick Start

Add this to your `Makefile`:

```makefile
.PHONY: lint
lint:
@curl -sSL https://raw.githubusercontent.com/open-cluster-management-io/sdk-go/main/ci/lint/run-lint.sh | bash
```

That's it! The script will:
1. Auto-detect Go version from `go.mod` (falls back to system Go if no `go.mod`)
2. Install a compatible golangci-lint v2 version (if needed)
3. Use the local config file from `ci/lint/golangci-v2.yml` (if no local config exists)
4. Run `golangci-lint run`

**Zero configuration needed** - just run `make lint` and everything works automatically.

**Seamless Go version upgrades**: When you update `go.mod` (e.g., Go 1.23 to 1.25), the script automatically selects the correct golangci-lint v2 version. No manual migration required!

**go.mod-based detection**: The script reads the Go version from your project's `go.mod`, not the system-installed Go. This ensures consistent behavior between local development (where you may have a newer Go) and CI (which matches `go.mod`).

### Configuration Priority

1. **Local config** (`.golangci.yml` or `.golangci.yaml`) - if exists, used as-is
2. **Bundled config** - copied from `ci/lint/golangci-v2.yml`

### Override Version (Optional)

If you need to use a specific version:

```bash
GOLANGCI_LINT_VERSION=v2.8.0 make lint
```

---

## Files Included

| File | Description |
|------|-------------|
| `run-lint.sh` | One-command lint runner (install + config + run) |
| `install-golangci-lint.sh` | Installation script with Go version detection |
| `golangci-v2.yml` | Default config for golangci-lint v2.x |

---

## Go Version Compatibility

The script reads the Go version from `go.mod` and selects the correct golangci-lint v2 version accordingly (falls back to system Go version if no `go.mod` is found).

| Go Version | golangci-lint Version | Config File |
|------------|----------------------|-------------|
| Go 1.24+ | v2.8.0 | `golangci-v2.yml` |
| Go 1.23 | v2.3.1 | `golangci-v2.yml` |

---

## Upgrading Version

To upgrade golangci-lint:

1. Edit the version mapping in both `run-lint.sh` and `install-golangci-lint.sh`
2. Commit and push the changes
3. The new version will be used on the next lint run

---

## Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `GOLANGCI_CONFIG_DIR` | `/tmp/golangci-lint-config` | Config cache directory |
| `GOLANGCI_UPDATE_CONFIG` | `false` | Force re-copy config if set to `true` |
| `GOLANGCI_LINT_VERSION` | (auto) | Override auto-detected golangci-lint version |

---

## Known Issues and Solutions

### 1. Go Version Mismatch Error

**Error**: `the Go language version used to build golangci-lint is lower than the targeted Go version`

**Solution**: This script automatically selects a compatible version. If you see this error, update the version mapping or use the environment variable override.

### 2. Network Issues

**Problem**: Download fails in CI or behind firewall.

**Solution**: The script skips download if the correct version is already installed. Consider caching the binary or using an internal artifact server.

---

## References

- [golangci-lint Configuration](https://golangci-lint.run/docs/configuration/)
- [Local Installation](https://golangci-lint.run/docs/welcome/install/local/)
- [Issue #5032: Go version compatibility](https://github.com/golangci/golangci-lint/issues/5032)
- [Discussion #3954: Sharing Configs Across Repos](https://github.com/golangci/golangci-lint/discussions/3954)

---

## License

Copyright (c) Red Hat, Inc.
Copyright Contributors to the Open Cluster Management project
101 changes: 101 additions & 0 deletions ci/lint/golangci-v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# golangci-lint v2.x configuration
# Compatible with golangci-lint v2.0.0+
# Documentation: https://golangci-lint.run/docs/configuration/
# Migration guide: https://golangci-lint.run/docs/product/migration-guide/

version: "2"

run:
timeout: 5m
modules-download-mode: readonly

linters:
# Use 'none' as default and explicitly enable linters
# Options: none, standard, all, fast
default: none

enable:
# Default/standard linters
- errcheck
- govet
- ineffassign
- staticcheck # includes gosimple and stylecheck
- unused

# Code style
- misspell
- unconvert
- unparam
- nakedret
- prealloc
- copyloopvar # replaces exportloopref in v2
- revive

settings:
misspell:
locale: US

nakedret:
max-func-lines: 30

revive:
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: increment-decrement
- name: var-naming
- name: var-declaration
- name: package-comments
- name: range
- name: receiver-naming
- name: time-naming
- name: unexported-return
- name: indent-error-flow
- name: errorf

# Exclusions configuration (v2 style)
exclusions:
# Use presets for common exclusions
# Options: comments, std-error-handling, common-false-positives, legacy
presets:
- comments
- std-error-handling

# Generated files handling: strict, lax, or disable
generated: strict

rules:
# Exported type names that stutter (e.g., grpc.GRPCServer) cannot be renamed
# without breaking external consumers of this SDK.
- linters: [revive]
text: "exported: type name will be used as"
# Exported functions returning unexported types are part of the public API
# and cannot be changed without breaking external consumers.
- linters: [revive]
text: "unexported-return: exported func"
# Package names (common, utils, util) cannot be renamed without breaking
# import paths for external consumers.
- linters: [revive]
text: "avoid meaningless package names"

# Paths to exclude from all linting
paths:
- _test\.go
- ^e2e/
- zz_generated\.deepcopy\.go

# Formatters are separate from linters in v2
formatters:
enable:
- gofmt
- goimports

settings:
goimports:
local-prefixes: open-cluster-management.io
Loading
Loading