Docker rig image stamps service.version / ProductVersion without the git SHA (.dockerignore excludes .git) #134

Closed
opened 2026-11-12 21:49:07 -05:00 by dohertj2 · 1 comment
Owner

Found during ScadaBridge#133 (2026-11-12). On the docker rig (built by docker/deploy.sh from main 482ac665), the OTLP Resource carries service.version = "1.0.0". A host-built process stamps 1.0.0+<git sha> (the scadaproj#55 Site run showed 1.0.0+a633005f…).

Cause: .dockerignore excludes .git/, so the in-container dotnet publish has no repository and no SourceRevisionId. Telemetry 0.3.0 defaults service.version from AssemblyInformationalVersion, so it falls back to the bare version. The same applies to anything else that reads the informational version on the rig, such as the VersionInfo used to identify a deployed commit.

This is rig-only. Wonder deploys are published from a checkout and keep the SHA.

Fix (recommended): docker/build.sh passes --build-arg SOURCE_REVISION=$(git rev-parse HEAD), and the Dockerfile adds ARG SOURCE_REVISION + -p:SourceRevisionId=$SOURCE_REVISION on the publish. That keeps .git out of the build context. Verify by rebuilding and checking /health or the OTLP Resource for +<sha>.

Found during ScadaBridge#133 (2026-11-12). On the docker rig (built by `docker/deploy.sh` from `main` `482ac665`), the OTLP Resource carries `service.version = "1.0.0"`. A host-built process stamps `1.0.0+<git sha>` (the scadaproj#55 Site run showed `1.0.0+a633005f…`). Cause: `.dockerignore` excludes `.git/`, so the in-container `dotnet publish` has no repository and no `SourceRevisionId`. Telemetry 0.3.0 defaults `service.version` from `AssemblyInformationalVersion`, so it falls back to the bare version. The same applies to anything else that reads the informational version on the rig, such as the `VersionInfo` used to identify a deployed commit. This is rig-only. Wonder deploys are published from a checkout and keep the SHA. **Fix (recommended):** `docker/build.sh` passes `--build-arg SOURCE_REVISION=$(git rev-parse HEAD)`, and the Dockerfile adds `ARG SOURCE_REVISION` + `-p:SourceRevisionId=$SOURCE_REVISION` on the publish. That keeps `.git` out of the build context. Verify by rebuilding and checking `/health` or the OTLP Resource for `+<sha>`.
dohertj2 added the type:followuptype:infrapriority:p3 labels 2026-11-12 21:49:07 -05:00
Author
Owner

Fixed on main in 7e34d7c2.

Change

  • docker/Dockerfile: the build stage declares ARG SOURCE_REVISION=, placed after COPY src/ src/ so a new commit doesn't invalidate the restore layer. The publish appends ${SOURCE_REVISION:+-p:SourceRevisionId=${SOURCE_REVISION}}, so an empty or missing arg leaves the publish command as it was.
  • docker/build.sh sets SOURCE_REVISION to git rev-parse HEAD, adding -dirty when git status --porcelain --untracked-files=no is non-empty. You can override it by exporting SOURCE_REVISION. Outside a git checkout it stays empty. The script prints Source revision: …. Both docker/deploy.sh and docker-env2/deploy.sh go through build.sh, so both are covered.
  • .git/ is still in .dockerignore.

Verification (image built from the commit; the version is read straight from the assembly's informational-version attribute)

$ docker build -t scadabridge:wt134 -f docker/Dockerfile --build-arg SOURCE_REVISION=7e34d7c2d5e86c57bc6ceae2bcaffac176496454 .
$ docker run --rm --entrypoint sh scadabridge:wt134 -c "grep -ao '1\.0\.0+[0-9a-f-]*' ZB.MOM.WW.ScadaBridge.Host.dll"
1.0.0+7e34d7c2d5e86c57bc6ceae2bcaffac176496454        # Commons.dll stamps the same

$ docker build -t scadabridge:wt134-noarg -f docker/Dockerfile .      # no build arg
... -> 1.0.0                                                           # falls back, build succeeds

I tested the build.sh revision snippet on its own: a dirty tree gives <sha>-dirty, and a non-git directory gives <none>.

I didn't redeploy the rig. It had been recreated about 20 min earlier, and another agent (#125) was running the full suite at the time. The next docker/deploy.sh from main will stamp 1.0.0+<sha>, and you can confirm it in the OTLP Resource service.version.

Family check

  • OtOpcUa docker-dev/ has the same gap: in-container publish, .git/ excluded, and the current otopcua-host:dev image stamps a bare 1.0.0. Filed as lmxopcua#893.
  • HistorianGateway (docker/Dockerfile, Dockerfile.production, f1b-gate) and BTDB docker/ aren't affected. They publish on the host and only COPY publish/, so the SHA comes from the checkout.
  • MxAccessGateway has no Dockerfile.
Fixed on `main` in **`7e34d7c2`**. **Change** - `docker/Dockerfile`: the build stage declares `ARG SOURCE_REVISION=`, placed after `COPY src/ src/` so a new commit doesn't invalidate the restore layer. The publish appends `${SOURCE_REVISION:+-p:SourceRevisionId=${SOURCE_REVISION}}`, so an empty or missing arg leaves the publish command as it was. - `docker/build.sh` sets `SOURCE_REVISION` to `git rev-parse HEAD`, adding `-dirty` when `git status --porcelain --untracked-files=no` is non-empty. You can override it by exporting `SOURCE_REVISION`. Outside a git checkout it stays empty. The script prints `Source revision: …`. Both `docker/deploy.sh` and `docker-env2/deploy.sh` go through `build.sh`, so both are covered. - `.git/` is still in `.dockerignore`. **Verification** (image built from the commit; the version is read straight from the assembly's informational-version attribute) ``` $ docker build -t scadabridge:wt134 -f docker/Dockerfile --build-arg SOURCE_REVISION=7e34d7c2d5e86c57bc6ceae2bcaffac176496454 . $ docker run --rm --entrypoint sh scadabridge:wt134 -c "grep -ao '1\.0\.0+[0-9a-f-]*' ZB.MOM.WW.ScadaBridge.Host.dll" 1.0.0+7e34d7c2d5e86c57bc6ceae2bcaffac176496454 # Commons.dll stamps the same $ docker build -t scadabridge:wt134-noarg -f docker/Dockerfile . # no build arg ... -> 1.0.0 # falls back, build succeeds ``` I tested the `build.sh` revision snippet on its own: a dirty tree gives `<sha>-dirty`, and a non-git directory gives `<none>`. I didn't redeploy the rig. It had been recreated about 20 min earlier, and another agent (#125) was running the full suite at the time. The next `docker/deploy.sh` from `main` will stamp `1.0.0+<sha>`, and you can confirm it in the OTLP Resource `service.version`. **Family check** - OtOpcUa `docker-dev/` has the same gap: in-container publish, `.git/` excluded, and the current `otopcua-host:dev` image stamps a bare `1.0.0`. Filed as lmxopcua#893. - HistorianGateway (`docker/Dockerfile`, `Dockerfile.production`, `f1b-gate`) and BTDB `docker/` aren't affected. They publish on the host and only `COPY publish/`, so the SHA comes from the checkout. - MxAccessGateway has no Dockerfile.
Sign in to join this conversation.