Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
7 changes: 7 additions & 0 deletions ci/OWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
approvers:
- qiujian16
- xuezhaojun

reviewers:
- qiujian16
- xuezhaojun
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