ci: pin templ CLI to go.mod runtime version - #597
Conversation
`templ generate` is run with `templ@latest`, but the runtime library is pinned in go.mod. When the upstream CLI emits new symbols (e.g. `templ.ResolveAttributeValue` introduced in v0.3.1020) that the pinned runtime (v0.3.1001) doesn't have, every CI run after the upstream release fails to build. Resolve the CLI version from go.mod so the generator and runtime move in lockstep. Future bumps via Renovate/Dependabot remain a single go.mod change. Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
|
Note Gemini is unable to generate a review for this pull request due to the file types involved not being currently supported. |
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
There was a problem hiding this comment.
Automated approval for maintainer PR
All automated quality gates passed. See SECURITY_CONTROLS.md for compensating controls.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #597 +/- ##
=======================================
Coverage 69.94% 69.94%
=======================================
Files 34 34
Lines 3437 3437
=======================================
Hits 2404 2404
Misses 873 873
Partials 160 160
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Updates the CI workflow to install the templ generator CLI at the same version as the github.com/a-h/templ runtime pinned in go.mod, preventing CI breakages when upstream releases a new CLI that generates code requiring newer runtime symbols.
Changes:
- Replace
templ@latestinstallation in CI with ago list -m-resolved version fromgo.mod. - Add inline workflow comments explaining the motivation and failure mode being avoided.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Same fix as the ci.yml pin extended to release.yml and container.yml, which also ran `templ@latest`. Without this, container and release builds would still break the next time upstream's CLI introduced a symbol the pinned runtime lacks. Caught by Copilot review on #597. Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
There was a problem hiding this comment.
Automated approval for maintainer PR
All automated quality gates passed. See SECURITY_CONTROLS.md for compensating controls.
Gitleaks/betterleaks scans the full git history and flags two base64 strings in old revisions of `docs/operations/deployment.md` as generic API keys. Both are placeholder K8s Secret values (`your_secure_password`, `svc_ldap_readonly@company.com`) — not real secrets. The current file still carries the same examples. Suppress the historical fingerprints so the secret-scanning gate can go green; the rule continues to detect any new credentials introduced after this commit. Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
There was a problem hiding this comment.
Automated approval for maintainer PR
All automated quality gates passed. See SECURITY_CONTROLS.md for compensating controls.
The existing godoc only described `Version`, but the same var block also declares `CommitHash` and `BuildTimestamp`. Cover all three so the comment matches the block. Also gives CodeQL a Go file to analyze on this PR — the `code_scanning` ruleset rule blocks merges when the standalone `CodeQL` aggregator returns NEUTRAL, which it does on PRs that touch no Go sources. Real fix lives in the reusable workflow at netresearch/.github (separate PR). Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
There was a problem hiding this comment.
Automated approval for maintainer PR
All automated quality gates passed. See SECURITY_CONTROLS.md for compensating controls.
|
## Summary CodeQL's Go extraction runs an autobuilder (`go build ./...`). Repos that gitignore generated sources (`templ generate`, `protoc`, OpenAPI clients, etc.) hit extraction warnings like: ``` Warning: encountered errors extracting package github.com/.../internal/web/templates ``` The standalone `CodeQL` aggregator then returns `NEUTRAL` because no real analysis was produced. Branch rulesets with a `code_scanning` rule on `tool: CodeQL` interpret `NEUTRAL` as "still expecting" and block merge — even on PRs that didn't touch any Go. Real example: [netresearch/ldap-manager#597](netresearch/ldap-manager#597), which only changes `.github/workflows/*.yml` + `.gitleaksignore`, is BLOCKED with the message: > Code scanning is still expecting 1 result from CodeQL for `a71e5c9` or `cdd69f7`. ## Change Add an optional `pre-build-cmd` input modeled after [`go-check.yml`](https://github.com/netresearch/.github/blob/main/.github/workflows/go-check.yml). Runs **after** CodeQL `init` (Go is already on `PATH`) and **before** `analyze` invokes the autobuilder, so generators see a complete module tree. ```yaml jobs: codeql: uses: netresearch/.github/.github/workflows/codeql.yml@main with: languages: auto pre-build-cmd: | go install github.com/a-h/templ/cmd/templ@\$(go list -m -f '{{.Version}}' github.com/a-h/templ) templ generate ``` Backward compatible: new input defaults to `''` and the step is conditional via `if:`. Existing callers (this repo's own CodeQL workflow, every Go repo using `languages: auto`) are unaffected. ## Test plan - [ ] CI on this PR passes - [ ] Caller test: open a follow-up PR on `netresearch/ldap-manager` that uses `pre-build-cmd: |` to run `templ generate` and confirm the standalone `CodeQL` check no longer goes `NEUTRAL`
The autobuilder hits extraction failures on internal/web and internal/web/templates because *_templ.go is gitignored. The standalone `CodeQL` aggregator then returns NEUTRAL, which the `code_scanning` ruleset on main treats as "still expecting a result" and blocks merge — even on PRs that don't touch any Go. Use the new `pre-build-cmd-go` input on the reusable workflow (netresearch/.github#119) to install templ at the go.mod-pinned version and run `templ generate` after CodeQL init and before the extractor walks the source tree. Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
There was a problem hiding this comment.
Automated approval for maintainer PR
All automated quality gates passed. See SECURITY_CONTROLS.md for compensating controls.
`go install` drops binaries into $(go env GOPATH)/bin, which is not on PATH for the bash shell the reusable codeql.yml spawns — `templ: command not found, exit code 127`. Same workaround already in container.yml. Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
There was a problem hiding this comment.
Automated approval for maintainer PR
All automated quality gates passed. See SECURITY_CONTROLS.md for compensating controls.
The codeql.yml change in this branch passes `pre-build-cmd-go` to run `templ generate` before CodeQL extraction. The go-app template's codeql.yml is the generic version (no templ workaround) — only repos with templ-style codegen need this. Record the deliberate divergence so check-template-drift.yml stops failing. Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
There was a problem hiding this comment.
Automated approval for maintainer PR
All automated quality gates passed. See SECURITY_CONTROLS.md for compensating controls.
The repo's required-status-checks ruleset requires
`Build :main container image / Build Container` to pass before
merge. container.yml only triggered on `push: branches: [main]`,
so the check never fired for PRs OR for merge-queue candidates —
PRs sit BLOCKED with "Expected — Waiting for status to be reported"
indefinitely.
Add `merge_group: {}` so the build runs against the merge candidate
and produces the required status. The push trigger stays in place
so direct admin pushes to main still rebuild the rolling :main image.
Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
There was a problem hiding this comment.
Automated approval for maintainer PR
All automated quality gates passed. See SECURITY_CONTROLS.md for compensating controls.
|



Summary
CI runs
go install github.com/a-h/templ/cmd/templ@latest && templ generatebefore every build. The runtime library is pinned ingo.mod(v0.3.1001), but the CLI floats. When upstream releases a CLI that emits a new symbol the pinned runtime doesn't have, every PR fails to build until someone notices and bumps both in lockstep.This happened on 2026-05-10: templ v0.3.1020 was published at 09:04 UTC and started emitting
templ.ResolveAttributeValue. The next CI run (PR #593 at 10:18 UTC) failed withundefined: templ.ResolveAttributeValueacross 5 jobs (failing run). Re-running main's last green build would fail the same way.Fix
Resolve the CLI version from
go.modat workflow runtime:gois already on PATH in the reusablego-check.ymlworkflow (set up beforepre-build-cmdruns), and the existingbash -euo pipefailwrapper means a failedgo listaborts the step instead of silently installingtempl@.The follow-up bump from
v0.3.1001→v0.3.1020will arrive via Renovate/Dependabot as a normalgo.modPR — the CLI follows automatically.Test plan