Stamp the git tag or short commit into the binary (closes #4)
check / check (push) Successful in 3m35s

A plain `docker build .` now stamps bsdaily's version: the VERSION
build argument when one is given, otherwise `git describe --tags
--always` on the .git in the build context, as the canonical
Dockerfile does. The build fails if .git is there and the version
still comes out empty, dev or unknown. A host `make` build stamps the
same `git describe`, or dev. bsdaily logs the version on the first
line of every run and prints it with --version; a build that stamps
nothing, or an empty value, reports dev.

Judgement call: the build line also takes the canonical -trimpath and
-s -w.
One //nolint (gochecknoglobals): -X can only set a package-level
variable.

Model: opus-5-5
Co-authored-by: clawbot <sneak+clawbot@sneak.cloud>
This commit was merged in pull request #5.
This commit is contained in:
2026-10-06 18:41:51 +02:00
committed by clawbot
parent c16f177575
commit f5c7614768
5 changed files with 59 additions and 7 deletions
+19 -3
View File
@@ -47,7 +47,9 @@ FROM golang:1.26.4-alpine@sha256:3ad57304ad93bbec8548a0437ad9e06a455660655d9af01
COPY --from=lint /src/go.sum /dev/null COPY --from=lint /src/go.sum /dev/null
COPY --from=test /src/go.sum /dev/null COPY --from=test /src/go.sum /dev/null
ARG VERSION=dev RUN apk add --no-cache git
# A tar-stream context keeps the sender's file owners, which git refuses.
RUN git config --system --add safe.directory /src
WORKDIR /src WORKDIR /src
@@ -58,8 +60,22 @@ RUN go mod download
# Copy source code # Copy source code
COPY . . COPY . .
# Build (pure Go, no CGO required since we use modernc.org/sqlite) # Build (pure Go, no CGO required since we use modernc.org/sqlite).
RUN CGO_ENABLED=0 go build -o /bsdaily ./cmd/bsdaily # The VERSION build arg when one is given, otherwise
# `git describe --tags --always` on the .git in the build context. With
# .git present, a version that is still empty, dev or unknown fails the
# build: git is missing or could not read the checkout.
ARG VERSION
RUN VERSION="${VERSION:-$(git describe --tags --always)}"; \
if [ -e .git ]; then \
case "$VERSION" in ""|dev|unknown) \
echo "version is '$VERSION' although .git is present" >&2; \
exit 1 ;; \
esac; \
fi; \
CGO_ENABLED=0 go build -trimpath \
-ldflags="-s -w -X main.Version=${VERSION}" \
-o /bsdaily ./cmd/bsdaily
# Runtime stage # Runtime stage
# alpine:3.21, 2026-06-28 # alpine:3.21, 2026-06-28
+5 -3
View File
@@ -1,7 +1,9 @@
.PHONY: all bootstrap setup check test lint fmt fmt-check build clean deps test-coverage test-integration install release release-snapshot docker hooks .PHONY: all bootstrap setup check test lint fmt fmt-check build clean deps test-coverage test-integration install release release-snapshot docker hooks
# Version number # Stamped into the binary: the same `git describe` a plain `docker build .`
VERSION := 0.1.0-dev # runs, or dev when it prints nothing (outside a git checkout, or where git is
# missing). ?= so that a VERSION already in the environment takes precedence.
VERSION ?= $(or $(shell git describe --tags --always 2>/dev/null),dev)
# Default target # Default target
all: bsdaily all: bsdaily
@@ -36,7 +38,7 @@ lint:
# Build binary (pure Go; no CGO required since we use modernc.org/sqlite). # Build binary (pure Go; no CGO required since we use modernc.org/sqlite).
bsdaily: internal/*/*.go cmd/bsdaily/*.go bsdaily: internal/*/*.go cmd/bsdaily/*.go
CGO_ENABLED=0 go build -o $@ ./cmd/bsdaily CGO_ENABLED=0 go build -ldflags "-X main.Version=$(VERSION)" -o $@ ./cmd/bsdaily
# Clean build artifacts. # Clean build artifacts.
clean: clean:
+17 -1
View File
@@ -189,6 +189,7 @@ A single run proceeds as follows:
bsdaily # extract the snapshot date minus one day bsdaily # extract the snapshot date minus one day
bsdaily --date 2026-06-27 # extract a single specific day bsdaily --date 2026-06-27 # extract a single specific day
bsdaily --from 2026-06-01 --to 2026-06-27 # extract an inclusive range bsdaily --from 2026-06-01 --to 2026-06-27 # extract an inclusive range
bsdaily --version # print the version and exit
``` ```
Flags: Flags:
@@ -197,9 +198,24 @@ Flags:
`--from`/`--to`. `--from`/`--to`.
- `--from YYYY-MM-DD` — start of an inclusive range (requires `--to`). - `--from YYYY-MM-DD` — start of an inclusive range (requires `--to`).
- `--to YYYY-MM-DD` — end of an inclusive range (requires `--from`). - `--to YYYY-MM-DD` — end of an inclusive range (requires `--from`).
- `-v`, `--version` — print the version and exit.
With no flags, the tool extracts the day before the latest snapshot. All With no flags, the tool extracts the day before the latest snapshot. All
progress is logged as structured `slog` text to stderr. progress is logged as structured `slog` text to stderr; the first line of every
run carries the version.
The version is set at link time and depends on how the binary was built:
- `docker build .` takes it from the `VERSION` build argument when one is given,
otherwise from `git describe --tags --always` on the `.git` in the build
context. The build fails if `.git` is there and the version still comes out
empty, `dev` or `unknown`. With neither `.git` nor `VERSION`, the binary
reports `dev`.
- `script/docker`, `script/cibuild` and `make docker` pass the host's
`git describe --tags --always --dirty` as `VERSION`, so on a modified tree the
version ends in `-dirty`. When that prints nothing, they pass `unknown`.
- `make` stamps the host's `git describe --tags --always`, without `-dirty`, or
`dev` when that prints nothing.
## Merging dumps back into a database ## Merging dumps back into a database
+4
View File
@@ -19,6 +19,10 @@ verification, and atomic-publish paths.
# Completed Steps # Completed Steps
- 2026-10-06: A plain `docker build .` and a host `make` build stamp the git tag
or short commit into the binary, which `bsdaily` logs on the first line of
every run and prints with `--version`
(https://git.eeqj.de/sneak/bsdaily/issues/4).
- 2026-10-06: Added the canonical `.golangci.yml`, moved the lint phase to - 2026-10-06: Added the canonical `.golangci.yml`, moved the lint phase to
golangci-lint v2.14.0, and fixed the code to pass it golangci-lint v2.14.0, and fixed the code to pass it
(https://git.eeqj.de/sneak/bsdaily/issues/6). (https://git.eeqj.de/sneak/bsdaily/issues/6).
+14
View File
@@ -20,7 +20,18 @@ var (
errFromAfterTo = errors.New("is after --to") errFromAfterTo = errors.New("is after --to")
) )
// Version is the git tag or short commit, set at link time with
// -X main.Version=... by the Dockerfile and the Makefile. A build that sets
// nothing, or sets it empty, reports dev.
//
//nolint:gochecknoglobals // -X can only set a package-level variable
var Version string
func main() { func main() {
if Version == "" {
Version = "dev"
}
logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{ logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
Level: slog.LevelInfo, Level: slog.LevelInfo,
})) }))
@@ -31,8 +42,11 @@ func main() {
rootCmd := &cobra.Command{ rootCmd := &cobra.Command{
Use: "bsdaily", Use: "bsdaily",
Short: "Extract a single day's data from the latest daily snapshot", Short: "Extract a single day's data from the latest daily snapshot",
Version: Version,
SilenceUsage: true, SilenceUsage: true,
RunE: func(_ *cobra.Command, _ []string) error { RunE: func(_ *cobra.Command, _ []string) error {
slog.Info("starting", "version", Version)
targetDates, err := parseTargetDates(dateFlag, fromFlag, toFlag) targetDates, err := parseTargetDates(dateFlag, fromFlag, toFlag)
if err != nil { if err != nil {
return err return err