Two independent defects in build metadata and developer tooling.
1. Docker images cannot report their version or commit
.dockerignore excludes .git, but the Dockerfile build stage embeds
the commit with:
-X '...Commit=$(git rev-parse HEAD 2>/dev/null || echo unknown)'
Inside the container there is no .git, so this always evaluates to unknown. Every Docker-built image reports commit: unknown, build date: unknown. Separately, ARG VERSION=dev is never passed by script/docker, so the version is dev too.
The result: a container image that cannot identify which source it was
built from. For a backup tool, being unable to answer "which build
produced this archive?" is a real operational problem, not cosmetic.
2. os.Exit(1) discards pprof output
cli.Entry() (internal/cli/entry.go:34-36) calls os.Exit(1) on any
command error. That skips main's defer pprof.StopCPUProfile()
(cmd/vaultik/main.go:26) and the entire deferred heap-profile writer
(main.go:31-44).
So profiling a failing command — often exactly the command you want to
profile — silently yields a truncated or empty profile, with no warning
that the data is unusable.
Definition of done
Version, commit, and build date are passed into the Docker build as ARGs from script/docker (computed on the host, where .git
exists), rather than being computed inside the container. Do not solve
this by un-ignoring .git — that bloats the build context and busts
the layer cache on every commit.
docker run … vaultik version prints a real version, commit sha, and
build date matching the host checkout it was built from.
A dirty working tree is reflected in the embedded version (e.g. a -dirty suffix) so an image built from uncommitted changes cannot
masquerade as a clean build.
Item 2 fixed so profiles are complete regardless of exit status:
restructure Entry/main so cleanup runs before exit — have Entry
return a status code that main turns into os.Exit after its
defers, rather than exiting from within. Do not paper over it by
duplicating the profile-flush logic at each exit site.
Manual verification recorded on this issue: run a deliberately failing
command with VAULTIK_CPUPROFILE set and confirm the resulting profile
is readable and non-empty.
Coordinate with #65, which reworks version derivation — if #65 lands
first, build on its mechanism rather than adding a second one.
make check green.
Two independent defects in build metadata and developer tooling.
## 1. Docker images cannot report their version or commit
`.dockerignore` excludes `.git`, but the Dockerfile build stage embeds
the commit with:
```
-X '...Commit=$(git rev-parse HEAD 2>/dev/null || echo unknown)'
```
Inside the container there is no `.git`, so this **always** evaluates to
`unknown`. Every Docker-built image reports `commit: unknown, build date:
unknown`. Separately, `ARG VERSION=dev` is never passed by
`script/docker`, so the version is `dev` too.
The result: a container image that cannot identify which source it was
built from. For a backup tool, being unable to answer "which build
produced this archive?" is a real operational problem, not cosmetic.
## 2. `os.Exit(1)` discards pprof output
`cli.Entry()` (`internal/cli/entry.go:34-36`) calls `os.Exit(1)` on any
command error. That skips `main`'s `defer pprof.StopCPUProfile()`
(`cmd/vaultik/main.go:26`) and the entire deferred heap-profile writer
(`main.go:31-44`).
So profiling a **failing** command — often exactly the command you want to
profile — silently yields a truncated or empty profile, with no warning
that the data is unusable.
## Definition of done
1. Version, commit, and build date are passed **into** the Docker build as
`ARG`s from `script/docker` (computed on the host, where `.git`
exists), rather than being computed inside the container. Do not solve
this by un-ignoring `.git` — that bloats the build context and busts
the layer cache on every commit.
2. `docker run … vaultik version` prints a real version, commit sha, and
build date matching the host checkout it was built from.
3. A dirty working tree is reflected in the embedded version (e.g. a
`-dirty` suffix) so an image built from uncommitted changes cannot
masquerade as a clean build.
4. Item 2 fixed so profiles are complete regardless of exit status:
restructure `Entry`/`main` so cleanup runs before exit — have `Entry`
return a status code that `main` turns into `os.Exit` after its
defers, rather than exiting from within. Do not paper over it by
duplicating the profile-flush logic at each exit site.
5. Manual verification recorded on this issue: run a deliberately failing
command with `VAULTIK_CPUPROFILE` set and confirm the resulting profile
is readable and non-empty.
6. Coordinate with #65, which reworks version derivation — if #65 lands
first, build on its mechanism rather than adding a second one.
7. `make check` green.
clawbot
added this to the 1.0.0 milestone 2026-08-09 03:44:22 +02:00
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.
Two independent defects in build metadata and developer tooling.
1. Docker images cannot report their version or commit
.dockerignoreexcludes.git, but the Dockerfile build stage embedsthe commit with:
Inside the container there is no
.git, so this always evaluates tounknown. Every Docker-built image reportscommit: unknown, build date: unknown. Separately,ARG VERSION=devis never passed byscript/docker, so the version isdevtoo.The result: a container image that cannot identify which source it was
built from. For a backup tool, being unable to answer "which build
produced this archive?" is a real operational problem, not cosmetic.
2.
os.Exit(1)discards pprof outputcli.Entry()(internal/cli/entry.go:34-36) callsos.Exit(1)on anycommand error. That skips
main'sdefer pprof.StopCPUProfile()(
cmd/vaultik/main.go:26) and the entire deferred heap-profile writer(
main.go:31-44).So profiling a failing command — often exactly the command you want to
profile — silently yields a truncated or empty profile, with no warning
that the data is unusable.
Definition of done
ARGs fromscript/docker(computed on the host, where.gitexists), rather than being computed inside the container. Do not solve
this by un-ignoring
.git— that bloats the build context and buststhe layer cache on every commit.
docker run … vaultik versionprints a real version, commit sha, andbuild date matching the host checkout it was built from.
-dirtysuffix) so an image built from uncommitted changes cannotmasquerade as a clean build.
restructure
Entry/mainso cleanup runs before exit — haveEntryreturn a status code that
mainturns intoos.Exitafter itsdefers, rather than exiting from within. Do not paper over it by
duplicating the profile-flush logic at each exit site.
command with
VAULTIK_CPUPROFILEset and confirm the resulting profileis readable and non-empty.
first, build on its mechanism rather than adding a second one.
make checkgreen.