Skip to content

ci: add golangci-lint + actionlint as PR gates#370

Merged
kotakanbe merged 3 commits intomainfrom
ci/lint-setup
May 4, 2026
Merged

ci: add golangci-lint + actionlint as PR gates#370
kotakanbe merged 3 commits intomainfrom
ci/lint-setup

Conversation

@kotakanbe
Copy link
Copy Markdown
Member

@kotakanbe kotakanbe commented May 2, 2026

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.yml changes.
  • .github/workflows/lint.yml — actionlint gate on workflow / composite-action changes (catches GitHub Actions specific issues + shellcheck-detectable bash issues in run: blocks).

Deliberately deferred to follow-up PRs

linter reason suggested follow-up
gosec full scan reports 8 findings on existing code that warrant project-owner triage before suppressing or fixing enable in a follow-up PR after each finding gets a proper #nosec annotation with justification
revive exported-symbol godoc backfill is single-purpose work better reviewed on its own enable after godoc backfill
depguard domain/ MUST NOT import application//infrastructure//interfaces//pkg/ per .claude/rules/ddd-architecture.md. depguard can express this deterministically, but the rule set deserves owner review before going live enable in a follow-up PR

gosec findings (require triage)

cmd/uzomuzo/commands.go:276                            G204 exec.CommandContext with variable
                                                            (likely false positive — dietBin appears configured)
internal/domain/licenses/generator/main.go:37,73       G304 ReadFile
                                                            (build-time generator, controlled paths)
internal/domain/licenses/generator/main.go:146         G306 WriteFile 0o644
                                                            (generator output, source-file permissions)
internal/infrastructure/treesitter/lang_python.go:287  G115 uint→uint32 conversion
                                                            (tree-sitter API contract)
scripts/update-doc-examples/main.go:102                G304 ReadFile (build script)
scripts/update-doc-examples/main.go:182,201            G306 WriteFile 0o644 (build script)

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:

reviewdog/action-actionlint and golangci/golangci-lint-action SHA pins match those projects.

Verification (local)

golangci-lint run ./...                          # 0 issues
actionlint .github/workflows/{lint,go-lint}.yml  # 0 findings
go build ./...                                   # clean

Test plan

  • This PR's own go-lint / actionlint jobs pass.
  • paths filter works (e.g. a README-only PR does not trigger go-lint).
  • Follow-up PR enables gosec after the 8 findings are triaged with #nosec annotations.
  • Follow-up PR enables revive once godoc is backfilled.
  • Follow-up PR enables depguard with the DDD layer rules.

🤖 Generated with Claude Code

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
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 を追加

Comment thread .github/workflows/go-lint.yml
Comment thread .github/workflows/go-lint.yml
Comment thread .github/workflows/go-lint.yml
Comment thread .github/workflows/go-lint.yml
Comment thread .github/workflows/lint.yml
@kotakanbe
Copy link
Copy Markdown
Member Author

@claude Follow the procedure in .github/prompts/review.prompt.md with --copilot-only mode for this PR.

Phase 2: Resolve all unresolved Copilot review threads (discover → classify → fix → build/test/lint → commit/push → reply/resolve).
Phase 3: Detect recurring patterns from FIX-classified comments, propose and apply coding rules to .github/instructions/, then run make sync-instructions.
Phase 4: Post a summary comment on this PR.

@kotakanbe
Copy link
Copy Markdown
Member Author

kotakanbe commented May 2, 2026

Claude finished @kotakanbe's task in 7m 46s —— View job


Review Summary

Copilot Resolution — PR #370

# File Classification Action
1 go-lint.yml:9 FIX **.go**/*.go — standard doublestar glob; requires manual fix (workflow file)
2 go-lint.yml:16 FIX Same as #1 (push trigger)
3 go-lint.yml:12 WONT_FIX Known overlap with ci.yml lint job — descope in follow-up
4 go-lint.yml:44 FIX version: latest → pin explicit version for deterministic CI; requires manual fix
5 lint.yml:25 FIX Add checks: write for github-pr-check reporter; requires manual fix

Commits: (none — all FIX items target .github/workflows/ which GitHub App permissions cannot modify)
Threads resolved: 5/5

Owner action needed: Apply fixes #1, #2, #4, #5 manually. Suggested diff:

  • go-lint.yml: Change '**.go''**/*.go' in both pull_request and push path filters; change version: latestversion: "2.2.1" (or current stable)
  • lint.yml: Add checks: write to the actionlint job permissions block

Rules Learned

Pattern Status Detail
ci-path-filters Accumulated (1/2) Use **/*.ext not **.ext in GH Actions path filters
dependency-pinning Accumulated (1/2) Pin CI tool binary versions, not just action SHAs
ci-permissions Accumulated (1/2) Verify reporter actions have required permissions

Commit: e9f747e — 3 new pending patterns recorded, no promotions this cycle


| Branch ci/lint-setup

- 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>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comment thread .github/workflows/go-lint.yml
Comment thread .github/workflows/go-lint.yml
Comment thread .github/workflows/go-lint.yml
Comment thread .github/workflows/lint.yml
@kotakanbe
Copy link
Copy Markdown
Member Author

@claude Follow the procedure in .github/prompts/review.prompt.md with --copilot-only mode for this PR.

Phase 2: Resolve all unresolved Copilot review threads (discover → classify → fix → build/test/lint → commit/push → reply/resolve).
Phase 3: Detect recurring patterns from FIX-classified comments, propose and apply coding rules to .github/instructions/, then run make sync-instructions.
Phase 4: Post a summary comment on this PR.

@kotakanbe
Copy link
Copy Markdown
Member Author

kotakanbe commented May 2, 2026

Claude finished @kotakanbe's task in 9m 38s —— View job


Review Summary

Copilot Resolution — PR #370

4 unresolved threads from Copilot's second review round (same issues as the first round, which was already resolved):

# File Classification Action
1 go-lint.yml:16 FIX **.go**/*.go in pull_request paths — requires manual push (PAT lacks workflow scope)
2 go-lint.yml:16 FIX Same fix for push trigger paths
3 go-lint.yml:44 FIX version: latestversion: "2.11.4" (latest stable, released 2026-03-22)
4 lint.yml:27 FIX Add checks: write to actionlint job permissions

Commits: (none — all FIX items target .github/workflows/ which requires workflow PAT scope)
Threads resolved: 4/4

Owner action needed: Apply these fixes manually and push:

# .github/workflows/go-lint.yml — lines 9 and 16
-      - '**.go'
+      - '**/*.go'

# .github/workflows/go-lint.yml — line 44
-          version: latest
+          version: "2.11.4"

# .github/workflows/lint.yml — after line 27
       pull-requests: read
+      checks: write

Rules Learned

Pattern Status Detail
defensive-coding Promotedcopilot-learned-coding.instructions.md 4 entries across PRs #345, #366 — use dedicated predicates and full renderers for sentinel/composed values
ci-path-filters Accumulated (1/2) Use **/*.ext not **.ext in GH Actions path filters
dependency-pinning Accumulated (1/2) Pin CI tool binary versions, not just action SHAs
ci-permissions Accumulated (1/2) Verify reporter actions have required permissions

Commit: 3fcc3af — 1 promotion (defensive-coding: 4 entries → 1 rule), 0 new pending patterns (duplicates of existing PR #370 entries from prior run)

--- | Branch ci/lint-setup

- Promote defensive-coding (PRs #345, #366) to rule: use dedicated
  predicates and full renderers for sentinel/composed values
- Remove 4 promoted entries from pending_patterns

Co-authored-by: Kota Kanbe <kotakanbe@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comment thread .github/workflows/go-lint.yml
Comment thread .github/workflows/go-lint.yml
Comment thread .github/workflows/go-lint.yml
Comment thread .github/workflows/lint.yml
@kotakanbe
Copy link
Copy Markdown
Member Author

@claude Follow the procedure in .github/prompts/review.prompt.md with --copilot-only mode for this PR.

Phase 2: Resolve all unresolved Copilot review threads (discover → classify → fix → build/test/lint → commit/push → reply/resolve).
Phase 3: Detect recurring patterns from FIX-classified comments, propose and apply coding rules to .github/instructions/, then run make sync-instructions.
Phase 4: Post a summary comment on this PR.

@kotakanbe
Copy link
Copy Markdown
Member Author

kotakanbe commented May 2, 2026

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):

# File Classification Action
1 go-lint.yml:16 FIX **.go**/*.go in pull_request paths — requires manual fix (workflow file)
2 go-lint.yml:16 FIX Same fix for push trigger paths
3 go-lint.yml:44 FIX version: latest → pin explicit version (e.g., "2.11.4")
4 lint.yml:25 FIX Add checks: write to actionlint job permissions

Commits: (none — all FIX items target .github/workflows/ which GitHub App permissions cannot modify)
Threads resolved: 4/4

Owner action needed: Apply these fixes manually and push:

# .github/workflows/go-lint.yml — lines 9 and 16
-      - '**.go'
+      - '**/*.go'

# .github/workflows/go-lint.yml — line 44
-          version: latest
+          version: "2.11.4"

# .github/workflows/lint.yml — after line 27
       pull-requests: read
+      checks: write

Rules Learned

Pattern Status Detail
ci-path-filters Accumulated (1/2) Use **/*.ext not **.ext in GH Actions path filters
dependency-pinning Accumulated (1/2) Pin CI tool binary versions, not just action SHAs
ci-permissions Accumulated (1/2) Verify reporter actions have required permissions

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).
| Branch ci/lint-setup

@kotakanbe kotakanbe merged commit 4fc523e into main May 4, 2026
26 of 29 checks passed
@kotakanbe kotakanbe deleted the ci/lint-setup branch May 4, 2026 19:01
kotakanbe added a commit that referenced this pull request May 4, 2026
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>
kotakanbe added a commit that referenced this pull request May 4, 2026
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants