Skip to content

chore(deps)(deps): bump the production-dependencies group with 2 updates #1516

chore(deps)(deps): bump the production-dependencies group with 2 updates

chore(deps)(deps): bump the production-dependencies group with 2 updates #1516

Workflow file for this run

name: Deploy Pages (demo + docs)
# Builds the wasm32 frontend with trunk, the workspace rustdoc, AND the
# Material for MkDocs documentation handbook, then publishes ALL THREE to
# GitHub Pages in a single deployment (https://doublegate.github.io/RustyNES/):
#
# / the playable wasm demo (the full winit + wgpu + egui build)
# /api/ the workspace API documentation (rustdoc)
# /docs/ the Material for MkDocs handbook (subsystem specs + user guide)
#
# GitHub Pages allows only one deployment source per repo, so the demo, the
# rustdoc, and the MkDocs handbook are assembled into one artifact and deployed
# together (the Pages source must be "GitHub Actions", build_type: workflow —
# NOT a branch). This replaces the legacy gh-pages-branch docs deploy.
#
# Two jobs: `build` produces + size-gates the demo, builds the rustdoc + the
# MkDocs handbook, assembles the combined `_site/`, and uploads it as a Pages
# artifact; `deploy` publishes it. The build also runs on pull requests (deploy
# does NOT) so the size budget gates PRs without publishing a preview.
#
# trunk auto-downloads the wasm-bindgen CLI + wasm-opt versions pinned in
# crates/rustynes-frontend/web/Trunk.toml.
on:
push:
branches: [main]
paths:
- "crates/**"
- "Cargo.toml"
- "Cargo.lock"
- ".cargo/config.toml"
- "rust-toolchain.toml"
- "scripts/wasm_size_budget.sh"
- ".github/workflows/web.yml"
- "docs/**"
- "mkdocs.yml"
pull_request:
branches: [main]
# `ready_for_review` runs the build on a PR opened as a draft; see the
# draft gate on `build`.
types: [opened, synchronize, reopened, ready_for_review]
paths:
- "crates/**"
- "Cargo.toml"
- "Cargo.lock"
- ".cargo/config.toml"
- "rust-toolchain.toml"
- "scripts/wasm_size_budget.sh"
- ".github/workflows/web.yml"
- "docs/**"
- "mkdocs.yml"
workflow_dispatch:
# Read-only by default. `pages: write` and `id-token: write` are granted per
# job below, to the two jobs that use them -- they used to sit here at
# workflow level, which handed a Pages-publishing OIDC token to every PR build
# that compiles and runs unreviewed code.
permissions:
contents: read
# Two groups, not one. `main` / dispatch share `pages` and never cancel: only
# one Pages deploy at a time, and a half-applied deploy is worse than a slow
# one. A PR gets its own per-ref group and cancels its superseded run.
#
# Until this split every event, PRs included, sat in the single global `pages`
# group with `cancel-in-progress: false`. PR builds from DIFFERENT PRs queued
# behind each other and behind `main`'s deploys, and because GitHub keeps only
# one PENDING run per group, a third arrival silently cancelled the second --
# a PR could lose its Pages build to an unrelated PR's push.
concurrency:
group: ${{ github.event_name == 'pull_request' && format('pages-pr-{0}', github.ref) || 'pages' }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
CARGO_TERM_COLOR: always
# Pin trunk for reproducible builds. Bump deliberately; keep in sync
# with the local toolchain note in Trunk.toml.
TRUNK_VERSION: "0.21.14"
# Repository ("project") Pages serve under /<repo>/, so every asset
# URL trunk emits must be prefixed. Overrides Trunk.toml's local "/"
# without editing it (local `trunk serve` stays root-mounted).
PUBLIC_URL: "/RustyNES/"
jobs:
build:
name: build demo + docs
runs-on: ubuntu-26.04
timeout-minutes: 30
# Draft gate, as in ci.yml's `setup`: a draft PR skips this build until it
# is marked ready. Not a required check, so the skip blocks nothing.
if: ${{ github.event_name != 'pull_request' || !github.event.pull_request.draft }}
# Read-only. This job compiles and runs PR code, so it holds no Pages
# permission at all: `configure-pages` (which needs `pages: write`) runs in
# `deploy`, which never runs on a pull request (review finding on #547 --
# skipping the step on a PR did not remove the permission from the job).
permissions:
contents: read
# A PR build is a CHECK, not a publication: it proves the wasm demo builds
# (the wasm-bindgen CLI pin in Trunk.toml must match Cargo.lock, which only
# a real `trunk build` exercises), holds the size budget, and that the
# MkDocs handbook builds. Everything that only feeds the deploy -- rustdoc
# (already gated with `-D warnings` by ci.yml's lint job), the site
# assembly, configure-pages and the artifact upload -- is skipped on a PR.
env:
IS_PR: ${{ github.event_name == 'pull_request' }}
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
# Shared toolchain + cargo cache. The native winit/wgpu/cpal system
# libraries are needed only by the rustdoc build, which compiles the
# whole workspace for the host; the wasm build routes through web-sys.
# So a PR, which skips rustdoc, skips the apt provisioning too.
- uses: ./.github/actions/rust-setup
with:
targets: wasm32-unknown-unknown
apt: ${{ github.event_name == 'pull_request' && 'false' || 'true' }}
cache-key: web-pages
- name: Install trunk (prebuilt release binary)
run: |
curl -fsSL \
"https://github.com/trunk-rs/trunk/releases/download/v${TRUNK_VERSION}/trunk-x86_64-unknown-linux-gnu.tar.gz" \
| tar -xz -C /usr/local/bin trunk
trunk --version
- name: Build the wasm demo (release) for GitHub Pages
working-directory: crates/rustynes-frontend/web
run: trunk build --release --public-url "${PUBLIC_URL}"
- name: Enforce wasm size budget (< 5 MiB gzip)
run: ./scripts/wasm_size_budget.sh crates/rustynes-frontend/web/dist 5242880
- name: Build the workspace API docs (rustdoc)
if: env.IS_PR != 'true'
# --no-deps keeps it to our own crates. No -D warnings here: the lint
# job in ci.yml already gates rustdoc, so the Pages build only needs the
# HTML and must not fail the deploy on a doc nit.
run: cargo doc --workspace --no-deps
# The MkDocs handbook needs Python + mkdocs-material. We pull the
# `[imaging]` extra (cairosvg + Pillow) because the `social` plugin renders
# per-page preview-card PNGs at build time; that in turn needs the Cairo +
# Pango system libraries, installed below. The `privacy` plugin self-hosts
# the theme/social web-fonts into the build (one build-time fetch, then a
# network-free served site). We build to a temp dir (`mkdocs-site`) rather
# than straight into `_site/docs`, because the assemble step below clears +
# recreates `_site`.
- name: Set up Python for MkDocs
uses: actions/setup-python@v7
with:
python-version: "3.12"
- name: Install the social-card image libraries (Cairo + Pango)
# Required by the mkdocs-material `social` plugin's PNG renderer.
run: |
sudo apt-get update
sudo apt-get install -y \
libcairo2-dev libpango1.0-dev libfreetype6-dev \
libffi-dev libjpeg-dev libpng-dev
- name: Install Material for MkDocs (with imaging extra)
# >=9.7.5 is load-bearing: that release caps MkDocs at `<2`. MkDocs 2.0
# removes the plugin system this site uses (social, privacy, the link
# hook) and has no migration path, per the Material team's 2026-02-18
# notice, so an uncapped install would break the handbook on the day it
# resolved. Moving off MkDocs 1.x (Zensical is the drop-in they name) is
# a decision for its own PR.
run: pip install "mkdocs-material[imaging]>=9.7.5,<10"
- name: Build the MkDocs documentation handbook
# --strict (2026-09-23): any WARNING fails the build. It could not be
# strict before because the source specs carry relative links into
# sibling trees (../to-dos/**, ../crates/**) that GitHub resolves and the
# handbook cannot -- 13 warnings on every build, each a dead link on the
# published site. `scripts/mkdocs_repo_links.py` (a `hooks:` entry in
# mkdocs.yml) now rewrites exactly those links to GitHub URLs at build
# time, leaving the sources untouched, so the build is clean and a NEW
# broken link is an error rather than line 14 of a warning list.
# The MkDocs 2.0 notice Material prints on every build is answered by
# the >=9.7.5 pin above (which caps MkDocs <2); NO_MKDOCS_2_WARNING is
# the switch that notice itself documents for acknowledging it.
env:
NO_MKDOCS_2_WARNING: "1"
run: mkdocs build --strict --site-dir mkdocs-site
- name: Assemble the Pages site (demo at /, rustdoc at /api/, handbook at /docs/)
if: env.IS_PR != 'true'
run: |
set -euo pipefail
rm -rf _site
mkdir -p _site/api _site/docs
cp -r crates/rustynes-frontend/web/dist/. _site/
cp -r target/doc/. _site/api/
cp -r mkdocs-site/. _site/docs/
# rustdoc emits no root index for a multi-crate workspace; add a
# redirect to the main library facade so /api/ lands somewhere useful.
cat > _site/api/index.html <<'HTML'
<!doctype html>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0; url=rustynes_core/index.html">
<title>RustyNES API documentation</title>
<a href="rustynes_core/index.html">RustyNES API documentation</a>
HTML
- name: Upload Pages artifact (demo + docs)
if: env.IS_PR != 'true'
uses: actions/upload-pages-artifact@v5
with:
path: _site
deploy:
name: deploy to GitHub Pages
timeout-minutes: 15
# Only publish from main / manual dispatch — PRs build + size-gate
# but never deploy.
if: github.event_name != 'pull_request'
needs: build
runs-on: ubuntu-26.04
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
# build_type is set to "workflow" (GitHub Actions source); enablement
# self-heals if Pages is ever disabled. Here rather than in `build` so
# that job needs no Pages permission.
- name: Configure Pages
uses: actions/configure-pages@v6
with:
enablement: true
- name: Deploy
id: deployment
uses: actions/deploy-pages@v5
# deploy-pages v5.0.1 (the latest release, 2026-09-01) bundles a
# dependency that imports Node's built-in `punycode`, which Node 24
# reports as DeprecationWarning DEP0040 on every deploy. It is in the
# action's own code, so the only thing this repo can do is decline to
# print THAT one code; any other deprecation still shows. Remove when a
# deploy-pages release no longer triggers it.
env:
NODE_OPTIONS: --disable-warning=DEP0040