4. Wire the build and deploy to GitHub Pages
Run generators before every build
LikeC4, CALM and Slidev all produce artifacts that the site imports. Run their
generators before start and build using npm's pre hooks:
{
"scripts": {
"likec4:codegen": "likec4 codegen model ./likec4 --use-core-package --outfile ./src/likec4/likec4-model.ts",
"calm:build": "node scripts/build-calm.mjs",
"slidev:build": "node scripts/build-slidev.mjs",
"prestart": "npm run likec4:codegen && npm run calm:build && npm run slidev:build",
"start": "docusaurus start",
"prebuild": "npm run likec4:codegen && npm run calm:build && npm run slidev:build",
"build": "docusaurus build"
}
}
The generated files are reproducible, so add them to .gitignore:
/src/likec4/likec4-model.ts
/src/calm/*.mdx
/src/slides-manifest.json
/static/slides
/slides/node_modules
/slides/decks/*/node_modules
/slides/decks/*/dist
Configure the base URL
For a project site at https://<user>.github.io/<repo>/, the baseUrl is
/<repo>/. Make it overridable so the Slidev build (which needs the same
prefix for its assets) stays in sync:
const config: Config = {
url: 'https://<user>.github.io',
baseUrl: process.env.DOCUSAURUS_BASE_URL || '/<repo>/',
organizationName: '<user>',
projectName: '<repo>',
// ...
};
GitHub Actions workflow
Create .github/workflows/deploy.yml. If the site lives in a subdirectory
(e.g. workspaces/docusaurus/), set working-directory and DOCUSAURUS_BASE_URL:
name: Deploy to GitHub Pages
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: false
defaults:
run:
working-directory: workspaces/docusaurus
jobs:
build:
runs-on: ubuntu-latest
env:
DOCUSAURUS_BASE_URL: /<repo>/
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
# Match local dev via a committed .nvmrc so npm resolves the same
# lockfile in CI and locally.
node-version-file: .nvmrc
cache: npm
cache-dependency-path: |
workspaces/docusaurus/package-lock.json
workspaces/docusaurus/slides/package-lock.json
- run: npm ci
# Decks are a separate npm workspace with their own Slidev versions.
- run: npm ci
working-directory: workspaces/docusaurus/slides
- run: npm run build
- uses: actions/upload-pages-artifact@v3
with:
path: workspaces/docusaurus/build
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v4
One manual step
In the repository, go to Settings → Pages → Build and deployment → Source
and select GitHub Actions. After that, every push to main publishes the
site.
Verify locally
Build exactly as CI does before pushing:
DOCUSAURUS_BASE_URL=/<repo>/ npm run build
npm run serve
That's the whole pipeline: three source formats (.c4, .architecture.json,
.md decks), three generators wired into prebuild, and one workflow to ship
it.