
Golang Continuous Integration
- 34k installs
- 2.9k repo stars
- Updated August 1, 2026
- samber/cc-skills-golang
golang-continuous-integration is a DevOps skill that integrates AI code review and automated testing into GitHub Actions workflows.
About
Go continuous integration skill covering GitHub Actions workflows for AI code review using Claude. Provides patterns for automated code review on pull requests, test integration, and CI/CD pipeline setup.
- GitHub Actions CI workflow for Go projects
- AI-powered code review with Claude integration
- Automated testing and quality checks
Golang Continuous Integration by the numbers
- 33,964 all-time installs (skills.sh)
- +355 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #11 of 1,435 DevOps & CI/CD skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
golang-continuous-integration capabilities & compatibility
- Works with
- github
- Use cases
- ci cd
What golang-continuous-integration says it does
AI Code Review (Claude)
pull_request
npx skills add https://github.com/samber/cc-skills-golang --skill golang-continuous-integrationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 34k |
|---|---|
| repo stars | ★ 2.9k |
| Security audit | 1 / 3 scanners passed |
| Last updated | August 1, 2026 |
| Repository | samber/cc-skills-golang ↗ |
How do you automate Claude code review on GitHub PRs?
Teams building Go projects need CI/CD automation with code review, testing, and deployment workflows integrated into pull request workflows.
Who is it for?
DevOps teams setting up Go CI/CD pipelines
Skip if: Repositories that cannot grant pull-requests:write to Actions or teams that need human-only review gates on untrusted forks.
When should I use this skill?
Setting up CI/CD for Go projects, integrating code review, automating testing
What you get
GitHub Actions workflow file, automated PR review comments, and resolved review threads on synchronize events.
- github actions workflow yaml
- automated pr review comments
By the numbers
- Workflow listens to 3 pull_request event types
- Declares 3 GitHub token permissions: contents, issues, pull-requests
Files
Persona: You are a Go DevOps engineer. You treat CI as a quality gate — every pipeline decision is weighed against build speed, signal reliability, and security posture.
Modes:
- Setup — adding CI to a project for the first time: start with the Quick Reference table, then generate workflows in this order: test → lint → security → release. Prefer the latest stable major version for each GitHub Action.
- Improve — auditing or extending an existing pipeline: read current workflow files first, identify gaps against the Quick Reference table, then propose targeted additions without duplicating existing steps.
Dependencies:
- goreleaser:
go install github.com/goreleaser/goreleaser/v2@latest - gh:
brew install gh
Go Continuous Integration
Set up production-grade CI/CD pipelines for Go projects using GitHub Actions.
Action Versions
The versions in the examples below are reference versions that may be outdated. GitHub Actions release frequently — the current major version for each action (actions/checkout, actions/setup-go, golangci/golangci-lint-action, codecov/codecov-action, goreleaser/goreleaser-action, etc.) may differ from what is shown here.
Quick Reference
| Stage | Tool | Purpose |
|---|---|---|
| Test | go test -race | Unit + race detection |
| Coverage | codecov/codecov-action | Coverage reporting |
| Lint | golangci-lint | Comprehensive linting |
| Vet | go vet | Built-in static analysis |
| SAST | gosec, CodeQL, Bearer | Security static analysis |
| Vuln scan | govulncheck | Known vulnerability detection |
| Docker | docker/build-push-action | Multi-platform image builds |
| Deps | Dependabot / Renovate | Automated dependency updates |
| Release | GoReleaser | Automated binary releases |
| AI Review | Claude Code / Copilot | AI-powered PR review |
---
Testing
.github/workflows/test.yml — see test.yml
Adapt the Go version matrix to match go.mod:
go 1.23 → matrix: ["1.23", "1.24", "1.25", "1.26", "stable"]
go 1.24 → matrix: ["1.24", "1.25", "1.26", "stable"]
go 1.25 → matrix: ["1.25", "1.26", "stable"]
go 1.26 → matrix: ["1.26", "stable"]Use fail-fast: false so a failure on one Go version doesn't cancel the others.
Test flags:
-race: CI MUST run tests with the-raceflag (catches data races — undefined behavior in Go)-shuffle=on: Randomize test order to catch inter-test dependencies-coverprofile: Generate coverage datagit diff --exit-code: Fails ifgo mod tidychanges anything
Coverage Configuration
CI SHOULD enforce code coverage thresholds. Configure thresholds in codecov.yml at the repo root — see codecov.yml
---
Integration Tests
.github/workflows/integration.yml — see integration.yml
Use -count=1 to disable test caching — cached results can hide flaky service interactions.
---
Linting
golangci-lint MUST be run in CI on every PR. .github/workflows/lint.yml — see lint.yml
golangci-lint Configuration
Create .golangci.yml at the root of the project. See the samber/cc-skills-golang@golang-lint skill for the recommended configuration.
---
Security & SAST
.github/workflows/security.yml — see security.yml
CI MUST run govulncheck. It only reports vulnerabilities in code paths your project actually calls — unlike generic CVE scanners. CodeQL results appear in the repository's Security tab. Bearer is good at detecting sensitive data flow issues.
CodeQL Configuration
Create .github/codeql/codeql-config.yml to use the extended security query suite — see codeql-config.yml
Available query suites:
- default: Standard security queries
- security-extended: Extra security queries with slightly lower precision
- security-and-quality: Security queries plus maintainability and reliability checks
Container Image Scanning
If the project produces Docker images, Trivy container scanning is included in the Docker workflow — see docker.yml
---
Dependency Management
Dependabot
.github/dependabot.yml — see dependabot.yml
Minor/patch updates are grouped into a single PR. Major updates get individual PRs since they may have breaking changes.
Auto-Merge for Dependabot
.github/workflows/dependabot-auto-merge.yml — see dependabot-auto-merge.yml
Security warning: This workflow requirescontents: writeandpull-requests: write— these are elevated permissions that allow merging PRs and modifying repository content. Theif: github.actor == 'dependabot[bot]'guard restricts execution to Dependabot only. Do not remove this guard. Note thatgithub.actorchecks are not fully spoof-proof — branch protection rules are the real safety net. Ensure branch protection is configured (see Repository Security Settings) with required status checks and required approvals so that auto-merge only succeeds after all checks pass, regardless of who triggered the workflow.
Renovate (alternative)
Renovate is a more mature and configurable alternative to Dependabot. It supports automerge natively, grouping, scheduling, regex managers, and monorepo-aware updates. If Dependabot feels too limited, Renovate is the go-to choice.
Install the Renovate GitHub App, then create renovate.json at the repo root — see renovate.json
Key advantages over Dependabot:
- `gomodTidy`: Automatically runs
go mod tidyafter updates - Native automerge: No separate workflow needed
- Better grouping: More flexible rules for grouping PRs
- Regex managers: Can update versions in Dockerfiles, Makefiles, etc.
- Monorepo support: Handles Go workspaces and multi-module repos
---
Release Automation
GoReleaser automates binary builds, checksums, and GitHub Releases. The configuration varies significantly depending on the project type.
Release Workflow
.github/workflows/release.yml — see release.yml
Security warning: This workflow requirescontents: writeto create GitHub Releases. It is restricted to tag pushes (tags: ["v*"]) so it cannot be triggered by pull requests or branch pushes. Only users with push access to the repository can create tags.
GoReleaser for CLI/Programs
Programs need cross-compiled binaries, archives, and optionally Docker images.
.goreleaser.yml — see goreleaser-cli.yml
GoReleaser for Libraries
Libraries don't produce binaries — they only need a GitHub Release with a changelog. Use a minimal config that skips the build.
.goreleaser.yml — see goreleaser-lib.yml
For libraries, you may not even need GoReleaser — a simple GitHub Release created via the UI or gh release create is often sufficient.
GoReleaser for Monorepos / Multi-Binary
When a repository contains multiple commands (e.g., cmd/api/, cmd/worker/).
.goreleaser.yml — see goreleaser-monorepo.yml
Docker Build & Push
For projects that produce Docker images. This workflow builds multi-platform images, generates SBOM and provenance attestations, pushes to both GitHub Container Registry (GHCR) and Docker Hub, and includes Trivy container scanning.
.github/workflows/docker.yml — see docker.yml
Security warning: Permissions are scoped per job: thecontainer-scanjob only getscontents: read+security-events: write, while thedockerjob getspackages: write(to push to GHCR) andattestations: write+id-token: write(for provenance/SBOM signing). This ensures the scan job cannot push images even if compromised. Thepushflag is set tofalseon pull requests so untrusted code cannot publish images. TheDOCKERHUB_USERNAMEandDOCKERHUB_TOKENsecrets must be configured in the repository secrets settings — never hardcode credentials.
Key details:
- QEMU + Buildx: Required for multi-platform builds (
linux/amd64,linux/arm64). Remove platforms you don't need. - `push: false` on PRs: Images are built but never pushed on pull requests — this validates the Dockerfile without publishing untrusted code.
- Metadata action: Automatically generates semver tags (
v1.2.3→1.2.3,1.2,1), branch tags (main), and SHA tags. - Provenance + SBOM:
provenance: mode=maxandsbom: truegenerate supply chain attestations. These requireattestations: writeandid-token: writepermissions. - Dual registry: Pushes to both GHCR (using
GITHUB_TOKEN, no extra secret needed) and Docker Hub (requiresDOCKERHUB_USERNAME+DOCKERHUB_TOKENsecrets). Remove the Docker Hub login and image line if not needed. - Trivy: Scans the built image for CRITICAL and HIGH vulnerabilities and uploads results to the Security tab.
- Adapt the image names and registries to your project. For GHCR-only, remove the Docker Hub login step and the
docker.io/line fromimages:.
---
Repository Security Settings
Repository security settings (branch protection, workflow permissions, secrets, environments) form the security foundation for the CI pipeline — these are documented in repo-security.md.
---
AI-Driven Code Review
Add AI agents as PR reviewers alongside traditional static analysis. When loaded with this skill plugin, the agent applies the relevant Go skills per review area — catching architectural drift, logic bugs, missing error context, and concurrency hazards that linters cannot detect.
Cost note: AI review agents run concurrently per PR. For cost control, remove jobs you don't need or raise the PR trigger filter to specific branches only.
Claude Code
.github/workflows/ai-review.yml — see claude-code-review.yml
The workflow runs parallel jobs, each scoped to a set of review areas and priority level:
| Job | Areas | Priority |
|---|---|---|
quality | Code style, Naming, Documentation, Design patterns | Suggestion-first |
correctness | Error handling, Code safety, Concurrency | Blocking-first |
security | Security, Dependencies | Blocking-first |
quality-depth | Tests, Performance, Observability, Modernize | Mixed |
Additional skills that may be relevant depending on the project: golang-cli, golang-context, golang-data-structures, golang-database, golang-dependency-injection, or any library-specific skill.
The Claude Code GitHub App integration is configured via the /install-github-app command, which sets up the required API secrets.
GitHub Copilot
Copy skills into your repo, then append copilot-review-instructions.md to .github/copilot-instructions.md:
npx skills add https://github.com/samber/cc-skills-golang --agent github-copilot --skill '*' -y --copy
ln -s .agents .copilot---
Common Mistakes
| Mistake | Fix |
|---|---|
Missing -race in CI tests | Always use go test -race |
No -shuffle=on | Randomize test order to catch inter-test dependencies |
| Caching integration test results | Use -count=1 to disable caching |
go mod tidy not checked | Add go mod tidy && git diff --exit-code step |
Missing fail-fast: false | One Go version failing shouldn't cancel other jobs |
| Not pinning action versions | GitHub Actions MUST use pinned major versions (e.g. @vN, not @master) |
No permissions block | Follow least-privilege per job |
| Ignoring govulncheck findings | Fix or suppress with justification |
| No AI review in CI | Add Claude Code or Copilot review — catches logic, security, and architectural issues that static analysis misses |
Related Skills
See samber/cc-skills-golang@golang-lint, samber/cc-skills-golang@golang-security, samber/cc-skills-golang@golang-testing, samber/cc-skills-golang@golang-dependency-management, samber/cc-skills-golang@golang-modernize skills.
name: AI Code Review (Claude)
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
pull_request_review_comment:
types: [created]
pull_request_review:
types: [submitted]
# Security note: these permissions apply to the entire repository, not just the current PR.
# `pull-requests: write` allows the workflow to post, edit, and resolve comments on ANY pull request.
# `actions: read` allows reading logs from ANY workflow run, which may contain sensitive output.
# Scope risk by restricting the trigger to PRs from trusted contributors or protected branches,
# and by never logging secrets in CI steps.
permissions:
contents: read
issues: read
pull-requests: write
actions: read
id-token: write
concurrency:
group: claude-review-${{ github.event.pull_request.number || github.event.issue.number }}-${{ github.event_name }}
cancel-in-progress: true
jobs:
# ── Job 1: Code quality (suggestion-first) ──────────────────────────────────
# Covers: style, naming, documentation
quality:
name: Review — Quality
runs-on: ubuntu-latest
timeout-minutes: 15
# Skip bot PRs (Dependabot, Renovate, etc.)
# Remove this filter if you want bots to get reviewed.
if: ${{ github.event_name == 'pull_request' && !endsWith(github.event.pull_request.user.login, '[bot]') }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 1
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Install Go skills
run: npx skills add https://github.com/samber/cc-skills-golang -a claude-code --skill '*' -y --copy
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
show_full_output: true
use_sticky_comment: true
track_progress: true
sticky_comment_header: "<!-- claude-review-quality -->"
additional_permissions: |
actions: read
claude_args: >-
--allowedTools "mcp__github_inline_comment__create_inline_comment,mcp__context7__resolve-library-id,mcp__context7__query-docs,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)"
prompt: |
REPO: ${{ github.repository }}
PR NUMBER: ${{ github.event.pull_request.number }}
AUTHOR: ${{ github.event.pull_request.user.login }}
You are a senior Go engineer performing a focused code quality review.
Review this pull request.
- Use `gh pr diff` to read the diff.
- Use `gh pr view` to read description and metadata.
- Use `mcp__github_inline_comment__create_inline_comment` with `confirmed: true`
for every line-specific issue. Include a ```suggestion block when the fix is
a direct 1:1 replacement of the selected lines.
- Use `gh pr comment` only for a top-level summary.
- Post nothing else. No chat output.
## Scope — apply these skill guidelines
- **Code style** — formatting, comment quality, idiomatic Go patterns (Skill("golang-code-style")).
- **Naming** — packages, types, variables, functions, constants (Skill("golang-naming")).
- **Documentation** — exported symbols, package-level docs, README impact (Skill("golang-documentation")).
## Priority — suggestion-first
These areas reflect style and readability, not correctness. Only raise an issue when it will confuse future readers, mislead consumers of an exported API, or make the codebase harder to navigate at scale. Do not flag formatting that `gofmt` handles automatically. Do not flag personal preferences when the code is otherwise clear.
## How to report
Every comment must:
1. Name the specific problem (not just its symptom)
2. Explain under what conditions it matters or fails
3. Provide a concrete fix — renamed identifier, corrected code snippet, or safer pattern
Write short, concise comments. Only comment when there is a specific issue. Do not praise the good stuff. Before posting, verify the point was not already raised in a previous review comment.
Note: the PR branch is already checked out in the current working directory.
Check project guidelines: @./CLAUDE.md
Check contributing guidelines: @./CONTRIBUTING.md
Check project description: @./docs/project-summary.md
Label each comment: 🟡 **SUGGESTION**
# ── Job 2: Correctness (blocking-first) ─────────────────────────────────────
# Covers: error handling, code safety, concurrency
correctness:
name: Review — Correctness
runs-on: ubuntu-latest
timeout-minutes: 15
# Skip bot PRs (Dependabot, Renovate, etc.)
# Remove this filter if you want bots to get reviewed.
if: ${{ github.event_name == 'pull_request' && !endsWith(github.event.pull_request.user.login, '[bot]') }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 1
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Install Go skills
run: npx skills add https://github.com/samber/cc-skills-golang -a claude-code --skill '*' -y --copy
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
show_full_output: true
use_sticky_comment: true
track_progress: true
sticky_comment_header: "<!-- claude-review-correctness -->"
additional_permissions: |
actions: read
claude_args: >-
--allowedTools "mcp__github_inline_comment__create_inline_comment,mcp__context7__resolve-library-id,mcp__context7__query-docs,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)"
prompt: |
REPO: ${{ github.repository }}
PR NUMBER: ${{ github.event.pull_request.number }}
AUTHOR: ${{ github.event.pull_request.user.login }}
You are a senior Go engineer performing a focused correctness and safety review.
Review this pull request.
- Use `gh pr diff` to read the diff.
- Use `gh pr view` to read description and metadata.
- Use `mcp__github_inline_comment__create_inline_comment` with `confirmed: true`
for every line-specific issue. Include a ```suggestion block when the fix is
a direct 1:1 replacement of the selected lines.
- Use `gh pr comment` only for a top-level summary.
- Post nothing else. No chat output.
## Scope — apply these skill guidelines
- **Error handling** — wrapping, sentinel errors, log-and-return, swallowed errors (Skill("golang-error-handling")).
- **Code safety** — nil dereference, map/slice aliasing, integer overflows, uninitialized state (Skill("golang-safety")).
- **Concurrency** — goroutine lifecycle, mutex usage, channel patterns, context propagation, data races (Skill("golang-concurrency")).
## Priority — blocking-first
A swallowed error, an unchecked nil, or an unsynchronized write can cause silent data corruption or production incidents — flag these even when the fix is non-trivial.
## How to report
Every comment must:
1. Name the specific problem (not just its symptom)
2. Explain under what conditions it matters or fails
3. Provide a concrete fix — renamed identifier, corrected code snippet, or safer pattern
Write short, concise comments. Only comment when there is a specific issue. Do not praise the good stuff. Before posting, verify the point was not already raised in a previous review comment.
Note: the PR branch is already checked out in the current working directory.
Check project guidelines: @./CLAUDE.md
Check contributing guidelines: @./CONTRIBUTING.md
Check project description: @./docs/project-summary.md
Label each comment with its severity:
- 🔴 **BLOCKING** — definite bug, data race, or correctness failure; must be fixed before merge.
- 🟠 **IMPORTANT** — significant risk that requires unusual conditions to manifest; strongly recommended to fix.
- 🟡 **SUGGESTION** — defensive improvement with low-probability failure mode or subtle edge case.
# ── Job 3: Security & dependencies (blocking-first) ─────────────────────────
# Covers: security, dependency health
security:
name: Review — Security & Dependencies
runs-on: ubuntu-latest
timeout-minutes: 15
# Skip bot PRs (Dependabot, Renovate, etc.)
# Remove this filter if you want bots to get reviewed.
if: ${{ github.event_name == 'pull_request' && !endsWith(github.event.pull_request.user.login, '[bot]') }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 1
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Install Go skills
run: npx skills add https://github.com/samber/cc-skills-golang -a claude-code --skill '*' -y --copy
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
show_full_output: true
use_sticky_comment: true
track_progress: true
sticky_comment_header: "<!-- claude-review-security -->"
additional_permissions: |
actions: read
claude_args: >-
--allowedTools "mcp__github_inline_comment__create_inline_comment,mcp__context7__resolve-library-id,mcp__context7__query-docs,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)"
prompt: |
REPO: ${{ github.repository }}
PR NUMBER: ${{ github.event.pull_request.number }}
AUTHOR: ${{ github.event.pull_request.user.login }}
You are a senior Go security engineer performing a focused security and dependency review.
Review this pull request.
- Use `gh pr diff` to read the diff.
- Use `gh pr view` to read description and metadata.
- Use `mcp__github_inline_comment__create_inline_comment` with `confirmed: true`
for every line-specific issue. Include a ```suggestion block when the fix is
a direct 1:1 replacement of the selected lines.
- Use `gh pr comment` only for a top-level summary.
- Post nothing else. No chat output.
## Scope — apply these skill guidelines
- **Security** — injection, auth, crypto misuse, sensitive data exposure, input validation (Skill("golang-security")).
- **Dependencies** — new imports, CVE history, abandoned packages, `replace` directives (Skill("golang-dependency-management")).
## Priority — blocking-first
Security issues and supply-chain risks must be flagged before style or quality concerns. A single unvalidated input or a weak PRNG can open a critical vulnerability — do not downgrade these findings.
## How to report
Every comment must:
1. Name the specific problem (not just its symptom)
2. Explain under what conditions it matters or fails
3. Provide a concrete fix — renamed identifier, corrected code snippet, or safer pattern
Write short, concise comments. Only comment when there is a specific issue. Do not praise the good stuff. Before posting, verify the point was not already raised in a previous review comment.
Note: the PR branch is already checked out in the current working directory.
Check project guidelines: @./CLAUDE.md
Check contributing guidelines: @./CONTRIBUTING.md
Check project description: @./docs/project-summary.md
Label each comment with its severity:
- 🔴 **BLOCKING** — exploitable vulnerability or high-risk dependency; must be fixed before merge.
- 🟠 **IMPORTANT** — significant risk that requires specific conditions; strongly recommended.
- 🟡 **SUGGESTION** — defense-in-depth improvement; optional but worthwhile.
# ── Job 4: Tests, performance, observability & modernization ─────────────────
# Covers: tests, performance, observability, modernize
quality-depth:
name: Review — Tests, Performance & Observability
runs-on: ubuntu-latest
timeout-minutes: 15
# Skip bot PRs (Dependabot, Renovate, etc.)
# Remove this filter if you want bots to get reviewed.
if: ${{ github.event_name == 'pull_request' && !endsWith(github.event.pull_request.user.login, '[bot]') }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 1
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Install Go skills
run: npx skills add https://github.com/samber/cc-skills-golang -a claude-code --skill '*' -y --copy
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
show_full_output: true
use_sticky_comment: true
track_progress: true
sticky_comment_header: "<!-- claude-review-quality-depth -->"
additional_permissions: |
actions: read
claude_args: >-
--allowedTools "mcp__github_inline_comment__create_inline_comment,mcp__context7__resolve-library-id,mcp__context7__query-docs,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)"
prompt: |
REPO: ${{ github.repository }}
PR NUMBER: ${{ github.event.pull_request.number }}
AUTHOR: ${{ github.event.pull_request.user.login }}
You are a senior Go engineer reviewing for test coverage, performance, observability, and code modernization.
Review this pull request.
- Use `gh pr diff` to read the diff.
- Use `gh pr view` to read description and metadata.
- Use `mcp__github_inline_comment__create_inline_comment` with `confirmed: true`
for every line-specific issue. Include a ```suggestion block when the fix is
a direct 1:1 replacement of the selected lines.
- Use `gh pr comment` only for a top-level summary.
- Post nothing else. No chat output.
## Scope — apply these skill guidelines
- **Tests** — coverage of new code, test quality, table-driven tests, use of t.Helper() (Skill("golang-testing")).
- **Performance** — unnecessary allocations, inefficient data structures, missing bounds (Skill("golang-performance")).
- **Observability** — logging, metrics, tracing added for new code paths (Skill("golang-observability")).
- **Modernize code** — outdated patterns replaced with Go 1.21+ idioms (Skill("golang-modernize")).
## Priority
- **Tests** and **Performance** are important — flag missing coverage on new exported paths and obvious allocation hot-spots on critical paths.
- **Observability** and **Modernize** are suggestion-first — raise only when the gap is material or the pattern is clearly outdated.
## How to report
Every comment must:
1. Name the specific problem (not just its symptom)
2. Explain under what conditions it matters or fails
3. Provide a concrete fix — renamed identifier, corrected code snippet, or safer pattern
Write short, concise comments. Only comment when there is a specific issue. Do not praise the good stuff. Before posting, verify the point was not already raised in a previous review comment.
Note: the PR branch is already checked out in the current working directory.
Check project guidelines: @./CLAUDE.md
Check contributing guidelines: @./CONTRIBUTING.md
Check project description: @./docs/project-summary.md
Label each comment with its severity:
- 🟠 **IMPORTANT** — missing test for a critical exported path; allocation hot-spot on a latency-sensitive path.
- 🟡 **SUGGESTION** — observability gap, modernization opportunity, or minor test quality improvement.
# ── Job 5: CI failure diagnosis ──────────────────────────────────────────────
# Waits for all review jobs to finish, then diagnoses any failures and suggests fixes.
ci-diagnosis:
name: Review — CI Failure Diagnosis
runs-on: ubuntu-latest
timeout-minutes: 15
needs: [quality, correctness, security, quality-depth]
if: ${{ always() && github.event_name == 'pull_request' && !endsWith(github.event.pull_request.user.login, '[bot]') }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 1
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
show_full_output: true
use_sticky_comment: true
track_progress: true
sticky_comment_header: "<!-- claude-review-ci-diagnosis -->"
additional_permissions: |
actions: read
claude_args: >-
--allowedTools "Bash(gh pr comment:*),Bash(gh pr view:*),Bash(gh run view:*),Bash(gh run list:*)"
prompt: |
REPO: ${{ github.repository }}
PR NUMBER: ${{ github.event.pull_request.number }}
WORKFLOW RUN ID: ${{ github.run_id }}
You are a senior Go engineer diagnosing CI failures on a pull request.
Check whether any of the parallel review jobs (quality, correctness, security, quality-depth)
failed in this workflow run. If all jobs succeeded, post nothing and exit.
If any job failed:
- Use `gh run view` to inspect the failed job logs and identify the root cause.
- Post a single `gh pr comment` summarizing:
1. Which job(s) failed and why (log excerpt).
2. Concrete steps to fix the failure (configuration change, missing secret, infra issue).
- Post nothing else. No chat output.
# ── Job 6: Discuss review comments ──────────────────────────────────────────
# Triggered when a human posts a review comment or submits a review.
# Replies to offer a counter-argument when warranted — stays concise.
discuss:
name: Review — Discuss
runs-on: ubuntu-latest
timeout-minutes: 15
if: ${{ (github.event_name == 'pull_request_review_comment' || github.event_name == 'pull_request_review') && !endsWith(github.event.sender.login, '[bot]') }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 1
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
show_full_output: true
use_sticky_comment: false
track_progress: false
claude_args: >-
--allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr view:*),Bash(gh pr diff:*)"
prompt: |
REPO: ${{ github.repository }}
PR NUMBER: ${{ github.event.pull_request.number }}
You are a senior Go engineer participating in a code review discussion.
A human just posted a review comment or submitted a review on this PR.
Read the comment thread and decide whether to reply.
Reply ONLY if:
- The comment contains a factual mistake about Go semantics, the standard library, or a third-party package.
- The proposed change would introduce a bug, a performance regression, or a security issue.
- A brief clarification would unblock the discussion.
Do NOT reply if:
- The comment is a style preference and both approaches are valid.
- The author has already acknowledged the feedback.
- A debate is already in progress — let it resolve naturally.
- You already replied to this thread.
When you reply: be short and direct. One or two sentences maximum. State the technical
fact. If the author disagrees after your reply, drop the thread.
You may also add a 👍 reaction to a comment to acknowledge it without adding another
comment — prefer this when the discussion is resolved or the point is already clear.
Use `mcp__github_inline_comment__create_inline_comment` to reply inline when the comment
is line-specific, otherwise use `gh pr comment`. Post nothing else. No chat output.
coverage:
status:
project:
default:
target: 80%
threshold: 2%
patch:
default:
target: 80%name: "CodeQL config"
queries:
- uses: security-and-quality
query-filters:
- exclude:
id: go/unused-result<!-- Prerequisites: The skills CLI (listed in the frontmatter install block) can be used to copy skills locally: npx skills add https://github.com/samber/cc-skills-golang --agent github-copilot --skill '*' -y --copy ln -s .agents .copilot Then copy this file to .github/copilot-instructions.md -->
Go Code Review Instructions
You are a senior Go engineer reviewing a pull request. Review the diff thoroughly and provide actionable, prioritized feedback.
The available skills can be discovered from the local skill files:
find .copilot/skills -type f -name SKILL.md -print0 \ | xargs -0 yq -o=json \ | jq -r '{name, description}'
Relevant skills should be loaded before reviewing the diff.
Scope of Review
Cover each area below. Where a dedicated skill is listed, apply its guidance.
- Code style — formatting, comment quality, idiomatic Go patterns (
.copilot/skills/golang-code-style/SKILL.md) - Naming — packages, types, variables, functions, constants (
.copilot/skills/golang-naming/SKILL.md) - Error handling — wrapping, sentinel errors, log-and-return, swallowed errors (
.copilot/skills/golang-error-handling/SKILL.md) - Concurrency — goroutine lifecycle, mutex usage, channel patterns, context propagation, data races (
.copilot/skills/golang-concurrency/SKILL.md) - Code safety — nil dereference, map/slice aliasing, integer overflows, uninitialized state (
.copilot/skills/golang-safety/SKILL.md) - Tests — coverage of new code, test quality, table-driven tests, use of t.Helper() (
.copilot/skills/golang-testing/SKILL.md) - Performance — unnecessary allocations, inefficient data structures, missing bounds (
.copilot/skills/golang-performance/SKILL.md) - Security — injection, auth, crypto misuse, sensitive data exposure, input validation (
.copilot/skills/golang-security/SKILL.md) - Dependencies — new imports, license compatibility, known vulnerabilities (
.copilot/skills/golang-dependency-management/SKILL.md) - Documentation — exported symbols, package docs, README impact (
.copilot/skills/golang-documentation/SKILL.md) - Observability — logging, metrics, tracing added for new code paths (
.copilot/skills/golang-observability/SKILL.md) - Modernize code — outdated patterns replaced with Go 1.21+ idioms (
.copilot/skills/golang-modernize/SKILL.md)
Review Priority
Not all areas carry the same risk. Apply this order when time or API budget is limited:
- Blocking-first areas (look for bugs and vulnerabilities before style): Security, Code safety, Error handling, Concurrency
- Important areas (significant quality impact): Tests, Performance, Dependencies
- Suggestion-first areas (raise only when notably wrong): Code style, Naming, Documentation, Observability, Modernize code
How to Report Issues
For each issue found:
- Reference the exact file and line number.
- Explain what is wrong and why it matters.
- Provide a concrete fix or example.
Classify severity:
- 🔴 BLOCKING — bug, vulnerability, data race, or correctness issue; must be fixed before merge.
- 🟠 IMPORTANT — significant quality or maintainability concern; strongly recommended.
- 🟡 SUGGESTION — style, naming, or minor improvement; optional but worthwhile.
Use inline comments on the specific diff line when possible. For concerns not tied to a specific line, post a PR-level summary.
Write short, concise comments. Only comment when there is a specific issue — do not praise the good stuff. If you have nothing to say, post nothing. Before posting, verify the point was not already raised in a previous review comment.
name: Dependabot Auto-Merge
on:
pull_request:
permissions:
contents: write
pull-requests: write
jobs:
auto-merge:
name: Auto-Merge
runs-on: ubuntu-latest
if: github.actor == 'dependabot[bot]'
steps:
- name: Fetch Dependabot metadata
id: metadata
uses: dependabot/fetch-metadata@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Auto-merge minor and patch updates
if: steps.metadata.outputs.update-type != 'version-update:semver-major'
run: gh pr merge --auto --squash "$PR_URL"
env:
PR_URL: ${{ github.event.pull_request.html_url }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}version: 2
updates:
# Go modules
- package-ecosystem: gomod
directory: /
schedule:
interval: weekly
day: monday
labels: ["dependencies", "go"]
open-pull-requests-limit: 10
groups:
go-minor-patch:
update-types: [minor, patch]
# GitHub Actions
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
labels: ["dependencies", "ci"]
groups:
actions:
patterns: ["*"]
# Docker (if applicable)
- package-ecosystem: docker
directory: /
schedule:
interval: weekly
labels: ["dependencies", "docker"]name: Docker
on:
push:
branches: [main]
tags: ["v*"]
pull_request:
jobs:
container-scan:
name: Container Scan
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v6
- name: Build image
run: docker build -t myapp:ci .
- name: Run Trivy
uses: aquasecurity/trivy-action@v0.35.0
with:
image-ref: myapp:ci
format: sarif
output: trivy-results.sarif
severity: CRITICAL,HIGH
exit-code: '1'
- name: Upload Trivy results
if: always()
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: trivy-results.sarif
docker:
name: Build & Push
runs-on: ubuntu-latest
needs: container-scan
permissions:
contents: read
packages: write
attestations: write
id-token: write
steps:
- uses: actions/checkout@v6
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Log in to Docker Hub
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/${{ github.repository }}
docker.io/${{ github.repository }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=ref,event=branch
type=sha
- name: Build and push
id: build
uses: docker/build-push-action@v6
with:
context: .
provenance: mode=max
sbom: true
push: ${{ github.event_name != 'pull_request' }}
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
version: 2
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- darwin
- windows
goarch:
- amd64
- arm64
ldflags:
- -s -w
- -X main.version={{.Version}}
- -X main.commit={{.Commit}}
archives:
- format: tar.gz
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
format_overrides:
- goos: windows
format: zip
checksum:
name_template: checksums.txt
changelog:
sort: asc
filters:
exclude: ["^docs", "^test", "^ci", "^chore", "^style"]version: 2
builds:
- skip: true
changelog:
sort: asc
filters:
exclude: ["^docs:", "^test:", "^ci:", "^chore:"]version: 2
builds:
- id: api
main: ./cmd/api
binary: api
env:
- CGO_ENABLED=0
goos:
- linux
- darwin
goarch:
- amd64
- arm64
- id: worker
main: ./cmd/worker
binary: worker
env:
- CGO_ENABLED=0
goos:
- linux
- darwin
goarch:
- amd64
- arm64
archives:
- format: tar.gz
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"name: Integration Tests
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
jobs:
integration:
name: Integration Tests
runs-on: ubuntu-latest
services:
postgres:
image: postgres:18-alpine
env:
POSTGRES_USER: test
POSTGRES_PASSWORD: test
POSTGRES_DB: testdb
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v6
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run integration tests
run: go test -v -race -tags=integration -count=1 ./...
env:
DATABASE_URL: postgres://test:test@localhost:5432/testdb?sslmode=disable
REDIS_URL: redis://localhost:6379name: Lint
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run go vet
run: go vet ./...
- name: golangci-lint
uses: golangci/golangci-lint-action@v9
with:
version: latest
args: --timeout 5m
name: Release
on:
push:
tags: ["v*"]
permissions:
contents: write
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v7
with:
version: "~> v2"
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended"
],
"postUpdateOptions": [
"gomodTidy"
],
"packageRules": [
{
"matchManagers": ["gomod"],
"matchUpdateTypes": ["minor", "patch"],
"automerge": true,
"groupName": "go minor/patch dependencies"
},
{
"matchManagers": ["github-actions"],
"automerge": true,
"groupName": "github actions"
}
]
}name: Security
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
security-events: write
jobs:
govulncheck:
name: Vulnerability Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run govulncheck
uses: golang/govulncheck-action@v1
gosec:
name: gosec
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Run gosec
uses: securego/gosec@v2
with:
args: -no-fail -fmt sarif -out gosec-results.sarif ./...
- name: Upload gosec results
if: always()
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: gosec-results.sarif
codeql:
name: CodeQL
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: go
config-file: .github/codeql/codeql-config.yml
- name: Autobuild
uses: github/codeql-action/autobuild@v4
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
bearer:
name: Bearer
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Bearer Security Scan
uses: bearer/bearer-action@v2
with:
format: sarif
output: bearer-results.sarif
- name: Upload Bearer results
if: always()
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: bearer-results.sarif
name: Tests
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
jobs:
test:
name: Test (Go ${{ matrix.go }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
go:
- "1.25"
- "1.26"
- "stable"
steps:
- uses: actions/checkout@v6
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: ${{ matrix.go }}
- name: Verify dependencies
run: |
go mod verify
go mod download
- name: Check go mod tidy
run: |
go mod tidy
git diff --exit-code go.mod go.sum
- name: Build
run: go build ./...
- name: Run tests
run: go test -v -race -shuffle=on -coverprofile=coverage.out ./...
- name: Upload coverage
if: matrix.go == 'stable'
uses: codecov/codecov-action@v5
with:
files: ./coverage.out
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }}[
{
"id": 1,
"name": "test-workflow-flags",
"description": "Tests whether CI test workflows include all required flags (-race, -shuffle, -coverprofile) and use fail-fast: false",
"prompt": "Create a GitHub Actions workflow file for running Go tests on a library that supports Go 1.25+. The project uses codecov for coverage. Just give me the YAML.",
"trap": "Model may omit -shuffle=on, forget fail-fast: false, or skip the go mod tidy check",
"assertions": [
{"id": "1.1", "text": "Workflow includes -race flag in the go test command"},
{"id": "1.2", "text": "Workflow includes -shuffle=on flag in the go test command"},
{"id": "1.3", "text": "Workflow includes -coverprofile flag in the go test command"},
{"id": "1.4", "text": "Strategy uses fail-fast: false"},
{"id": "1.5", "text": "Go version matrix includes at least 'stable' and one explicit version like '1.25' or '1.26'"}
]
},
{
"id": 2,
"name": "go-mod-tidy-check",
"description": "Tests whether the workflow enforces go mod tidy consistency via git diff --exit-code",
"prompt": "I want to make sure our Go CI catches cases where someone forgot to run go mod tidy before pushing. How should I add this check to our GitHub Actions workflow?",
"trap": "Model may suggest running go mod tidy without the git diff --exit-code step to actually fail the build on changes",
"assertions": [
{"id": "2.1", "text": "Suggests running 'go mod tidy' as a CI step"},
{"id": "2.2", "text": "Includes 'git diff --exit-code' after go mod tidy to detect uncommitted changes"},
{"id": "2.3", "text": "The git diff checks go.mod and/or go.sum specifically, or uses a general git diff --exit-code"},
{"id": "2.4", "text": "Also includes 'go mod verify' or 'go mod download' step"}
]
},
{
"id": 3,
"name": "integration-test-caching",
"description": "Tests knowledge that integration tests must use -count=1 to disable caching",
"prompt": "I have integration tests that interact with PostgreSQL and Redis via GitHub Actions service containers. Sometimes tests pass even when the services are broken because Go seems to cache test results. How do I set up the workflow?",
"trap": "Model may not know about -count=1 to disable test caching, or may suggest other workarounds",
"assertions": [
{"id": "3.1", "text": "Uses -count=1 flag to disable test result caching"},
{"id": "3.2", "text": "Includes -race flag for integration tests"},
{"id": "3.3", "text": "Uses build tags (e.g., -tags=integration) to separate integration tests"},
{"id": "3.4", "text": "Uses GitHub Actions 'services' block for PostgreSQL and/or Redis"},
{"id": "3.5", "text": "Includes health check options for service containers"}
]
},
{
"id": 4,
"name": "security-scanning-pipeline",
"description": "Tests whether the model recommends the full security stack: govulncheck, gosec, CodeQL, and Bearer",
"prompt": "I want to add security scanning to my Go project's CI pipeline. What tools should I use and how do I set them up in GitHub Actions?",
"trap": "Model may only suggest one or two tools (e.g., just gosec) and miss govulncheck (call-path-aware), CodeQL (Security tab integration), or Bearer (sensitive data flow)",
"assertions": [
{"id": "4.1", "text": "Recommends govulncheck and explains it only reports vulnerabilities in actually-called code paths"},
{"id": "4.2", "text": "Recommends gosec for Go security scanning"},
{"id": "4.3", "text": "Recommends CodeQL and mentions the security-extended or security-and-quality query suite"},
{"id": "4.4", "text": "Recommends Bearer for sensitive data flow issues"},
{"id": "4.5", "text": "Workflow includes security-events: write permission for SARIF upload"},
{"id": "4.6", "text": "Suggests creating a CodeQL config file to use an extended query suite rather than just the default"}
]
},
{
"id": 5,
"name": "dependabot-grouping-strategy",
"description": "Tests whether Dependabot config groups minor/patch updates but keeps major updates separate",
"prompt": "Set up Dependabot for my Go project on GitHub. I want automated dependency update PRs for Go modules, GitHub Actions, and Docker base images.",
"trap": "Model may not group minor/patch into a single PR, or may group all updates including majors which could have breaking changes",
"assertions": [
{"id": "5.1", "text": "Configures Dependabot for gomod package ecosystem"},
{"id": "5.2", "text": "Configures Dependabot for github-actions package ecosystem"},
{"id": "5.3", "text": "Configures Dependabot for docker package ecosystem"},
{"id": "5.4", "text": "Groups minor and patch Go module updates into a single PR"},
{"id": "5.5", "text": "Major updates are NOT grouped (individual PRs for breaking changes)"},
{"id": "5.6", "text": "Sets a weekly schedule"}
]
},
{
"id": 6,
"name": "dependabot-auto-merge-security",
"description": "Tests awareness of security implications in auto-merge workflow (elevated permissions, actor guard, branch protection as safety net)",
"prompt": "I want Dependabot PRs to auto-merge when CI passes, but only for minor and patch updates. Create the workflow. What security concerns should I be aware of?",
"trap": "Model may create the workflow without the github.actor guard, without mentioning elevated permissions risk, or without recommending branch protection as the real safety net",
"assertions": [
{"id": "6.1", "text": "Workflow has 'if: github.actor == dependabot[bot]' guard to restrict execution"},
{"id": "6.2", "text": "Workflow checks metadata to exclude major updates from auto-merge"},
{"id": "6.3", "text": "Warns about contents: write and pull-requests: write being elevated/high-risk permissions"},
{"id": "6.4", "text": "Mentions branch protection rules as the real safety net (not just the actor guard)"},
{"id": "6.5", "text": "Notes that github.actor checks are not fully spoof-proof"}
]
},
{
"id": 7,
"name": "renovate-vs-dependabot",
"description": "Tests knowledge of Renovate advantages over Dependabot",
"prompt": "I'm using Dependabot for my Go monorepo with multiple modules but it's creating too many PRs and doesn't run go mod tidy. What are my options?",
"trap": "Model may suggest workarounds for Dependabot rather than recommending Renovate with its gomodTidy, native automerge, and monorepo support",
"assertions": [
{"id": "7.1", "text": "Recommends Renovate as an alternative to Dependabot"},
{"id": "7.2", "text": "Mentions Renovate's gomodTidy feature (automatic go mod tidy after updates)"},
{"id": "7.3", "text": "Mentions Renovate's native automerge without needing a separate workflow"},
{"id": "7.4", "text": "Mentions Renovate's monorepo/workspace support"},
{"id": "7.5", "text": "Mentions Renovate's better grouping rules"}
]
},
{
"id": 8,
"name": "goreleaser-library-vs-cli",
"description": "Tests knowledge that GoReleaser config differs significantly between libraries and CLI programs",
"prompt": "I need to set up GoReleaser for my Go project which is a library (no main package). How should I configure it?",
"trap": "Model may generate a full GoReleaser config with builds, archives, and cross-compilation that doesn't apply to libraries",
"assertions": [
{"id": "8.1", "text": "Uses 'skip: true' in the builds section since libraries don't produce binaries"},
{"id": "8.2", "text": "Keeps the config minimal (mainly changelog generation)"},
{"id": "8.3", "text": "Mentions that for libraries, a simple GitHub Release via gh release create may be sufficient without GoReleaser"},
{"id": "8.4", "text": "Does NOT include cross-compilation (goos/goarch) in the library config"},
{"id": "8.5", "text": "Includes changelog configuration"}
]
},
{
"id": 9,
"name": "docker-workflow-security",
"description": "Tests awareness of Docker workflow security: push: false on PRs, per-job permissions, dual registry, provenance/SBOM",
"prompt": "Create a GitHub Actions workflow that builds a multi-platform Docker image and pushes it to GHCR. Include security best practices.",
"trap": "Model may push images on PRs (allowing untrusted code to publish), use overly broad permissions, or skip provenance/SBOM attestations",
"assertions": [
{"id": "9.1", "text": "Sets push to false on pull requests to prevent untrusted code from publishing images"},
{"id": "9.2", "text": "Uses per-job permissions scoping (not just top-level)"},
{"id": "9.3", "text": "Includes QEMU and Buildx setup for multi-platform builds"},
{"id": "9.4", "text": "Includes provenance and/or SBOM attestation configuration"},
{"id": "9.5", "text": "Includes packages: write permission for GHCR push"},
{"id": "9.6", "text": "Login step is conditional on non-PR events"}
]
},
{
"id": 10,
"name": "permissions-least-privilege",
"description": "Tests whether the model follows least-privilege permissions principle and sets GITHUB_TOKEN to read-only by default",
"prompt": "I'm setting up CI for a new open-source Go project. What GitHub repository settings should I configure for security? I already have the workflow files.",
"trap": "Model may focus only on branch protection and miss workflow permissions, fork PR restrictions, and environment-based approval gates",
"assertions": [
{"id": "10.1", "text": "Recommends setting default GITHUB_TOKEN to read-only at the repository level"},
{"id": "10.2", "text": "Recommends branch protection with required status checks"},
{"id": "10.3", "text": "Recommends requiring PR approvals (at least 1)"},
{"id": "10.4", "text": "Recommends dismissing stale approvals when new commits are pushed"},
{"id": "10.5", "text": "Recommends restricting fork PR workflows for outside collaborators"},
{"id": "10.6", "text": "Warns against pull_request_target with untrusted code"},
{"id": "10.7", "text": "Recommends creating a release environment with required reviewers"}
]
},
{
"id": 11,
"name": "release-workflow-fetch-depth",
"description": "Tests whether the release workflow uses fetch-depth: 0 for changelog generation",
"prompt": "Create a GitHub Actions release workflow that triggers on version tags and runs GoReleaser to produce binaries and a changelog.",
"trap": "Model may use default checkout which does a shallow clone, causing GoReleaser to generate an incomplete or empty changelog",
"assertions": [
{"id": "11.1", "text": "Checkout step uses fetch-depth: 0 for full git history"},
{"id": "11.2", "text": "Workflow triggers on tag push with a v* pattern"},
{"id": "11.3", "text": "Uses contents: write permission for creating releases"},
{"id": "11.4", "text": "Passes GITHUB_TOKEN to GoReleaser"}
]
},
{
"id": 12,
"name": "action-version-pinning",
"description": "Tests whether actions are pinned to major versions not branches",
"prompt": "Review this GitHub Actions step and tell me if there are any issues:\n\n```yaml\nsteps:\n - uses: actions/checkout@master\n - uses: actions/setup-go@main\n with:\n go-version: stable\n```",
"trap": "Model may not notice the branch references (@master, @main) instead of pinned major versions",
"assertions": [
{"id": "12.1", "text": "Identifies that using @master and @main is wrong and insecure"},
{"id": "12.2", "text": "Recommends pinning to major versions like @v4, @v6"},
{"id": "12.3", "text": "Explains the risk: branch references can change unexpectedly or be compromised"}
]
},
{
"id": 13,
"name": "coverage-threshold-configuration",
"description": "Tests knowledge of codecov.yml configuration with project and patch targets",
"prompt": "I want to enforce that our Go project maintains at least 80% code coverage and that each PR doesn't drop coverage by more than 2%. How do I configure this?",
"trap": "Model may only configure project-level thresholds and miss patch-level coverage targets",
"assertions": [
{"id": "13.1", "text": "Configures codecov.yml (not just CLI flags) for coverage thresholds"},
{"id": "13.2", "text": "Sets project target to 80%"},
{"id": "13.3", "text": "Sets a threshold value (e.g., 2%) to allow small drops"},
{"id": "13.4", "text": "Configures patch coverage target for new code in PRs"},
{"id": "13.5", "text": "Coverage upload is conditional on a single matrix entry (e.g., only on stable)"}
]
},
{
"id": 14,
"name": "ai-review-workflow-setup",
"description": "Tests whether the model recommends Claude Code Action or Copilot with skills for AI-driven PR review, rather than generic tools or manual checklists",
"prompt": "I want to add AI-powered code review to my Go project's CI pipeline. How do I set it up?",
"trap": "Model may suggest generic tools (CodeRabbit, PR-Agent, Reviewdog) or manual checklists instead of Claude Code Action / Copilot with Go skills loaded",
"assertions": [
{"id": "14.1", "text": "Recommends using anthropics/claude-code-action or GitHub Copilot for AI review"},
{"id": "14.2", "text": "Mentions installing Go skills via 'npx skills add' so the agent loads skill-based review guidelines"},
{"id": "14.3", "text": "Workflow includes pull-requests: write permission for inline PR comments"},
{"id": "14.4", "text": "References review areas mapped to specific Go skills (golang-security, golang-concurrency, etc.)"},
{"id": "14.5", "text": "References the claude-code-review.yml or copilot-review-instructions.md asset"}
]
},
{
"id": 15,
"name": "ai-review-vs-linting",
"description": "Tests whether the model explains that AI review complements linting by catching issues linters cannot detect",
"prompt": "I already have golangci-lint, govulncheck, and CodeQL in my CI. Why would I also need AI code review?",
"trap": "Model may say linting is sufficient or treat AI review as a luxury, failing to explain the complementary value",
"assertions": [
{"id": "15.1", "text": "Explains that AI review catches architectural drift and logic bugs that static analysis misses"},
{"id": "15.2", "text": "Mentions at least one concrete example: missing error context, goroutine leaks, broken contracts, or design issues"},
{"id": "15.3", "text": "Positions AI review as a complement to linting, not a replacement"},
{"id": "15.4", "text": "Notes that AI agents loaded with Go skills apply the same expertise as a senior Go reviewer"}
]
},
{
"id": 16,
"name": "ai-review-prompt-customization",
"description": "Tests whether the model explains how to scope the review prompt and apply the priority guidance",
"prompt": "Our Go project CI is slow. We want AI review but only for security and correctness issues — not style or documentation. How do we configure this?",
"trap": "Model may keep all 12 review areas or not know about the 4-job structure that can be selectively disabled",
"assertions": [
{"id": "16.1", "text": "Suggests removing or disabling the 'quality' job (style, naming, documentation) from the workflow"},
{"id": "16.2", "text": "Recommends keeping the 'correctness' and 'security' jobs as blocking-first areas"},
{"id": "16.3", "text": "Mentions the depth vs. speed tradeoff: fewer jobs = faster feedback, lower API cost"},
{"id": "16.4", "text": "References the priority guidance: Security, Code safety, Error handling, Concurrency are blocking-first"}
]
},
{
"id": 17,
"name": "ai-review-claude-vs-copilot",
"description": "Tests whether the model clearly differentiates Claude Code Action (GitHub Actions workflow) from Copilot (copilot-instructions.md) and their respective setups",
"prompt": "We use both GitHub Copilot and Claude Code in our team. Can we use both for CI code review? What's the difference?",
"trap": "Model may conflate the two setups, not know about copilot-instructions.md, or miss that Claude uses /golang-* syntax while Copilot uses golang-* without slash",
"assertions": [
{"id": "17.1", "text": "Explains Claude Code review runs as a GitHub Actions workflow using anthropics/claude-code-action"},
{"id": "17.2", "text": "Explains Copilot review uses .github/copilot-instructions.md to configure the review prompt"},
{"id": "17.3", "text": "Notes that both require installing Go skills so the AI loads skill-based guidelines"},
{"id": "17.4", "text": "Correctly describes that both can coexist — they run independently and complement each other"}
]
},
{
"id": 18,
"name": "ai-review-permissions-security",
"description": "Tests whether the model correctly identifies required permissions and security implications of the AI review workflow",
"prompt": "Our security team is concerned about giving an AI workflow write access to pull requests. What permissions does the Claude Code review workflow actually need and why?",
"trap": "Model may not know the minimal permission set, may suggest contents: write (too broad), or may not warn about fork PR risks",
"assertions": [
{"id": "18.1", "text": "Identifies pull-requests: write as required for posting inline review comments"},
{"id": "18.2", "text": "Identifies contents: read as sufficient for reading the repository code"},
{"id": "18.3", "text": "Does NOT suggest contents: write (that would be excessive for a review-only workflow)"},
{"id": "18.4", "text": "Warns about fork PR security: untrusted code in forks can access the ANTHROPIC_API_KEY secret if the workflow triggers on pull_request_target without careful guards"}
]
}
]
Repository Security Settings
After creating workflow files, repository security settings should be configured. These are not optional — they are the security foundation that makes the CI pipeline trustworthy.
The project's GitHub URL can be determined from its git remote (e.g., git remote -v). For a project hosted at https://github.com/{owner}/{repo}, the relevant settings links are:
- Branch protection:
https://github.com/{owner}/{repo}/settings/branches - Actions permissions:
https://github.com/{owner}/{repo}/settings/actions - Secrets:
https://github.com/{owner}/{repo}/settings/secrets/actions - Environments:
https://github.com/{owner}/{repo}/settings/environments
These links allow direct navigation to the appropriate settings page.
Branch Protection Rules
Configure a branch protection rule for main (or the default branch):
1. Require a pull request before merging — prevents direct pushes to main 2. Require approvals (at least 1) — no self-merging without review 3. Dismiss stale pull request approvals when new commits are pushed — prevents approving then sneaking in changes 4. Require status checks to pass before merging — add all CI workflow job names as required checks (e.g., Test (Go 1.24), Test (Go stable), Lint) 5. Require branches to be up to date before merging — prevents merging stale PRs that haven't been tested against latest main 6. Do not allow bypassing the above settings — applies rules to admins too
Workflow Permissions
Set the default GITHUB_TOKEN to read-only at the repository level:
1. Go to Actions permissions (link above) 2. Workflow permissions MUST follow least privilege. Under Workflow permissions, select "Read repository contents and packages permissions" 3. Uncheck "Allow GitHub Actions to create and approve pull requests" (unless auto-merge is needed — then check it only for that purpose)
This means workflows start with no write access by default. Each workflow that needs elevated permissions must explicitly declare them in its permissions: block. This is defense-in-depth: if a workflow is compromised, it cannot write to the repository unless explicitly granted.
Fork Pull Request Restrictions
For public/open-source repositories:
1. In Actions permissions (link above), set "Fork pull request workflows from outside collaborators" to "Require approval for all outside collaborators" 2. This prevents untrusted forks from running workflows that consume your Actions minutes or access secrets 3. NEVER use pull_request_target with untrusted code — it runs with write access to the base repo
Secrets and Environments
- Never put secrets in workflow files — use Secrets settings (link above)
- For release workflows, create a "release" environment with required reviewers in Environments (link above) to add a manual approval gate before publishing
- Rotate
CODECOV_TOKENand other third-party tokens periodically
Permissions Cheat Sheet
The security implications of every permission used are documented below:
| Permission | Workflows that need it | Risk |
|---|---|---|
contents: read | All workflows | Low — read-only, default safe |
contents: write | Release, auto-merge | High — can modify repo contents, create releases |
packages: write | Docker | High — can push container images to GHCR |
pull-requests: write | Auto-merge | High — can merge PRs, approve changes |
attestations: write | Docker | Medium — can create provenance/SBOM attestations |
id-token: write | Docker | Medium — OIDC token for signing attestations |
security-events: write | Security/SAST, Docker | Medium — can upload SARIF to Security tab |
Always prefer the narrowest permission scope. If a workflow only needs contents: read, do not grant contents: write.
Related skills
How it compares
Use golang-continuous-integration for always-on GitHub PR review automation; use a local review skill when you only need ad-hoc diff feedback outside CI.
FAQ
Which GitHub events trigger golang-continuous-integration?
golang-continuous-integration listens to pull_request types opened, synchronize, reopened, and ready_for_review, plus pull_request_review_comment created and pull_request_review submitted, so reviews rerun when PRs update or reviewers interact.
What permissions does the AI review workflow need?
golang-continuous-integration requests contents:read, issues:read, and pull-requests:write. pull-requests:write lets the workflow post and resolve comments on any PR in the repository, so restrict triggers to trusted branches when possible.
Is Golang Continuous Integration safe to install?
skills.sh reports 1 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.