Skip to content

fix(deploy): trust the artifacts, not only the diff - #25

Merged
datlechin merged 1 commit into
mainfrom
fix/deploy-trusts-artifacts-not-only-diff
Aug 17, 2026
Merged

fix(deploy): trust the artifacts, not only the diff#25
datlechin merged 1 commit into
mainfrom
fix/deploy-trusts-artifacts-not-only-diff

Conversation

@datlechin

Copy link
Copy Markdown
Member

The changed-paths pattern classifies a diff. This adds the question the diff is only ever a proxy for: is what we built older than what we built it from?

if [ "$FRONTEND_CHANGED" = false ] && bundles_are_stale; then
    echo "    the built bundles are older than the sources — rebuilding regardless of the diff"
    FRONTEND_CHANGED=true
fi

Why a classifier alone can't be right

A skipped rebuild doesn't retry itself. The next deploy diffs against the commit that skipped it, finds nothing front-end in that range, and leaves the stale bundle in place. One misclassified path strands the site until someone runs FORCE=1 by hand.

That happened twice today, in sequence:

  1. resources/data/ was classified as content → fix(compare): correct four stale counts and four wrong prices #21's corrected prices and counts deployed green and never reached the page.
  2. fix(deploy): rebuild when the data the bundle inlines changes #24 fixed the classifier — but couldn't undo its own backlog, because by then the data change was two commits behind. /compare/postico is live right now promising "Postgres plus 17 other databases" on a page whose own table says 25.

The second failure is the interesting one: the fix was correct and still left the site wrong. Any classifier will have this property, because the thing it's approximating is the artifact's freshness, and only the artifact knows that.

What it costs

One find, already written for #22's skip branch and reused here. It cannot be fooled by a pattern nobody remembered to update, and it heals a backlog on the next deploy rather than requiring a human on the server.

bundles_are_stale is defined once and consulted in both places; the test asserts the definition precedes both uses, since a function referenced before definition is an empty command in shell.

Verification

pint:  passed
Tests: 169 passed (2157 assertions)   ← REQUIRE_SSR=1, no skips
bash -n scripts/deploy.sh: syntax OK

This deploy should print the built bundles are older than the sources — rebuilding regardless of the diff and finally ship #21's corrections.

The changed-paths pattern classifies a diff. This adds the question the diff is
only ever a proxy for: is what we built older than what we built it from?

The two disagree whenever a release is skipped, and a skipped rebuild does not
retry itself. The next deploy diffs against the commit that skipped it, finds
nothing front-end in that range, and leaves the stale bundle in place — so one
misclassified path strands the site until somebody runs FORCE=1 by hand.

That is exactly what happened today, twice over. resources/data was classified
as content, so corrected prices and database counts deployed green and never
reached the page. Then the deploy that fixed the classifier could not undo its
own backlog, because by then the data change was behind it: /compare/postico is
live promising "Postgres plus 17 other databases" while its own table says 25,
two commits after the fix for it merged.

Comparing the manifest's timestamp against the front-end sources costs one
`find`, cannot be fooled by a pattern nobody remembered to update, and heals a
backlog on the next deploy instead of requiring a human on the server.
@datlechin
datlechin merged commit a256fa7 into main Aug 17, 2026
4 of 6 checks passed
@datlechin
datlechin deleted the fix/deploy-trusts-artifacts-not-only-diff branch August 17, 2026 15:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant