Skip to content
Merged
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
44 changes: 39 additions & 5 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ concurrency:

env:
CF_WORKER: nebari-docs
CF_CLASSIC_WORKER: nebari-docs-classic

jobs:
docs:
Expand All @@ -43,11 +44,11 @@ jobs:
run: bun install --frozen-lockfile
working-directory: docs

- name: Test (builds the site into dist/)
- name: Test (builds both sites into dist/ and dist-classic/)
run: bun test test
working-directory: docs
env:
SITE: https://www.nebari.dev
# Each site sets its own SITE (www.nebari.dev / classic.nebari.dev) in astro.config.mjs.
BASE: /
# `bun test` would otherwise set NODE_ENV=test for the build it runs, which
# makes Astro build in dev mode and drops the Pagefind search UI from every
Expand Down Expand Up @@ -111,12 +112,45 @@ jobs:
workingDirectory: docs
command: deploy

- name: Upload preview version to the nebari-docs-classic Worker
id: classic-preview-deploy
if: ${{ github.ref != 'refs/heads/main' && steps.candeploy.outputs.ok == 'true' }}
uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
workingDirectory: docs
# Same one-time seeding as the main Worker above.
preCommands: npx wrangler deployments list --config wrangler.classic.jsonc > /dev/null 2>&1 || npx wrangler deploy --config wrangler.classic.jsonc
command: versions upload --config wrangler.classic.jsonc --preview-alias ${{ steps.site.outputs.alias }}

- name: Extract Classic preview URL
id: classic-preview
if: ${{ steps.classic-preview-deploy.outcome == 'success' }}
env:
WRANGLER_OUTPUT: ${{ steps.classic-preview-deploy.outputs.command-output }}
run: |
URL=$(printf '%s\n' "$WRANGLER_OUTPUT" | grep -Eo 'https://[a-zA-Z0-9-]+\.[a-zA-Z0-9-]+\.workers\.dev' | tail -n1)
echo "url=${URL}" >> "$GITHUB_OUTPUT"
echo "::notice::Classic preview URL: ${URL}"

- name: Deploy production to the nebari-docs-classic Worker
id: classic-deploy
if: ${{ github.ref == 'refs/heads/main' && steps.candeploy.outputs.ok == 'true' }}
uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
workingDirectory: docs
command: deploy --config wrangler.classic.jsonc

- name: Comment preview URL
if: ${{ github.event_name == 'pull_request' && steps.preview-deploy.outcome == 'success' }}
if: ${{ github.event_name == 'pull_request' && steps.preview-deploy.outcome == 'success' && steps.classic-preview-deploy.outcome == 'success' }}
uses: marocchino/sticky-pull-request-comment@5770ad5eb8f42dd2c4f34da00c94c5381e49af88 # v3.0.5
with:
header: docs-preview
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
message: |
**Docs preview** for `${{ github.event.pull_request.head.ref }}` (via the `${{ env.CF_WORKER }}` Worker):
${{ steps.preview.outputs.url }}
**Docs preview** for `${{ github.event.pull_request.head.ref }}`:
- Nebari (via the `${{ env.CF_WORKER }}` Worker): ${{ steps.preview.outputs.url }}
- Nebari Classic (via the `${{ env.CF_CLASSIC_WORKER }}` Worker): ${{ steps.classic-preview.outputs.url }}
38 changes: 29 additions & 9 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ The structure of this repository is as follows:
.
├── .github
├── docs
│ ├── classic
│ │ ├── content/docs
│ │ ├── public
│ │ └── content.config.ts
│ ├── public
│ ├── src
│ │ ├── components
Expand All @@ -23,6 +27,7 @@ The structure of this repository is as follows:
│ ├── package.json
│ ├── README.md
│ ├── tsconfig.json
│ ├── wrangler.classic.jsonc
│ └── wrangler.jsonc
├── .editorconfig
├── .gitignore
Expand All @@ -40,47 +45,62 @@ This directory contains the following

- `ISSUE_TEMPLATE`: the various issue templates for the repository
- `PULL_REQUEST_TEMPLATE`: this project's pull request template
- `workflows/`: GitHub actions workflows for this repository. `docs.yml` builds, tests and deploys the site to Cloudflare.
- `workflows/`: GitHub actions workflows for this repository. `docs.yml` builds, tests and deploys both sites to Cloudflare.

> **Note**
> The issue and pull request templates are located in the [nebari-dev/.github](https://github.com/nebari-dev/.github) repository and are synced across repositories through a GitHub action.

# `docs/`

This is the top-level directory for the documentation site. It contains the following files and directories.
This is the top-level directory for the documentation. One Astro project builds two sites from it:

- **www.nebari.dev**, from `src/` and `public/` (`bun run build`, output in `dist/`)
- **classic.nebari.dev**, the Nebari Classic docs, from `classic/` (`bun run build:classic`, output in `dist-classic/`)

Setting `DOCS_SITE=classic` switches `astro.config.mjs` to the Classic site's source, public and output directories, sidebar, and header links. Both sites share the components and styles in `src/`.

It contains the following files and directories.

## `src/content/docs`

All the pages of the site. The path of a file is its URL, so the directory names match the site's sections:

- `docs/`: the current Nebari documentation, organized following the Diátaxis framework (`get-started`, `how-tos`, `explanations`, `references`) plus `software-packs`.
- `classic/`: the Nebari Classic documentation (`get-started`, `tutorials`, `how-tos`, `explanations`, `references`, plus `troubleshooting`, `faq`, and `glossary`).
- `community/`: our community-related content covering items like contribution guidelines and style guides.
- `index.mdx` and `404.md`: the landing page and the not-found page.

## `src/components`

Astro components used from content pages (`PlannedProvider`, `MarkdownTable`, `SubpageCards`) and the Starlight component overrides (`Head` adds analytics and the cookie banner, `MarkdownContent` adds the Nebari Classic phase-out notice).
Astro components used from content pages (`PlannedProvider`, `MarkdownTable`, `SubpageCards`) and the Starlight component overrides (`Head` adds analytics and the cookie banner, `MarkdownContent` adds the Nebari Classic phase-out notice, and only the Classic site uses it).

## `src/routeData.ts`

A Starlight route middleware. The sidebar in `astro.config.mjs` is defined as three top-level groups (Nebari, Nebari Classic, Community) and this middleware shows only the group matching the current section, so each section keeps its own navigation like the previous multi-instance setup.
A Starlight route middleware for www.nebari.dev. Its sidebar in `astro.config.mjs` is defined as two top-level groups (Nebari, Community) and this middleware shows only the group matching the current section, so each section keeps its own navigation like the previous multi-instance setup. The Classic site has a single sidebar and doesn't use it.

## `src/styles`

`custom.css` holds the landing-page styles. Everything else (colors, fonts, header, footer) comes from the `@nebari/starlight` theme.

## `public`

All the static files for the site, served from the root URL: the Nebari logos and favicon (`logo/`), the images for the documentation content (`img/`, organized like the content), the AWS IAM policy files (`policies/`), and `_redirects`, the Cloudflare redirect rules that keep legacy Docusaurus URLs working.
All the static files for the site, served from the root URL: the Nebari logos and favicon (`logo/`), the images for the documentation content (`img/`, organized like the content), the AWS IAM policy files (`policies/`), and `_redirects`, the Cloudflare redirect rules that send `/classic/*` and legacy Docusaurus URLs to classic.nebari.dev.

## `classic`

Everything specific to classic.nebari.dev, used as the Astro `srcDir` and `publicDir` when building with `DOCS_SITE=classic`:

- `content/docs/`: the Nebari Classic pages (`get-started`, `tutorials`, `how-tos`, `explanations`, `references`, plus `troubleshooting`, `faq`, `glossary`, and `404.md`), served from the site root.
- `public/`: the Classic images (`img/`), the favicon, and `_redirects`, which sends the site root to `/welcome/`.
- `content.config.ts`: the content collection for the Classic site.

## Other files in `/docs`

- `astro.config.mjs`: Astro and Starlight configuration, including the header tabs, the three sidebars and the links validator
- `package.json` and `bun.lock`: dependencies and scripts (`bun run dev`, `bun run build`, `bun test`)
- `astro.config.mjs`: Astro and Starlight configuration, including the header tabs, the sidebars for both sites and the links validator
- `package.json` and `bun.lock`: dependencies and scripts (`bun run dev`, `bun run build`, `bun test`, and the `:classic` variants)
- `test/build.test.ts`: build smoke tests, run in CI
- `tsconfig.json`: TypeScript configuration for Astro
- `wrangler.jsonc`: Cloudflare Worker configuration for deployment
- `wrangler.jsonc`: Cloudflare Worker configuration for www.nebari.dev (the `nebari-docs` Worker)
- `wrangler.classic.jsonc`: Cloudflare Worker configuration for classic.nebari.dev (the `nebari-docs-classic` Worker)
- `README.md`: detailed step-by-step instructions for using the documentation site and building it locally

## Files in `./` - the root directory of this repository
Expand Down
1 change: 1 addition & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

# Production
/dist
/dist-classic

# Generated files
/.astro
Expand Down
1 change: 1 addition & 0 deletions docs/.prettierignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# build artifacts
dist
dist-classic
.astro

# Dependencies
Expand Down
56 changes: 39 additions & 17 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ bun run dev

This command starts a local development server with hot reload.

The Nebari Classic docs are a separate site (classic.nebari.dev) built from
the same project. To work on them, run:

```bash
bun run dev:classic
```

> **Note**
> By default, this will load your site at <http://localhost:4321/>.

Expand All @@ -111,22 +118,26 @@ To build the static files of the documentation (and see how they would look once
bun run build
```

This command generates static content into the `docs/dist` directory. The build
This command generates static content into the `docs/dist` directory.
`bun run build:classic` does the same for the Nebari Classic site
(classic.nebari.dev) into `docs/dist-classic`. The build
also validates every internal link (including `#anchors`) with
[`starlight-links-validator`](https://github.com/HiDeoo/starlight-links-validator)
and fails on broken ones. You can check the built site with:

```bash
bun run preview
# or, for the Classic site
bun run preview:classic
```

### Running the tests

The smoke tests in `test/build.test.ts` build the site and then verify that
The smoke tests in `test/build.test.ts` build both sites and then verify that
every content page renders with its title, each section shows only its own
sidebar, every internal `href` and image on every page resolves, the search
index exists, and the legacy redirects in `public/_redirects` point at real
pages. Run them with:
index exists, no page links to the old `/classic/` path, and the redirects in
both `_redirects` files point at real pages. Run them with:

```bash
bun test
Expand All @@ -136,29 +147,34 @@ bun test

```
docs/
├── astro.config.mjs # Starlight config: theme plugin, header tabs, sidebars
├── public/ # Static assets served at the site root (/img, /logo, /policies)
│ └── _redirects # Legacy URL redirects (Cloudflare format)
├── astro.config.mjs # Starlight config for both sites: theme plugin, header tabs, sidebars
├── public/ # www.nebari.dev static assets served at the site root (/img, /logo, /policies)
│ └── _redirects # Redirects /classic/* and legacy URLs to classic.nebari.dev (Cloudflare format)
├── src/
│ ├── components/ # Astro components used by content and Starlight overrides
│ ├── content/docs/ # All pages; the path of a file is its URL
│ ├── content/docs/ # www.nebari.dev pages; the path of a file is its URL
│ │ ├── index.mdx # Landing page
│ │ ├── docs/ # Current Nebari documentation -> /docs/*
│ │ ├── classic/ # Nebari Classic documentation -> /classic/*
│ │ └── community/ # Community guidelines -> /community/*
│ ├── routeData.ts # Shows one sidebar per section
│ └── styles/custom.css # Landing-page styles
├── test/build.test.ts # Build smoke tests
└── wrangler.jsonc # Cloudflare Worker (static assets) config
├── classic/ # Nebari Classic, built as classic.nebari.dev with DOCS_SITE=classic
│ ├── content/docs/ # Classic pages, served from the site root -> classic.nebari.dev/*
│ └── public/ # Classic static assets and _redirects
├── test/build.test.ts # Build smoke tests for both sites
├── wrangler.jsonc # Cloudflare Worker config for www.nebari.dev
└── wrangler.classic.jsonc # Cloudflare Worker config for classic.nebari.dev
```

## Writing content

- Every page needs a `title` in its frontmatter; Starlight renders it as the page heading, so don't repeat it as a `# Heading`.
- Use root-relative links with a trailing slash, for example `/classic/how-tos/nebari-aws/`. Broken links fail the build.
- Use root-relative links with a trailing slash, for example `/docs/how-tos/deploy/`. Broken links fail the build.
- Links between the two sites must be absolute: `https://classic.nebari.dev/how-tos/nebari-aws/` from the main docs, `https://www.nebari.dev/community/introduction/` from Classic.
- Callouts use Starlight's syntax: `:::note`, `:::tip`, `:::caution`, `:::danger`, optionally with a title as `:::note[Title]`.
- Files that use components (`<Tabs>`, `<TabItem>`, `<Aside>`, `<LinkCard>`, ...) must have the `.mdx` extension and import them from `@astrojs/starlight/components`. HTML comments are not valid in `.mdx`; use `{/* ... */}`.
- New pages must be added to the matching sidebar in `astro.config.mjs` to appear in navigation.
- Nebari Classic pages go under `classic/content/docs/` and their images under `classic/public/img/`.
- Mermaid diagrams work in fenced ```` ```mermaid ```` blocks.

## Adding a new dependency
Expand All @@ -169,16 +185,22 @@ bun add package-name

## Deployment

The [Docs workflow](../.github/workflows/docs.yml) builds and tests the site on
every pull request and push to `main`. Pushes to `main` deploy `docs/dist` to
the `nebari-docs` Cloudflare Worker with
The [Docs workflow](../.github/workflows/docs.yml) builds and tests both sites
on every pull request and push to `main`. Pushes to `main` deploy `docs/dist` to
the `nebari-docs` Cloudflare Worker (www.nebari.dev) and `docs/dist-classic` to
the `nebari-docs-classic` Worker (classic.nebari.dev) with
[`cloudflare/wrangler-action`](https://github.com/cloudflare/wrangler-action);
same-repository pull requests get a preview deployment whose URL is posted as a
PR comment. The workflow needs these repository secrets:
same-repository pull requests get a preview deployment of each, with both URLs
posted as a PR comment. The workflow needs these repository secrets:

- `CLOUDFLARE_API_TOKEN`
- `CLOUDFLARE_ACCOUNT_ID`

The token must be able to deploy both Workers. `wrangler.classic.jsonc` also
attaches `classic.nebari.dev` as a custom domain on deploy, which creates its
DNS record and TLS certificate, so the token also needs DNS and Workers Routes
edit access on the `nebari.dev` zone.

<!-- links -->

[nebari-docs-repo]: https://github.com/nebari-dev/nebari-docs
Loading
Loading