Skip to content

Build1 publisher3 min readPublished

A build target greps a fake version string out of both binaries to prove the ldflags symbol exists

In Anton Brilliantov's Go fleet the pipelines read the service manifest. What is left for a person to check is whether the version string is really inside the shipped binary.

The Engineer · Build desk

What happened

  • Anton Brilliantov, who is carving a live PHP monolith into Go services, says one path to production covers every service because the pipelines read off the manifest what they are shipping.
  • Go's linker ignores an -X flag aimed at a symbol that does not exist without a warning or a non-zero exit, so the build goes green and the variable inside the binary keeps its default value of dev.
  • The fix is a build target that compiles both binaries with a deliberately fake version string and fails when grep cannot find that string in the output.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • exposure An audit trail whose actor field says dev cannot attribute a write to a release, so the record is unusable for exactly the question it exists to answer.
  • constraint Duplicated flags mean only the both-files fix counts, and the partial fix is worse than none because it makes the copy an engineer inspects the honest one.
  • capability A grep for a probe literal turns a whole class of silent misconfiguration into a build failure, whatever the cause, so the control does not depend on anyone reading a standard.
  • decision Teams keeping per-service pipelines now have a stated cost to weigh, and Brilliantov's post asks for the counterargument.

The check is two lines of shell and its result has one bit. The `verify-version` target builds both binaries with a deliberately fake version string, greps that string out of the produced binaries, and fails if it is not there [15]. In the form Brilliantov published, the build passes `-X <platform-symbol>.Version=vX.Y.Z-probe` and then runs `strings bin/server | grep vX.Y.Z-probe`, and empty output means the symbol is wrong [16]. "It doesn't matter whether the symbol is wrong because someone renamed a package, or because the template was wrong, or because a copy-paste dropped a path segment - the probe string is either in the bytes or it isn't," he wrote [17].

Because the probe substitutes a fixed literal for the release version, what it asserts is that the linker can write to that symbol at all [2]. A pipeline that hands the build a bad version value still ships a binary the probe accepts.

The duplication is where this gets expensive. The flags live in the `Makefile` and in the `Dockerfile`, so fixing the `Makefile` alone leaves a local build stamping correctly while the image, the thing that actually runs, does not [12]. Two files with two states each give four combinations. One of them is correct. One puts the honest stamp on the copy an engineer would inspect and the wrong one on production [1]. "The flags target the platform's symbol, and they get fixed in both files, together, or the fix isn't a fix," Brilliantov wrote [13].

This came out of the template. It historically carried a dead target, so every service generated from it inherited an `-X` aimed at a symbol that isn't there [11]. Brilliantov's objection to answering that with a coding standard is stated as a test of controls: "A rule you can violate while the build stays green is not a control" [14].

Brilliantov's claim is that deployment stopped being a per-service artefact because there is exactly one place that says what a service is made of, and that the three pipelines are the same for every service in the fleet [4][18]. The published post breaks off inside the diagram of that delivery surface, before the three pipelines and the three human decisions are set out [21]. So the portable piece here is the verification, and it ports only if your services all import the same platform symbol and both build paths point at it [13].

Everything else about the failure argues for the check independently of how you ship. The linker ignores an `-X` aimed at a missing symbol with no warning and no non-zero exit, the image is pushed, the tag looks right in the registry, and the variable inside the binary still holds `dev` [6][7]. That default then rides into the audit trail, where every record claims it was written by `dev`, and into the version attribute on the trace, so the spans of three different releases are indistinguishable [8][9]. Brilliantov says the error is invisible everywhere except the version field, and that you find it on the day you needed the version to find something [10].

He is explicit that the tradeoff is arguable: "Maybe you looked at it and decided a per-service pipeline is worth the duplication. I'd genuinely like to hear which" [20].

What to watch

  • Whether the rest of the series publishes the three pipelines and names the three decisions left to a person.
  • Whether verify-version is wired into CI for every service or only run locally by the engineer who remembers it.
  • Whether a future package rename of the platform symbol is caught by the probe across the whole fleet.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories