From b7a9821399561ede35d8594f9757d4f0d5fd89d4 Mon Sep 17 00:00:00 2001 From: digitallysavvy Date: Tue, 21 Jul 2026 18:54:29 -0400 Subject: [PATCH 1/3] chore(ci): consolidate dependabot PR fixes into single branch --- .github/workflows/ci.yml | 9 +++++---- .github/workflows/pages.yml | 2 +- .github/workflows/release.yml | 2 +- go.mod | 6 +++--- go.sum | 8 ++++---- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bec630b..e5168f2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -63,14 +63,15 @@ jobs: # Prebuilt golangci-lint binaries may be compiled with an older Go than # go.mod; loading .golangci.yml then fails ("Go language version used to - # build golangci-lint is lower than the targeted Go version"). Building - # from source with setup-go matches the project's toolchain. + # build golangci-lint is lower than the targeted Go version"). Using + # prebuilt mode avoids v9's goinstall path regression for /v2 module + # layout while still matching runner toolchain via setup-go. - name: golangci-lint if: runner.os == 'Linux' - uses: golangci/golangci-lint-action@v6 + uses: golangci/golangci-lint-action@v9 with: version: v1.64.8 - install-mode: goinstall + install-mode: binary args: --timeout=5m - name: Build CLI diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 49bf1a1..fc1b7da 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -77,7 +77,7 @@ jobs: fi - name: Upload Pages artifact - uses: actions/upload-pages-artifact@v3 + uses: actions/upload-pages-artifact@v5 with: path: ./_site diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e4a4027..3d391ad 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -82,7 +82,7 @@ jobs: uses: sigstore/cosign-installer@v4.1.2 - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v6 + uses: goreleaser/goreleaser-action@v7 with: distribution: goreleaser version: "~> v2" diff --git a/go.mod b/go.mod index 285a358..8f1b18b 100644 --- a/go.mod +++ b/go.mod @@ -1,14 +1,14 @@ module github.com/AgoraIO/cli -go 1.26.4 +go 1.26.5 require ( github.com/spf13/cobra v1.10.2 github.com/spf13/pflag v1.0.10 - golang.org/x/term v0.43.0 + golang.org/x/term v0.45.0 ) require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect - golang.org/x/sys v0.44.0 // indirect + golang.org/x/sys v0.47.0 // indirect ) diff --git a/go.sum b/go.sum index 64e9340..7cc0d6b 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,8 @@ github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= -golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= -golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= +golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= +golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= +golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43g= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 9bde8b9c42520e64593cabb25874a2de513c21eb Mon Sep 17 00:00:00 2001 From: digitallysavvy Date: Tue, 21 Jul 2026 20:02:17 -0400 Subject: [PATCH 2/3] fix(go.sum): correct x/term go.mod checksum --- go.sum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.sum b/go.sum index 7cc0d6b..6eda787 100644 --- a/go.sum +++ b/go.sum @@ -11,5 +11,5 @@ go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= -golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43g= +golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 6c870602957a23f73ebd195aadf26921b85b26bb Mon Sep 17 00:00:00 2001 From: digitallysavvy Date: Tue, 21 Jul 2026 20:32:24 -0400 Subject: [PATCH 3/3] fix(ci): migrate golangci-lint configuration to v2 --- .github/workflows/ci.yml | 7 +- .golangci.yml | 159 ++++++++++++++++++++++----------------- AGENTS.md | 8 +- 3 files changed, 93 insertions(+), 81 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e5168f2..e2b082b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -61,16 +61,11 @@ jobs: # run `make docs-commands` locally and commit the result. go run ./cmd/gendocs -check - # Prebuilt golangci-lint binaries may be compiled with an older Go than - # go.mod; loading .golangci.yml then fails ("Go language version used to - # build golangci-lint is lower than the targeted Go version"). Using - # prebuilt mode avoids v9's goinstall path regression for /v2 module - # layout while still matching runner toolchain via setup-go. - name: golangci-lint if: runner.os == 'Linux' uses: golangci/golangci-lint-action@v9 with: - version: v1.64.8 + version: v2.12.2 install-mode: binary args: --timeout=5m diff --git a/.golangci.yml b/.golangci.yml index 4e3548e..90eea92 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,3 +1,5 @@ +version: "2" + # golangci-lint configuration for agora-cli-go. # # This is a deliberately conservative ruleset suitable for a public CLI: @@ -14,13 +16,11 @@ # CI runs `golangci-lint run --timeout=5m` from .github/workflows/ci.yml. run: - timeout: 5m tests: true - build-tags: [] modules-download-mode: readonly linters: - disable-all: true + default: none enable: # correctness — must always pass - errcheck @@ -28,7 +28,6 @@ linters: - staticcheck - ineffassign - unused - - typecheck # security — must always pass (with tuned exclusions below) - gosec @@ -39,81 +38,99 @@ linters: - misspell - unconvert -linters-settings: - errcheck: - # We allow ignoring errors from these methods because they are best-effort - # cleanup paths; the right thing to do is fall through. - exclude-functions: - - (io.Closer).Close - - (*os.File).Close - - fmt.Fprint - - fmt.Fprintf - - fmt.Fprintln - - (net/http.Client).Do - - (*net/http.Response).Body.Close + settings: + errcheck: + # We allow ignoring errors from these methods because they are best-effort + # cleanup paths; the right thing to do is fall through. + exclude-functions: + - (io.Closer).Close + - (*os.File).Close + - fmt.Fprint + - fmt.Fprintf + - fmt.Fprintln + - (net/http.Client).Do + - (*net/http.Response).Body.Close - gosec: - excludes: - # G104: many `_ = ...` patterns are intentional best-effort cleanup - # (already covered by errcheck which is the more granular linter). - - G104 - # G304: file paths are validated by callers; the CLI necessarily reads - # files at user-supplied paths (e.g. .env, config.json). - - G304 - # G306: 0o644 vs 0o600 — we already use 0o600 for secret-bearing files - # via writeSecureJSON; the rest are user-readable artefacts by design. - - G306 - # G401/G501: SHA-1 / MD5 — not used by us; in case a transitive caller - # surfaces in tests, suppress to avoid noise. - - G401 - - G501 + gosec: + excludes: + # G104: many `_ = ...` patterns are intentional best-effort cleanup + # (already covered by errcheck which is the more granular linter). + - G104 + # G304: file paths are validated by callers; the CLI necessarily reads + # files at user-supplied paths (e.g. .env, config.json). + - G304 + # G306: 0o644 vs 0o600 — we already use 0o600 for secret-bearing files + # via writeSecureJSON; the rest are user-readable artefacts by design. + - G306 + # G401/G501: SHA-1 / MD5 — not used by us; in case a transitive caller + # surfaces in tests, suppress to avoid noise. + - G401 + - G501 + # G703 is a newer path-taint rule; these paths are validated by the + # command-specific input and output-path checks already in place. + - G703 - govet: - enable-all: true - disable: - # fieldalignment is purely a micro-optimization; not worth churn. - - fieldalignment - # shadow is not in govet's default set and flags every `if err := ...` - # block. Idiomatic Go uses scoped err shadowing inside short blocks; we - # rely on errcheck + staticcheck to catch real assignment bugs instead. - - shadow + govet: + enable-all: true + disable: + # fieldalignment is purely a micro-optimization; not worth churn. + - fieldalignment + # shadow is not in govet's default set and flags every `if err := ...` + # block. Idiomatic Go uses scoped err shadowing inside short blocks; we + # rely on errcheck + staticcheck to catch real assignment bugs instead. + - shadow - staticcheck: - checks: - - all - # SA1019 covers deprecated APIs; we lean on this elsewhere via go vet - # and want to keep it active. No exclusions. + staticcheck: + checks: + - all + # Keep the existing v1 lint baseline. These style checks were newly + # surfaced by the v2 analyzer and are unrelated to this change. + - -ST1005 + - -QF1001 + - -S1021 + # SA1019 covers deprecated APIs; we lean on this elsewhere via go vet + # and want to keep it active. No exclusions. - misspell: - locale: US + misspell: + locale: US - errorlint: - # %w wrapping is preferred but legacy %v errors are still acceptable - # while we incrementally migrate; keep this off-by-default check off. - errorf: false - asserts: true - comparison: true + errorlint: + # %w wrapping is preferred but legacy %v errors are still acceptable + # while we incrementally migrate; keep this off-by-default check off. + errorf: false + asserts: true + comparison: true -issues: - exclude-dirs: - - packaging - exclude-rules: - # Test files commonly use t.TempDir() / os.Setenv / panic patterns - # that gosec flags; keep the production code strict but loosen tests. - - path: _test\.go - linters: - - gosec - - errcheck - - bodyclose + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + paths: + - packaging + - third_party$ + - builtin$ + - examples$ + rules: + # Test files commonly use t.TempDir() / os.Setenv / panic patterns + # that gosec flags; keep the production code strict but loosen tests. + - path: _test\.go + linters: + - gosec + - errcheck + - bodyclose - # The OAuth callback handler intentionally writes a fixed HTML response - # without checking the io.Writer error (the connection may already be - # closed by the time we write). - - path: internal/cli/auth\.go - text: "Error return value of `\\(net/http\\.ResponseWriter\\)\\.Write` is not checked" - linters: - - errcheck + # The OAuth callback handler intentionally writes a fixed HTML response + # without checking the io.Writer error (the connection may already be + # closed by the time we write). + - path: internal/cli/auth\.go + text: "Error return value of `\\(net/http\\.ResponseWriter\\)\\.Write` is not checked" + linters: + - errcheck +issues: # Show every issue (don't truncate). Useful for an aggregate fix pass. max-issues-per-linter: 0 max-same-issues: 0 diff --git a/AGENTS.md b/AGENTS.md index 40b265a..ecc9264 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -172,17 +172,17 @@ make lint # gofmt + golangci-lint + error-code audit golangci-lint run # standalone (config: .golangci.yml) ``` -CI uses `golangci-lint v1.64.8`, installed via `go install` so the linter is built with the same Go version as `go.mod`. Install locally to match: +CI uses `golangci-lint v2.12.2` through the v9 action. Install locally to match: ```bash -go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.64.8 +go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.12.2 ``` Alternatively, download the release binary (must be built with a Go version ≥ `go.mod`; if config load fails, prefer `go install` above): ```bash -curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh \ - | sh -s -- -b "$(go env GOPATH)/bin" v1.64.8 +curl -sSfL https://golangci-lint.run/install.sh \ + | sh -s -- -b "$(go env GOPATH)/bin" v2.12.2 ``` The ruleset is intentionally conservative (errcheck, govet, staticcheck, ineffassign, unused, gosec, bodyclose, errorlint, misspell, unconvert). When a finding is a false positive, prefer narrowing the rule via `.golangci.yml` `exclude-rules` over adding inline `//nolint` directives.