Skip to content

feat: deploy web app to GitHub Pages on push to main #4

feat: deploy web app to GitHub Pages on push to main

feat: deploy web app to GitHub Pages on push to main #4

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
jobs:
# ── Change detection ────────────────────────────────────────
changes:
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
rust: ${{ steps.filter.outputs.rust }}
web: ${{ steps.filter.outputs.web }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
rust:
- 'src/**'
- 'silkprint-wasm/**'
- 'Cargo.toml'
- 'Cargo.lock'
- 'themes/**'
- 'fonts/**'
- 'tests/**'
- 'deny.toml'
- 'rust-toolchain.toml'
web:
- 'web/**'
# ── Rust format + clippy ────────────────────────────────────
check:
name: Format & Clippy
needs: changes
if: needs.changes.outputs.rust == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Format
run: cargo fmt --all --check
- name: Clippy
run: cargo clippy --workspace --all-targets --all-features -- -D warnings
# ── Tests ───────────────────────────────────────────────────
test:
name: Test
needs: changes
if: needs.changes.outputs.rust == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- uses: taiki-e/install-action@v2
with:
tool: cargo-nextest
- name: Tests
run: cargo nextest run --workspace --locked
- name: Doc tests
run: cargo test --doc --workspace --locked
# ── Supply-chain security audit ─────────────────────────────
deny:
name: Deny
needs: changes
if: needs.changes.outputs.rust == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: EmbarkStudios/cargo-deny-action@v2
# ── WASM build ──────────────────────────────────────────────
wasm:
name: WASM
needs: changes
if: needs.changes.outputs.rust == 'true' || needs.changes.outputs.web == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Get wasm-bindgen version
id: wb-version
run: |
version=$(grep -A1 '^name = "wasm-bindgen"$' Cargo.lock | grep '^version' | head -1 | sed 's/.*"\(.*\)"/\1/')
if [ -z "$version" ]; then
echo "::error::Could not determine wasm-bindgen version from Cargo.lock"
exit 1
fi
echo "version=$version" >> "$GITHUB_OUTPUT"
- uses: taiki-e/install-action@v2
with:
tool: wasm-bindgen-cli@${{ steps.wb-version.outputs.version }}
- name: Build WASM
run: cargo build --release --locked -p silkprint-wasm --target wasm32-unknown-unknown
- name: Generate bindings
run: |
mkdir -p wasm-out
wasm-bindgen --out-dir wasm-out --target web \
target/wasm32-unknown-unknown/release/silkprint_wasm.wasm
# Patch import.meta.url so Turbopack doesn't resolve it statically
sed -i "s|new URL('silkprint_wasm_bg.wasm', import.meta.url)|'/wasm/silkprint_wasm_bg.wasm'|" \
wasm-out/silkprint_wasm.js
- name: Optimize WASM
run: |
sudo apt-get update -qq && sudo apt-get install -y -qq binaryen > /dev/null 2>&1 || true
if command -v wasm-opt >/dev/null 2>&1; then
wasm-opt -Oz --enable-bulk-memory wasm-out/silkprint_wasm_bg.wasm -o wasm-out/silkprint_wasm_bg.wasm
fi
- uses: actions/upload-artifact@v4
with:
name: wasm
path: wasm-out/
retention-days: 1
# ── Web app ─────────────────────────────────────────────────
web:
name: Web
needs: [changes, wasm]
if: needs.changes.outputs.rust == 'true' || needs.changes.outputs.web == 'true'
runs-on: ubuntu-latest
defaults:
run:
working-directory: web
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: wasm
path: wasm-out/
- name: Install WASM artifacts and fonts
working-directory: .
run: |
mkdir -p web/src/lib/wasm web/public/wasm web/public/fonts
cp wasm-out/silkprint_wasm.js wasm-out/silkprint_wasm.d.ts web/src/lib/wasm/
cp wasm-out/silkprint_wasm_bg.wasm web/public/wasm/
cp -r fonts/core/* web/public/fonts/
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
cache-dependency-path: web/pnpm-lock.yaml
- run: pnpm install --frozen-lockfile
- name: Typecheck
run: pnpm typecheck
- name: Lint
run: pnpm lint
- name: Build
run: pnpm build
# ── Deploy to GitHub Pages ─────────────────────────────────
deploy:
name: Deploy
needs: [changes, wasm, web]
if: github.ref == 'refs/heads/main' && (needs.changes.outputs.rust == 'true' || needs.changes.outputs.web == 'true')
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
defaults:
run:
working-directory: web
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: wasm
path: wasm-out/
- name: Install WASM artifacts and fonts
working-directory: .
run: |
mkdir -p web/src/lib/wasm web/public/wasm web/public/fonts
cp wasm-out/silkprint_wasm.js wasm-out/silkprint_wasm.d.ts web/src/lib/wasm/
cp wasm-out/silkprint_wasm_bg.wasm web/public/wasm/
cp -r fonts/core/* web/public/fonts/
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
cache-dependency-path: web/pnpm-lock.yaml
- run: pnpm install --frozen-lockfile
- name: Build for Pages
env:
GITHUB_PAGES: 'true'
NEXT_PUBLIC_BASE_PATH: /silkprint
run: pnpm build
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v3
with:
path: out
- uses: actions/deploy-pages@v4
id: deployment