The generator is unpinned; the runtime library is pinned. CI therefore runs whatever templ released most recently against a library it may not match.
Why it matters
task check runs templ generate before linting and testing. The *_templ.go files are committed. So the moment upstream templ changes its codegen, CI regenerates different Go than what is in the repo — and depending on how the diff falls, that surfaces as a lint failure, a compile error against the pinned runtime, or silently different rendered HTML that no test covers.
Nothing fails today, which is the problem: the drift is invisible until an upstream release lands, and then it fails on an unrelated commit and looks like that commit's fault. This estate has already lost time to a templ version skew once.
Found while running task check locally: templ was absent on koala, and installing @latest rather than the pinned version would have silently reproduced the CI configuration rather than the repo's.
Proposed
Pin the generator to the library:
go install github.com/a-h/templ/cmd/templ@v0.3.1020
Better, so the two cannot drift apart again: add a tool directive (Go 1.24+) or a tools.go, and install with go install github.com/a-h/templ/cmd/templ so the version comes from go.mod itself and Dependabot-style bumps move both together.
Optionally add a CI guard: run templ generate then git diff --exit-code on *_templ.go, so regenerating in CI must be a no-op. That turns silent drift into an explicit failure at the commit that caused it.
Done when
The templ binary version used in CI is derived from go.mod, not @latest.
Regenerating in CI produces no diff against the committed *_templ.go.
Notes
Found while implementing #10, 2026-08-28. Same class as the pinned-vs-latest drift already recorded for this estate.
## Problem
`.gitea/workflows/cd.yml:49`:
```yaml
go install github.com/a-h/templ/cmd/templ@latest
```
`go.mod:5`:
```
require github.com/a-h/templ v0.3.1020
```
The generator is unpinned; the runtime library is pinned. CI therefore runs whatever `templ` released most recently against a library it may not match.
## Why it matters
`task check` runs `templ generate` before linting and testing. The `*_templ.go` files are **committed**. So the moment upstream `templ` changes its codegen, CI regenerates different Go than what is in the repo — and depending on how the diff falls, that surfaces as a lint failure, a compile error against the pinned runtime, or silently different rendered HTML that no test covers.
Nothing fails today, which is the problem: the drift is invisible until an upstream release lands, and then it fails on an unrelated commit and looks like that commit's fault. This estate has already lost time to a templ version skew once.
Found while running `task check` locally: `templ` was absent on koala, and installing `@latest` rather than the pinned version would have silently reproduced the CI configuration rather than the repo's.
## Proposed
Pin the generator to the library:
```yaml
go install github.com/a-h/templ/cmd/templ@v0.3.1020
```
Better, so the two cannot drift apart again: add a `tool` directive (Go 1.24+) or a `tools.go`, and install with `go install github.com/a-h/templ/cmd/templ` so the version comes from `go.mod` itself and Dependabot-style bumps move both together.
Optionally add a CI guard: run `templ generate` then `git diff --exit-code` on `*_templ.go`, so regenerating in CI must be a no-op. That turns silent drift into an explicit failure at the commit that caused it.
## Done when
- The `templ` binary version used in CI is derived from `go.mod`, not `@latest`.
- Regenerating in CI produces no diff against the committed `*_templ.go`.
## Notes
Found while implementing #10, 2026-08-28. Same class as the pinned-vs-latest drift already recorded for this estate.
Fixed by mathias/cad@8a0c76e as part of the cad-atlas merge.
The root cause was as described: templ generate ran at build time against a CLI installed with @latest, while the runtime came from go.mod. Worse, after the merge go mod tidyremoveda-h/templ entirely — the only importers were generated files that are neither tracked nor present, so tidy saw no requirement, and the image build then failed on generated code importing a module go.mod no longer required.
Fixed at the cause rather than by pinning the CLI: the _templ.go files are now committed (matching cobalt-dingo's precedent), so go mod tidy keeps the runtime and the build needs neither a templ install nor network. Verified with buildctl --opt target=atlas-runtime.
Fixed by `mathias/cad@8a0c76e` as part of the cad-atlas merge.
The root cause was as described: `templ generate` ran at build time against a CLI installed with `@latest`, while the runtime came from `go.mod`. Worse, after the merge `go mod tidy` *removed* `a-h/templ` entirely — the only importers were generated files that are neither tracked nor present, so tidy saw no requirement, and the image build then failed on generated code importing a module go.mod no longer required.
Fixed at the cause rather than by pinning the CLI: the `_templ.go` files are now **committed** (matching cobalt-dingo's precedent), so `go mod tidy` keeps the runtime and the build needs neither a templ install nor network. Verified with `buildctl --opt target=atlas-runtime`.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
.gitea/workflows/cd.yml:49:go.mod:5:The generator is unpinned; the runtime library is pinned. CI therefore runs whatever
templreleased most recently against a library it may not match.Why it matters
task checkrunstempl generatebefore linting and testing. The*_templ.gofiles are committed. So the moment upstreamtemplchanges its codegen, CI regenerates different Go than what is in the repo — and depending on how the diff falls, that surfaces as a lint failure, a compile error against the pinned runtime, or silently different rendered HTML that no test covers.Nothing fails today, which is the problem: the drift is invisible until an upstream release lands, and then it fails on an unrelated commit and looks like that commit's fault. This estate has already lost time to a templ version skew once.
Found while running
task checklocally:templwas absent on koala, and installing@latestrather than the pinned version would have silently reproduced the CI configuration rather than the repo's.Proposed
Pin the generator to the library:
Better, so the two cannot drift apart again: add a
tooldirective (Go 1.24+) or atools.go, and install withgo install github.com/a-h/templ/cmd/templso the version comes fromgo.moditself and Dependabot-style bumps move both together.Optionally add a CI guard: run
templ generatethengit diff --exit-codeon*_templ.go, so regenerating in CI must be a no-op. That turns silent drift into an explicit failure at the commit that caused it.Done when
templbinary version used in CI is derived fromgo.mod, not@latest.*_templ.go.Notes
Found while implementing #10, 2026-08-28. Same class as the pinned-vs-latest drift already recorded for this estate.
Fixed by
mathias/cad@8a0c76eas part of the cad-atlas merge.The root cause was as described:
templ generateran at build time against a CLI installed with@latest, while the runtime came fromgo.mod. Worse, after the mergego mod tidyremoveda-h/templentirely — the only importers were generated files that are neither tracked nor present, so tidy saw no requirement, and the image build then failed on generated code importing a module go.mod no longer required.Fixed at the cause rather than by pinning the CLI: the
_templ.gofiles are now committed (matching cobalt-dingo's precedent), sogo mod tidykeeps the runtime and the build needs neither a templ install nor network. Verified withbuildctl --opt target=atlas-runtime.