ci: add golangci-lint + actionlint as PR gates#370
Conversation
CI currently builds and tests but no static lint runs as a merge gate.
This PR adds two minimal lint workflows:
1. .golangci.yml + .github/workflows/go-lint.yml — golangci-lint v2
on Go-source PRs. Initial set: errcheck, govet, ineffassign,
staticcheck, unused. Runs cleanly on the current codebase.
2. .github/workflows/lint.yml — actionlint on workflow YAML PRs.
Catches GitHub Actions specific issues plus shellcheck-detectable
bash issues in run: blocks.
Deferred to follow-up PRs (so this one merges cleanly):
- gosec: 8 findings on existing code need owner triage before fixing
or suppressing (most look like false positives in build-time
generators / scripts). See PR description for the list.
- revive (exported godoc): backfill is single-purpose work better
reviewed on its own.
- depguard for DDD layers (domain MUST NOT import application/...):
rule design deserves owner review before going live.
Workflow details:
- paths filter so docs-only PRs don't trigger unrelated lint runs
- All actions SHA-pinned (golangci-lint-action v9.2.0,
reviewdog/action-actionlint v1.72.0, actions/checkout v6.0.2,
actions/setup-go v6.4.0)
- permissions: minimal (contents/pull-requests read only)
Verified locally:
golangci-lint run ./... # 0 issues
actionlint .github/workflows/{lint,go-lint}.yml # 0 findings
go build ./... # clean
There was a problem hiding this comment.
Pull request overview
CI に lint gate を追加し、PR 時に Go コードは golangci-lint、GitHub Actions は actionlint で検査できるようにする変更です。
Changes:
.golangci.ymlを追加し、golangci-lint のベースライン設定を導入- Go 変更時に golangci-lint を実行する
.github/workflows/go-lint.ymlを追加 - workflow/composite action 変更時に actionlint を実行する
.github/workflows/lint.ymlを追加
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
.golangci.yml |
golangci-lint の有効化リンターと除外ルールを追加 |
.github/workflows/go-lint.yml |
Go 変更をトリガに golangci-lint を走らせる gate を追加 |
.github/workflows/lint.yml |
Actions 定義変更をトリガに actionlint を走らせる gate を追加 |
|
@claude Follow the procedure in Phase 2: Resolve all unresolved Copilot review threads (discover → classify → fix → build/test/lint → commit/push → reply/resolve). |
|
Claude finished @kotakanbe's task in 7m 46s —— View job Review SummaryCopilot Resolution — PR #370
Commits: (none — all FIX items target
Rules Learned
Commit: |
- Record 3 new pattern(s) from PR #370 (ci-path-filters, dependency-pinning, ci-permissions) - No promotions this cycle (new categories below 2-PR threshold) Co-authored-by: Kota Kanbe <kotakanbe@users.noreply.github.com>
|
@claude Follow the procedure in Phase 2: Resolve all unresolved Copilot review threads (discover → classify → fix → build/test/lint → commit/push → reply/resolve). |
|
Claude finished @kotakanbe's task in 9m 38s —— View job Review SummaryCopilot Resolution — PR #3704 unresolved threads from Copilot's second review round (same issues as the first round, which was already resolved):
Commits: (none — all FIX items target
Rules Learned
Commit: --- | Branch |
|
@claude Follow the procedure in Phase 2: Resolve all unresolved Copilot review threads (discover → classify → fix → build/test/lint → commit/push → reply/resolve). |
|
Claude finished @kotakanbe's task in 3m 11s —— View job Copilot Resolution — PR #370 (Round 3)4 unresolved threads from Copilot's third review round (same issues as rounds 1 and 2, already recorded as pending patterns):
Commits: (none — all FIX items target
Rules Learned
No new pending patterns recorded (all 4 threads are duplicates of existing PR #370 entries from prior rounds). No promotions this cycle (no category has 2+ entries across different PRs). |
Reworked from the original "create lint.yml" form (#373 v1) to a modification of the existing lint.yml that #370 introduced. Functional changes vs. main: 1. permissions: + `checks: write` — required for reviewdog's `github-pr-check` reporter to publish inline annotations via the Checks API. Without it, findings only show up in the run log, not on the PR diff (silent degradation). 2. paths filter: `.github/actions/**` → `.github/actionlint.yaml`. actionlint's default invocation does NOT lint composite actions under `.github/actions/`, so the previous filter triggered the workflow on changes that never affected lint output. The new filter tracks the actionlint config (which DOES affect lint results). 3. Documentation: caveats around `set -euo pipefail` × `$(... | jq ...)` exit-propagation gaps, composite-action coverage, and per-setting rationale. Synced from `vuls-saas/vuls-reach` PR #9. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…373) Reworked from the original "create lint.yml" form (#373 v1) to a modification of the existing lint.yml that #370 introduced. Functional changes vs. main: 1. permissions: + `checks: write` — required for reviewdog's `github-pr-check` reporter to publish inline annotations via the Checks API. Without it, findings only show up in the run log, not on the PR diff (silent degradation). 2. paths filter: `.github/actions/**` → `.github/actionlint.yaml`. actionlint's default invocation does NOT lint composite actions under `.github/actions/`, so the previous filter triggered the workflow on changes that never affected lint output. The new filter tracks the actionlint config (which DOES affect lint results). 3. Documentation: caveats around `set -euo pipefail` × `$(... | jq ...)` exit-propagation gaps, composite-action coverage, and per-setting rationale. Synced from `vuls-saas/vuls-reach` PR #9. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
CI currently runs build / test but no static lint as a merge gate. This PR adds two minimal lint workflows.
Changes
.golangci.yml— golangci-lint v2 baseline (errcheck, govet, ineffassign, staticcheck, unused). Runs cleanly on the current codebase (0 issues)..github/workflows/go-lint.yml— golangci-lint gate on Go source /go.mod/.golangci.ymlchanges..github/workflows/lint.yml— actionlint gate on workflow / composite-action changes (catches GitHub Actions specific issues + shellcheck-detectable bash issues inrun:blocks).Deliberately deferred to follow-up PRs
#nosecannotation with justificationdomain/MUST NOT importapplication//infrastructure//interfaces//pkg/per.claude/rules/ddd-architecture.md. depguard can express this deterministically, but the rule set deserves owner review before going livegosec findings (require triage)
Most look like false positives in build-time generators / scripts or use controlled inputs, but each warrants an explicit
// #nosec G2XX -- <reason>annotation rather than a blanket exclude.Pattern alignment
Sibling projects use the same pattern:
vuls-saas/vuls-reachPR chore: add branch protection policy to git workflow rules #9 (actionlint) and refactor: migrate CLI from stdlib flag to urfave/cli v3 #10 (golangci-lint).reviewdog/action-actionlintandgolangci/golangci-lint-actionSHA pins match those projects.Verification (local)
Test plan
go-lint/actionlintjobs pass.pathsfilter works (e.g. a README-only PR does not triggergo-lint).gosecafter the 8 findings are triaged with#nosecannotations.reviveonce godoc is backfilled.depguardwith the DDD layer rules.🤖 Generated with Claude Code