Skip to content

Commit d5ddce1

Browse files
authored
Merge pull request #8 from Gecode/codex/docs-cutover-checks
Index only latest documentation and complete Cloudflare cutover checks
2 parents 30ccd96 + 902d2a7 commit d5ddce1

18 files changed

Lines changed: 538 additions & 99 deletions

‎.github/workflows/workers.yml‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,17 @@ jobs:
120120
if: inputs.operation == 'deploy' && inputs.environment == 'canary' && (inputs.worker == 'both' || inputs.worker == 'documentation')
121121
run: npx wrangler deploy --env canary --config workers/docs/wrangler.jsonc
122122

123+
- name: Verify production documentation
124+
if: inputs.operation == 'deploy' && inputs.environment == 'production' && (inputs.worker == 'both' || inputs.worker == 'documentation')
125+
run: |
126+
version=$(node -p "JSON.parse(require('fs').readFileSync('workers/docs/wrangler.jsonc', 'utf8')).env.production.vars.LATEST_DOC_VERSION")
127+
for attempt in 1 2 3 4 5 6 7 8 9 10 11 12; do
128+
if node scripts/docs/smoke-worker.mjs https://www.gecode.dev "$version"; then exit 0; fi
129+
if [ "$attempt" -eq 12 ]; then exit 1; fi
130+
echo "Waiting for the production deployment to propagate (attempt $attempt)."
131+
sleep 30
132+
done
133+
123134
- name: Verify documentation canary
124135
if: inputs.operation == 'deploy' && inputs.environment == 'canary' && inputs.worker == 'documentation'
125136
run: |
@@ -133,7 +144,7 @@ jobs:
133144
134145
- name: Remove documentation canary
135146
if: inputs.operation == 'remove-canary'
136-
run: npx wrangler delete --env canary --config workers/docs/wrangler.jsonc --force
147+
run: node scripts/docs/remove-canary.mjs
137148

138149
- name: Deploy redirect Worker to staging
139150
if: inputs.operation == 'deploy' && inputs.environment == 'staging' && (inputs.worker == 'both' || inputs.worker == 'redirects')

‎docs/deployment-runbook.md‎

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,16 @@ small Pages fallback files.
1515
As checked on 5 September 2026, Cloudflare is authoritative for `gecode.dev`.
1616
Cloudflare proxies the apex GitHub Pages A records and the `www` CNAME to
1717
`gecode.github.io` with Full (strict) TLS and Always Use HTTPS. GitHub Pages
18-
still serves the production website and documentation; the Astro artifact has
19-
not been deployed.
18+
still serves the active website. The 6.4.0 documentation canary now uses R2;
19+
other versions and aliases await production rollout. Astro has not been deployed.
2020

2121
Cloudflare Email Routing is ready. Its managed MX, SPF, and DKIM records are
2222
authoritative, both forwarding destinations are verified, and the catch-all
2323
rule sends mail through the checked-in `gecode-email-routing` Worker. The
2424
private R2 documentation archive and `docs-staging.gecode.dev` Worker custom
25-
domain are live and pass the phase 4 smoke tests. No canary or production
26-
documentation Worker routes exist yet.
25+
domain are live and pass the phase 4 smoke tests. Full R2 verification passed
26+
for all nine versions (52,385 files / 1,138,898,740 bytes). The 6.4.0 canary
27+
passes live checks and its two routes are fail-closed.
2728

2829
The `cloudflare-staging`, `cloudflare-canary`, and `cloudflare-production`
2930
GitHub environments contain the stable Cloudflare account ID and the dedicated
@@ -36,7 +37,8 @@ The [5 September readiness review](migration-readiness-review-2026-09-05.md)
3637
records the local fixes, rollback build, verification limits and remaining
3738
work. Phases 2–4 below describe the original migration sequence; DNS delegation
3839
and infrastructure setup are largely complete. Staging deployment through
39-
GitHub now passes. Continue with clean-checkout website CI and phase 5 checks.
40+
GitHub and clean-checkout website CI pass. The website migration is merged
41+
in PR #7; Pages remains manual. Continue with phase 5 production rollout.
4042

4143
## Cutover overview
4244

@@ -116,12 +118,14 @@ The successful [staging run](https://github.com/Gecode/gecode.github.io/actions/
116118
used commit `5ec53f3b111a46d92c42f8b996d79b86dc39cd80` on
117119
`codex/verify-docs-staging-20260905`. That branch contains a limited Worker
118120
snapshot with a staging-only push workflow and suppresses the old Pages
119-
workflow for its branch. Land the complete website migration separately.
121+
workflow for its branch. The complete website migration was subsequently
122+
merged in [PR #7](https://github.com/Gecode/gecode.github.io/pull/7).
120123
Worker tests, dry-run builds, deployment and all HTTP smoke checks passed.
121124
The deployed `gecode-documentation-staging` version is
122125
`f9295ce3-1641-4727-b3d9-8f0c7f31b016`. The pre-rehearsal version was
123-
`8bfa5cfb-1c96-4cb6-8f57-d5d2bb85080c`. Production and canary zone routes remain
124-
absent, and the classic production pages still return 200.
126+
`8bfa5cfb-1c96-4cb6-8f57-d5d2bb85080c`. The later
127+
[canary run](https://github.com/Gecode/gecode.github.io/actions/runs/33967976199)
128+
passed from merged `main`. Classic production pages still return 200.
125129

126130
To replace the token, create a new token with those permissions, set
127131
`CLOUDFLARE_API_TOKEN` in all three environments, verify a staging deployment,
@@ -231,14 +235,21 @@ Worker route remains sufficient rollback.
231235
documentation Worker.
232236
5. Deploy the production documentation routes and rerun the smoke tests.
233237
Confirm `/doc/sitemap.xml` serves the selected version's index and that its
234-
shards contain immutable versioned URLs.
238+
shards contain only canonical `/doc/latest/...` URLs. Confirm versioned
239+
content and `/doc-latest/...` return `X-Robots-Tag: noindex`, including PDFs.
240+
`/robots.txt` must allow documentation crawling so search engines can read
241+
those headers; it continues to exclude the users archive.
235242
6. Use the workflow's `remove-canary` operation with the `canary` environment.
236243
The narrow canary route is more specific than `/doc/*` and would otherwise
237244
keep intercepting that version.
238245

239-
The production documentation routes are `/doc`, `/doc/*`, `/doc-latest`, and
240-
`/doc-latest/*`. The Worker selects aliases through `LATEST_DOC_VERSION`; it
241-
does not copy alias objects.
246+
The production documentation routes are `/doc`, `/doc/*`, `/doc-latest`,
247+
`/doc-latest/*` and `/robots.txt`. The Worker serves the same checked-in robots
248+
file as Astro so the indexing policy takes effect before the website cutover.
249+
It selects aliases through `LATEST_DOC_VERSION`; it does not copy alias objects.
250+
Only `https://www.gecode.dev/doc/latest/...` is indexable. Versioned URLs remain
251+
available for citations and downloads. Stored versioned sitemaps stay immutable;
252+
the Worker rewrites the selected sitemap responses to latest URLs.
242253

243254
Set the documentation routes to fail closed: after documentation leaves the
244255
Pages artifact, fail-open traffic would reach a missing origin path. Set the
@@ -359,7 +370,8 @@ Run `python3 scripts/build-classic-rollback.py` from the website checkout with
359370
the existing Bundler dependencies installed. It creates
360371
`dist/classic-rollback/` and `dist/classic-rollback.tar.gz`, refusing to replace
361372
an existing output directory. The 5 September rehearsal produced 91,168,795
362-
uncompressed bytes. Keep the tarball outside this checkout before cutover;
373+
uncompressed bytes. A verified copy is retained at
374+
`/Users/zayenz/gecode/website-rollback/classic-site-2026-07-15.tar.gz`;
363375
restore its contents as the Pages artifact when needed.
364376

365377
Before Astro, removing the documentation routes restores the existing origin

‎docs/gecode-release-pipeline.md‎

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ Record the website-tool commit and final manifest digest in release state.
8585
The final manifest's SHA-256 values identify the approved local release tree;
8686
do not describe them as hashes recomputed by R2.
8787

88+
Stored sitemap artifacts may contain immutable version URLs. The Worker
89+
rewrites the selected release's published sitemap index and shards to
90+
`/doc/latest/...`; submit only `/doc/sitemap.xml`. Do not rewrite completed R2
91+
objects to change indexing policy.
92+
8893
The ordinary release must not invoke this repository's historical Doxygen
8994
patcher, staging publisher, staging verifier, or promotion scripts. Those
9095
scripts may remain useful for the one-time migration of historical content,
@@ -160,8 +165,12 @@ content release, the candidate updates:
160165
- the production `LATEST_DOC_VERSION` selection.
161166

162167
Keep generated documentation and R2 credentials out of the candidate. Use
163-
`latest` aliases for human entry points, but use immutable version URLs in
164-
release news and citations.
168+
`/doc/latest/...` for human entry points and immutable version URLs in release
169+
news and citations. Only the production latest URLs are indexable and
170+
canonical. Immutable version URLs, including PDFs, and the HTTP 200
171+
`/doc-latest/...` compatibility alias carry `X-Robots-Tag: noindex`; staging
172+
documentation is also `noindex`. Producer HTML must not contain conflicting
173+
versioned canonical links; the Worker owns the served canonical selection.
165174

166175
Run the configured website quality command and validate the release,
167176
download, and documentation pages. Before changing either alias, smoke-test
@@ -197,6 +206,12 @@ caches may serve the previous version for up to five minutes. Roll back an
197206
alias failure by redeploying the previous `LATEST_DOC_VERSION`; immutable
198207
versions remain unchanged.
199208

209+
Check indexing headers on HTML and PDFs: only production `/doc/latest/...`
210+
may be indexed. Verify latest HTML canonicals and that the published sitemap
211+
index and every shard contain only latest URLs, including after alias
212+
promotion. Keep immutable and compatibility paths crawlable so crawlers can
213+
observe their `noindex` headers.
214+
200215
Staging and canary Worker deployments belong to the initial migration or to a
201216
Worker-code change. They are not required for an ordinary content-only
202217
release.

0 commit comments

Comments
 (0)