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
52 changes: 52 additions & 0 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Build the MkDocs site (with the slide deck at /slides/) using Nix and
# deploy it to GitHub Pages. Pull requests only check and build.
#
# One-time setup: Settings → Pages → Build and deployment → Source:
# "GitHub Actions".
name: pages

on:
push:
branches: [main]
pull_request:
workflow_dispatch:

permissions:
contents: read

# One deployment at a time; a newer push cancels an older pending one.
concurrency:
group: pages-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v31
- name: Check (both builds + Nix lint)
run: nix flake check -L
- name: Build the site
run: |
nix build .#documentation -L
# Copy out of the read-only Nix store for the Pages upload.
cp -rL result _site
chmod -R u+w _site
- uses: actions/upload-pages-artifact@v3
with:
path: _site

deploy:
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
needs: build
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v4
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ the browser.
```text
flake.nix inputs (nixpkgs, flake-parts, mkdocs-flake, reveal.js), locked in flake.lock
flake-parts/ flake modules, auto-imported: docs settings, slides build, checks
.github/workflows/ pages.yml: check, build and deploy the docs site to GitHub Pages
documentation/ MkDocs site: mkdocs.yml + docs/*.md
slides/ reveal.js deck: index.html + slides.md
```
18 changes: 12 additions & 6 deletions documentation/docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,16 @@ nix fmt . # format the .nix files
nix flake check # builds both sites and lints the Nix code
```

## 6. Publish (example: GitHub Pages)
## 6. Publish to GitHub Pages

Any host that serves a folder works. For GitHub Pages, a workflow can run
`nix build .#documentation`, copy `result/` and upload it with
[`actions/upload-pages-artifact`](https://github.com/actions/upload-pages-artifact).
Put the slides in a subfolder of the same upload if you want both on one
site, for example `cp -rL result-1/. public/slides/`.
The repo ships `.github/workflows/pages.yml`. On every push to `main` it
runs `nix flake check`, builds the docs site (slides included under
`/slides/`) and deploys it to GitHub Pages. Pull requests run the same
checks and build without deploying.

Turn it on once per repo: **Settings → Pages → Build and deployment →
Source: GitHub Actions**. The site then appears at
`https://<owner>.github.io/<repo>/`.

Any other static host works the same way: upload the contents of the
`nix build .#documentation` result.
4 changes: 3 additions & 1 deletion documentation/docs/nix.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ flake.lock # exact versions of every input (generated, commit it)
flake-parts/
├── default.nix # formatter + MkDocs settings
├── slides.nix # the reveal.js build and the serve-slides app
├── scripts/
│ └── inline-markdown.py # folds slides.md into index.html at build time
├── checks.nix # `nix flake check`: both builds + the Nix linters
└── template.nix # lets `nix flake init -t` copy this repo (delete it in your copy if you like)
documentation/ # the MkDocs site
Expand Down Expand Up @@ -63,7 +65,7 @@ module sets options inside `perSystem`, for example `packages.slides` or

| Command | Output |
| --- | --- |
| `nix build .#documentation` | the docs website (from mkdocs-flake) |
| `nix build .#documentation` | the docs website, with the deck at `/slides/` |
| `nix build .#slides` | the slide deck |
| `nix run .#watch-documentation` | live docs preview |
| `nix run .#serve-slides` | live slides preview |
Expand Down
24 changes: 24 additions & 0 deletions documentation/docs/presentation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Presentation

The slide deck from `slides/`, embedded in this site. Click it and use the
arrow keys, or <a href="../slides/index.html" target="_blank">open it on its own</a>.

<!-- Plain HTML links on purpose: MkDocs checks Markdown links against
documentation/docs/, where the deck only exists during
`nix build .#documentation`, and strict mode would fail the live
preview. URLs are relative to this page's URL, /presentation/. -->

<iframe src="../slides/index.html" title="Slide deck"
style="width: 100%; aspect-ratio: 16 / 9; border: 0;"
allowfullscreen></iframe>

!!! info "How the deck gets here"
`nix build .#documentation` builds the deck (`nix build .#slides`)
first and copies it into the site at `/slides/` before MkDocs runs
(`mkdocs-preBuildHook` in `flake-parts/default.nix`). The deck still
builds and works on its own, too.

The live preview (`nix run .#watch-documentation`) serves only
`documentation/`, so the frame above is empty there. Preview the deck
with `nix run .#serve-slides`, or build the whole site and serve it:
`nix build .#documentation && python3 -m http.server -d result`.
18 changes: 14 additions & 4 deletions documentation/docs/reveal-js.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ slides/
└── slides.md # the slides themselves, in Markdown
```

When you build, Nix copies `slides/` and adds reveal.js under `reveal/`:
When you build, Nix copies `slides/`, folds `slides.md` into
`index.html`, and adds reveal.js under `reveal/`:

```text
result/
├── index.html
├── slides.md
├── index.html # with slides.md inlined
└── reveal/ # reveal.js' prebuilt dist/: reveal.js, reveal.css, theme/, plugin/
```

Expand Down Expand Up @@ -106,7 +106,17 @@ at the bottom of `index.html`. See the
`index.html` loads `slides.md` with a web request, and browsers block those
requests from pages opened straight from disk (`file://`). That is why the
repo has `nix run .#serve-slides` instead of "double-click index.html".
Hosted on any web server, the built deck works as-is.

The **built** deck does not have this problem: `nix build .#slides` copies
the Markdown into `index.html` itself (a `<textarea data-template>` block,
done by `flake-parts/scripts/inline-markdown.py`), so `result/index.html`
opens straight from disk and works on any host.

## The deck inside the docs site

`nix build .#documentation` also puts the built deck at `/slides/` of the
website, and the [Presentation](presentation.md) page embeds it with an
`<iframe>`. Anything you change in `slides/` shows up in both.

## More than one deck

Expand Down
1 change: 1 addition & 0 deletions documentation/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ nav:
- Getting started: getting-started.md
- MkDocs basics: mkdocs.md
- reveal.js basics: reveal-js.md
- Presentation: presentation.md
- How the Nix flake works: nix.md

# Material for MkDocs — the theme. Options:
Expand Down
11 changes: 10 additions & 1 deletion flake-parts/default.nix
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{
perSystem = {pkgs, ...}: {
perSystem = {
pkgs,
config,
...
}: {
# Formatter: `nix fmt .`
formatter = pkgs.alejandra;

Expand All @@ -10,6 +14,11 @@
mkdocs-root = ../documentation;
# Broken links / missing nav pages fail the build instead of warning.
strict = true;
# Ship the built slide deck inside the website at /slides/
# (embedded by docs/presentation.md). Runs in the build directory,
# where docs/ is a symlink copy of documentation/docs (read-only
# directories, hence the chmod).
mkdocs-preBuildHook = "chmod u+w docs && cp -r ${config.packages.slides} docs/slides";
};
};
}
37 changes: 37 additions & 0 deletions flake-parts/scripts/inline-markdown.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""Inline external reveal.js Markdown into the deck's HTML.

For every .html file under the given directory, each
`<section data-markdown="x.md" ...></section>` becomes
`<section data-markdown ...><textarea data-template>…x.md…</textarea></section>`,
and the inlined .md files are deleted. The built deck then needs no
fetch() (works from file://), and MkDocs never sees a stray .md file when
the deck is copied into the docs site.
"""

import html
import pathlib
import re
import sys

SECTION = re.compile(
r'<section(?P<pre>[^>]*?)\sdata-markdown="(?P<src>[^"]+)"(?P<post>[^>]*)>\s*</section>'
)

root = pathlib.Path(sys.argv[1])
inlined = set()
for page in root.rglob("*.html"):
text = page.read_text(encoding="utf-8")

def inline(match):
src = (page.parent / match["src"]).resolve()
inlined.add(src)
body = html.escape(src.read_text(encoding="utf-8"), quote=False)
return (
f'<section{match["pre"]} data-markdown{match["post"]}>'
f"<textarea data-template>\n{body}</textarea></section>"
)

page.write_text(SECTION.sub(inline, text), encoding="utf-8")

for src in inlined:
src.unlink()
10 changes: 7 additions & 3 deletions flake-parts/slides.nix
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@
in {
# nix build .#slides → ./result is the static slide deck: the files in
# slides/ plus reveal.js under reveal/ (index.html links reveal/...).
packages.slides = pkgs.runCommand "slides" {} ''
mkdir -p $out
cp -r ${../slides}/. $out/
# Each `data-markdown="x.md"` deck gets its Markdown inlined into the
# .html (scripts/inline-markdown.py), so the built deck opens straight
# from disk and nests cleanly inside the MkDocs site (default.nix).
packages.slides = pkgs.runCommand "slides" {nativeBuildInputs = [pkgs.python3];} ''
cp -r ${../slides} $out
chmod -R u+w $out
python3 ${./scripts/inline-markdown.py} $out
cp -r ${reveal} $out/reveal
'';

Expand Down
Loading