Files
ersatztv/scripts/update-openapi.sh
T
timothy b93a7d33ff docs(578): record the update-openapi.sh incremental-skip trap that made my own check vacuous
Verifying the regenerated OpenAPI artifacts, I re-ran the pipeline against an already-built tree and
got a clean git diff — which I nearly reported as "artifacts confirmed". It was a no-op.

When the project is already built and unchanged, MSBuild skips the document-generation work but
still runs RenameOpenApiFiles (AfterTargets), whose Move then fails with MSB3680 "ErsatzTV.json does
not exist" — nothing produced it. The script exits non-zero correctly, but I had piped it
(`./scripts/update-openapi.sh 2>&1 | tail -2`), so the shell reported tail's 0 and the failure was
invisible. A clean diff after a regeneration that never regenerated proves nothing.

Caught it with a positive control: tamper all three artifacts, re-run, see which get restored.
v1.d.ts came back (npm run generate:api is unconditional) while v1.json and endpoint-index.md stayed
tampered. A `touch` on a compiled source then made the real regeneration run and restore all three
byte-exact, which is the verification that actually means something.

CI is unaffected — the api-docs job restores into a clean tree, so generation never skips. This is a
local-dev hazard only, and it is the same shape as the bug arc this branch is about: a check that
reports success without examining anything, exactly what LIMIT was doing to the row bound.
2026-07-27 03:10:36 +02:00

27 lines
1.6 KiB
Bash
Executable File

#! /usr/bin/env bash
cd "$(git rev-parse --show-toplevel)" || exit
REPO_ROOT="$(pwd)"
# Only regenerate the endpoint index if the spec build succeeded, so a failed
# build can't render docs/endpoint-index.md from a stale/partial v1.json.
#
# A full `dotnet build` MUST run before the doc-gen target: OpenApiGenerateDocumentsOnBuild
# is false, so `-t:GenerateOpenApiDocuments` alone does NOT compile the project — it invokes
# dotnet-getdocument against ErsatzTV.dll + ErsatzTV.deps.json, which don't exist in a clean
# tree (e.g. the CI api-docs job, which only restores). Without the build the target fails with
# "The specified deps.json … does not exist" (exit 129). Build first, then generate.
#
# LOCAL-DEV SHARP EDGE: if the project is ALREADY built and nothing changed, MSBuild skips the
# document-generation work but still runs RenameOpenApiFiles (AfterTargets), whose Move then fails
# with MSB3680 "ErsatzTV.json does not exist" — because nothing produced it. The script correctly
# exits non-zero, but a caller that pipes this (`./scripts/update-openapi.sh | tail`) sees the
# PIPELINE's status, i.e. tail's 0, and reads a no-op as success — leaving stale artifacts to fail
# the blocking api-docs CI job. Before verifying artifacts are current, `touch` a file the project
# compiles (or check this script's own exit status, unpiped). CI is unaffected: it restores into a
# clean tree, so the generation never skips.
(cd ErsatzTV && dotnet build && dotnet build -t:GenerateOpenApiDocuments) || exit
cd "$REPO_ROOT" || exit
python3 scripts/generate-endpoint-index.py