Skip to content

feat: add comprehensive Go repository support with monorepo detection#412

Open
natifridman wants to merge 3 commits intoambient-code:mainfrom
natifridman:golang
Open

feat: add comprehensive Go repository support with monorepo detection#412
natifridman wants to merge 3 commits intoambient-code:mainfrom
natifridman:golang

Conversation

@natifridman
Copy link
Copy Markdown
Contributor

Summary

  • Add Go-specific assessment logic to 6 assessors that previously returned not_applicable or used wrong language paths for Go repos
  • Add monorepo support for projects with go.mod in subdirectories (e.g., multi-service repos)
  • Fix primary language detection for mixed Go/Python repos using root manifest tiebreaker

Assessors extended

  • TestExecutionAssessor (T1, 10%): *_test.go detection, go test/coverage/race scoring, subdirectory Makefile scanning
  • TypeAnnotationsAssessor (T1, 8%): auto-pass for static typing, interface{}/any overuse penalty
  • StandardLayoutAssessor (T1, 5%): Go layout detection (go.mod, cmd/, internal/, pkg/) with monorepo aggregation
  • CyclomaticComplexityAssessor (T3, 3%): gocyclo tool + golangci-lint cyclop/gocyclo config detection in subdirs
  • StructuredLoggingAssessor (T3, 1.5%): zap/logrus/zerolog/slog detection across all go.mod files
  • InlineDocumentationAssessor (T2, 3%): godoc comment coverage on exported symbols, doc.go detection

Infrastructure

  • BaseAssessor._primary_language(): dispatches by file count with root manifest tiebreaker for mixed-language repos
  • BaseAssessor._find_go_module_roots(): finds go.mod at root and in one-level subdirectories
  • Go.arsrc: directory exclusion list for Go project layout detection
  • Bootstrap templates updated to Go 1.23/1.24, golangci-lint-action v6, added govulncheck
  • go vet added to CI typecheck patterns, enhanced gitignore patterns
  • _has_golangci_lint() searches module root dirs for .golangci.toml/.golangci.json variants

Real-world testing

Repository Before After Delta
opendatahub-io/models-as-a-service (Go monorepo) 40.9 Bronze 59.6 Bronze +18.7
opendatahub-io/opendatahub-operator (Go single-module) N/A 68.4 Silver
opendatahub-io/kserve (Go+Python mixed) 44.3 Bronze 52.9 Bronze +8.6

Test plan

  • 41 new Go-specific unit tests covering all assessors and monorepo patterns (tests/unit/test_assessors_go.py)
  • Full test suite passes: 1193 passed, 0 failed
  • Linting clean: black, isort, ruff check all pass
  • Tested against 3 real-world Go repositories (single-module, monorepo, mixed-language)
  • Existing Python/JS assessor paths unaffected (verified by existing test suite)

🤖 Generated with Claude Code

natifridman and others added 2 commits May 11, 2026 11:42
Add Go-specific assessment logic to 6 assessors that previously returned
not_applicable or used wrong language paths for Go repos. Includes monorepo
support for projects with go.mod in subdirectories (e.g., multi-service repos).

Assessors extended:
- TestExecutionAssessor: *_test.go detection, go test/coverage/race scoring
- TypeAnnotationsAssessor: auto-pass for static typing, interface{}/any penalty
- StandardLayoutAssessor: Go layout detection (go.mod, cmd/, internal/, pkg/)
- CyclomaticComplexityAssessor: gocyclo + golangci-lint cyclop detection
- StructuredLoggingAssessor: zap/logrus/zerolog/slog in go.mod and source
- InlineDocumentationAssessor: godoc comment coverage on exported symbols

Infrastructure:
- BaseAssessor._primary_language(): dispatches by file count for multi-lang repos
- BaseAssessor._find_go_module_roots(): finds go.mod at root and in subdirs
- Go.arsrc: directory exclusion list for Go projects
- Bootstrap templates updated to Go 1.23/1.24, golangci-lint-action v6, govulncheck
- go vet added to CI typecheck patterns, enhanced gitignore patterns

Tested against opendatahub-io/models-as-a-service (Go monorepo): score improved
from 40.9 to 59.6 (+18.7 points) with 6 previously-failing assessors now passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When file counts between two languages are within 30% of each other,
use root-level project manifests (go.mod, pyproject.toml, package.json)
as a tiebreaker to determine the primary language. This fixes repos like
Go Kubernetes operators with Python SDK subdirectories, where Python may
have slightly more files but Go owns the project root.

Tested against opendatahub-io/kserve (524 Go vs 597 Python files):
Go assessors now correctly fire instead of Python ones (+8.6 points).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 11, 2026

Warning

Rate limit exceeded

@natifridman has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 47 minutes and 40 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: a33127b2-1b7b-4171-963a-2afd3ffe4727

📥 Commits

Reviewing files that changed from the base of the PR and between bd5a68d and 7585cd9.

📒 Files selected for processing (7)
  • src/agentready/assessors/base.py
  • src/agentready/assessors/code_quality.py
  • src/agentready/assessors/documentation.py
  • src/agentready/assessors/structure.py
  • src/agentready/assessors/stub_assessors.py
  • src/agentready/assessors/testing.py
  • src/agentready/templates/bootstrap/go/workflows/security.yml.j2

Warning

.coderabbit.yaml has a parsing error

The CodeRabbit configuration file in this repository has a parsing error and default settings were used instead. Please fix the error(s) in the configuration file. You can initialize chat with CodeRabbit to get help with the configuration file.

💥 Parsing errors (1)
Validation error: String must contain at most 250 character(s) at "tone_instructions"
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Walkthrough

This PR adds comprehensive Go language support to the code quality assessment framework by introducing language detection and dispatch mechanisms, implementing Go-specific assessments for type safety, complexity, logging, layout, documentation, and testing, updating bootstrap workflow templates, and providing extensive test coverage across all new functionality.

Changes

Go Language Support Across Assessors

Layer / File(s) Summary
Language Detection & Selection
src/agentready/assessors/base.py
_primary_language() selects the primary language from candidates using repository.languages counts with root-manifest tiebreaker. _find_go_module_roots() locates Go module directories by scanning for go.mod. _LANG_ROOT_MANIFESTS maps language names to their characteristic root files.
Type Safety Assessment
src/agentready/assessors/code_quality.py (TypeAnnotationsAssessor)
assess() dispatches by primary language to Python or new _assess_go_types(). Go scoring counts func definitions and penalizes interface{}/any usage (excluding _test.go), returning pass/fail with remediation.
Complexity Assessment
src/agentready/assessors/code_quality.py (CyclomaticComplexityAssessor)
is_applicable() adds Go support. assess() dispatches to _assess_go_complexity() which prefers gocyclo output or searches module roots for golangci-lint configs enabling complexity linters; includes Go-specific remediation.
Logging Assessment
src/agentready/assessors/code_quality.py (StructuredLoggingAssessor)
assess() dispatches by primary language. _assess_go_logging() detects structured logging via go.mod dependency scan (zap, logrus, zerolog) and stdlib log/slog usage, returning pass/fail with Go remediation.
Code Smells Detection
src/agentready/assessors/code_quality.py (CodeSmellsAssessor)
_has_golangci_lint() expands to recognize .golangci.json and searches module roots via _find_go_module_roots() for config files.
Layout Validation
src/agentready/assessors/structure.py
assess() routes Go repositories to new _assess_go_layout(). Validates go.mod presence, scans module roots for standard directories (cmd/, internal/, pkg//api/), detects entrypoints and tests (via git ls-files with fallback), and generates Go-targeted remediation including go mod init commands.
Documentation Coverage
src/agentready/assessors/documentation.py
is_applicable() extends to Go. assess() dispatches between Python docstrings and new _assess_go_godoc(). Godoc assessment tracks exported symbols (func/type/var/const) with comment coverage vs. 80% threshold, detects doc.go package docs, excludes test files and private symbols.
Testing Assessment
src/agentready/assessors/testing.py
is_applicable() detects Go via _has_go_test_files() (finds *_test.go). assess() dispatches coverage by primary language. _assess_go_coverage() evaluates test presence, coverage flags, and -race detection from build files/CI workflows; includes Go remediation.
Dependency Pinning
src/agentready/assessors/stub_assessors.py
DependencyPinningAssessor now globs for */go.sum in subdirectories when root go.sum is missing, supporting monorepos.
Gitignore Patterns
src/agentready/assessors/stub_assessors.py
Expected patterns extended with Go-specific entries: bin/, cover.out, coverage.txt.
Go Project Configuration
src/agentready/data/Go.arsrc
Directory exclusion configuration for Go layout detection: vendor, testdata, docs, scripts, build output, CI, and hidden directories.
Bootstrap Workflow Templates
src/agentready/templates/bootstrap/go/workflows/tests.yml.j2
Go version matrix updated from 1.21, 1.22 to 1.23, 1.24. golangci-lint action bumped from v3 to v6. Coverage condition keyed to 1.24.
Security Workflow Template
src/agentready/templates/bootstrap/go/workflows/security.yml.j2
Go version updated to 1.24. Added govulncheck ./... step for vulnerability scanning.
Comprehensive Test Suite
tests/unit/test_assessors_go.py
Helper functions _make_go_repo() and _git_add() for Go repository setup. Test classes for each assessor (TestTestExecutionAssessorGo, TestTypeAnnotationsAssessorGo, TestStandardLayoutAssessorGo, TestCyclomaticComplexityAssessorGo, TestStructuredLoggingAssessorGo, TestInlineDocumentationAssessorGo, TestCodeSmellsAssessorGo, TestCIQualityGatesAssessorGo, TestGoMonorepoSupport) covering applicability, scoring, remediation, monorepo support, and integration scenarios.
Test Expectations
tests/unit/test_bootstrap_templates.py
Updated Go template test expectations for versions 1.23, 1.24.

Sequence Diagram

sequenceDiagram
    participant Caller
    participant Assessor
    participant LanguageSelector as Language<br/>Selector
    participant GoLogic as Go-Specific<br/>Logic
    participant Repository

    Caller->>Assessor: assess(repository)
    Assessor->>Repository: repository.languages
    Repository-->>Assessor: {'Python', 'Go', ...}
    
    Assessor->>LanguageSelector: _primary_language(repository, candidates)
    
    alt Has Root Manifest Tie-breaker
        LanguageSelector->>Repository: repository.path
        Repository-->>LanguageSelector: /path/to/repo
        LanguageSelector->>LanguageSelector: Check go.mod, setup.py existence
    end
    
    LanguageSelector-->>Assessor: 'Go'
    
    Assessor->>GoLogic: _assess_go_*(repository)
    
    alt Go Module Roots
        GoLogic->>Repository: _find_go_module_roots()
        Repository-->>GoLogic: [list of go.mod directories]
    end
    
    GoLogic->>GoLogic: Analyze Go sources, configs
    GoLogic-->>Assessor: Finding{score, evidence, remediation}
    
    Assessor-->>Caller: Finding
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add comprehensive Go repository support with monorepo detection' accurately and specifically summarizes the main changes in the pull request, which adds Go assessment logic and monorepo support across multiple assessors.
Description check ✅ Passed The description is well-structured, comprehensive, and directly related to the changeset. It clearly outlines the assessors extended, infrastructure changes, and provides real-world testing results demonstrating the impact of the changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 11, 2026

📈 Test Coverage Report

Branch Coverage
This PR 73.1%
Main 72.5%
Diff ✅ +0.6%

Coverage calculated from unit tests only

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 10

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/agentready/assessors/base.py`:
- Around line 125-137: _find_go_module_roots currently only checks one directory
level; change it to search recursively (e.g., use rglob or equivalent) for all
go.mod files under repository.path, skip any matches that live inside vendor
directories, and collect the parent directories as module roots; also keep the
repository root if it contains go.mod and dedupe the resulting list (use
Path.parent to get roots and filter out duplicates).
- Around line 109-123: _primary_language() is non-deterministic because it
iterates a set of candidate languages; make the tie-break deterministic by
ordering contenders before checking manifests: build a sorted list of (lang,
count) from lang_counts (sort by descending count then by language name) and
iterate that list (skip top_lang), apply the existing 0.7 closeness check, then
check manifests using self._LANG_ROOT_MANIFESTS for the contender and for
top_lang in a fixed order; return the chosen language accordingly so repeated
runs yield the same result.

In `@src/agentready/assessors/code_quality.py`:
- Around line 554-575: The fallback that returns a Passing Finding when any
.golangci.* file exists is unsafe; update the loop that iterates search_dirs and
config_name to actually parse the matched config file and verify complexity
linters (gocyclo, cyclop, gocognit) are enabled—specifically, read the config
contents, check for disable/disable-all entries and the linters/linters-settings
sections to ensure those linters are not explicitly disabled (or are present in
enabled linters); only then return the Finding with measured_value
"golangci-lint configured". If parsing fails or the file explicitly disables
those linters, do not return the pass Finding (instead return no Finding or a
neutral/failed Finding); keep references to repository.path, search_dirs,
config_name and the Finding construction (attribute=self.attribute) when
implementing this change.

In `@src/agentready/assessors/documentation.py`:
- Around line 1224-1254: The exported-symbol detection and doc-comment check are
wrong: update exported_pattern to also match exported methods with receivers
(e.g., change exported_pattern to allow an optional receiver group before the
name so it matches lines like "func (s *Server) Start()") and adjust the
documentation check so it only counts a preceding comment when it actually
begins with the symbol name (use prev_line.startswith(f"// {symbol_name}")
rather than accepting any "//" line); also handle preceding block comments (/*
... */) by examining the last non-empty previous token block and ensuring its
first line starts with the symbol name before incrementing documented_exported
(references: exported_pattern, symbol_name, documented_exported, total_exported,
the loop over go_files/lines).

In `@src/agentready/assessors/structure.py`:
- Around line 124-125: The current check "if 'Go' in repository.languages"
wrongly triggers Go layout when any Go file exists; change it to only choose the
Go assessor when Go is the repository's primary language (or otherwise wins the
tiebreaker). Update the conditional around the call to
self._assess_go_layout(repository) to inspect the repository's primary-language
field or tiebreaker result (e.g., repository.primary_language or a helper that
returns the dominant language) instead of membership in repository.languages so
mixed repos aren't misclassified.

In `@src/agentready/assessors/stub_assessors.py`:
- Around line 67-71: The check for Go monorepo lockfiles only searches one level
deep (repository.path.glob("*/go.sum")), missing nested modules like
services/auth/go.sum; update the search to recursively find go.sum files (use
repository.path.rglob("go.sum") or repository.path.glob("**/go.sum")) and append
their relative paths to found_strict (keep the existing break logic if you only
need the first hit), referencing the found_strict list and the
repository.path.glob usage in stub_assessors.py.

In `@src/agentready/assessors/testing.py`:
- Around line 414-421: The current scan only looks one level deep for module
build files; update the search to recursively scan the repo for nested
build/task files by replacing the one-level glob used when appending to
files_to_check (currently repository.path.glob("*/Makefile")) with a recursive
search (repository.path.rglob or glob with "**/Makefile"), and also add
recursive patterns for other common build/task filenames (e.g.,
Taskfile.yml/Taskfile.yaml and deeper Makefiles) so files_to_check collects
matches like services/**/Makefile and **/Taskfile.{yml,yaml}; keep using the
same files_to_check list and ci_dir logic for .github workflows but apply rglob
patterns for completeness.
- Around line 369-374: The coverage detection currently only matches
"-coverprofile" and "-covermode" so plain "go test -cover" is missed; update the
regex used to set has_coverage in testing.py (the expression that assigns
has_coverage from re.search) to also recognize plain "-cover" (and variants like
"-cover=", "-cover ./...") by including "-cover" as an alternative (e.g., make
the pattern match "-cover" or "-coverprofile" or "-covermode" with appropriate
word-boundary/optional suffix handling) so the block that increments score and
appends evidence correctly flags repos that use "go test -cover".

In `@src/agentready/templates/bootstrap/go/workflows/security.yml.j2`:
- Around line 24-27: Replace the unpinned installation of govulncheck in the
workflow step that runs "go install golang.org/x/vuln/cmd/govulncheck@latest"
with a pinned version; update the install command to use a specific semantic
version (e.g., `@vX.Y.Z`) or a template variable so CI uses a fixed govulncheck
release, and ensure any documentation or template variables (the govulncheck
install line and the "Run govulncheck" step) are adjusted accordingly to avoid
using `@latest`.

In `@src/agentready/templates/bootstrap/go/workflows/tests.yml.j2`:
- Around line 32-34: The workflow currently sets golangci-lint action version to
"latest" (uses: golangci/golangci-lint-action@v6 with version: latest); change
the version key to a pinned, specific release (for example a concrete
semver/tag) so CI is deterministic, e.g. replace the version: latest entry with
a fixed version string and optionally add a comment or dependabot config to
update it periodically; keep the uses: golangci/golangci-lint-action@v6 line
as-is but ensure the version input is a specific pinned tag rather than
"latest".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 824f50a2-7a19-4949-a344-0d1311be59fe

📥 Commits

Reviewing files that changed from the base of the PR and between 59989f0 and bd5a68d.

📒 Files selected for processing (11)
  • src/agentready/assessors/base.py
  • src/agentready/assessors/code_quality.py
  • src/agentready/assessors/documentation.py
  • src/agentready/assessors/structure.py
  • src/agentready/assessors/stub_assessors.py
  • src/agentready/assessors/testing.py
  • src/agentready/data/Go.arsrc
  • src/agentready/templates/bootstrap/go/workflows/security.yml.j2
  • src/agentready/templates/bootstrap/go/workflows/tests.yml.j2
  • tests/unit/test_assessors_go.py
  • tests/unit/test_bootstrap_templates.py

Comment thread src/agentready/assessors/base.py
Comment thread src/agentready/assessors/base.py Outdated
Comment thread src/agentready/assessors/code_quality.py Outdated
Comment on lines +1224 to +1254
exported_pattern = re.compile(r"^(?:func|type|var|const)\s+([A-Z]\w*)")

for file_path in go_files:
full_path = repository.path / file_path
if full_path.name == "doc.go":
has_doc_go = True

try:
lines = full_path.read_text(encoding="utf-8").splitlines()
except (OSError, UnicodeDecodeError):
continue

for i, line in enumerate(lines):
match = exported_pattern.match(line.strip())
if not match:
continue

total_exported += 1
symbol_name = match.group(1)

# Check if previous non-empty line is a comment starting with symbol name
if i > 0:
prev_idx = i - 1
while prev_idx >= 0 and not lines[prev_idx].strip():
prev_idx -= 1
if prev_idx >= 0:
prev_line = lines[prev_idx].strip()
if prev_line.startswith(
f"// {symbol_name}"
) or prev_line.startswith("//"):
documented_exported += 1
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

In Go's documentation conventions, do exported methods require doc comments, and should doc comments on exported declarations start with the declaration name?

💡 Result:

Yes—Go’s documentation conventions say that every exported (capitalized) name should have a doc comment, and doc comments for types (and similarly for funcs/methods) should start with the declared symbol’s name. Go doc comments are defined as the comments that appear immediately before top-level package, const, func, type, and var declarations, with no intervening blank line. The documentation rules further state: “Every exported (capitalized) name should have a doc comment.”[1] It also says that “These rules all apply both to plain functions and to methods.”[1] For the “should start with the declaration name” part: the Go docs explain that, for types, “doc comments for types start with naming the declared symbol” and give examples; this same “rules all apply … to plain functions and to methods” guidance indicates the same convention applies to exported functions/methods as well.[1] So, in practice: exported methods (which are part of the doc-comment rules for funcs/methods) should have doc comments, and those doc comments should begin with the method name (the declared symbol), typically as the first sentence.

Citations:


Godoc coverage is undercounting methods and overcounting unrelated comments.

The regex pattern fails to capture exported methods because it doesn't account for receivers (e.g., func (s *Server) Start() won't match). Additionally, the documentation check accepts any preceding // line, not just those starting with the symbol name, inflating coverage. Go's official documentation requires every exported name—including methods—to have a doc comment starting with the declared symbol's name, so the assessment is both under- and over-inclusive.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/agentready/assessors/documentation.py` around lines 1224 - 1254, The
exported-symbol detection and doc-comment check are wrong: update
exported_pattern to also match exported methods with receivers (e.g., change
exported_pattern to allow an optional receiver group before the name so it
matches lines like "func (s *Server) Start()") and adjust the documentation
check so it only counts a preceding comment when it actually begins with the
symbol name (use prev_line.startswith(f"// {symbol_name}") rather than accepting
any "//" line); also handle preceding block comments (/* ... */) by examining
the last non-empty previous token block and ensuring its first line starts with
the symbol name before incrementing documented_exported (references:
exported_pattern, symbol_name, documented_exported, total_exported, the loop
over go_files/lines).

Comment thread src/agentready/assessors/structure.py Outdated
Comment thread src/agentready/assessors/stub_assessors.py Outdated
Comment thread src/agentready/assessors/testing.py Outdated
Comment thread src/agentready/assessors/testing.py Outdated
Comment thread src/agentready/templates/bootstrap/go/workflows/security.yml.j2
Comment on lines +32 to 34
uses: golangci/golangci-lint-action@v6
with:
version: latest
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

What is the current stable golangci-lint release recommended for golangci/golangci-lint-action@v6 pinning in GitHub Actions workflows?

💡 Result:

The current stable golangci-lint release is v2.12.2, released on 2026-05-06.[1][2][3] For pinning in GitHub Actions workflows using golangci/golangci-lint-action@v6, the official documentation and examples recommend specifying a particular version like version: v1.60 or version: latest (which installs the latest stable).[4][5][6] While "latest" is shown in examples, for reproducible CI as emphasized in the official docs, pin to the current stable v2.12.2.[7] Note that v6 of the action supports golangci-lint v1 versions based on compatibility notes (e.g., v2.0.0+ works with >=v1.28.3), but given no explicit restriction to v1 and examples using high v1.x, it likely supports v2.x; however, for safety with v6 pinning, consider upgrading to v7+ if using v2.x is needed, as v7 explicitly supports v2 only.[8][9]

Citations:


Pin golangci-lint to a fixed version instead of latest.

Using version: latest makes generated CI nondeterministic and can cause unexpected build failures when upstream releases change behavior. Pinning to a specific version ensures reproducible builds across environments.

Proposed fix
       - name: Run golangci-lint
         uses: golangci/golangci-lint-action@v6
         with:
-          version: latest
+          version: v1.60.3
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
uses: golangci/golangci-lint-action@v6
with:
version: latest
uses: golangci/golangci-lint-action@v6
with:
version: v1.60.3
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/agentready/templates/bootstrap/go/workflows/tests.yml.j2` around lines 32
- 34, The workflow currently sets golangci-lint action version to "latest"
(uses: golangci/golangci-lint-action@v6 with version: latest); change the
version key to a pinned, specific release (for example a concrete semver/tag) so
CI is deterministic, e.g. replace the version: latest entry with a fixed version
string and optionally add a comment or dependabot config to update it
periodically; keep the uses: golangci/golangci-lint-action@v6 line as-is but
ensure the version input is a specific pinned tag rather than "latest".

Fixes 9 of 10 CodeRabbit review findings:

1. _primary_language(): deterministic tiebreaker — only returns a winner
   when exactly one language has a root manifest match
2. _find_go_module_roots(): use rglob for recursive search, exclude
   vendor/testdata, deduplicate and sort results
3. CyclomaticComplexityAssessor: remove unsafe fallback that assumed
   golangci-lint default linters without parsing config
4. InlineDocumentationAssessor: fix godoc pattern to capture exported
   methods with receivers (func (s *Server) Start()); require doc
   comments to start with "// SymbolName" per Go convention
5. StandardLayoutAssessor: use _primary_language() dispatch instead of
   bare "Go" in repository.languages check
6. DependencyPinningAssessor: use rglob for go.sum search with vendor
   exclusion, find all matches (not just first)
7. TestExecutionAssessor: coverage regex now matches plain -cover flag
   in addition to -coverprofile/-covermode
8. TestExecutionAssessor: use _find_go_module_roots() for build file
   scanning instead of one-level glob
9. Bootstrap template: pin govulncheck to v1.3.0 instead of @latest

Skipped ambient-code#10 (pin golangci-lint version: latest): intentional for
bootstrap templates — golangci-lint-action@v6 documents this pattern.

Co-Authored-By: Claude Opus 4.6 (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.

1 participant