feat(govulncheck): add call-dagger-govulncheck.yaml, fix module-pin blind spot - #161
Merged
Merged
Conversation
…lind spot Closes #157. The go module gained Govulncheck in stuttgart-things/dagger v0.128.0 (#342). This is the other half: a Dagger function nobody can call from a workflow gets used once. Two calls rather than one. The module's own doc comment explains why: with --fail-on-finding it returns an error, so a `govulncheck ... export --path` never reaches the export and the report goes missing exactly when somebody wants it. The report pass writes the file, the artifact upload sits between them, and the gate pass decides the build. The second call hits the cache from the first and costs nothing. The gate pass is pinned to --format text regardless of the report format, because govulncheck sets exit 3 on a finding only in text mode -- json, sarif and openvex exit 0 and expect the caller to parse. The module handles that internally with a second text pass; asking for it directly is cheaper. fail-on-finding defaults to true, unlike the gosec template's report-only posture. Reachability analysis is what earns that: govulncheck stays quiet about a CVE whose affected function is never called, so a finding means something is genuinely exposed. Also fixes a Renovate blind spot the new template would have inherited. The dagger customManager matched `dagger-module-version:` but not the full-path form (github.com/stuttgart-things/dagger/<mod>@vX.Y.Z inline in a default), so eleven pins across six workflows were unwatched and had drifted to v0.103.0, v0.114.0 and v0.82.1 while every watched pin sat at v0.128.0 -- the same drift the manager was written against, one notation further. One matchString covers them independently of the input name. The two scan templates are bumped to v0.128.0 here so the family is consistent. The rest (call-dagger-ko-build, call-push-kustomize, call-go-release, call-go-microservice-release) are left to Renovate now that it can see them; the v0.82.1 pins are a 46-release jump that wants looking at on its own, not folded into this change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DGshyN1b9amKkrRRUubhbM
This was referenced Sep 5, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #157. First consumer:
stuttgart-things/schmetterpause#86part 2.What is here
1.
call-dagger-govulncheck.yaml— new, modelled oncall-dagger-security-scan.yaml, same conventions (actions pinned by SHA with the tag as a trailing comment, dagger module pinned to a released tag).2. A Renovate blind spot, fixed — and it is the more consequential half.
3. The two scan templates bumped to
@v0.128.0.The call form, and the thing #157 could not know yet
#157 left one question open: "the
export --pathstep runs after the scan, and a failing scan would skip it and lose the report."go/vuln.go@v0.128.0answers it in its own doc comment — the module does not solve this, the template has to:So: report pass → artifact upload → gate pass. The upload sits between them deliberately; behind the gate it would be skipped exactly when the report matters.
Second finding from the implementation: exit 3 is a text-mode-only signal. With
json,sarifandopenvexgovulncheck exits 0 even on a reachable finding, on the assumption that the caller parses. The module compensates with an internal second text pass; asking for--format textdirectly on the gate step is cheaper and does the same thing. So the report honoursformat, the gate is always text.fail-on-findingdefaults totrue, unlike the gosec template's report-only posture — the argument in #157, and a default is the only place it gets expressed.The Renovate blind spot
The dagger
customManagermatcheddagger-module-version:but not the full-path form (github.com/stuttgart-things/dagger/<mod>@vX.Y.Zinline in adefault:). Eleven pins across six workflows were therefore unwatched:call-dagger-security-scan.yamlgo@v0.103.0→ bumped herecall-dagger-trivy-image-scan.yamltrivy@v0.103.0→ bumped herecall-dagger-ko-build.yamlgo@v0.103.0call-push-kustomize.yamlkcl@v0.114.0call-go-release.yamlrelease@v0.82.1,kcl@v0.82.1call-go-microservice-release.yamlrelease/go/crane/kcl@v0.82.1Every watched pin sits at
v0.128.0. This is the same drift the manager's own description was written against ("HAD DRIFTED TO FIVE DIFFERENT VERSIONS ACROSS FIVE WORKFLOWS BECAUSE NOTHING WAS WATCHING IT"), one notation further along. One matchString covers all of them independently of the input name, and matches only literal pins — never the@${{ inputs.… }}form.Expect a Renovate PR straight after this merges that lifts the remaining pins. The
v0.82.1ones are a 46-release jump and want looking at on their own, which is why they are not folded in here.Verified, and not
pre-commit runover all four changed files: passes, includingcheck-github-workflowsschema validation.dagger-version: 0.21.9≥engineVersion: v0.21.8fromgo/dagger.json.One knock-on for #85
no-cacheis exposed because the vulnerability database changes independently of the source, so a cached hit can report a clean tree against a weeks-old database. It sets a timestamp cache-buster in the module, which means withno-cache: truethe gate pass misses the report pass's cache and scans twice over. Suited to aschedule:run, not to every pull request — hence the defaultfalse.And a note for the pinning decision #85 leaves open: #86 argued
@mainwas acceptable for the Trivy call because it is report-only and holds no credentials. That argument does not carry over here — withfail-on-finding: truean upstream change to this workflow can turn a consumer's build red. This is the first call site where a tag instead of@mainactually earns its keep.🤖 Generated with Claude Code
https://claude.ai/code/session_01DGshyN1b9amKkrRRUubhbM