Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions docs/decisions/0001-myst-migration/0001-migrate-to-mystmd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# ADR 0001 — Migrate build system from Hugo to MyST-MD

Date: 2026-05-11
Status: Proposed — **open question for maintainers (see below)**
Branch: lb/myst-migration
Issue: scientific-python/scientific-python.org#846

## Context

`learn.scientific-python.org` builds with Hugo via `make html` and deploys via
Netlify (auto-deploy on push to `main`). We want to convert the content files
to MyST syntax.

Three realistic MyST toolchain options exist. They are not equivalent:
`jupyter-book` is a higher-level tool built on top of `mystmd`; `mystmd` is the
underlying engine and is available as both a Node package (npm) and a Python
package (pip/conda) that bundles Node internally.

## Decision (proposed)

Replace Hugo with **`mystmd` Python package** (`pip install mystmd`,
`myst build --html`) as the build tool.

## Options considered

| Option | Pros | Cons |
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Stay on Hugo** | Theme parity with sibling SP sites; no content changes needed | Hugo is not Python; MyST content conversion still desirable long-term |
| **jupyter-book 2.x** | Pure Python (`pip install jupyter-book`); SP ecosystem familiar with JB; conda-forge package; handles notebook execution natively | Wraps `mystmd` under the hood — extra abstraction; config format (`_config.yml`, `_toc.yml`) is not portable to plain `myst.yml` if JB is dropped later; JB 2.x released late 2024 — docs and community experience thin; feature lag vs direct `mystmd` |
| **mystmd — Node CLI** (`npm install mystmd`) | Native runtime; latest npm releases immediately; same `myst.yml` config; active ExecutableBooks development | Requires Node.js in every build environment (Netlify, RTD, CI); unfamiliar to Python contributors |
| **mystmd — Python package** (`pip install mystmd`) | Python-centric install (pip/conda-forge); bundles Node internally — no separate Node needed; same `myst.yml` config as Node CLI (no extra abstraction layer); proven by `tools.scientific-python.org` PR #81; works on all considered deploy platforms | Node bundled internally — slightly opaque; PyPI/conda releases may lag npm by 1–7 days |

## Rationale for proposed decision

**Why not jupyter-book:** `learn.scientific-python.org` contains no Jupyter
notebooks; JB's primary value (notebook execution, Sphinx integration) does not
apply here. JB 2.x uses `mystmd` as its build engine, so the team would get
`mystmd` indirectly with an extra config layer on top. The JB config format
(`_config.yml`, `_toc.yml`) is not portable — if JB were dropped later, the
config would need to be rewritten to `myst.yml` from scratch.

**Why not the Node CLI:** Requires Node.js in every build environment. SP
contributors and maintainers work in Python environments; npm is unfamiliar and
adds friction for new contributors. The Python package provides identical
functionality without any Node setup.

**Why the Python package:** Fits SP's Python-centric workflow; `conda install
-c conda-forge mystmd` works for conda users. No Node.js needed in Netlify,
RTD, or GitHub Actions (Node is bundled inside the package). The `myst.yml`
config is identical to the Node CLI — switching delivery method later is a
one-line change.

## Open question for maintainers

> **Which MyST toolchain should `learn.scientific-python.org` adopt?**
>
> A. `mystmd` Python package — proposed above (`pip install mystmd`)
> B. `jupyter-book 2.x` — if the team prefers a unified JB-based approach
> C. `mystmd` Node CLI — if the team prefers the native Node runtime
>
> This is the foundational decision for the migration. All downstream ADRs
> (0002–0007) assume option A. If maintainers choose B, the `myst.yml` /
> `_toc.yml` structure and config format change significantly. Option C
> requires Node.js toolchain setup in `netlify.toml` and CI.

## Installation

For Netlify builds and RTD: `pip install mystmd` (no Node configuration needed
in `netlify.toml`; see ADR 0007).

Local dev: install via any preferred method (pip, conda, npm — developer's
choice). The repo does not mandate a specific local environment.

## Consequences

- `myst build --html` replaces `make html` (Hugo)
- `pip install mystmd` is the chosen delivery method; no Node toolchain required
in CI or `netlify.toml`
- The `scientific-python-hugo-theme` submodule is removed (see ADR 0003)
- `netlify.toml` is updated to use `mystmd` (see PLAN.md Phase 6)
- Nine content files require shortcode conversion (see ADR 0002)
- Footer/quicklinks are not yet supported in MyST default templates (see ADR 0005)
- Other SP repos remain on Hugo until they choose to migrate (see ADR 0006)
57 changes: 57 additions & 0 deletions docs/decisions/0001-myst-migration/0002-shortcode-mapping.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# ADR 0002 — Hugo shortcode → MyST directive mapping

Date: 2026-05-11
Status: Proposed
Branch: lb/myst-migration

## Context

Nine content files use Hugo shortcodes that MyST does not understand:

| Shortcode type | Files affected (pre-Phase-2 names) |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{{< grid >}}` / `[[item]]` | `_index.md` (root), `contributors/_index.md`, `documentation/_index.md` |
| `{{< admonition >}}` | `maintainers/_index.md`, `maintainers/interacting-with-new-contributors.md`, `maintainers/managing-conflict.md`, `maintainers/meeting_types.md`, `contributors/first-contribution.md`, `community/onboarding.md` |

## Decision

Convert shortcodes in two **type-batched commits** (one per shortcode type,
not one per file), using the following canonical mappings:

```
{{< grid columns="1 2 2 3" >}} → ::::{grid} 1 2 2 3
:gutter: 2

[[item]] → :::{card} <title>
type = 'card' :link: <link>
title = 'X'
link = 'y' <body>
body = 'z' :::

{{< /grid >}} → ::::

{{< admonition warning >}}… → :::{warning}
{{< /admonition >}} …
:::

{{< admonition note >}}… → :::{note}
{{< /admonition >}} …
:::
```

## Options considered

- **Custom MyST plugin** to interpret Hugo TOML shortcode syntax — high effort,
no value once content is converted.
- **Per-file commits** — nine files but ten shortcode occurrences (one file
has two grid blocks); reviewers re-read the same mapping repeatedly.
- **Type-batched commits** — two diffs total; reviewers evaluate the mapping
pattern once per type.

## Consequences

- Two commits in Phase 3 of the migration (see [PLAN.md](PLAN.md))
- Reviewers can verify correctness by comparing rendered output against the
Hugo-built site for these nine pages
- `grep -rE '\{\{<' content/` returns zero matches after these commits
- `content/index.md` is the canonical style reference going forward
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# ADR 0003 — Remove scientific-python-hugo-theme submodule

Date: 2026-05-11
Status: Proposed
Branch: lb/myst-migration

## Context

`themes/scientific-python-hugo-theme` is a git submodule pinned to `v0.21`.
The same theme submodule is also referenced by three sibling repos:
`scientific-python.org`, `blog.scientific-python.org`, and
`tools.scientific-python.org`. Each repo pins the submodule independently in
its own `.gitmodules`; they do not share a checkout.

MyST-MD does not use Hugo themes. Once Hugo is removed from this repo, the
submodule has no consumer here.

## Decision

Remove the submodule from this repo in Phase 7 of the migration.

```bash
git submodule deinit -f themes/scientific-python-hugo-theme
git rm themes/scientific-python-hugo-theme
rm -rf .git/modules/themes/scientific-python-hugo-theme
```

## Options considered

1. **Remove in this PR** — clean cut; no dead code after Hugo is gone.
2. **Keep until all four SP repos migrate** — delays cleanup by months or
quarters; leaves a submodule that nothing in this repo uses.
3. **Vendor a snapshot** — no benefit; MyST doesn't use it.

## Consequences

- The `themes/` directory is deleted from this repo
- The three sibling repos are **unaffected** — they reference the submodule
from their own `.gitmodules` and pin their own SHA
- The upstream `scientific-python-hugo-theme` repo is not affected
- A follow-up PR to the sibling repos removes their copies when they migrate
(see ADR 0006)
42 changes: 42 additions & 0 deletions docs/decisions/0001-myst-migration/0004-defer-cookie-jekyll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# ADR 0004 — Defer migration of external-content/cookie (Jekyll)

Date: 2026-05-11
Status: Proposed
Branch: lb/myst-migration

## Context

`external-content/cookie` is a Jekyll site (git submodule, pinned to
`2025.10.01`). It is built separately via `make cookie` and its output is
merged into `public/development/` before deploy. It has its own upstream
release cadence and contributors independent of `learn`.

## Decision

Leave `external-content/cookie` unchanged in this PR. File a follow-up issue:
_"MyST: migrate external-content/cookie off Jekyll"_.

The `make cookie`, `make external`, `cookie_ruby_deps`, `cookie_web_prepare`,
and `prepare` Makefile targets are preserved. `make html-all` continues to
build the MyST site then merge the Jekyll output into `public/`.

## Options considered

1. **Keep as-is permanently** — MyST output and Jekyll output coexist forever;
`ghp-import` merges them. Lowest risk but leaves a Jekyll dependency
indefinitely.
2. **Convert cookie to MyST** — large, independent effort; distracts from this
PR and would require its own review.
3. **Drop cookie** — would break the `/development/` path; not acceptable
without a replacement.
4. **Defer with follow-up issue** — keep `make cookie` working now; track
conversion separately so it gets its own focused review.

## Consequences

- `external-content/cookie` submodule remains at `2025.10.01`
- `public/development/` continues to be produced by Jekyll
- The `html-all` Makefile target reconciles MyST's `_build/html/` output
with cookie's `public/development/` via `mkdir -p public && cp -r _build/html/* public/`
before `make external` overlays `/development/`
- A follow-up issue tracks the eventual Jekyll → MyST conversion
49 changes: 49 additions & 0 deletions docs/decisions/0001-myst-migration/0005-defer-footer-quicklinks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# ADR 0005 — Defer footer and quicklinks to follow-up

Date: 2026-05-11
Status: Proposed
Branch: lb/myst-migration

## Context

Hugo `config.yaml` defines two visual elements that have no direct equivalent
in MyST default templates:

1. **Footer social icons** — GitHub, YouTube, Mastodon, Discourse, Discord
2. **Quicklinks columns** — three columns of site-wide nav links (About,
Maintainers/SPECs, Press kit)

MyST's default HTML template renders a minimal footer with no configurable
social links or quicklinks.

## Decision

Ship this PR with the MyST default footer. File a follow-up issue:
_"MyST: footer + quicklinks parity with Hugo theme"_.

Add a comment block at the bottom of `myst.yml` pointing at the follow-up
issue number so the gap is immediately discoverable.

## Options considered

1. **Custom MyST theme / template override** — achieves full parity but is a
month of separate work; blocks the migration on a visual detail.
2. **Static HTML injected via template** — fragile; bypasses MyST conventions
and creates a maintenance burden.
3. **`site.parts.footer:` with a `footer.md` file + custom CSS + scienceicons
plugin** — uses MyST's built-in parts mechanism; no custom theme required.
Demonstrated in `tools.scientific-python.org` PR #81 (brianhawthorne,
October 2025). Viable path for the follow-up issue.
4. **Defer with documented issue** — unblocks the migration for SciPy 2026;
footer work is tracked and discoverable.

## Consequences

- The deployed site will have a minimal footer until the follow-up is resolved
- `config.yaml`'s `params.footer` and `params.quicklinks` sections are not
ported to `myst.yml`
- The follow-up issue is linked from `myst.yml` and from the PR description
- Option 3 above (`site.parts.footer:` + CSS) is the recommended implementation
path for the follow-up; `tools.scientific-python.org` PR #81 is the reference
- If the SP community decides MyST theming is too limited, this ADR is a
natural decision point to reconsider the tool choice (see ADR 0001)
52 changes: 52 additions & 0 deletions docs/decisions/0001-myst-migration/0006-sibling-repo-migration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# ADR 0006 — Sibling SP repos migrate independently

Date: 2026-05-11
Status: Proposed
Branch: lb/myst-migration

## Context

The Scientific Python ecosystem has four Hugo-based sites sharing the same
theme submodule:

| Repo | Domain |
| ----------------------------------------------- | ------------------------------------------- |
| `scientific-python/learn.scientific-python.org` | learn.scientific-python.org ← **this repo** |
| `scientific-python/scientific-python.org` | scientific-python.org |
| `scientific-python/blog.scientific-python.org` | blog.scientific-python.org |
| `scientific-python/tools.scientific-python.org` | tools.scientific-python.org |

Cross-site nav links are plain absolute URLs (not build-time references).
There is no shared build pipeline coupling the repos.

`tools.scientific-python.org` already has an open MyST migration PR
([#81](https://github.com/scientific-python/tools.scientific-python.org/pull/81),
brianhawthorne, opened October 2025, stale as of May 2026). It demonstrates
a working shortcode conversion and a footer implementation using
`site.parts.footer:` + custom CSS (see ADR 0005 option 3).

## Decision

`learn` migrates first. File one tracking issue per sibling repo after this
PR merges, each linking to this PR as a worked example. Sibling repos adopt
MyST on their own schedule.

## Options considered

1. **Migrate all four in lock-step** — synchronizes visual consistency; blocks
`learn` on the slowest-moving repo.
2. **`learn` first; siblings when ready** — proves the pattern; doesn't block
SciPy 2026 deadline.
3. **Wait for MyST theme parity** — defers everything until ADR 0005 follow-up
is resolved; not necessary since content parity is achievable now.

## Consequences

- Cross-site nav continues to work: all links are absolute URLs
- Sibling repos remain on Hugo until they choose to migrate; no visual
breakage to end users
- This PR and `tools.scientific-python.org` PR #81 together form the reference
corpus for sibling repos evaluating MyST migration
- Tracking issues are filed in Phase 8 of the migration plan
- The `scientific-python-hugo-theme` submodule removal in ADR 0003 affects
only this repo; the other three repos remove it in their own migration PRs
62 changes: 62 additions & 0 deletions docs/decisions/0001-myst-migration/0007-deploy-strategy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# ADR 0007 — Update netlify.toml for MyST build

Date: 2026-05-11
Status: Proposed
Branch: lb/myst-migration

## Context

Both `scientific-python.org` and `learn.scientific-python.org` deploy via
Netlify, which auto-deploys on push to `main` and generates PR preview deploys.
The build command is defined in `netlify.toml`. The current command builds with
Hugo + Dart Sass.

GitHub Actions runs only a lint workflow (`lint.yml`). There is no gh-pages
deploy workflow.

## Decision

Update `netlify.toml` in Phase 6 of the migration: remove the Dart Sass and
Hugo toolchain setup; add `pip install mystmd` before the existing
`make html-all` call. Build command, publish directory, and
`netlify-plugin-checklinks` are otherwise unchanged.

## Options considered

1. **Update `netlify.toml`** — minimal change; keeps Netlify as the deploy
target, PR previews continue to work automatically.
2. **Replace Netlify with gh-pages** — larger change; requires creating new
GitHub Actions deploy workflows, reconfiguring DNS, and losing Netlify PR
previews. Out of scope for this PR.
3. **Keep `netlify.toml` for the checklinks plugin only** — the Netlify
checklinks plugin can be replaced by a `lychee`-based GitHub Actions job
as a separate improvement; not required for this migration.
4. **Drop Netlify entirely; use CircleCI for builds + circleci-artifacts-
redirector-action for PR previews** — demonstrated by
`tools.scientific-python.org` PR #81. Viable but introduces CircleCI
account dependency and is a larger infrastructure change than needed here.
5. **Migrate to Read the Docs** — RTD has first-class MyST/Sphinx support,
built-in PR preview deploys (including for forks), and is already used
widely across the Scientific Python ecosystem. Would replace Netlify
entirely; requires a `.readthedocs.yaml` config and DNS reconfiguration.
Resolves the fork-contributor preview gap (ADR 0007 future work item 1)
as a side effect. Not pursued in this PR — custom domain setup and RTD
account provisioning are out of scope for the migration itself.

## Consequences

- Dart Sass and Hugo version pins removed from `netlify.toml`
- `pip install mystmd` added before `make html-all` in the build command
- Build command (`make html-all`), publish dir (`public/`), and
`netlify-plugin-checklinks` are unchanged
- Netlify auto-deploy and PR previews continue unchanged

## Future work (out of scope)

Two follow-up improvements; both filed as issues before Phase 4 commit 2
(see PLAN.md Phase 4 prerequisite):

- **gh-pages PR preview**: allows contributors working from a fork to
preview builds on their own GitHub Pages without requiring Netlify access.
- **Replace `netlify-plugin-checklinks` with a `lychee`-based GitHub Actions
job**: keeps link checking in CI, removes the Netlify plugin dependency.
Loading