Skip to content

fix(ci): actually publish docs.conduction.nl — gh-pages is not the live site - #497

Merged
rubenvdlinde merged 2 commits into
mainfrom
fix/docs-publish-to-worker
Aug 17, 2026
Merged

fix(ci): actually publish docs.conduction.nl — gh-pages is not the live site#497
rubenvdlinde merged 2 commits into
mainfrom
fix/docs-publish-to-worker

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

deploy-docs.yml has never published this site. It pushes the build to
gh-pages — and for three months everyone, including me, read that as "the docs
deployed".

docs.conduction.nl is served by the Cloudflare Worker conduction-docs
(Workers Static Assets), the same pattern as the ~33 other *.conduction.nl
docs sites. That Worker was deployed from Forgejo
(.forgejo/workflows/documentation-deploy.yml). When Forgejo was retired the
deploy stopped and the Worker froze at its 2026-06-01 build.

Why nothing reported it

Every instrument said fine:

Signal Said Actually
gh-pages branch updating correct, and unread by the live site
GitHub Pages config cname: docs.conduction.nl, protected_domain_state: verified serves nobody
The public URL HTTP 200 content from June

Three green lights over a site three months stale. The gap was never visible
because nothing measured whether the bytes reached the public host.

What this adds

A publish-worker job that deploys the gh-pages build to the Worker, with two
deliberate choices:

A missing secret FAILS, it does not skip. A skipped publish is precisely the
silence that hid this: the workflow goes green while the live site quietly stops
tracking main. Red here means "the docs did not reach the public site", which
is the truth worth reporting.

The last step round-trips the bytes. It compares an md5 of the index.html
just published against what https://docs.conduction.nl/ actually serves, and
fails if they differ. HTTP 200 is not evidence — the stale Worker answered 200
for months.

Required before this can go green

Two repo secrets, neither of which currently exists here (the repo holds only
ALGOLIA_CRAWLER_ID / ALGOLIA_CRAWLER_SECRET, and total_count for
org-visible secrets is 0):

  • CF_API_TOKEN — Cloudflare API token scoped to Account → Workers Scripts → Edit
  • CF_ACCOUNT_IDa2d03dfcc6758e48447baee66d7a8fa5

Until they are added this job fails with an explicit annotation naming the
missing secrets. That is intended: the failure already existed, it simply
had no way to announce itself.

Note on the current state

The site is live and current right now — I deployed this build to the Worker by
hand to verify the procedure end to end (app-health 200, 61,600 bytes, and a
page that exists only in the new build also 200). This PR is what stops it going
stale again on the next docs commit.

Finding a Worker-backed hostname

For anyone who hits this next: GET /accounts/{id}/workers/domains. Worker
custom domains do not appear under zones/{id}/workers/routes — checking
routes and seeing nothing is what led me to exclude Workers for an hour.

@rubenvdlinde

Copy link
Copy Markdown
Contributor Author

Restructured after review of what this gate should actually assert.

Before: the job failed when CF_API_TOKEN / CF_ACCOUNT_ID were absent.
That alarms on configuration, which is a proxy for the real defect and would
have put this repo into a red state it could not clear without a new credential.

Now: the job asserts "the public host serves what we just built" — an
md5 of the published index.html against https://docs.conduction.nl/ — and
fails only on drift.

That distinction is the entire lesson of the three-month outage. gh-pages was
updating, GitHub Pages reported the domain verified, and the URL answered 200.
All three were true while the site was stale. Only a byte comparison against the
live host could see it.

Behaviour:

Credentials Site state Result
absent already current pass — nothing to do, nothing to alarm about
absent stale after a docs change fail, naming the two secrets to add
present any deploys, then verifies the bytes landed

Verified against production as it stands: the built index.html and the live
homepage are the same object (a154356d873f), so this gate passes today rather
than importing a red state.

The deploy step is skipped rather than failed when credentials are missing —
but the skip cannot hide anything, because the verification step runs
unconditionally and is what decides the job.

@rubenvdlinde
rubenvdlinde merged commit cbedb2e into main Aug 17, 2026
40 of 42 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.

1 participant