---
key: blazor.rollback-tag
title: 2026-07-11 — Pre-removal Blazor rollback tag `blazor-final` (#205)
status: active
since: '2026-07-11'
supersedes: none
superseded-by: none
rule: The commit immediately preceding the Blazor-removal merge is tagged `blazor-final` (not a `v*` tag, so it doesn't trigger a prod release build) as the documented rollback/restore path.
signals: '`git tag -a blazor-final`, `ersatztv:blazor-final` test-image restore path · paths: none · issues: #205'
mechanics: '`git tag blazor-final`'
---

Removal-gate item #205: the removal PR deletes both the Blazor reference implementation and the
`/system/health` escape hatch, so a post-deletion parity gap would otherwise be an archaeology exercise
(guessing which release tag still matches `main` minus Blazor). Decision + procedure, to run as the **first
action of the Step 2 deletion PR merge** (not before — `main` moves until then):

1. On the `main` commit **immediately preceding** the removal merge (the last commit that still contains
   `ErsatzTV/Pages/**`), cut an annotated tag and push it:
   `git tag -a blazor-final -m "Last commit with the legacy Blazor Server UI (pre-#91-phase-b removal)"`
   then `git push origin blazor-final`. The tag name is **`blazor-final`** (not `v*`) so it does **not**
   trigger the `v*` prod-release build in `.gitea/workflows/docker-build.yml`.
2. **Restore path** (if a gap surfaces post-removal): `git checkout blazor-final` → `docker build -f
   docker/Dockerfile -t ersatztv:blazor-final .` → pin the **test** container to that image while the gap is
   fixed forward on `main`. Alternatively `git revert` the single deletion merge commit (keep the deletion as
   one squash/merge commit specifically to make this a one-liner).
3. Document the tag + restore path in the removal PR body; update this entry with the tag's commit sha when
   cut.

Not cut this session — `main` still carries Blazor and will advance before the removal PR.
