Conversation
The binary and the landing page ship on different schedules. Deploying a copy fix should not require cutting a vump release, which would tell everyone pinning the binary that something changed when nothing did. vump.toml now declares two projects, told apart by the shape of their tag: `main` tracks Cargo.toml and Cargo.lock and tags `v1.2.3`, `website` tracks website/package.json and tags `website-v1.2.3`. Each shape triggers one workflow, and `vump check` infers the project from the tag, so neither has to name --project. The shapes cannot collide: a website tag does not start with `v`. website/package.json gets its version back. It was dropped when the site had no release line, on the grounds that a number nobody maintains is exactly the kind of lie this repository exists to prevent — but vump now keeps it in step with the tag, which is what makes it true rather than decorative. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The masthead used to fetch the newest release from the GitHub API on every page load. Unauthenticated, that is sixty requests an hour per address, so the version would simply vanish for anyone behind a busy NAT — and a landing page that says different things to different people at different moments is not one anybody can quote. It is a declared input now: src/content/release.json, read at build time. Reading Cargo.toml instead is the obvious move and is wrong. Cargo.toml holds the version most recently bumped, which is not the version most recently published — right now it says 0.8.0-alpha.0 for a tag that was never pushed, while the newest release is 0.7.0. The page would advertise a download with no binaries behind it, which is the defect this tool exists to prevent, pointed at itself. Pre-releases are skipped for the same reason: the button beside the number hands over the newest stable, and stating an alpha next to it would be two answers to one question. `pnpm bump:vump` picks the newest stable from the repository's own tags, so pointing the site at a new release is one offline command rather than a lookup that can be rate-limited. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The deployed page shipped an empty #root: correct in a browser, and nothing at all to a crawler, a link preview, or an agent fetching it. That is a strange thing for a page whose entire job is being read by someone deciding whether to try the tool. `vite build` still produces the client bundle; a second pass builds entry-server.tsx to dist-ssr/, prerender.mjs inlines that HTML into #root, and the intermediate is deleted rather than deployed. main.tsx hydrates when #root already has children and renders normally when it does not, which is what the dev server serves. Three things had to stop depending on the browser for this to render on the server, and none of them are workarounds: The theme now lives on the document element rather than in React state. The pre-paint script in index.html is what keeps the page from flashing the wrong theme, and mirroring that into state would have given the server-rendered HTML a theme it cannot know. Reading the attribute at the moment of the click cannot drift from what is on screen. The theme toggle renders both icons and hides one in CSS. Choosing between them in JavaScript would mean the prerendered HTML picks a theme the visitor may not be using, and hydration would swap it under them. The entrance animations are gated on a `js` class the pre-paint script adds. Without that, content held at opacity zero waiting for an observer would leave a scripting-disabled client staring at a blank page — the prerendered markup would be there, and invisible. The site's own address is settled while we are here: vump.codehacks.io, at the root, so the base-path environment variable and its .env are gone. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A bug report is a screenshot. The badge is fixed to the corner rather than placed in the footer so it appears in every one of them without the reporter scrolling to the bottom first, and it names the pair that identifies a build: the site's version and the commit it was built from. The version is read straight from package.json, which is the file vump keeps in step with the website-v* tag. A separately computed value could drift from that tag; this cannot. The commit arrives as a build-time variable the deploy workflow sets, and reads as "local" when there is no deploy to name. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
release-website.yml builds website/ and publishes it to Pages, gated on `vump check` agreeing the tag matches website/package.json — the same gate the binary's release has, for the same reason: find out before the work, not after the deploy. It uses the composite action rather than the build in the checkout, which is the opposite of what release.yml does and deliberate. release.yml verifies the binary it is about to publish, where an older vump cannot catch a regression in the very code being released. Here the subject is the website's own version, so there is no such regression to miss, and building vump would drag a Rust toolchain and two minutes into a job that ships static files. Installing is `pnpm install --frozen-lockfile`. The committed lockfile is the deploy's declared input, so nothing is resolved or discovered at deploy time and a rebuild of the same commit produces the same bytes. website.yml runs typecheck, lint, format and build on pull requests that touch the site, so a broken page is caught in review rather than by a failed deploy. It is a separate workflow with a path filter rather than a job in test.yml, which has no path filters and would otherwise run the Rust suite for a copy edit. Also anchors release.yml's tag glob to a digit. `v*` matches `voldemort`; it is the same fix the sibling repository already made, and with a second tag shape in play the trigger should be exact about which one it wants. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The action was given `working-directory`, which it does not accept. With no package.json at the repository root — this is a Rust project with a site in a subdirectory — it had nowhere to read a pnpm version from and stopped before installing anything. `package-json-file` is the input that exists, and it is the whole point of keeping `packageManager` in website/package.json: one declared version for local development and CI both. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Every `uses:` in the repository was checked against its published releases rather than assumed. actions/checkout was a major behind and moves to v7; setup-node, configure-pages, upload-pages-artifact, deploy-pages, attest, upload-artifact, download-artifact and pnpm/setup were already current. dtolnay/rust-toolchain stays on `stable`, which is a moving reference that action documents rather than a pin left behind. release-website.yml also loses its workflow_dispatch trigger. On a manual run `github.ref_name` is a branch, so the version gate — `vump check` against the pushed tag — has nothing to check and the deploy would either fail or, worse, be made to skip the one step it exists for. A deploy is a tagged release here. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
okcodes
had a problem deploying
to
github-pages
September 11, 2026 04:03 — with
GitHub Actions
Failure
This branch had an error being deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Wires the landing page up for GitHub Pages, following the shape already proven
in the sibling repository: a second vump project, a
website-v*tag line, and adeploy workflow gated on
vump check.Two release lines
vump.tomlnow declares two projects, told apart by the shape of their tag.mainCargo.toml,Cargo.lockv1.2.3release.ymlwebsitewebsite/package.jsonwebsite-v1.2.3website/to Pages, viarelease-website.ymlvump checkinfers the project from the tag, so neither workflow names--project. The shapes cannot collide — a website tag does not start withv—and
release.yml's glob is anchored to a digit while we are here, sov*nolonger matches
voldemort.Shipping a site-only change is
vump patch --project website --through push. Novump version, nothing said to anyone pinning the binary.
website/package.jsongets its version back. It was dropped when the site hadno release line, on the grounds that a number nobody maintains is a lie — vump
now keeps it in step with the tag, which is what makes it true.
The version the page states
Read at build time from
website/src/content/release.json. The masthead used tofetch it from the GitHub API on every page load: unauthenticated that is sixty
requests an hour per address, so the version would vanish for anyone behind a
busy NAT, and the page would say different things to different people.
Reading
Cargo.tomlinstead is the obvious move and is wrong.Cargo.tomlholds the version most recently bumped, not the version most recently
published — right now it says
0.8.0-alpha.0for a tag that was never pushed,while the newest release is
0.7.0. The page would advertise a download with nobinaries behind it, which is this tool's own defect pointed at itself.
pnpm bump:vumppicks the newest stable tag from the repository itself, somoving the site to a new release is one offline command, not a lookup that can
be rate-limited. Pre-releases are skipped: the download button hands over the
newest stable, and stating an alpha beside it would be two answers to one
question.
Prerendering
dist/index.htmlnow ships with the page rendered into it. A second Vite passbuilds
src/entry-server.tsx,scripts/prerender.mjsinlines the result into#rootand deletes the intermediate, andmain.tsxhydrates when#rootalready has children.
Three things had to stop depending on the browser, none of them workarounds:
the theme now lives on the document element instead of React state (the
pre-paint script is what prevents the flash, and mirroring it into state would
have given the server HTML a theme it cannot know); the theme toggle renders
both icons and hides one in CSS, so hydration cannot swap it under the visitor;
and the entrance animations are gated on a
jsclass, without which ascripting-disabled client would get the prerendered markup at opacity zero —
there, and invisible.
Version badge
Fixed to the corner, not in the footer: a bug report is a screenshot, and this
needs to be in every one without the reporter scrolling first. It shows the
site's version — read from the file vump keeps in step with the tag, so it
cannot drift — and the commit the deploy was built from.
Workflows
release-website.ymlbuilds and deploys on awebsite-v*tag. It uses thecomposite check action rather than the build in the checkout, which is the
opposite of
release.ymland deliberate: what is verified here is the website'sversion, not the binary about to be published, so there is no regression an
older vump could miss — and building one would drag a Rust toolchain into a job
that ships static files.
website.ymlruns typecheck, lint, format and build on pull requests touchingthe site. Separate workflow with a path filter rather than a job in
test.yml,which has none and would run the Rust suite for a copy edit.
Installing is
pnpm install --frozen-lockfilein both: the committed lockfileis the declared input, so a rebuild of the same commit produces the same bytes.
Every
uses:in the repository was checked against its published releasesrather than assumed.
actions/checkoutwas a major behind and moves to v7across all four workflows; everything else was already current.
dtolnay/rust-toolchainstays onstable, which is the moving reference thataction documents rather than a pin left behind.
release-website.ymlhas noworkflow_dispatch. On a manual rungithub.ref_nameis a branch, so the version gate would have nothing to check— a deploy here is a tagged release or it does not happen.
Address
vump.codehacks.io, at the root — so the base-path environment variable and its.envare gone, and canonical,og:urlandog:imageare absolute. The customdomain goes in the repository's Pages settings; a workflow-based deploy needs no
CNAMEfile.Before the first deploy
Three things outside this branch: point the DNS at Pages, set the custom domain
and
Source: GitHub Actionsin the repository's Pages settings, thenvump patch --project website --through push. The rootREADME.mdgets thelink once the domain answers.