Chapter 11Lesson 04~105 minutes

Tags, Signed Releases, Semantic Versioning, Changelogs, and Support Lines: Diagnostics, Failure Modes, Security, and Performance

Diagnose release provenance failures: missing remote tags, moved public versions, signature/trust confusion, wrong-commit tagging, SemVer misuse, and drifting support branches.

Release diagnosticsTag immutabilityTrustSupport drift

Learning objectives

  • Apply an evidence-first diagnostic sequence to local/remote release refs.
  • Detect and contain published-tag OID mismatches without silently rewriting them.
  • Separate signature validity from signer trust and release authorization.
  • Diagnose wrong-commit tags and choose unpublished versus published correction strategies.
  • Audit support-line divergence and source/backport relationships.

1. Release diagnostic sequence

  1. Preserve evidence: local/remote tag OIDs, peeled target OIDs, signer/verification output, branch tips, changelog/release record.
  2. Inspect refs/history/config: do not create or force-move tags while the mismatch is unexplained.
  3. Identify the affected layer: local tag ref, remote tag ref, tag object/signature, released commit, version policy, or support branch.
  4. Choose the least destructive correction: usually publish a new identifier rather than rewrite distributed release history.
  5. Verify source-to-artifact provenance and communicate any correction.

2. Failure mode — “I pushed the branch, so the tag must be remote”

git show-ref --tags
git ls-remote --heads origin
git ls-remote --tags origin
git config --show-origin --get push.followTags

Branch refs and tag refs are separate. A release job should verify the intended remote tag explicitly after push rather than infer success from a branch update.

3. Failure mode — silently moving a published version tag

Compare exact local and remote ref values:

git rev-parse refs/tags/v1.4.2
git rev-parse v1.4.2^{commit}
git ls-remote --tags origin v1.4.2

If the tag has already been distributed, do not normalize the mismatch by forcing whichever side “looks newer.” Preserve both OIDs, determine what artifacts were built from each, and publish a new version/correction under the project's incident policy.

Plain force-pushing a release tag can make the same public version resolve to different source in different clones. That is a provenance incident, not routine cleanup.

4. Failure mode — “Good signature” is treated as “authorized release”

Signature verification answers whether the object validates under a key/principal known to the verifier. Release authorization requires additional questions: Was this signer expected for this repository/version? Was the key valid at release time? Is it revoked? Did the release workflow require approvals/checks? Was the resulting artifact built from the verified peeled commit?

git verify-tag v2.0.0
git show --no-patch --format=fuller v2.0.0^{commit}
git rev-parse v2.0.0^{tag}
git rev-parse v2.0.0^{commit}

5. Intentionally broken example — tag the wrong commit

Imagine the current HEAD contains one unreleased experiment, but the intended release is HEAD~1:

git log --decorate --oneline -5
git tag -a v2.1.0 -m "Release 2.1.0"
git rev-parse v2.1.0^{commit}
git show --stat v2.1.0

The command succeeded because Git defaults the target to HEAD; success does not prove that HEAD was the intended release commit. If the tag is still private, delete/recreate it only after capturing the mistaken OID. If it was published, prefer a new version name and a visible correction rather than silent replacement.

6. Intentionally broken verification — annotated is not signed

git tag -a unsigned-demo -m "Unsigned annotated tag"
git verify-tag unsigned-demo

Typical output reports that no signature is present, and the command exits non-zero. Diagnose the original cause: -a created annotation metadata but did not request signing. Do not hide this by disabling verification. Either the project's policy permits unsigned tags or the release process must create a signed replacement before publication.

7. Failure mode — applying SemVer numbers without a compatibility model

A team increments “minor every month” and “patch every Friday,” yet claims SemVer. If no declared public API exists, the numbers may not communicate the SemVer compatibility promises users expect. Diagnose the release contract first: what interface is public, what counts as incompatible, and who consumes it?

8. Failure mode — support branches drift without backport/forward-port policy

git log --graph --decorate --oneline --all --max-count=30
git rev-list --left-right --count support/1.0...trunk
git log --oneline support/1.0..trunk
git log --oneline trunk..support/1.0
git tag --contains support/1.0

Divergence is expected in maintained lines. The problem is undocumented divergence: fixes present only on one side, release tags without matching changelog entries, or cherry-picks whose source relationship cannot be traced.

9. Diagnose backport provenance, not only patch similarity

A cherry-picked backport gets a different commit ID. Record source fix OID, support-line backport OID, tests run, and release tag. Later merge/cherry-pick analysis should not assume identical OIDs are required for equivalent fixes.

git show --stat <source-fix-oid>
git show --stat <backport-oid>
git patch-id --stable < <(git show <source-fix-oid>)

The last form is shell-specific and intentionally optional; normal release records should store explicit source/backport OIDs rather than depend on ad-hoc patch-id parsing.

10. Security where release identifiers are trust anchors

  • Never treat a tag signature as proof that the built artifact itself is authentic unless the build/provenance chain connects artifact → verified source OID.
  • If a signing key is compromised, revoke/rotate it according to the backend and document which releases were affected.
  • Protect release-ref creation/deletion on the server when unauthorized tag movement would affect consumers.
  • Do not expose private signing keys in repository config, CI logs, or examples.

11. Performance only where release tooling can become expensive

Listing refs is cheap compared with repeatedly walking very large histories to generate exhaustive release notes or containment reports. Prefer bounded release ranges (v1.4.0..v1.5.0), stable machine-readable ref formats, and cached CI artifacts where appropriate. Do not sacrifice provenance checks merely to save milliseconds.

12. Red-zone release operations

Require explicit incident/change control before: force-updating a published release tag, deleting a public version tag, rewriting commits reachable from published releases, replacing signing identity without audit, or mass-mirroring refs. Preserve old OIDs and artifacts first.

13. Symptom → evidence → least destructive correction

Symptom Evidence First safe response
Tag absent remotely local show-ref + remote ls-remote Push exact intended tag ref
Local/remote tag OIDs differ tag object + peeled target OIDs Freeze mutation; trace artifacts/consumers
Signature verifies but signer unexpected verification + trust policy Treat as authorization incident
Tag points at wrong commit log + peeled target If unpublished recreate; if published create correction version
Support fix missing left/right history + release records Backport/forward-port under policy and test

14. Knowledge check

Question 1. A branch push succeeded but the release tag is missing. What should you inspect first?

Question 2. Why should a remote/local tag mismatch freeze further tag mutation?

Question 3. Why is git tag -a insufficient when policy requires signed releases?

Question 4. What is the key risk of support-branch drift?

Question 5. A signed tag validates, but an unauthorized contractor created it. Is it a trusted release?

15. Summary

Release failures are provenance failures. Preserve local/remote tag OIDs, peel targets, validate signatures and signer policy separately, confirm version semantics, and track support-line fix relationships before changing refs.

Next

Build a two-line release history and provenance report

Lesson 5 creates annotated releases, a changelog, a support branch, a backported fix with distinct OID, and exact reachability checks suitable for later CI automation.

Authoritative references

 git-tag
 git-verify-tag
 git-rev-list
 git-push

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.