Flow Demo Publishing — Design
Goal
Publish a live, browsable demo of @apitomy/flow-ui (the WorkflowEditor, WorkflowDiffViewer,
and WorkflowViewer components) to apitomy.io/flow/demo/, so visitors can try the components
without integrating Flow into their own application first. The published demo must always reflect
the most recently released version of apitomy-flow, and must be rebuilt and republished
automatically whenever a new release is created.
Background
apitomy-flowis the source repo (this repo). Theui/directory contains the@apitomy/flow-uinpm package (WorkflowEditor,WorkflowDiffViewer,WorkflowViewer).ui/src/dev/App.tsxis an existing internal dev harness (npm run dev) that already exercises all three components against realistic sample workflow data, with a PatternFly masthead/nav shell. It already carries the brand text "Apitomy Flow Demo" in its masthead.apitomy.github.iois the Jekyll-based static site published toapitomy.io(GitHub Pages, custom domain viaCNAME).- A directly analogous pattern already exists for a sibling project,
apitomy-openapi-editor: - It has a standalone
test-app/(a small Vite+React app that imports the library'ssrc/directly, not through the built npm package). .github/workflows/publish-demo.ymlbuildstest-appwithVITE_BASE_PATH=/openapi-editor/demo/and pushes the built output intoapitomy.github.ioatopenapi-editor/demo/, committing with message"Update OpenAPI Editor demo application (automated)".- However, that workflow triggers on
push: branches: [main](paths-filtered), not on release — it always reflects the tip ofmain, not a specific released version. apitomy-flowalready has a separateupdate-website.yamlworkflow, triggered onrelease: [released], that checks outapitomy.github.io, updates release-metadata JSON files, and pushes — this is the pattern to follow for release-gating (not the openapi-editor push-to-main pattern).apitomy-flow'srelease.yamlperforms version bumping, tagging (vX.Y.Z), building, andgh release create;npm-publish.yaml(triggered onrelease: [created]) publishes@apitomy/flow-uito npm from the release tag.
Decisions (confirmed with stakeholder)
- Demo app source: Reuse
ui/src/dev/App.tsxas-is (no new dedicated demo app). It already covers all three components with realistic sample data. - Build source: Build from the released source, checked out at the release git tag —
not from the published npm package. This matches the openapi-editor
test-appapproach (importing library source directly) and avoids any npm-propagation timing dependency. - Demo location:
apitomy.io/flow/demo/(pathflow/demo/inapitomy.github.io, mirroringopenapi-editor/demo/). Add a "Live Demo" link to the Flow project page (_pages/projects/flow.html). - Trigger: A new, separate GitHub Actions workflow in
apitomy-flow,.github/workflows/publish-demo.yaml, triggered onrelease: [released]— decoupled fromrelease.yaml, independently re-runnable, consistent with the existingupdate-website.yamlpattern in this repo. - Base path handling:
ui/vite.config.tsgainsbase: process.env.VITE_BASE_PATH || '/'(mirrors openapi-editor'stest-app/vite.config.ts). Defaults to/for local dev; CI setsVITE_BASE_PATH=/flow/demo/for the demo build. - Branding: Small public-facing tweaks only — update
ui/index.html<title>to "Apitomy Flow — Live Demo", and add a small link/banner in the dev app back tohttps://apitomy.io/projects/flow/(and/or the GitHub repo) so visitors can navigate back to docs. No deeper rework of the dev app's UI/content. - Notifications: No Slack notifications for the new workflow (unlike other apitomy-flow workflows, which do send Slack notifications).
Non-goals
- No changes to
release.yaml,npm-publish.yaml, orupdate-website.yaml. - No new demo-specific sample data or scenarios — reuse what
ui/src/dev/App.tsxalready has. - No changes to how
@apitomy/flow-uiis packaged/published to npm. - Not addressing the pre-existing gap where the OpenAPI Editor project page has no demo link yet (out of scope for this work, could be a quick follow-up but not part of this spec).
Design
1. ui/vite.config.ts — base path support
Add:
This is a no-op change for the existing library build (vite build with the lib config) and for
local npm run dev, since the env var will be unset in those contexts. It only takes effect when
explicitly set by the demo-build CI step.
2. Separate demo build target
The existing npm run build script (vite build && tsc -p tsconfig.lib.json) builds the
library (dist/index.js, dist/index.d.ts, dist/style.css) using the build.lib config in
vite.config.ts — entry src/index.ts, with React/PatternFly/xyflow externalized. This is not
suitable for producing a standalone demo app (externals wouldn't be bundled; output isn't an
index.html-based app).
We need a distinct Vite build mode that:
- Uses index.html → src/dev/App.tsx as the entry point (an app build, not a library
build).
- Bundles all dependencies (does not externalize React/PatternFly/xyflow).
- Outputs to a separate directory so it never collides with the library's dist/ (which is what
npm publish ships and what files: ["dist"] in package.json references).
Approach: add a second Vite config file, ui/vite.demo.config.ts, used only for the demo build:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
base: process.env.VITE_BASE_PATH || '/',
build: {
outDir: 'dist-demo',
},
});
Add an npm script in ui/package.json:
index.html's existing script tag (/src/dev/App.tsx) becomes the entry point Vite discovers
automatically — no changes needed there beyond the <title> tweak. tsc -p tsconfig.lib.json is
NOT run for the demo build (that step only emits library type declarations, irrelevant to an app
bundle).
3. ui/index.html — title tweak
(Applies to local dev too; harmless.)
4. ui/src/dev/App.tsx — small banner/link addition
Add a small, unobtrusive link in the masthead content (next to or below the existing
"Apitomy Flow Demo" brand text) pointing to https://apitomy.io/projects/flow/, e.g. an
ExternalLinkAltIcon-accompanied link with text like "apitomy.io" or "Docs & GitHub". Exact
placement/copy left to implementation, kept minimal — this is a demo app, not a marketing page.
5. New workflow: .github/workflows/publish-demo.yaml
Triggered on release: [released] (same event as update-website.yaml), with an optional
workflow_dispatch for manual re-runs/dry-runs. Steps:
- Guard:
if: github.repository_owner == 'Apitomy'. - Checkout
apitomy-flowat the release tag. The release event payload providesgithub.event.release.tag_name(e.g.v2.0.3); use it as the checkoutref. Forworkflow_dispatchruns, default to fetchinghttps://api.github.com/repos/Apitomy/apitomy-flow/releases/latestto resolve the tag (mirrors theFetch required Detailsstep inupdate-website.yaml). - Set up Node.js (same version as other workflows,
24.21.0). npm ciinui/.npm run build:demoinui/, with envVITE_BASE_PATH=/flow/demo/.- Checkout
apitomy.github.iointo awebsite/subdirectory, usingsecrets.ACCESS_TOKEN(same pattern asupdate-website.yaml/ openapi-editor'spublish-demo.yml). - Replace
website/flow/demo/with the freshly builtui/dist-demo/contents: - Commit and push, guarded on there being actual changes:
- No Slack notification steps.
6. apitomy.github.io changes
- New directory
flow/demo/— populated only by the CI workflow above. No placeholder needed: the workflow'smkdir -p website/flowstep creates the parent directory itself before copying in the built output, so nothing needs to be pre-committed by hand. _pages/projects/flow.html: add a "Live Demo" link in the existing Links section:
Risks / Trade-offs
- Timing gap: Because
publish-demo.yamlis a separate workflow fromrelease.yaml, there's a window after a GitHub release is published where the demo hasn't been rebuilt yet. This mirrors the existingupdate-website.yamlbehavior (release metadata also lags slightly behind release creation) — an accepted, pre-existing pattern in this repo, not a new risk class. The gap is on the order of a CI run (a few minutes), not blocking for any existing workflow. - Duplicate build config: Introducing
vite.demo.config.tsalongside the library'svite.config.tsadds a small amount of config duplication (plugins, base path logic). Kept deliberately minimal (no aliasing/resolve complexity like openapi-editor'stest-appneeds, since the demo app lives insideui/and sharesnode_modulesdirectly — no cross-package React duplication risk). - Two checkouts required by the tag-based build: the workflow must resolve the tag name
correctly for both
releaseevents and manualworkflow_dispatchruns — mirrors existing logic inupdate-website.yaml, low risk.
Testing
- Locally verify
npm run build:demoproduces a workingdist-demo/when serving with a base path (e.g.,npx serve -s dist-demoor similar, adjusting for the/flow/demo/base by testing via a reverse-proxy path, or simply confirming asset URLs in the emittedindex.htmlare correctly prefixed whenVITE_BASE_PATH=/flow/demo/is set). - Confirm existing
npm run lint,npm test, and the existingnpm run build(library build) are unaffected by the newvite.demo.config.ts/package.jsonscript additions. - Dry-run the new workflow via
workflow_dispatch(against the latest existing release) before relying on therelease: [released]trigger, to validate the full checkout → build → cross-repo push flow end-to-end.