Jak używać
- Skopiuj polecenie instalacji i sprawdź źródła przed instalacją we własnym środowisku agenta.
- W oryginale sprawdź wymagane narzędzia, dane dostępowe i obsługiwane środowiska.
- Opisz dane wejściowe i oczekiwany rezultat; porównaj wynik ze źródłami.
npx skills add https://github.com/victorzhuk/skills --skill z-go-ciPrzed rozpoczęciem
- Instalacja nie obejmuje subskrypcji modelu, limitu API ani uprawnień do plików.
- Gwiazdki i instalacje pokazują aktywność, a nie niezależny test jakości lub bezpieczeństwa.
Treść z repozytorium z zachowaniem nagłówków, przykładów, kodu, tabel, linków i obrazów.
Go CI
Quick Reference
| Stage | Tool | Purpose |
|---|---|---|
| Test | go test -race | Unit tests + race detection |
| Lint | golangci-lint | Static analysis |
| Vuln scan | govulncheck | CVEs in call-reachable paths only |
| Release | GoReleaser | Cross-compiled binaries + changelog, only when a binary ships |
This is the real baseline: one pinned Go version, race-detected tests, lint, govulncheck, and GoReleaser for anything that produces a binary. See Optional hardening below for coverage gates, version matrices, SAST, dependency bots, and multi-platform Docker — each is a real, addable option, none is the default.
Test workflow
.github/workflows/test.yml:
name: test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
- run: timeout 15m go test -parallel 4 -p 2 -race -timeout 10m ./...Pin one Go version — either go-version-file: go.mod (tracks the module automatically) or the project's explicitly selected supported Go version. No version matrix by default. -count=1 on integration jobs to disable caching for service-backed tests. Set a job deadline, a process deadline, a per-test-binary timeout, and package/test worker caps; none substitutes for all the others.
Lint workflow
.github/workflows/lint.yml:
name: lint
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
- uses: golangci/golangci-lint-action@v9
with:
version: v2.13The action/linter pair above follows the official compatibility example, checked 2026-10-13. Preserve a verified project pin and check runner/Go compatibility before upgrading it.
Security workflow
.github/workflows/security.yml:
name: security
on: [push, pull_request]
jobs:
govulncheck:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with: { go-version-file: go.mod }
- run: go run golang.org/x/vuln/cmd/govulncheck@latest ./...govulncheck only reports CVEs in paths your code actually calls — prefer it over generic dependency scanners. This is the whole security job by default; gosec findings are usually surfaced through a golangci-lint linter (see [[z-go-lint]]) rather than run as their own step, and CodeQL is optional hardening (below), not part of the baseline.
Release workflow
.github/workflows/release.yml — triggers on v* tags only:
name: release
on:
push:
tags: ["v*"]
jobs:
release:
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: actions/setup-go@v5
with: { go-version-file: go.mod }
- uses: goreleaser/goreleaser-action@v6
with:
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}Minimal .goreleaser.yml: builds → main: ./cmd/myapp, goos: [linux, darwin, windows], goarch: [amd64, arm64]; archives with tar.gz and a Windows zip override; checksum; changelog: sort: asc. For a library omit builds and set release: { draft: false }. For multi-binary add one entry per cmd/*.
Docker workflow
Add the publisher to the same workflow as the required test, lint, and security jobs. All jobs must check the same commit. The following job publishes trusted default-branch pushes only; a PR cannot enter the privileged path:
jobs:
build:
needs: [test, lint, security]
if: github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
- name: Compute build metadata
id: meta
run: echo "commit-date=$(git log -1 --format=%cI)" >> "$GITHUB_OUTPUT"
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v6
with:
context: .
push: true
# VERSION: the release tag on a release build, or the version file the repo already maintains
build-args: |
VERSION=${{ github.ref_name }}
GIT_COMMIT=${{ github.sha }}
BUILD_DATE=${{ steps.meta.outputs.commit-date }}
tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
# third-party action: pinned to a version tag; full commit SHA only where supply-chain policy requires an immutable reference
- uses: aquasecurity/trivy-action@v0.36.0
with:
image-ref: ghcr.io/${{ github.repository }}:${{ github.sha }}
severity: HIGH,CRITICAL
exit-code: 0The snippets above are job ingredients, not independent publication gates: merge them under one workflow and name the vulnerability job security, or adjust needs to its actual ID. If an existing design requires workflow_run, restrict its triggering event/branch, bind checkout to the verified head SHA, and require every release check before publishing. Never execute an arbitrary PR head with registry credentials.
One docker/build-push-action call, one platform. Multi-platform builds, provenance/sbom attestations, and image scanning are real options — see Optional hardening — not part of the baseline.
The Trivy step scans the just-pushed image ref at HIGH,CRITICAL severity and is additive hardening — exit-code: 0 reports findings without failing the publish. Pin the action to its version tag (aquasecurity/trivy-action@v0.36.0); use a full commit SHA only where supply-chain policy requires an immutable reference, and bump deliberately. Keep .dockerignore correct: .git must be excluded, or every commit changes the build context and invalidates the Docker layer cache.
Repository settings: protect the actual default/release branch (required status checks, PR approval, no force push); contents: read as the default workflow permission; grant write only per-job where needed; credentials in repository secrets, never inline.
Optional hardening
Each of these is a real, well-known option and worth adding once a specific risk justifies the extra job — none of them is the default, and adding all of them preemptively is cost without a matching need:
| Hardening | What it adds | Add it when |
|---|---|---|
codecov/codecov-action coverage gate | Coverage percentage tracked and gated in PRs | Someone actually reads the coverage number and acts on drops |
Go version matrix + fail-fast: false + -shuffle=on | Compatibility across Go versions; catches order-dependent test bugs | A library needs to prove multi-version compatibility, or shuffle-sensitive flakiness is suspected |
CodeQL (github/codeql-action) | Deeper SAST than a linter | An internet-facing service needs a documented SAST story beyond golangci-lint's gosec linter |
Dependabot (.github/dependabot.yml) or Renovate (renovate.json) | Automated dependency-bump PRs | Dependency drift has actually caused a problem, or the team wants it hands-off |
Multi-platform Docker + provenance: mode=max + sbom: true + Trivy scan | linux/amd64,linux/arm64 images, supply-chain attestations, vulnerability scanning | The image ships to more than one architecture, or a consumer requires attestations |
go mod tidy && git diff --exit-code tidy-check | Catches stale go.sum | go.sum drift has bitten the project before |
OIDC federation (aws-actions/configure-aws-credentials, google-github-actions/auth, etc.) | Exchanges a short-lived, workflow-scoped identity token for cloud credentials instead of a static key in secrets | A workflow needs to authenticate to a cloud provider — prefer this over long-lived cloud secrets by default, not just for high-risk repos |
Do not
- Omit
-racefrom the test job — data races are undefined behaviour. - Cache integration test results — use
-count=1for service-backed tests. - Use
@masteror@latestfor action refs — pin to a major version tag (@v4) as the baseline; pin third-party (non-actions/, non-docker/) actions to a full commit SHA instead where supply-chain policy requires an immutable reference, since a tag can be moved. - Grant
contents: writeglobally — scope it to the release job. - Add a version matrix,
-shuffle=on, CodeQL, Dependabot, multi-platform Docker, or a tidy-check by default "just in case" — each is real, useful hardening, but add it for a specific risk, not preemptively.
Verify
gh workflow list
gh run list --workflow=test.yml --limit 5
go run golang.org/x/vuln/cmd/govulncheck@latest ./...
