aquasecurity/trivy
Development workflow
This page is a quick reference for the day-to-day mechanics of contributing to Trivy: branching, building, committing, pushing, and getting a PR merged.
1. Set up a working tree
git clone https://github.com/aquasecurity/trivy.git
cd trivy
go build -o ./trivy ./cmd/trivyTrivy targets the Go version pinned in go.mod (currently go 1.25.8). Older Go versions will not compile.
2. Pick or open an issue
For non-trivial work, open an issue or comment on an existing one before opening a PR. Tag the issue with what kind of change it is — kind/bug, kind/feature, or discuss — and assign yourself if you intend to take it.
3. Branch, code, test
Branch from main. Make focused commits — small commits are easier to review and easier to revert.
git checkout -b fix/sbom-spdx-license
# ... edit, test ...
go test ./...Run targeted tests to iterate quickly:
go test ./pkg/sbom/spdx/...
go test ./pkg/iac/scanners/terraform/... -run TestParser4. Lint
The project uses golangci-lint with the config in .golangci.yaml. Many rules matter (gocritic, errcheck with check-blank: true, depguard rules that ban golang.org/x/exp/slices, golang.org/x/exp/maps, and io/ioutil).
golangci-lint runCommon issues to look out for:
- Use the standard library
slicesandmapspackages, notgolang.org/x/exp/*. - Use
osorioinstead of the deprecatedio/ioutil. - Wrap errors with
golang.org/x/xerrors.Errorf("...: %w", err)(the codebase has not yet migrated to standard libraryfmt.Errorfin most places). - Don't use blank assignments to silently drop errors (
errcheckwill flag them).
5. Commit
Trivy uses Conventional Commits because release-please (.github/workflows/release-please.yaml) generates CHANGELOG.md from PR titles. Common prefixes:
feat:— user-visible feature.fix:— bug fix.refactor:— internal restructuring with no behavior change.chore:— tooling, dependency, or housekeeping changes.docs:— documentation only.test:— test changes only.
Append a scope when it helps: feat(image): support OCI 1.1 compatibility images. The semantic-pr workflow validates the title.
6. Push and open a PR
Push to your fork and open a PR against main. Fill in the PR template; the auto-close-issue workflow (.github/workflows/auto-close-issue.yaml) will link the issue when you reference it.
PRs are run through a multi-job CI matrix:
- Lint
- Unit tests (
go test ./...) - Integration tests (
integration/) — gated by build tag. - Module tests — for the WebAssembly module subsystem.
- Doc tests — for
docs/. - Helm chart tests — for
helm/trivy/.
If you need to skip flaky CI on docs-only changes, the bypass-test.yaml workflow supports it for maintainers.
7. Address review
Responding to review comments is normal. Maintainers prefer "fixup" commits during review and a clean commit history at merge time, but the project squash-merges most PRs so the in-PR commit shape is less important than the title and final diff.
8. Merge and release
Once approved and green, a maintainer merges the PR. release-please opens (or updates) a release PR that bumps the version in .release-please-manifest.json, regenerates CHANGELOG.md, and tags a release. When that release PR merges, goreleaser (driven by .github/workflows/release.yaml) builds and uploads binaries, container images, and Homebrew taps.
Canary builds (Dockerfile.canary, .github/workflows/canary.yaml) are produced from every push to main, so your change is consumable as a canary the moment it lands.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.