docs: verify the base path on the real host
The real-host smoke test was the migration's #1 production-only failure mode and had never run. It has now run, without taking the site down: the Astro dist was published to `pages` additively under two previously-unused paths (`_astro/` and `_verify/summary/`), so all ten live pages stayed up, then force-pushed away. Astro's base-prefixed absolute asset URLs resolve on the Pages Server — that was the actual risk, and it is now proven rather than assumed. Trailing-slash redirects match `trailingSlash: 'always'`. Also corrects two things the guide got wrong: - a `?v=$(git rev-parse --short HEAD)` cache-busting idiom. The Pages Server caches for ten minutes keyed on path, so a query string never busted it; the guide was telling operators to trust a check that could not work. A file you just deleted keeps serving 200 until the cache expires. - the claim that a push to `main` publishes. It no longer does, and must not until cutover. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -54,8 +54,8 @@ flowchart LR
|
|||||||
E[Edit main] --> V[pnpm run gate]
|
E[Edit main] --> V[pnpm run gate]
|
||||||
V --> C[Commit]
|
V --> C[Commit]
|
||||||
C --> P[Push main]
|
C --> P[Push main]
|
||||||
P --> G[Gitea Actions: gate + build]
|
P --> G[Gitea Actions: gate]
|
||||||
G --> B[Force-push dist to pages]
|
G -.manual dispatch.-> B[Build + force-push dist to pages]
|
||||||
B --> S[Gitea Pages Server]
|
B --> S[Gitea Pages Server]
|
||||||
S --> L[Live URL]
|
S --> L[Live URL]
|
||||||
```
|
```
|
||||||
@@ -108,9 +108,16 @@ committing.
|
|||||||
|
|
||||||
### 5. CI publication and its manual fallback
|
### 5. CI publication and its manual fallback
|
||||||
|
|
||||||
On a successful `main` push, Gitea Actions builds `dist/` and force-pushes it to
|
Gitea Actions builds `dist/` and force-pushes it to `pages`. This force-push is
|
||||||
`pages`. This force-push is intentional: `pages` is machine-owned generated
|
intentional: `pages` is machine-owned generated output, and no person or other
|
||||||
output, and no person or other workflow may write it.
|
workflow may write it.
|
||||||
|
|
||||||
|
**For the duration of the Astro migration, publication is manual.** The
|
||||||
|
`publish` job runs only from a `workflow_dispatch` with its `publish` input set
|
||||||
|
to true — a push to `main` runs the gate and stops there. The reason: `dist/`
|
||||||
|
currently holds three HTML files (`/summary/` plus the two `hands-on/` fixtures)
|
||||||
|
against the ten pages the live branch serves, so publishing on every push would
|
||||||
|
take the site down to a stub. Task 20 (cutover) makes it automatic again.
|
||||||
|
|
||||||
This Gitea's act-runner registration is kept in an `emptyDir`. A pod restart
|
This Gitea's act-runner registration is kept in an `emptyDir`. A pod restart
|
||||||
silently removes the registration; if a site does not update, check and
|
silently removes the registration; if a site does not update, check and
|
||||||
@@ -135,7 +142,7 @@ git worktree remove /tmp/ai-for-dummies-pages
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -sS -o /dev/null -w '%{http_code}\n' \
|
curl -sS -o /dev/null -w '%{http_code}\n' \
|
||||||
"https://netcracker.pages.marcospaulo.dev.br/ai-for-dummies/summary/?v=$(git rev-parse --short HEAD)"
|
"https://netcracker.pages.marcospaulo.dev.br/ai-for-dummies/summary/"
|
||||||
```
|
```
|
||||||
|
|
||||||
Also check a nested static asset; base-path problems usually appear on assets
|
Also check a nested static asset; base-path problems usually appear on assets
|
||||||
@@ -143,9 +150,17 @@ first:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -sS -o /dev/null -w '%{http_code}\n' \
|
curl -sS -o /dev/null -w '%{http_code}\n' \
|
||||||
"https://netcracker.pages.marcospaulo.dev.br/ai-for-dummies/hands-on/starter/?v=$(git rev-parse --short HEAD)"
|
"https://netcracker.pages.marcospaulo.dev.br/ai-for-dummies/hands-on/starter/"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**The Pages Server caches for ten minutes** (`x-pages-cache: true`,
|
||||||
|
`cache-control: public, max-age=600`), and the cache is keyed on the _path_. A
|
||||||
|
`?v=$(git rev-parse …)` query string does **not** bust it — that idiom used to
|
||||||
|
be in this guide and it never worked. After a publish, a URL can keep serving
|
||||||
|
the previous content, or keep serving a file you just deleted, for up to ten
|
||||||
|
minutes. Budget for that before concluding a deploy failed. Check
|
||||||
|
`last-modified` and `etag` with `curl -I` to tell fresh from cached.
|
||||||
|
|
||||||
The correct URL pattern is **owner subdomain + repository path**:
|
The correct URL pattern is **owner subdomain + repository path**:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
|||||||
@@ -78,10 +78,11 @@ tasks 05 and 06.
|
|||||||
|
|
||||||
## Still open from task 01's own report
|
## Still open from task 01's own report
|
||||||
|
|
||||||
- Real-host smoke test of `/ai-for-dummies/summary/` never ran — the branch is
|
- ~~Real-host smoke test of `/ai-for-dummies/summary/`~~ — **done**, see
|
||||||
not merged and CI has not published. **This is the #1 production-only failure
|
"Resolved: the base path serves correctly on the real host" above.
|
||||||
mode in the whole migration.** Do it before trusting any page work.
|
- No Playwright locally, so screenshot comparison still cannot run anywhere.
|
||||||
- No Playwright locally, so screenshot comparison could not run in CI.
|
`visual-regression.mjs` also has no compare mode, so it is out of CI until it
|
||||||
|
grows one. See `.agents/rules/gates.md`.
|
||||||
|
|
||||||
## The decision that is still yours
|
## The decision that is still yours
|
||||||
|
|
||||||
@@ -94,24 +95,44 @@ external-CSS assertion. See `.agents/context/design-system.md`.
|
|||||||
|
|
||||||
## Next steps, in order
|
## Next steps, in order
|
||||||
|
|
||||||
1. **Decide the font question** (see below). It blocks task 19 and it is the
|
1. **Decide the font question** (see below). It blocks task 19 and it is now the
|
||||||
only thing here that needs a human.
|
only thing here that needs a human.
|
||||||
2. Push `main` — nothing has left this machine yet. Safe now: the `publish` job
|
2. Fan out phase 1 and 2:
|
||||||
is `workflow_dispatch`-only, so pushing no longer overwrites the live site.
|
|
||||||
Watch that first CI run; the act-runner has never executed a job.
|
|
||||||
3. Once CI is green, do the real-host smoke test of `/ai-for-dummies/summary/`.
|
|
||||||
**This is still the #1 production-only failure mode in the migration** and it
|
|
||||||
has not been done. Publish manually via the workflow's `publish` input, on a
|
|
||||||
throwaway basis, or accept the risk until task 20.
|
|
||||||
4. Clean up the four merged worktrees and branches.
|
|
||||||
5. Fan out phase 1 and 2:
|
|
||||||
```bash
|
```bash
|
||||||
.agents/scripts/launch.sh 05 content-guide --base main
|
.agents/scripts/launch.sh 05 content-guide --base main
|
||||||
.agents/scripts/launch.sh 06 content-review --base main
|
.agents/scripts/launch.sh 06 content-review --base main
|
||||||
.agents/scripts/launch.sh 07 primitives --base main
|
.agents/scripts/launch.sh 07 primitives --base main
|
||||||
```
|
```
|
||||||
All three are unblocked now that 02 and 04 are in `main`. After 07 lands,
|
All three are unblocked now that 02 and 04 are in `main`. After 07 lands,
|
||||||
08–11 run four at a time.
|
08-11 run four at a time. **Task 07 is the routing calibration point** -
|
||||||
|
judge it before committing to MiniMax for the other twelve.
|
||||||
|
3. Clean up the four merged worktrees and branches in `~/Projects/af-task-0*`.
|
||||||
|
`~/Projects/af-task-02/before/` holds 29 MB of misplaced untracked
|
||||||
|
screenshots; delete or move them first.
|
||||||
|
|
||||||
|
## Resolved: the base path serves correctly on the real host
|
||||||
|
|
||||||
|
This was the #1 production-only failure mode and it is now **verified against
|
||||||
|
the live Pages Server**, not just `pnpm run preview`.
|
||||||
|
|
||||||
|
Method, which is reusable and costs no downtime: the Astro `dist/` was published
|
||||||
|
to the `pages` branch **additively** — `_astro/` plus a single page at
|
||||||
|
`_verify/summary/`, both paths previously unused, so no existing file was
|
||||||
|
touched and all ten live pages stayed up throughout. Results:
|
||||||
|
|
||||||
|
- `/ai-for-dummies/_verify/summary/` → 200, and it really is the Astro page
|
||||||
|
(`<title>AI For Dummies — Route map</title>`), not a 200-ing error page.
|
||||||
|
- `/ai-for-dummies/_astro/chapters.PwjFDHFw.css` → 200 `text/css`. **This is the
|
||||||
|
actual base-path proof**: Astro emits base-prefixed _absolute_ asset URLs, and
|
||||||
|
the server resolves them.
|
||||||
|
- `/ai-for-dummies/_verify/summary` (no trailing slash) → 307 to the slashed
|
||||||
|
form, which matches `trailingSlash: 'always'`.
|
||||||
|
|
||||||
|
The probe was force-pushed away immediately; `pages` is back at `37a1e48`.
|
||||||
|
|
||||||
|
Note for whoever publishes next: **the Pages Server caches for ten minutes**,
|
||||||
|
keyed on path. A deleted file keeps serving 200 until the cache expires, and a
|
||||||
|
`?v=<sha>` query does not bust it. See `docs/operations-guide.md` step 6.
|
||||||
|
|
||||||
## Carried over from the phase 0 review
|
## Carried over from the phase 0 review
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user