Skip to content

security(deps): upgrade docs to Astro 6 / Starlight 0.38#816

Merged
BYK merged 3 commits intomainfrom
build/docs-astro-6-upgrade
Apr 22, 2026
Merged

security(deps): upgrade docs to Astro 6 / Starlight 0.38#816
BYK merged 3 commits intomainfrom
build/docs-astro-6-upgrade

Conversation

@BYK
Copy link
Copy Markdown
Member

@BYK BYK commented Apr 22, 2026

Summary

Why #812 can't land on its own

Dependabot's PR only bumps astro in isolation. That breaks two ways:

  1. Immediate: Dependabot regenerates package-lock.json, not bun.lock, so bun install --frozen-lockfile fails in the Build Docs CI job.
  2. Actual: @astrojs/starlight@0.31.1 pins peerDependencies.astro to ^5.1.5, and Astro 6 removes the automatic legacy content-collections backwards-compat layer. Starlight must move along with Astro.

Changes

Dependencies

  • astro: ^5.1.1^6.1.8
  • @astrojs/starlight: ^0.31.1^0.38.3
  • @sentry/astro, sharp, shiki unchanged (already compatible)

Content Layer API migration

Moved docs/src/content/config.tsdocs/src/content.config.ts and rewrote it to pair docsSchema() with docsLoader(). Astro 6 removes the automatic legacy content-collections backwards-compat layer, so every collection must now go through the Content Layer API.

Starlight config changes

  • social config: deprecated object shorthand → array-of-entries form (Starlight 0.33 breaking change).
  • PageTitle.astro override: reads sidebar/entry from Astro.locals.starlightRoute instead of Astro.props (the Props type from @astrojs/starlight/props is deprecated and no longer populated by Starlight).
  • Header.astro override: same route-data migration; slug is now starlightRoute.id (empty string on the landing page, per Starlight's normalizeIndexSlug).

Build scripts (Astro 6 Node engine)

Astro 6 enforces engines.node >= 22.12.0 at runtime, but the GitHub-hosted Ubuntu runner ships Node 20.20.2 and astro's bin has #!/usr/bin/env node. docs/package.json scripts (dev, build, preview) now invoke astro via bun --bun so the build runs under Bun and bypasses the Node shebang. Works transparently in CI and on local machines stuck on Node 20.x.

Out of scope

  • No CLI code / repo-root lockfile changes — strictly docs/.
  • No Tailwind migration (site has no Tailwind integration).

Verification

cd docs
rm -rf node_modules
bun install --frozen-lockfile   # clean install, 538 packages
bun run build                   # 29 pages built, no errors

Closes #812

Dependabot #812 tried to bump astro 5 -> 6 in isolation, but the
upgrade can't land on its own: @astrojs/starlight@0.31 pins
peerDependencies.astro to ^5.1.5, and Astro 6 drops automatic legacy
content-collections backwards compatibility.

This PR does the coordinated upgrade instead:

- astro ^5.1.1 -> ^6.1.8
- @astrojs/starlight ^0.31.1 -> ^0.38.3
- Migrate docs/src/content/config.ts -> docs/src/content.config.ts
  using the Content Layer API (docsLoader() + docsSchema()).
- Convert Starlight social config from the deprecated object shorthand
  to the array-of-entries form required since 0.33.
- Update the PageTitle and Header overrides to read route data from
  Astro.locals.starlightRoute (the old Astro.props API was removed).
  Header.slug is now starlightRoute.id (empty string on the landing page).
- Regenerate docs/bun.lock.

Verified locally with:
  cd docs && bun install --frozen-lockfile && bun run build

Closes #812.
Astro 6 enforces Node >=22.12 at runtime. The GitHub-hosted Ubuntu
runner ships Node 20.20.2, which trips the check even though we use
Bun to install and orchestrate.

Switching the docs build command to `bun run --bun build` runs the
`astro` bin under Bun directly, bypassing the Node shebang and the
engine check. Bun is already installed via oven-sh/setup-bun, so no
extra setup step is needed.

Applied to both the Build Docs job in ci.yml and the preview job in
docs-preview.yml.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 22, 2026

PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://cli.sentry.dev/_preview/pr-816/

Built to branch gh-pages at 2026-04-22 12:54 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 22, 2026

Codecov Results 📊

138 passed | Total: 138 | Pass Rate: 100% | Execution Time: 0ms

📊 Comparison with Base Branch

Metric Change
Total Tests
Passed Tests
Failed Tests
Skipped Tests

✨ No test changes detected

All tests are passing successfully.

✅ Patch coverage is 100.00%. Project has 1964 uncovered lines.
❌ Project coverage is 95.17%. Comparing base (base) to head (head).

Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
- Coverage    95.19%    95.17%    -0.02%
==========================================
  Files          282       282         —
  Lines        40651     40650        -1
  Branches         0         0         —
==========================================
+ Hits         38695     38686        -9
- Misses        1956      1964        +8
- Partials         0         0         —

Generated by Codecov Action

Outside-review follow-ups on PR #816:

- docs/package.json scripts (`dev`, `build`, `preview`) now invoke
  astro via `bun --bun` so local `bun run build` works on Node <
  22.12 too. Previously only CI was patched and local devs on the GHA
  runner's node version silently hit Astro 6's engine check.
- CI workflows revert to plain `bun run build` now that the script
  itself forces Bun, with an explanatory comment pointing at the
  engine-check interaction.
- Drop the redundant `as StarlightRouteData` cast in PageTitle.astro
  — `Astro.locals.starlightRoute` is already typed via Starlight's
  ambient `locals.d.ts`, matching the reference implementation.
@BYK BYK changed the title build(deps): upgrade docs to Astro 6 / Starlight 0.38 security(deps): upgrade docs to Astro 6 / Starlight 0.38 Apr 22, 2026
@BYK BYK merged commit e1765bd into main Apr 22, 2026
26 checks passed
@BYK BYK deleted the build/docs-astro-6-upgrade branch April 22, 2026 13:01
BYK added a commit that referenced this pull request Apr 22, 2026
## Summary

Node 20 reached EOL in April 2026. This PR drops it from the supported
set and cleans up the Astro 6 engine-check workaround that #816 left in
place.

## Changes

### `package.json` — tighten engines
- `engines.node`: `>=22` → `>=22.12` (matches Astro 6 and reflects Node
20 EOL).

### `docs/package.json` — revert `bun --bun astro` workaround
- Scripts are back to plain `astro dev / build / preview`.
- #816 prefixed them with `bun --bun` only to route around the GHA
runner's Node 20 shipping below Astro 6's `engines.node: ">=22.12"`.
With a real Node pin in CI (below) and Node 24 locally, there's no
reason to keep it.

### Workflows — pin Node 24 for docs jobs
- `ci.yml` `Build Docs` and `docs-preview.yml` `preview` now both run
`actions/setup-node@v6` with `node-version: "24"` before the docs build.
- Dropped the `# works on Node < 22.12 …` comments.

### Unchanged
- `Build npm Package` CI matrix stays at `["22", "24"]`. Node 22 is
still LTS (EOL April 2027) and above the new 22.12 minimum.
- Other jobs already pinning `node-version: 22` (release workflows) are
fine as-is.

## Verification

```sh
cd docs && rm -rf node_modules && bun install --frozen-lockfile && bun run build
# 29 pages built in ~6s
```
BYK added a commit that referenced this pull request Apr 25, 2026
…#846)

Fixes #845.

## Summary

Two related bugs caused Sentry events for `cli.sentry.dev` to ship
unsymbolicated in production with no CI signal:

1. **Docs build emitted no `.map` files** since the Astro 6 upgrade
(#816). `astro.config.mjs` sets `vite.build.sourcemap: "hidden"`, but
Astro 6 reads from `vite.environments.{client,ssr}.build.sourcemap`
(Vite 7 Environments API), falling back to `false`. The legacy top-level
path is silently ignored for the client bundle.
2. **`sentry sourcemap inject`/`upload` silently succeeded on zero
pairs.** The docs step logged "Files uploaded: 0" and exited 0 for 20+
consecutive main-push runs, hiding the misconfiguration.

## Behavior change

`sentry sourcemap inject` and `sentry sourcemap upload` now **exit
non-zero by default** when zero JS+sourcemap pairs are discovered.
Callers that legitimately invoke these commands on potentially-empty
directories should pass `--allow-empty` to preserve the old behavior.

This is a deliberate default-strict change — the silent-zero-file
failure mode has no legitimate use case in CI and turns every bundler
regression into a silent production outage. Worth calling out in release
notes.

## Changes

- **`docs/astro.config.mjs`**: set `sourcemap: "hidden"` on
`vite.environments.client` (and `ssr`, defensive). Verified locally:
`docs/dist/_astro/` now contains 11 `.map` files (previously 0), and
`sentry sourcemap inject docs/dist/` injects debug IDs into 5 module
chunks.
- **`src/lib/sourcemap/inject.ts`**:
  - Export `discoverFilePairs` for read-only discovery (no writes).
- Add `assertDirectoryReadable(dir)` — distinguishes ENOENT /
not-a-directory / EACCES with specific error messages.
- Add `diagnoseEmptyDiscovery(dir)` + `buildEmptyDiscoveryError(dir,
diag)` — tailors the zero-pair error to the specific shape (empty dir /
JS-only / maps-only / basename-mismatch).
- **`src/commands/sourcemap/{inject,upload}.ts`**:
- New control flow: `assertDirectoryReadable → discoverFilePairs →
empty-check → resolveOrgAndProject → injectDirectory → upload`. All
pre-API error paths are side-effect-free — no debug IDs get written
until we know the upload will proceed.
  - Add `--allow-empty` flag (boolean, default `false`).
- Tailored error messages with bundler-specific config snippets
(Vite/Astro, webpack, esbuild).
- **Tests**: 16 new tests in `test/commands/sourcemap/upload.test.ts`
covering every empty-discovery branch, the non-existent-dir and
not-a-directory branches, happy path (uploadSourcemaps spy), and a
regression test that asserts the command does not mutate files on the
error path.
- **Docs**: new "Error handling" section in
`docs/src/fragments/commands/sourcemap.md` with `--allow-empty` examples
and bundler-config cheat-sheet.

## CI wiring

No workflow changes needed. The default-strict behavior catches any
future regression automatically — `.github/workflows/ci.yml` and
`docs-preview.yml` don't pass `--allow-empty`, so they'll fail loud if
`.map` files stop being emitted again.

## Verification

- 47 sourcemap-related tests pass locally (`bun test test/lib/sourcemap
test/commands/sourcemap test/lib/api/sourcemaps.test.ts`).
- `bun run typecheck` clean.
- `bun run lint` has only a single pre-existing warning (unrelated, in
`src/lib/formatters/markdown.ts`).
- End-to-end manual verification covers all 6 error branches (empty dir,
JS-only, maps-only, nonexistent, not-a-directory, basename-mismatch)
plus `--allow-empty` and the happy path.

## Review cycle

- Initial review (1 Cursor Bugbot finding on auth mocking) — false
positive; replied with evidence from CI logs.
- Self-review via subagent surfaced 5 IMPORTANT and 5 MINOR findings —
addressed in commit `1094d9bf`. See review thread on that commit for
per-item responses.
- Second-round bot pass (Cursor + Seer) found a real
side-effect-ordering issue (debug IDs written before credential
resolution) and a misleading `--allow-empty` hint — fixed in `e8452ad7`
with a regression test that locks in the discover-first invariant.
- Final: all bots SUCCESS / NEUTRAL, zero unresolved review threads,
mergeable = CLEAN.

## Follow-ups (not in this PR)

- Zstd compression (#823) has been exercised correctly for every
CLI-binary build since it merged (verified in `Build Binary` step logs,
where each target uploads its `bin.js.map` with auth). Once this PR
merges and a real docs push happens, zstd will finally be exercised on
docs uploads too — I'll confirm from the resulting CI logs and update
#845.
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