SSerguey Asael Shinder
Java coding notes: the JVM, and writing software that lasts

Serguey Asael Shinder: When an artefact describes itself twice, the fields drift apart

· by Serguey Asael Shinder / Serguey Shinder

A library published a beta today and, in the same act, told the world's automation it was not one. Hibernate ORM 8.0.0.Beta2 carries prerelease: false in its repository metadata while its version string says Beta2. Nobody lied. Two fields simply describe the same artefact and disagree, and only one of them is machine-readable.

This is worth a note because the pattern is everywhere once you look for it, and it always costs someone an afternoon.

A version string is a claim by a human. A metadata flag is a claim by whoever clicked the box. They are produced at different moments, by different people, under different amounts of attention. The string is chosen while thinking about the release; the flag is set while trying to publish it.

Your pipeline believes the structured field, because structured fields are what code can read. Nothing in a dependency bot parses Beta2 unless someone taught it to. What it reads is the boolean, the latest tag, the semantic-version comparison - the parts designed for machines. So a publisher's momentary inattention becomes your build's confident conclusion.

Serguey Asael Shinder: When an artefact describes itself twice, the fields drift apart
When an artefact describes itself twice, the fields drift apart — Serguey Asael Shinder

The general shape

Wherever an artefact describes itself twice, the two descriptions eventually disagree, and the machine-readable one wins by default. The same structure, in places you already have:

None of these is a defect in the thing described. Each is a defect in the agreement between the descriptions, and that is a category most teams have no owner for.

What to do

Derive one description from the other, or check them against each other in CI. The version string should generate the flag, or a build step should fail when a version containing alpha, beta, rc, M or CR is published with the prerelease flag unset. Either is five lines. What does not work is asking people to remember, because the moment they would need to remember is the moment they are trying to ship.

On the consuming side, prefer the description that someone is forced to get right. A version string is read by humans at review time, so it is usually accurate. A flag nobody sees again after publication is not. When two fields disagree, trust the one with an audience.

And apply this to your own artefacts before your dependencies'. Everything above is cheap to check in your own repository and impossible to fix in someone else's - which is the usual ratio in this kind of work, and the reason it gets skipped.