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
10 changes: 8 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,17 @@ jobs:
cache: true

- name: golangci-lint
uses: golangci/golangci-lint-action@v6
uses: golangci/golangci-lint-action@v8
with:
# Pin golangci-lint to a version built against Go >= 1.24.
# When go.mod's `go` directive advances, bump this accordingly.
version: v1.64.8
#
# We track the v2 line (.golangci.yml targets the v2 schema
# via `version: "2"`). v2.12.2 matches the version Homebrew
# currently installs, so a contributor's local `make lint`
# result agrees byte-for-byte with CI. See #62 for why the
# v1 line was abandoned.
version: v2.12.2
args: --timeout=5m

- name: commitlint
Expand Down
130 changes: 83 additions & 47 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,86 +3,122 @@
# We run golangci-lint with this file in CI (see .github/workflows/ci.yml)
# and recommend developers run it locally via `make lint`.
#
# The defaults below are intentionally pragmatic:
# This file targets the v2 schema (`version: "2"`). The migration from
# v1 was done with `golangci-lint migrate` (see #62); the manually
# written comments below describe the lint set and exclusions.
#
# Linter set (linters.enable):
# - errcheck: catches unchecked errors. We treat these as bugs.
# - govet: standard static checks.
# - staticcheck: a curated set of additional checks (formerly part of
# honnef.co/go/tools).
# honnef.co/go/tools). gosimple was folded into staticcheck in v2.
# - unused: catches unused vars/funcs/types.
# - gosimple: suggests simplifications.
# - ineffassign: catches assignments whose result is never used.
# - gocritic: opinionated extra checks (kept light to avoid noise).
# - gofmt / goimports: format consistency.
# - misspell: catches common spelling mistakes (US locale).
# - bodyclose: catches http.Body that wasn't Close()'d.
# - contextcheck: catches ctx not flowing through call chains.
#
# Formatters (formatters.enable): gofmt + goimports. The latter has
# `local-prefixes: github.com/dipto0321/nodeup` so goimports orders
# that path first in import blocks.
#
# Linters we DELIBERATELY do not enable yet:
# - revive / golint: superseded by staticcheck's style checks.
# - stylecheck: too noisy at this stage.
# - exhaustive: useful but noisy for switch statements over manager names.
# - funlen / cyclomatic: more useful once the code has stabilized.

version: "2"

run:
timeout: 5m
tests: true

linters:
disable-all: true
default: none
enable:
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
- unused
- gofmt
- goimports
- ineffassign
- gocritic
- misspell
- bodyclose
- contextcheck
settings:
gocritic:
enabled-tags:
- diagnostic
- style
- performance
disabled-checks:
- ifElseChain # too noisy on early-return patterns
- hugeParam # not relevant yet
misspell:
locale: US
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
rules:
# errcheck / gocritic on test helpers — unchecked errors and
# opinionated suggestions are fine in tests.
- path: _test\.go
linters:
- errcheck
- gocritic
# Windows-only symbols appear unused on linux runners.
- path: internal/detector/.*_windows\.go
linters:
- unused
# Cross-file calls via root.go registration — upgrade.go's
# init symbols are referenced from root.go, not from
# anything in the same file.
- path: internal/cli/upgrade\.go
linters:
- unused
paths:
- docs
- dist
- vendor
- nodeup-npm
- third_party$
- builtin$
- examples$

linters-settings:
gocritic:
enabled-tags:
- diagnostic
- style
- performance
disabled-checks:
- ifElseChain # too noisy on early-return patterns
- hugeParam # not relevant yet
misspell:
locale: US
goimports:
local-prefixes: github.com/dipto0321/nodeup
formatters:
enable:
- gofmt
- goimports
settings:
goimports:
local-prefixes:
- github.com/dipto0321/nodeup
exclusions:
generated: lax
paths:
- docs
- dist
- vendor
- nodeup-npm
- third_party$
- builtin$
- examples$

issues:
# Don't bail out on first failure — show all problems.
max-issues-per-linter: 0
max-same-issues: 0
# Skip auto-generated / vendored / build-output directories.
# In v1.64.x the `run.exclude-dirs` key was removed from the run-schema
# and consolidated here as `issues.exclude-dirs`.
exclude-dirs:
- docs
- dist
- vendor
- nodeup-npm
# Exclude generated files from lint checks.
exclude-rules:
- path: _test\.go
linters:
- errcheck # unchecked errors in test helpers are fine
- gocritic
- path: internal/detector/.*_windows\.go
linters:
- unused # windows-only symbols appear unused on linux runners
- path: internal/cli/upgrade\.go
linters:
- unused # cross-file calls via root.go registration

# Output configuration.
# Output configuration. v2's `output.formats` is a MAP (not a list
# like v1) — see #62 for the v1→v2 schema migration.
output:
formats:
- format: colored-line-number
text:
path: stdout
print-issued-lines: true
print-linter-name: true
print-issued-lines: true
print-linter-name: true
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
for the full rationale.

### Fixed
- `.golangci.yml` / `Makefile` / `.github/workflows/ci.yml`:
migrated to the golangci-lint **v2** schema. The pre-fix file
targeted the v1 schema (no `version:` field, flat
`linters.enable`, `output.formats` as a slice), but the
Makefile told contributors to `brew install golangci-lint` —
which installs the current major version, v2.x, today. Any
contributor with a current Homebrew got
`Error: can't load config: ... 'output.formats' expected a
map, got 'slice'` instead of a lint failure, blocking
`make lint` and `make ci` end-to-end. CI was unaffected
because `golangci-lint-action@v6` pinned to `version:
v1.64.8`, but the local dev workflow documented in the
Makefile was effectively broken. We migrated with
`golangci-lint migrate` (preserving the original
exclusions/presets/rationale in hand-written comments),
bumped CI to `golangci/lint-action@v8` pinned to
`v2.12.2` (matching what Homebrew ships today), and updated
the Makefile `lint` target to refuse to run when
golangci-lint isn't installed and point contributors at
the exact `go install` command matching the CI pin. The
same lint set + exclusion rules + presets that v1 ran
with still apply (`bodyclose`, `contextcheck`, `errcheck`,
`gocritic`, `govet`, `ineffassign`, `misspell`,
`staticcheck`, `unused`; `gosimple` is folded into
`staticcheck` in v2; formatters `gofmt` + `goimports`
with `local-prefixes: github.com/dipto0321/nodeup`).
Confirmed locally: `make ci` is now green on a Homebrew
v2.12.2 install. Closes #62.
- `internal/detector/n.go`: `N.Current()` no longer shells out
to `n current` — an undocumented subcommand that upstream
`tj/n` resolves as a label equivalent to "latest" and
Expand Down
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,14 @@ test: ## Run unit tests with race + coverage
@echo "Coverage report: $(COVERAGE_HTML)"

.PHONY: lint
lint: ## Run golangci-lint (must be installed: brew install golangci-lint)
lint: ## Run golangci-lint (must match .github/workflows/ci.yml's pinned version)
@if ! command -v golangci-lint >/dev/null 2>&1; then \
echo "golangci-lint not installed."; \
echo "Install the version pinned in .github/workflows/ci.yml with:"; \
echo " go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.12.2"; \
echo "(or update both this Makefile and ci.yml together when bumping)."; \
exit 1; \
fi
golangci-lint run ./...

.PHONY: fmt
Expand Down
Loading