| .. | ||
| backfill-release-assets.yml | ||
| build-and-test.yml | ||
| canonical-governance.yml | ||
| close-needs-retest-timeout.yml | ||
| create-release.yml | ||
| deploy-demo-server.yml | ||
| eval-model-matrix.yml | ||
| helm-ci.yml | ||
| helm-pages.yml | ||
| install-sh-smoke.yml | ||
| issue-version-label-sync.yml | ||
| issue-version-retest-comment.yml | ||
| promote-floating-tags.yml | ||
| publish-docker.yml | ||
| publish-helm-chart.yml | ||
| README.md | ||
| release-dry-run.yml | ||
| repo-boundary-audit.yml | ||
| test-e2e.yml | ||
| test-updates.yml | ||
| update-demo-server.yml | ||
| validate-release-assets.yml | ||
GitHub Actions Workflows
Issue Triage Automation
Files:
issue-version-label-sync.ymlissue-version-retest-comment.yml
Issue intake is split deliberately:
issue-version-label-sync.ymlis the silent metadata path. It runs onopened,edited, andreopenedissue events so version labels,needs-version-info, andneeds-retest-on-lateststay correct when maintainers tidy issue metadata.issue-version-retest-comment.ymlis the public guidance path. It only runs onopenedandreopened, and only posts reporter-facing retest guidance when the issue is an older-version bug report from a non-maintainer.- Both workflows load the shared helper at
.github/scripts/issue-version-triage.cjsso parsing and classification logic lives in one place instead of drifting across duplicated inline scripts.
Update Demo Server
File: update-demo-server.yml
Automatically updates the governed demo target after a release is published. Stable releases update the public demo. Prerelease tags no longer update a separate v6 preview demo after GA.
Configuration Required
Create one GitHub Environment:
demo-stable
The environment must define the secret names used by the governed demo target.
Required environment secrets:
-
DEMO_SERVER_SSH_KEY
- The private SSH key for accessing the demo server
- Generate with:
cat ~/.ssh/id_ed25519(or your key file) - Should be the full private key including
-----BEGINand-----ENDlines
-
DEMO_SERVER_HOST
- The hostname or IP of the demo server
-
DEMO_SERVER_USER
- The SSH username for the demo server (e.g.
rootor a deploy user with sudo access)
- The SSH username for the demo server (e.g.
Required shared secret:
- TS_AUTHKEY
- Tailscale auth key used by the governed demo deploy/update workflows before SSH
- Allows GitHub-hosted runners to reach private demo targets such as the stable
pulse-relayTailscale host - May be stored as a repository secret or repeated in the selected environment if desired
Required environment variables:
-
DEMO_EXPECTED_HOSTNAME
- The remote
hostnamevalue the stable demo environment is expected to report - Stable example:
pulse-relay - This is a host-identity guard: the workflow fails closed if the SSH secret points at the wrong machine
- The remote
-
DEMO_LOCAL_BASE_URL
- Local URL used on the target host for version and mock-mode verification
- Example stable value:
http://localhost:7655
-
DEMO_PUBLIC_HEALTH_URL
- Public health endpoint for the stable demo target
- Example stable value:
https://demo.pulserelay.pro/api/health
Optional environment variables:
-
DEMO_SERVICE_NAME
- Stable default:
pulse - When set, the server installer derives the instance-specific install dir, config dir, update helper, and update timer from this service identity.
- Stable default:
-
DEMO_AUTH_USER / DEMO_AUTH_PASS
- Demo credentials used for post-update mock verification
- Defaults to
demo/demowhen omitted
How It Works
- Trigger: Runs automatically when a GitHub release is published
- Target selection: Stable tags deploy to
demo-stable; prerelease tags are skipped because the public v6 preview target is retired after GA - Service identity: Stable runs default to the
pulseservice identity - Governance check: Validates the selected tag is reachable from the governed release branch for that version
- Latest check: Refuses to update the public demo unless the published tag is the latest stable release
- Network attach: Joins Tailscale before any SSH step so governed demo targets can stay on private hostnames or Tailscale IPs
- Update: SSHs to the selected demo host and runs the tag-matched root installer from that exact git tag
- Host identity check: Verifies the SSH target reports the governed expected hostname before running installer or deploy steps
- Verify: Checks that the new version is running, mock mode is active, and the public demo HTML serves the same frontend entry asset as the target service
- Browser smoke: Uses the governed Playwright helper to prove the public demo still renders the login shell in a real browser
- Cleanup: Removes SSH key from runner
Testing
To test without publishing a release:
- Go to
Actionstab in GitHub - Select
Update Demo Serverworkflow - Provide a stable tag and choose
stableorauto
Benefits
- ✅ The public demo follows the stable v6 release line after GA
- ✅ Prereleases no longer require a second public v6 preview surface
- ✅ Validates the real server installer path on the selected target
- ✅ Removes release-operator guesswork about which demo should move
Deploy Demo Server
File: deploy-demo-server.yml
Manually deploys the current branch build to the stable demo environment without changing the governed release workflow.
- Uses the same
demo-stableenvironment contract as the release-driven updater - Joins Tailscale before SSH so governed demo targets can stay on private addresses instead of requiring public runner reachability
- Requires
DEMO_EXPECTED_HOSTNAME,DEMO_LOCAL_BASE_URL, andDEMO_PUBLIC_HEALTH_URL - Supports optional
DEMO_SERVICE_NAME,DEMO_INSTALL_DIR,DEMO_TEST_PORT,DEMO_AUTH_USER, andDEMO_AUTH_PASS - Assumes the target service and install directory already exist on the host
- Verifies the SSH target reports the governed expected hostname before deploy
- Verifies that the public demo shell serves the same frontend entry asset that was built and deployed
- Uses
scripts/run_demo_public_browser_smoke.shto prove the public demo still renders the login shell in Chromium after deploy/update verification
Helm CI
File: helm-ci.yml
Runs helm lint --strict and renders the chart with common configuration combinations on every pull request that touches Helm content (and on pushes to main). This prevents regressions before they land.
- Triggered by PRs/pushes touching
deploy/helm/**, docs, or the workflow itself - Uses Helm v3.15.2
- Renders both the default deployment and an agent-enabled configuration to catch template issues
Publish Helm Chart
File: publish-helm-chart.yml
Packages the Helm chart and pushes it to the GitHub Container Registry (OCI) whenever a GitHub Release is published. Also makes the packaged .tgz available as both an Actions artifact and a release asset. The same behaviour can be triggered locally via ./scripts/package-helm-chart.sh <version> [--push].
- Triggered automatically on
release: published, or manually via workflow dispatch (requireschart_versioninput) - Chart and app versions mirror the Pulse release tag (e.g.,
v4.24.0→4.24.0) - Publishes to
oci://ghcr.io/<owner>/pulse-chart - Verifies the pushed OCI chart can be read from GHCR without registry credentials
- Requires no additional secrets—uses the built-in
GITHUB_TOKENwithpackages: writepermission