Skip to content

chore(deps): upgrade to Astro 7 and Starlight 0.41 - #339

Merged
marc0olo merged 4 commits into
mainfrom
infra/astro-7-upgrade
Aug 4, 2026
Merged

marc0olo merged 4 commits into
mainfrom
infra/astro-7-upgrade

Conversation

@marc0olo

@marc0olo marc0olo commented Aug 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Replaces #337 (dependabot), which could not merge as-is: Astro 7 / Starlight 0.41 need repo-side changes. Dependabot's bump commit is preserved here, with the required fixes on top.

  • astro 6.3.2 → 7.1.6, @astrojs/starlight 0.38.1 → 0.41.6 (cherry-picked from chore(deps): bump astro and @astrojs/starlight #337)
  • Wrap all autogenerate sidebar configs in items arrays (Starlight 0.39 removed labelled autogenerated groups)
  • Normalise the sidebar shape in scripts/postprocess-motoko.mjs so synced Motoko pages keep working
  • Fix deriveSections() in plugins/astro-agent-docs.mjs so llms.txt keeps its section labels, and make the same class of failure fail the build in future
  • Migrate markdown.remarkPlugins / rehypePlugins to processor: unified({ ... })
  • Align validate.yml on Node 22

Why the extra changes

Sidebar (build blocker). Starlight 0.39 requires the autogenerate config to sit inside an items array:

  {
    label: "Backends",
    collapsed: true,
-   autogenerate: { directory: "guides/backends" },
+   items: [{ autogenerate: { directory: "guides/backends", collapsed: true } }],
  }

collapsed is set on the autogenerate config too, because autogenerated subgroups no longer inherit the parent's collapsed state as of 0.39. No autogenerate directory currently has subdirectories, so this is a no-op today and keeps behaviour correct if one is added.

Motoko sidebar (would regress on the next sync). sidebar-motoko.mjs is generated from doc/site/sidebar.mjs in the pinned .sources/motoko submodule, which still uses the pre-0.39 shape. Hand-editing the generated file alone would be undone by the next Motoko sync, breaking the build again. Instead transformEntry() now normalises both shapes, so the output is valid whichever shape upstream emits and no coordination with caffeinelabs/motoko is required. Verified: both shapes produce byte-identical output, and regeneration is idempotent.

llms.txt (silent break, now guarded). deriveSections() read the section label off the autogenerate node. Once nested, that node is unlabelled and the label lives on the parent group, so all 15 autogenerated sections rendered as ## undefined in llms.txt — with a clean build log and a zero exit code. Beyond fixing the derivation, the derived sections are now validated at module load and the build throws with the offending directory and the function to update. Verified by reintroducing the original bug: the build fails immediately instead of shipping. This guards the whole class of failure, since these labels are inferred from the sidebar's shape and future Starlight majors can change it again.

Markdown processor. Astro 7 defaults to the Sätteri processor and deprecates the top-level plugin arrays (the build warned about it). processor: unified({ ... }) opts back into the remark/rehype pipeline the 5 remark and 2 rehype plugins need. @astrojs/markdown-remark is declared as a direct dependency instead of relying on Astro's transitive copy; only the root dependency entry is added to the lockfile.

Node 22 in validate.yml. Astro 7 requires ^20.19.0 || >=22.12.0. The previous '20' pin resolved to a satisfying 20.x and that job does not run Astro, so this aligns it with the other five workflows rather than fixing a break.

Verification

Built against a main baseline and compared output:

  • 209 pages build clean, no errors, no deprecation warnings
  • Sidebar identical: 38 groups, same labels, same collapsed states, 196 nav links
  • llms.txt, llms-full.txt, feed.xml and all 209 markdown endpoints byte-identical
  • Rendered article content identical on 204 of 208 pages; the 4 differences are 3 smart-quote corrections (”Canister is not ready” → “Canister is not ready”) and one whitespace change between flex items in a Starlight LinkCard on the homepage, which does not render
  • Confirmed on the deployed preview: the submodule-sourced Motoko pages that use file= includes render in full, and llms.txt is byte-identical to the local build
  • Build time 33s → 28s

Notes

  • Starlight 0.41 drops support for Chromium < 111 and Safari < 16.4.
  • Upstream caffeinelabs/motoko pins Starlight ^0.41.3 in doc/site/package.json while its sidebar.mjs still uses the pre-0.39 shape, and no workflow there builds doc/site, so their own preview site hits this same error unnoticed. Worth a separate upstream PR; this branch does not depend on it.

dependabot Bot and others added 3 commits August 4, 2026 12:44
Bumps [astro](https://github.com/withastro/astro/tree/HEAD/packages/astro) and [@astrojs/starlight](https://github.com/withastro/starlight/tree/HEAD/packages/starlight). These dependencies needed to be updated together.

Updates `astro` from 6.3.2 to 7.1.6
- [Release notes](https://github.com/withastro/astro/releases)
- [Changelog](https://github.com/withastro/astro/blob/main/packages/astro/CHANGELOG.md)
- [Commits](https://github.com/withastro/astro/commits/astro@7.1.6/packages/astro)

Updates `@astrojs/starlight` from 0.38.1 to 0.41.6
- [Release notes](https://github.com/withastro/starlight/releases)
- [Changelog](https://github.com/withastro/starlight/blob/main/packages/starlight/CHANGELOG.md)
- [Commits](https://github.com/withastro/starlight/commits/@astrojs/starlight@0.41.6/packages/starlight)

---
updated-dependencies:
- dependency-name: astro
  dependency-version: 7.1.6
  dependency-type: direct:production
- dependency-name: "@astrojs/starlight"
  dependency-version: 0.41.6
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Starlight 0.39 removed support for autogenerated sidebar groups that carry a
`label`; the autogenerate config must now sit inside an `items` array. Without
this the build fails at the `astro:config:setup` hook.

- sidebar.mjs: wrap all 13 autogenerate configs. Groups marked
  `collapsed: true` also set `collapsed` on the autogenerate config, since
  autogenerated subgroups no longer inherit the parent's collapsed state.
- scripts/postprocess-motoko.mjs: normalise both shapes in transformEntry, so
  sidebar-motoko.mjs stays valid whichever shape upstream caffeinelabs/motoko
  emits. Without this the next Motoko sync regenerates the pre-0.39 shape and
  breaks the build again.
- sidebar-motoko.mjs: regenerated with the fixed generator.
- plugins/astro-agent-docs.mjs: deriveSections() read the label off the
  autogenerate node, which is now unlabelled, so every autogenerated section in
  llms.txt rendered as "undefined". Unwrap the nested config and use the
  group's label. This failed silently, without a build error.

Verified against a main baseline: sidebar structure (38 groups, labels and
collapsed states), llms.txt and llms-full.txt are byte-identical.
Astro 7 defaults to the Sätteri markdown processor and deprecates
`markdown.remarkPlugins` / `markdown.rehypePlugins`, which the build warned
about. Opt back into the remark/rehype pipeline explicitly via
`processor: unified({ ... })`.

@astrojs/markdown-remark is added as a direct dependency rather than relying on
Astro's transitive copy. Only the root dependency entry is added to the
lockfile; the package itself was already resolved there.

All 209 pages render identically to a main baseline.
deriveSections() infers llms.txt section labels from the sidebar tree's shape,
so a change to that shape degrades them instead of failing. Starlight 0.39
moving `autogenerate` inside `items` did exactly that: every autogenerated
section's label became `undefined` and would have shipped as "## undefined" in
llms.txt with a clean build log and a zero exit code.

Validate the derived sections at module load and throw with the offending
directory and the function to update. Verified by reintroducing the original
bug: the build fails immediately with the new message.

Also aligns validate.yml on Node 22, matching the other five workflows. Astro 7
requires ^20.19.0 || >=22.12.0; the previous '20' pin resolved to a satisfying
20.x and this job does not run Astro, so this is consistency rather than a fix.
@marc0olo
marc0olo merged commit 66f2c02 into main Aug 4, 2026
7 checks passed
@marc0olo
marc0olo deleted the infra/astro-7-upgrade branch August 4, 2026 12:21
marc0olo added a commit that referenced this pull request Sep 14, 2026
## Summary

Closes #384, which cannot resolve: astro 7.2.10 changed its
`@astrojs/markdown-remark` peer from an exact pin to `^7.3.0`, and only
`@astrojs/mdx` 8 satisfies that, which only arrives with Starlight 0.42.
Dependabot bumps one package, so `npm ci` fails with ERESOLVE. Same
shape as #337 → #339.

Clears three advisories:

| | severity | patched in |
|---|---|---|
| GHSA-26w7-cxv4-gfx2 — astro RCE via AVIF image optimization | critical
| astro 7.2.8 |
| GHSA-376h-93r7-7g6f — astro auth bypass when stripping `base` | medium
| astro 7.2.4 |
| GHSA-2v37-7h3g-55p8 — nanoid infinite loop (transitive, via postcss) |
high | nanoid 3.3.18 |

`npm audit` reports 0 vulnerabilities after the bump.

## Starlight 0.42 breaking changes

- **Mobile menu** moved to `popover` + `.sl-menu-button`, dropping
`starlight-menu-button`, `aria-expanded` and
`data-mobile-menu-expanded`. Nothing in `src/` or `custom.css` targets
those.
- **`tagline` config option removed.** Our `Hero.astro` uses the
`hero.tagline` frontmatter field, which is unaffected.
- **Package now ships JS + `.d.ts`** instead of TS source. We only
import `@astrojs/starlight/loaders`, `/schema` and `/components`.
- **Browser floor raised** to Chrome/Edge 116, Safari 17, Firefox 125.

## Verification

Built against a `main` baseline, both on node 22:

- `llms.txt`, `llms-full.txt`, `sitemap.xml` and all 210 `.md` endpoints
byte-identical; `feed.xml` differs only by `lastBuildDate` and item
order (pre-existing nondeterminism)
- HTML diffs across all 210 pages are confined to the new mobile-menu
markup, the `generator` meta tags, and page-local tab ids (a 0.41.8
change)
- `package-lock.json` keeps its `libc` metadata; a macOS `npm install`
strips it, so it was restored by hand and re-validated with `npm ci`

## One upstream bug worked around

Under astro 7.3 / mdx 8, an `.astro` component with scoped styles
rendered inside another component's slot in MDX gets `xmlns` serialized
as `:xmlns`. It reproduces with a minimal component inside `<TabItem>`
and is specific to `xmlns` (`xmlns:xlink`, `viewBox` and ordinary
attributes are fine). Here it hit the two footer icons of `CodeExample`,
so those SVGs now omit `xmlns` — inline SVG does not need it. To be
reported upstream; nothing is filed yet.
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.

2 participants