Deploy site (project page + docs) workflow (RUC-NLPIR/Arbor)
The Deploy site (project page + docs) workflow from RUC-NLPIR/Arbor, explained and optimized by Latchkey.
CI health: A - excellent
Point runs-on at Latchkey and get job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.
What it does
This is the Deploy site (project page + docs) workflow from the RUC-NLPIR/Arbor repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
name: Deploy site (project page + docs)
# Builds two things and publishes them to one GitHub Pages site:
# - project_page/ (Vite/React) -> served at the site root (/Arbor/)
# - docs/ (MkDocs) -> served under (/Arbor/docs/)
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment; don't cancel an in-progress run.
concurrency:
group: pages
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# ── Docs: MkDocs Material -> _site/docs ──────────────────────────
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Build docs
run: |
python -m pip install --upgrade pip
pip install "mkdocs-material>=9.5" "mkdocs-static-i18n>=1.2"
mkdocs build --strict -d _site/docs
# ── Live demo: arbor replay --demo --html -> _site/demo.html ─────
# Regenerated from source on every deploy so the hosted, zero-install
# demo always matches the shipped code (no committed artifact to go stale).
- name: Build live demo page
run: |
pip install .
arbor replay --demo --html --no-open --out _site/demo.html
# ── Project page: Vite/React -> _site (root) ─────────────────────
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: npm
cache-dependency-path: project_page/package-lock.json
- name: Build project page
working-directory: project_page
run: |
npm ci
npm run build
- name: Place landing page at site root
run: cp -R project_page/dist/. _site/
- uses: actions/upload-pages-artifact@v3
with:
path: _site
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
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
name: Deploy site (project page + docs) # Builds two things and publishes them to one GitHub Pages site: # - project_page/ (Vite/React) -> served at the site root (/Arbor/) # - docs/ (MkDocs) -> served under (/Arbor/docs/) on: push: branches: [main] workflow_dispatch: permissions: contents: read pages: write id-token: write # Allow only one concurrent deployment; don't cancel an in-progress run. concurrency: group: pages cancel-in-progress: false jobs: build: timeout-minutes: 30 runs-on: latchkey-small steps: - uses: actions/checkout@v4 # ── Docs: MkDocs Material -> _site/docs ────────────────────────── - uses: actions/setup-python@v5 with: python-version: "3.12" - name: Build docs run: | python -m pip install --upgrade pip pip install "mkdocs-material>=9.5" "mkdocs-static-i18n>=1.2" mkdocs build --strict -d _site/docs # ── Live demo: arbor replay --demo --html -> _site/demo.html ───── # Regenerated from source on every deploy so the hosted, zero-install # demo always matches the shipped code (no committed artifact to go stale). - name: Build live demo page run: | pip install . arbor replay --demo --html --no-open --out _site/demo.html # ── Project page: Vite/React -> _site (root) ───────────────────── - uses: actions/setup-node@v4 with: node-version: "20" cache: npm cache-dependency-path: project_page/package-lock.json - name: Build project page working-directory: project_page run: | npm ci npm run build - name: Place landing page at site root run: cp -R project_page/dist/. _site/ - uses: actions/upload-pages-artifact@v3 with: path: _site deploy: timeout-minutes: 30 needs: build runs-on: latchkey-small environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} steps: - id: deployment uses: actions/deploy-pages@v4
What changed
- Run on Latchkey managed runners with one line (
runs-on), which apply the fixes below automatically and self-heal transient failures. This example useslatchkey-small; pick the runner size that fits the job. - Add a job timeout so a hung step cannot burn hours of runner time.
What Latchkey heals here
This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:
- Dependency installs
This workflow runs 2 jobs per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.