Skip to content

Promote develop to main: restore the deploy, and run the release script in validation - #80

Merged
ptr727 merged 1 commit into
mainfrom
develop
Aug 9, 2026
Merged

Promote develop to main: restore the deploy, and run the release script in validation#80
ptr727 merged 1 commit into
mainfrom
develop

Conversation

@ptr727

@ptr727 ptr727 commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Promotes develop to main. One commit, already reviewed and squash-merged to develop as #79.

main currently cannot deploy. The previous promotion carried a regression that fails the deploy at the assemble step, so this is the promotion that makes a deploy possible again rather than an incremental one.

The regression this fixes

deploy/make-release.sh has two callers, and the change that made git-restore-mtime mandatory only considered one. CI restores with a pinned action that runs the tool from the action's own directory, so it is genuinely absent from PATH there:

4. Restore file mtimes step: success         <- the action worked
5. Assert mtimes were restored step: success <- the guarantee held
8. Assemble release bundle step: FAILURE
   git-restore-mtime not found, as either 'git-restore-mtime' or 'git restore-mtime'
9-12. Install key / Upload / Flip / Verify: skipped

Nothing was uploaded and nothing flipped. The failure landed before the deploy key was installed, which is the two-phase design working.

MTIME_RESTORED lets a caller that has already restored skip the restore only. The assertion always runs, so a caller that sets it without having restored fails the same check as one that never tried. Demonstrated three ways against a PATH carrying hugo and no mtime tool:

Case Result
knob set, tool absent, tree restored installs, exit 0
no knob, tool absent the failure that broke the deploy
knob set, tree not restored assertion fails, exit 1

Why it reached a deploy, which is the part worth carrying

validate-task.yml linted make-release.sh and never ran it. The only thing that executed it was a dispatch-only workflow, so a broken caller contract was invisible to every pull request. shellcheck cannot see that class: the defect was in what the script demanded of its caller rather than in its syntax.

Validation now assembles a release into a scratch root, and that step is the build and URL-contract gate rather than a second one beside it, since the script runs hugo --panicOnWarning and check-url-parity itself. Confirmed on #79's own CI run: the assemble step took the MTIME_RESTORED path, built, passed the contract, and installed a release into the scratch root.

A knob letting the script reuse an existing public/ under CI was rejected. It would make the script behave differently in CI than locally, and a CI-only divergence in this exact script is what caused the failure being fixed.

Cost, measured rather than asserted

Validation is about 15 seconds slower. Per-step timings, since a first attempt at attributing this was wrong and corrected on #79:

Step before now
Assemble release bundle absent 16s
Build site, Check URL contract ~1-2s each folded into the above

The increase is the price of executing the release script rather than only linting it, not of building twice.

Merge

Plain --merge, never --delete-branch: on a develop -> main promotion that flag deletes develop.

Nothing publishes on this merge. After it, a deploy from main becomes possible again, and the first restored deploy is still expected to link zero for the reason recorded in TODO.md.

* Let CI assemble a release, and run the script that assembles it

make-release.sh has two callers and the last change only considered one.
It began requiring git-restore-mtime on PATH, which CI cannot satisfy: the
workflows restore with a pinned action that runs the tool from the
action's own directory. The staging deploy failed at the assemble step
with the tool genuinely absent, before any transport, so nothing was
uploaded and nothing flipped.

MTIME_RESTORED lets a caller that restored already skip the restore. It
skips the work and never the assertion, so a caller setting it without
having restored fails the same check as one that never tried. Verified all
three ways, with a PATH carrying hugo and no mtime tool:

  knob set, tool absent, tree restored      installs, exit 0
  no knob, tool absent                      the failure that broke the deploy
  knob set, tree NOT restored               assertion fails, exit 1

The second half is why this reached a deploy at all. validate-task.yml
linted make-release.sh and never ran it, so the only thing that executed
it was a dispatch-only workflow, and a broken caller contract could not be
seen by any pull request. shellcheck cannot see that class: the defect was
in what the script demanded of its caller, not in its syntax.

Validation now assembles a release into a scratch root, which exercises
the deploy's path short of the transport: the mtime contract, the build,
the URL gate, the precompression, the staging tree and the release stamp.
The root is empty, so no previous release exists and the hard-link guard
does not apply. That step reproduces case A above, so this specific defect
now fails on the pull request that introduces it.

Its checkout takes fetch-depth: 0, since the restore has no commit to date
a file from without history.

Comments in the touched files are cut back to the house style: one
sentence per line, no wrapped prose, no incident narrative. Several had
grown across the day's edits, which is the creep the style rule names.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Name what MTIME_RESTORED skips, and what it does not

The comment, the log line and the reference row all said the knob skips
the work and not the assertion, which reads as a distinction without a
stated boundary. Each now says the two effects plainly: no restore is run
and the tool is not required, while the assertion runs regardless.

The log line said the mtimes were restored by the caller, which describes
a state rather than the decision being taken. It now says the restore is
being skipped and the assertion still follows.

Found by Copilot review on #79.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Make the release assembly the build gate, not a second one

The assemble step re-ran the two most expensive things the job had already
done: make-release.sh does rm -rf public, rebuilds with the same
--panicOnWarning, and re-runs check-url-parity. Measured on this branch,
the job went from 38s to 48s for no additional coverage.

The standalone build and URL-contract steps are removed and the script is
the gate. It runs the identical commands, so nothing is lost, and the
reasoning that belonged to those steps moves to where the work now
happens.

The alternative was a knob letting the script reuse an existing public/ in
CI. That was rejected: it makes the script behave differently under CI
than locally, and a CI-only divergence in this script is precisely what
broke the deploy this pull request is fixing.

Found by Copilot review on #79, as a suppressed comment.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 9, 2026 15:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR promotes the already-reviewed develop changes (from #79) to main to restore the broken deploy path by fixing the make-release.sh caller contract around git-restore-mtime, and by exercising that contract during validation (so regressions fail in PR CI rather than during deploy).

Changes:

  • Add and document MTIME_RESTORED=1 as an explicit caller contract so workflows that already restored static/ mtimes can skip make-release.sh’s internal restore while still running the mtime assertion.
  • Update validation to restore mtimes and run deploy/make-release.sh (including Hugo build + URL contract checks) to prevent deploy-only failures from slipping past CI.
  • Update the deploy workflow to set MTIME_RESTORED=1 when calling make-release.sh, aligning it with the pinned restore action behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
ENVIRONMENT.md Documents the new MTIME_RESTORED knob and its exact behavior/guarantees.
deploy/make-release.sh Implements MTIME_RESTORED handling to skip only the restore step while keeping the assertion gate.
checks/check-env-docs.py Adds MTIME_RESTORED to the KNOBS set so env-doc validation stays complete.
.github/workflows/validate-task.yml Restores mtimes and runs make-release.sh during validation to catch caller-contract regressions.
.github/workflows/deploy-site-task.yml Sets MTIME_RESTORED=1 when invoking make-release.sh after restoring mtimes via the pinned action.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@ptr727
ptr727 merged commit 35cb2a8 into main Aug 9, 2026
5 checks passed
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.

2 participants