Deployment / Releases (Netlify + GitHub Actions)
How the project ships. There are three independent pipelines, each with one home:
| Pipeline | Where | What it does |
|---|---|---|
| CI (test on every push) | .github/workflows/ci.yml |
Lint + format check + smoke + Node/jsdom Vitest suites; builds the React SPA; Playwright E2E + a11y + visual-regression. |
| Docs site | .github/workflows/pages.yml |
Builds the JSDoc doc-site (code API + the notes) and deploys it to GitHub Pages on every push to master. |
| Software release | .github/workflows/release.yml |
Version-gated GitHub Release: source tarball + docs zip. |
| Visual baselines | .github/workflows/visual-baselines.yml |
Manual (workflow_dispatch): regenerates the Linux Playwright visual baselines on the e2e runner and uploads them as an artifact to download + commit. |
| Web app deploy | netlify.toml |
Builds + hosts the web-app/ SPA on Netlify (separate from the GitHub release). |
CI — .github/workflows/ci.yml
Runs on push to dev/master, on PRs, and on demand. Node 24. Three jobs: (1) check — npm ci,
then npm run lint, npm run format:check, npm run smoke (the import smoke test),
and npm run test:unit (the Node Vitest suite); (2) web-app — npm --prefix web-app ci, then
npm --prefix web-app run build (the SPA is proven to build) and npm --prefix web-app run test (the jsdom
Vitest suite); (3) e2e — installs root + web-app deps and the bundled Playwright chromium, then
npm run test:e2e (E2E + accessibility + visual-regression). Visual works cross-OS because baselines
are committed per platform — *-chromium-win32.png (local, system Chrome) and *-chromium-linux.png (CI,
bundled chromium); playwright.config.js picks the browser by process.platform and only skips visual when
PLAYWRIGHT_SKIP_VISUAL is set (an escape hatch for a platform without baselines). Regenerate the Linux set
with the Update visual baselines (Linux) workflow (see below) — never hand-edit the PNGs. Green here
means the same thing as green locally — it's the CI mirror of npm test + the build + the browser specs.
Visual baselines — .github/workflows/visual-baselines.yml
Manual workflow_dispatch. Runs on ubuntu-latest with the same setup as the e2e job (Node 24, npm ci
- web-app
npm ci,npx playwright install --with-deps chromium), thenplaywright test visual.spec.js --update-snapshots, and uploadstests/e2e/visual.spec.js-snapshots/as thelinux-visual-baselinesartifact. Because it renders in the exact environment the e2e job checks against, the baselines match CI. Workflow: trigger it (gh workflow run visual-baselines.yml), download the artifact, copy the*-chromium-linux.pngfiles intotests/e2e/visual.spec.js-snapshots/, and commit. Do this whenever the SPA's stable chrome changes (the Windows*-win32.pngset is refreshed locally withnpm run test:e2e:update).
Docs site — .github/workflows/pages.yml
On every push to master, runs npm ci then npm run docs (scripts/build-docs.mjs → JSDoc with
the docdash template) and deploys docs/jsdoc to GitHub Pages. README.md is the home
(jsdoc opts.readme), so the site is the README + the code API (per-function JSDoc) + the full
living notes wired in as tutorial pages (hierarchy mirrors the notes/ tree). See
documentation.md.
One-time repo setup: Settings → Pages → Build and deployment → Source = GitHub Actions. The
workflow needs pages: write + id-token: write and the github-pages environment (already declared
in the workflow).
Software release — .github/workflows/release.yml
The version gate
Trigger: push to master (FF-only from green dev, so always all-green). Gate: the tag
v<VERSION> must not already exist — i.e. VERSION was bumped since the last release. So:
- Bump
VERSION(+package.json, same commit; seeversioning.md) → the next timemasteradvances, that commit cuts the release and creates tagvX.Y.Z. - A
masterpush that did not bumpVERSION→ the tag already exists → no-op (no duplicate release). This is exactly why tags key offVERSION. - A
VERSIONcarrying-alpha/-beta/-rcmarks the GitHub Release as a prerelease.
What it publishes
random-ai-prompt-<v>.tar.gz— a clean source tarball viagit archive(tracked files only; nonode_modules,output/, or build junk). Run it with Node 24:npm installthennpm start/npm run server.random-ai-prompt-<v>-docs.zip— the generated JSDoc doc-site (archival snapshot; the live site is on Pages).
The release body is composed automatically: a plain-English "what it is", a prerelease note, "What's
new in this release" pulled from the lines added to notes/version/ since the previous tag
(git diff <prev>..HEAD), and a downloads list — then softprops/action-gh-release appends the auto
"What's Changed" commit list.
Dry run
workflow_dispatch with dry_run = true (the default for manual runs) builds + uploads everything as
workflow artifacts but does not create the Release — use it to shake out the build without
publishing: gh workflow run release.yml -f dry_run=true, then gh run watch.
Web app deploy — netlify.toml
The web-app/ SPA is built and hosted on Netlify, independent of the GitHub release:
command = npm --prefix web-app install && npm --prefix web-app run build
publish = web-app/dist
functions = web-app/netlify/functions
/api/* routes to the serverless functions (the stateless BYOK generation proxy — see
../systems/web-app.md); every other path falls back to index.html for
client-side routing. Set VITE_ONLINE=true in the Netlify build env so the deployed build hides the
local-only providers.
Policy (standing rules)
- GitHub Releases are SOFTWARE releases only — never a docs-only or images-only release. The
versioned
release.ymlrelease is the only kind. - Every Release gets a clear, user-facing description by default —
release.ymlcomposes it from the living changelog; keep that quality bar if you edit the step. - The docs site lives on GitHub Pages, not in git or a release (no repo-size growth). The release attaches its own docs zip as an archival snapshot.
Not done yet (intentional)
- No deployments yet — too early in the rewrite/re-adapt (owner's call, 2026-06-18). All three
pipelines are wired but deliberately dormant:
masteris held at the old241a148(work stays ondev, which only runs CI — build/test, not a deploy), GitHub Pages is not enabled on the repo (Settings → Pages → Source still unset), and no Netlify site is connected. Advancingmasteris the single trigger for both the Pages docs deploy and the software Release, so nothing ships until the owner says go. Planned homes when ready: GitHub Pages for the docs (like the sibling project), Netlify for the app (functions). - The hosted BYOK provider dispatch in
web-app/netlify/functions/generate.jsis a stub (migration phase 2). Local generation works today; the hosted path is wired but not yet pointed at a provider. - No code signing / packaged installers (it's a Node app shipped as source). Revisit if a packaged binary is ever wanted.