Build toolchain versioning #27

Closed
opened 2026-07-07 11:12:39 +01:00 by danny · 8 comments
danny commented 2026-07-07 11:12:39 +01:00 (Migrated from gitlab.keyop.co.uk)

When building locally, the build is sensitive to tool versions used. In particular, go v1.25.x seems to give odd issues, but the versions of goreleaser, golangcilint and others also matter.

The versions of all of these tools should be stored in a file in the repository, and checked in both the CI and local builds. A clear warning should be given if tools are wrongly versioned, but the build should not exit until all tools have been checked and warnings given to avoid having to iterate over the upgrades required.

When building locally, the build is sensitive to tool versions used. In particular, go v1.25.x seems to give odd issues, but the versions of goreleaser, golangcilint and others also matter. The versions of all of these tools should be stored in a file in the repository, and checked in both the CI and local builds. A clear warning should be given if tools are wrongly versioned, but the build should not exit until all tools have been checked and warnings given to avoid having to iterate over the upgrades required.
danny commented 2026-07-07 11:15:03 +01:00 (Migrated from gitlab.keyop.co.uk)

changed the description

changed the description
claude commented 2026-07-08 08:22:36 +01:00 (Migrated from gitlab.keyop.co.uk)

Plan for this ticket:

  1. Add a .tool-versions file at the repo root pinning exact versions for go, golangci-lint, goreleaser, gitleaks, and yamllint - the tools flagged in the description plus the other two already pinned into the golang-ci CI image (golang-ci !46).
  2. Add scripts/check-tool-versions.sh, wired in as a new make check-tool-versions target: it checks every tool in .tool-versions against what's actually installed and prints a WARNING: for each mismatch or missing tool. Per the description, it checks all tools before reporting (so you see every mismatch in one pass, not one at a time) and never fails the build - a drift is a hint, not a hard gate.
  3. Wire check-tool-versions as a prerequisite of build/test/lint/package/release/coverage/coverage-html, same pattern as the existing check-build-requirements - this covers CI for free (no .gitlab-ci.yml change needed) since those jobs already run make lint/make test/make package.
  4. Update Makefile's setup-goreleaser/setup-gitleaks to install the exact pinned version from .tool-versions instead of @latest, so a fresh local install lands on the same version CI/the image use rather than drifting immediately.
  5. Document in README.md/CLAUDE.md.

Note on scope: this is warn-only, matching "the build should not exit" - I'm not raising go.mod's go 1.25.0 minimum-version directive, since that would hard-block anyone below it from building at all, which the ticket explicitly doesn't want.

Plan for this ticket: 1. Add a `.tool-versions` file at the repo root pinning exact versions for `go`, `golangci-lint`, `goreleaser`, `gitleaks`, and `yamllint` - the tools flagged in the description plus the other two already pinned into the golang-ci CI image ([golang-ci !46](https://gitlab.keyop.co.uk/keyop/docker/golang-ci/-/merge_requests/5)). 2. Add `scripts/check-tool-versions.sh`, wired in as a new `make check-tool-versions` target: it checks every tool in `.tool-versions` against what's actually installed and prints a `WARNING:` for each mismatch or missing tool. Per the description, it checks *all* tools before reporting (so you see every mismatch in one pass, not one at a time) and never fails the build - a drift is a hint, not a hard gate. 3. Wire `check-tool-versions` as a prerequisite of `build`/`test`/`lint`/`package`/`release`/`coverage`/`coverage-html`, same pattern as the existing `check-build-requirements` - this covers CI for free (no `.gitlab-ci.yml` change needed) since those jobs already run `make lint`/`make test`/`make package`. 4. Update `Makefile`'s `setup-goreleaser`/`setup-gitleaks` to install the exact pinned version from `.tool-versions` instead of `@latest`, so a fresh local install lands on the same version CI/the image use rather than drifting immediately. 5. Document in `README.md`/`CLAUDE.md`. Note on scope: this is warn-only, matching "the build should not exit" - I'm not raising `go.mod`'s `go 1.25.0` minimum-version directive, since that *would* hard-block anyone below it from building at all, which the ticket explicitly doesn't want.
claude commented 2026-07-08 08:25:25 +01:00 (Migrated from gitlab.keyop.co.uk)

mentioned in commit d5dfb4a2af

mentioned in commit d5dfb4a2afe8fe9c032b6dd4fab939b7db14f7d3
claude commented 2026-07-08 08:25:38 +01:00 (Migrated from gitlab.keyop.co.uk)

mentioned in merge request !77

mentioned in merge request !77
claude commented 2026-07-08 08:46:10 +01:00 (Migrated from gitlab.keyop.co.uk)

mentioned in commit 5fd8c5811c

mentioned in commit 5fd8c5811c69bf6602418c77c99ba0cfbae5773e
claude commented 2026-07-08 10:02:55 +01:00 (Migrated from gitlab.keyop.co.uk)

mentioned in commit 08aa545eeb

mentioned in commit 08aa545eeb1e0c1e6c36c23d083e723de9c622f4
claude commented 2026-07-08 10:03:50 +01:00 (Migrated from gitlab.keyop.co.uk)

mentioned in commit cb8f04b3e8

mentioned in commit cb8f04b3e8653f9d21f85d84c7e64eff8a1d7342
claude (Migrated from gitlab.keyop.co.uk) closed this issue 2026-07-08 10:03:51 +01:00
claude commented 2026-07-08 10:04:43 +01:00 (Migrated from gitlab.keyop.co.uk)

Merged via !77 (merge commit cb8f04b).

For the record on the pipeline #405 confusion: it actually did run against the right commit (5fd8c58, the MR head at the time) - it wasn't stale. The real cause was a shellcheck version difference: this MR pins shellcheck >= 0.10.0, and the CI image installs exactly 0.10.0 via apt, which raises SC2317 ("command appears unreachable") on the indirectly-invoked installed_version_<tool> functions in addition to SC2329 - my local shellcheck was 0.11.0, which doesn't raise SC2317 for these, so it looked clean locally. Fixed in 08aa545 (verified against a real downloaded v0.10.0 binary before pushing, not just reasoning about it) and pipeline 406 passed cleanly.

This is dev-tooling/CI-only - nothing in the shipped binary changes - so following the precedent set on #35, I'd suggest this doesn't need a version tag either. Let me know if you'd like one anyway.

Merged via !77 (merge commit `cb8f04b`). For the record on the pipeline #405 confusion: it actually did run against the right commit (`5fd8c58`, the MR head at the time) - it wasn't stale. The real cause was a shellcheck version difference: this MR pins `shellcheck >= 0.10.0`, and the CI image installs exactly `0.10.0` via apt, which raises `SC2317` ("command appears unreachable") on the indirectly-invoked `installed_version_<tool>` functions in addition to `SC2329` - my local shellcheck was `0.11.0`, which doesn't raise `SC2317` for these, so it looked clean locally. Fixed in `08aa545` (verified against a real downloaded `v0.10.0` binary before pushing, not just reasoning about it) and pipeline 406 passed cleanly. This is dev-tooling/CI-only - nothing in the shipped binary changes - so following the precedent set on #35, I'd suggest this doesn't need a version tag either. Let me know if you'd like one anyway.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
keyop-go/nfq_forwarder#27
No description provided.