Pulse/.github/workflows
2026-08-29 19:59:04 +01:00
..
backfill-release-assets.yml Refresh workflow action pins 2026-06-14 19:26:21 +01:00
build-and-test.yml Fix main CI fallout from the 50-node demo estate 2026-08-24 08:56:07 +01:00
build-release-candidate.yml Bind container qualification to caller commit 2026-08-26 03:36:46 +01:00
canonical-governance.yml Require immutable attested releases 2026-08-29 19:59:04 +01:00
close-needs-retest-timeout.yml Route triage comments through dedicated identity 2026-08-26 09:59:10 +01:00
compile-release-payload.yml Isolate PC compilation from SignPath workflow 2026-08-23 15:02:33 +01:00
create-release.yml Require immutable attested releases 2026-08-29 19:59:04 +01:00
deploy-demo-server.yml fix(release): make customer promotion convergent 2026-08-08 02:36:28 +01:00
eval-model-matrix.yml Refresh workflow action pins 2026-06-14 19:26:21 +01:00
helm-ci.yml feat(kubernetes): add OpenShift-safe Helm profile 2026-07-30 17:38:02 +01:00
helm-pages.yml Bind Helm convergence to the release repository 2026-08-21 17:46:55 +01:00
install-sh-smoke.yml fix(release): allow draft asset smoke access 2026-08-08 18:57:11 +01:00
issue-version-label-sync.yml Clarify continuous maintenance provenance 2026-08-26 11:23:05 +01:00
issue-version-retest-comment.yml Clarify continuous maintenance provenance 2026-08-26 11:23:05 +01:00
patrol-qualification-live.yml Complete Patrol autonomous qualification loop 2026-07-14 15:35:48 +01:00
patrol-qualification-regression.yml fix(ci): stub the embedded frontend dist so patrol lifecycle proofs compile 2026-07-17 15:52:22 +01:00
promote-floating-tags.yml fix(release): make customer promotion convergent 2026-08-08 02:36:28 +01:00
promote-private-pro-runtime.yml Promote qualified release payloads directly 2026-08-21 14:47:52 +01:00
public-docs.yml docs: refresh public repository surface 2026-08-06 01:00:41 +01:00
publish-docker.yml Parallelize exact-version Docker publication 2026-08-21 18:25:26 +01:00
publish-helm-chart.yml Verify public Helm chart publication 2026-07-05 09:40:20 +01:00
qualify-release-containers.yml Qualify embedded agent executable mode 2026-08-29 11:01:59 +01:00
README.md Preserve secondary issue feedback 2026-08-29 12:24:03 +01:00
recover-demo-server.yml Bound legacy demo history startup 2026-08-29 03:47:09 +01:00
recover-release-activation.yml Require immutable attested releases 2026-08-29 19:59:04 +01:00
release-convergence.yml Require immutable attested releases 2026-08-29 19:59:04 +01:00
release-dry-run.yml Disable Windows signing until SignPath is ready 2026-08-25 22:24:07 +01:00
repo-boundary-audit.yml Ratchet private boundary audit debt 2026-07-29 20:09:23 +01:00
retry-release-convergence.yml fix(release): make customer promotion convergent 2026-08-08 02:36:28 +01:00
security-scan.yml Add a weekly scheduled dependency vulnerability scan 2026-08-23 14:40:01 +01:00
signpath-test-signing.yml ci(signing): trust test certificate at machine scope 2026-08-06 16:08:33 +01:00
test-e2e.yml Stabilize telemetry candidate validation 2026-08-29 18:21:50 +01:00
unified-agent-native.yml Prevent RC regressions at release boundary 2026-08-01 13:58:05 +01:00
update-demo-server.yml Bound legacy demo history startup 2026-08-29 03:47:09 +01:00
validate-release-assets.yml Keep published release validation non-destructive 2026-08-29 10:27:08 +01:00

GitHub Actions Workflows

Issue Triage Automation

Files:

  • issue-version-label-sync.yml
  • issue-version-retest-comment.yml

Issue intake is split deliberately:

  • issue-version-label-sync.yml is the silent metadata path. It runs on opened, edited, and reopened issue events so version labels, needs-version-info, needs-retest-on-latest, and the explicit needs-decomposition topic-integrity signal stay correct when maintainers tidy issue metadata.
  • issue-version-retest-comment.yml is the scheduled public guidance path. It gives maintainers a grace window, then posts reporter-facing retest guidance only when an older-version bug report from a non-maintainer has no existing maintainer response. This prevents generic stable-version advice from contradicting a specific maintainer fix or prerelease boundary.
  • Both workflows load the shared helper at .github/scripts/issue-version-triage.cjs so parsing and classification logic lives in one place instead of drifting across duplicated inline scripts.
  • needs-decomposition is driven only by the structured Additional actionable topics form field. The triage contract requires human or agent judgment to create linked dispositions; the workflow does not infer or auto-create issues from free text.

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:

  1. demo-stable

The environment must define the secret names used by the governed demo target.

Required environment secrets:

  1. 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 -----BEGIN and -----END lines
  2. DEMO_SERVER_HOST

    • The hostname or IP of the demo server
  3. DEMO_SERVER_USER

    • The SSH username for the demo server (e.g. root or a deploy user with sudo access)

Required shared secret:

  1. TS_OAUTH_CLIENT_ID and TS_OAUTH_SECRET
    • Tailscale OAuth client (business tailnet tawny-powan.ts.net, scope Auth Keys write, tag tag:infra) used by the governed demo deploy/update workflows before SSH
    • The action mints an ephemeral, pre-authorized, tagged node key per run, so runners join and garbage-collect themselves; unlike the retired static TS_AUTHKEY, the OAuth secret does not expire every 90 days
    • Allows GitHub-hosted runners to reach private demo targets such as the stable pulse-relay Tailscale host
    • May be stored as repository secrets or repeated in the selected environment if desired

Required environment variables:

  1. DEMO_EXPECTED_HOSTNAME

    • The remote hostname value 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
  2. DEMO_LOCAL_BASE_URL

    • Local URL used on the target host for version and mock-mode verification
    • Example stable value: http://localhost:7655
  3. DEMO_PUBLIC_HEALTH_URL

    • Public health endpoint for the stable demo target
    • Example stable value: https://demo.pulserelay.pro/api/health

Optional environment variables:

  1. 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.
  2. DEMO_AUTH_USER / DEMO_AUTH_PASS

    • Demo credentials used for post-update mock verification
    • Defaults to demo / demo when omitted

How It Works

  1. Trigger: Runs from the lease-owning Release Convergence workflow after an exact activation marker is committed
  2. Target selection: Stable tags deploy to demo-stable; prerelease tags are skipped because the public v6 preview target is retired after GA
  3. Service identity: Stable runs default to the pulse service identity
  4. Governance check: Validates the selected tag is reachable from the governed release branch for that version
  5. Latest check: Refuses to update the public demo unless the published tag is the latest stable release
  6. Network attach: Joins Tailscale before any SSH step so governed demo targets can stay on private hostnames or Tailscale IPs
  7. Update: SSHs to the selected demo host and runs the tag-matched root installer from that exact git tag
  8. Host identity check: Verifies the SSH target reports the governed expected hostname before running installer or deploy steps
  9. 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
  10. Browser smoke: Uses the governed Playwright helper to prove the public demo still renders the login shell in a real browser
  11. Cleanup: Removes SSH key from runner

Testing

Use Release Dry Run for the governed no-mutation demo-path preflight, or run Verify Demo Server to verify the current committed stable target manually.

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

Verify Demo Server

File: deploy-demo-server.yml

The former branch-build deploy path is retired because it could replace the stable public demo with unreleased main. Its manual dispatch is now a non-mutating wrapper that verifies the current committed stable target. All stable demo writes require an exact stable tag and activation marker and run from release-convergence.yml under the global customer-promotion lease.

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 (requires chart_version input)
  • 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_TOKEN with packages: write permission