Commit Graph

108 Commits

Author SHA1 Message Date
courtmanr@gmail.com 81974c7f62 Authorize v6.1.2 unsigned Windows release exception 2026-07-26 21:07:47 +01:00
rcourtman 781e168e34 Prepare v6.1.1 emergency patch release 2026-07-23 13:28:17 +01:00
rcourtman e1f33c1bad Fix release integration gate target 2026-07-22 18:15:19 +01:00
rcourtman 674364c749 Record v6.1.0 unsigned Windows exception 2026-07-22 15:37:48 +01:00
rcourtman 67d7a1b454 Delegate candidate artifact read permission 2026-07-22 11:41:10 +01:00
rcourtman 43bb95a406 Integrate SignPath Windows release signing 2026-07-21 22:34:00 +01:00
rcourtman 7ab605452d fix(release): fail closed on malformed release notes 2026-07-17 11:12:22 +01:00
rcourtman a393744894 Add in-app release highlights 2026-07-13 18:30:29 +01:00
rcourtman d5437a9353 Allow RCs while Windows signing is pending 2026-07-10 23:12:12 +01:00
rcourtman 255c7c23d4 Modernize Unified Agent lifecycle and platform support 2026-07-09 23:20:35 +01:00
rcourtman 8dda0b6efa Build releases once and promote verified candidates 2026-07-09 22:21:34 +01:00
rcourtman 910418c3b2 Make stable patch releases unattended 2026-07-09 20:16:13 +01:00
rcourtman 5fe6bfde57 Harden release integration diagnostics and login retries 2026-07-09 12:50:55 +01:00
rcourtman e240f162e9 Reserve the latest markers for the highest stable release
A maintenance cut of an older line (v5.1.36 after v6 GA, or a future
6.0.x patch after 6.1 ships) was allowed to move Docker/GHCR :latest and
the GitHub latest release marker onto itself, silently downgrading every
install that follows latest. Promote :MAJOR and :MAJOR.MINOR
unconditionally, but :latest and make_latest only when the tag is the
highest stable semver. workflow_dispatch gains force_latest as the
explicit rollback escape hatch.
2026-07-09 09:37:40 +01:00
rcourtman 155023d86a Add mobile impact gate to release dispatch 2026-07-07 18:21:20 +01:00
rcourtman de0c5ff5c1 Retire v6 preview demo target after GA 2026-07-04 16:16:57 +01:00
rcourtman c04ac2f7cf Make private Pro publication block v6 releases 2026-06-15 15:37:13 +01:00
rcourtman 377fd5131d Harden release integration bootstrap gate 2026-06-14 22:26:13 +01:00
rcourtman 50cbc27b71 Refresh workflow action pins 2026-06-14 19:26:21 +01:00
rcourtman bd6f77e093 Prepare v6.0.0 release candidate
Tighten v5-to-v6 upgrade safety, release installability, provider MSP mode handling, AI cost accounting, metrics flushing, and frontend guardrails for the v6.0.0 GA candidate.
2026-06-04 14:07:14 +01:00
rcourtman 7c35977fcb Fix post-publish pipeline failures for v6.0.0-rc.6
promote-floating-tags.yml waited on rcourtman/pulse-agent:${TAG} and
promoted floating tags for it, but publish-docker.yml never pushes the
agent image — Pulse Agent ships as GitHub Release binaries
(publish-docker.yml line 199 confirms). The wait timed out after 5
minutes on every release since the pulse-agent push step was removed,
leaving floating tags unpromoted. Stripped the vestigial wait block,
the agent promote step, and the agent line in the summary. Updated
header comments in both files to drop the past-tense reference.

install-sh-smoke.yml booted jrei/systemd-debian:12 without
--cgroupns=host, so on GHA ubuntu-24.04 (cgroup v2 unified hierarchy)
the container's systemd PID 1 exited before mounting the cgroup tree
and the container disappeared during readiness polling. Added
--cgroupns=host, an explicit /run/lock tmpfs, and dropped --rm so the
container persists for diagnostic capture on failure (trap handles
cleanup). Added an "is container still running" probe inside the
readiness loop and richer diagnostic output on timeout.
2026-05-27 22:08:15 +01:00
rcourtman 22a94f47d9 Skip release publish downstreams for drafts 2026-05-12 17:32:11 +01:00
rcourtman 29a815ef2a Fail closed on stale API action plans 2026-05-12 16:55:51 +01:00
rcourtman 3566a4d61d Drive promote-floating-tags via workflow_call from create-release
promote-floating-tags.yml's `workflow_run` chain off publish-docker.yml
silently stopped firing for rc.3 → rc.5 because publish-docker failed at
the now-removed pulse-agent push step. Customers pulling
rcourtman/pulse:latest, :6, or :6.0 stayed on whatever the previous
successful release had tagged — there was no warning anywhere that the
floating tags were stale.

Same fix pattern as install-sh-smoke (commit 7c0f65425) and
publish-helm-chart (commit 14c79a28e): add a workflow_call trigger to
promote-floating-tags.yml and call it explicitly from create-release.yml
after validate_release_assets succeeds.

Gating on validate_release_assets is intentional: that workflow waits
for the docker image to be pullable from the registry (with retry
backoff), so by the time it succeeds the image manifest exists and
re-tagging it to latest/major/minor cannot point at vapor.

The legacy workflow_run trigger stays as the primary path; this just
guarantees promotion even when the chain doesn't fire.

Tag-resolver step now accepts inputs from workflow_call / workflow_dispatch
and only falls back to the workflow_run derivation when inputs are absent,
so all three entry paths converge on the same identity.

Pinned in build_release_assets_test.go:
- new TestPromoteFloatingTagsReachableViaWorkflowCall pins the trigger
  declaration and the input-priority resolver
- existing TestCreateReleaseUploadsPowerShellInstaller extended to pin
  the promote_floating_tags job wiring (uses, tag, prerelease)

Contract delta in deployment-installability.md Extension Point 7
documents the same explicit-workflow_call requirement that applies to
publish-helm-chart, extended to promote-floating-tags.
2026-05-12 16:47:51 +01:00
rcourtman 14c79a28e7 Trigger publish-helm-chart via workflow_call from create-release
v6 rc.1 → rc.5 published successfully but the Helm chart never landed on
rcourtman.github.io/Pulse/index.yaml — the index still ends at v5.1.30.
`helm install pulse pulse/pulse --version 6.0.0-rc.5` returns
chart-not-found; without `--version` helm pulls the latest published
chart (v5.1.30) into a customer's v6 cluster.

Root cause: GitHub does not fire `release: published` for releases that
were created as drafts and later PATCHed to draft=false. create-release.yml
deliberately uses that path so it can upload assets and run
validate-release-assets against the draft before promoting. Inspection of
the workflow run history confirms: every gh-API `release: published` event
since 2026-03-02 has been from manually-dispatched v5 stable cuts; zero
fired for v6 RCs published through the create-release pipeline.

Fix the same way install-sh-smoke was wired in commit 7c0f65425: add a
`workflow_call` trigger to publish-helm-chart.yml and call it explicitly
from create-release.yml as a downstream of validate_release_assets. The
chart-version resolver in publish-helm-chart now accepts inputs from
either workflow_call or workflow_dispatch and only falls back to the
release-event tag when no inputs are present, keeping the legacy
release-event path working for forks / manual gh-CLI publishes that
create with draft=false from the start.

Pinned in build_release_assets_test.go:
- create-release.yml wiring (publish_helm_chart job, version inputs)
- publish-helm-chart.yml workflow_call trigger declaration
- chart-version resolver's input-priority logic

Contract delta in deployment-installability.md Extension Point 7
documents the workflow_call requirement and forbids relying on the
release-published webhook for the create-release.yml draft-promotion
path.

The fix takes effect on the next release through the pipeline. Backfill
of the v6.0.0-rc.5 chart needs a one-time manual dispatch of
publish-helm-chart.yml against chart_version=6.0.0-rc.5.
2026-05-12 16:30:53 +01:00
rcourtman 7c0f654253 Wire install.sh smoke gate into create-release.yml release pipeline
The smoke gate workflow exists from commit 065ebdb27 but until it is
called from create-release.yml it does not actually protect any release.
That is exactly the regression class that let rc.1 → rc.5 ship with a
broken install.sh: nothing in the release pipeline exercised the
documented secure-install flow against the published GitHub Release URL.

Wire install-sh-smoke.yml as a downstream workflow_call after
validate_release_assets succeeds. Gated on
historical_asset_backfill_only != 'true' since asset-backfill flows
re-upload to an already-published release and the smoke would just
re-confirm what hasn't changed.

Pre-install structural checks were verified locally against rc.5 — the
gate correctly fires the banner / agent-banner / --version handler
assertions against the broken release. The end-to-end container portion
(privileged systemd boot, install.sh execution, /api/health, /api/version
match) will run for the first time on the next release that publishes
through this workflow; existing retry loops on systemd readiness,
service activation, and health endpoint absorb transient runner flakes.

Add install-sh-smoke.yml to the deployment-installability canonical files
and to the release-promotion proof policy's match_files, and add
scripts/installtests/build_release_assets_test.go to that policy's
exact_files (matching the existing pin set for related policies in the
deployment-installability subsystem). Update subsystem_lookup_test.py
fixtures that pinned the exact_files list literally.

Pinned the create-release.yml wiring in build_release_assets_test.go
alongside the validate-release-assets wiring so the smoke step cannot
silently be unwired.

Document the gate's contract responsibilities in
deployment-installability Extension Point 2.
2026-05-12 11:44:04 +01:00
rcourtman 3da835c5bc Publish a distribution path for pulse-mcp
The MCP adapter shipped in slice 51 with one install option:
clone the repo and go build. This slice integrates pulse-mcp
into Pulse's existing governed release pipeline so a Pulse
release publishes a pulse-mcp binary alongside the unified agent
and the install scripts that bring it home in one command.

What ships:

  - scripts/build-release.sh extended to build pulse-mcp for
    the same multi-OS matrix as the unified agent, package
    per-platform tarballs and zips, and copy bare binaries to
    RELEASE_DIR for /releases/latest/download/ redirect
    compatibility.
  - .github/workflows/create-release.yml extended to upload
    the bare pulse-mcp binaries plus install-mcp.sh and
    install-mcp.ps1 as release assets.
  - scripts/install-mcp.sh: bash one-line installer that
    detects platform/arch, downloads the matching binary from
    the configured release (latest by default), verifies SHA256
    against the published checksums.txt, places at
    ~/.local/bin/pulse-mcp (or /usr/local/bin if not writable).
    Honors PULSE_MCP_VERSION, PULSE_MCP_BIN_DIR, PULSE_MCP_REPO,
    PULSE_MCP_NO_VERIFY env vars; declines Windows shells with
    a pointer at the .ps1 sibling.
  - scripts/install-mcp.ps1: PowerShell installer for Windows,
    placing pulse-mcp.exe at $LOCALAPPDATA\pulse-mcp.

Documentation aligned:

  - cmd/pulse-mcp/README.md gains an Install section above
    Quick start with three options: one-line installer,
    GitHub Release download, go install. Documents the macOS
    Gatekeeper bypass since v1 is unnotarized by design.
  - The Settings -> API Access agent-integrations panel now
    surfaces the curl|bash command above the config snippet so
    operators see "install pulse-mcp" before "configure your
    MCP client."
  - docs/releases/AGENT_PARADIGM.md drops the "no published
    distribution path" item from "what it does not do yet" and
    documents the Gatekeeper / Homebrew gaps as next-tier
    follow-ups.

Trade-offs surfaced and chosen:

  - Same cadence as Pulse: pulse-mcp ships per Pulse release,
    not on its own track. The MCP server reads the manifest
    from the Pulse it talks to, so version alignment is the
    natural model.
  - No Homebrew tap or core formula in v1. Maintaining a tap
    is real ongoing work; foundation supports adding Homebrew
    later as a layer.
  - No Docker image. Stdio JSON-RPC fights Docker's stdin
    /stdout pattern.
  - No notarization in v1. SHA256 verification through the
    installer preserves the audit trail; README documents the
    Gatekeeper bypass.

Subsystem contract: deployment-installability.md gains
scripts/install-mcp.sh, scripts/install-mcp.ps1, and
cmd/pulse-mcp/ in canonical files (mid-list entries
renumbered) plus a paragraph documenting the new MCP entry
point alongside the existing installer family.

Verification artifacts:

  - scripts/installtests/build_release_assets_test.go gains
    TestBuildReleasePackagesPulseMcpForAllPlatforms which pins
    the build/package/copy wiring and the load-bearing
    install-mcp.sh helpers (platform detection, SHA256
    verification, install-dir resolution).
  - scripts/release_control/render_release_body_test.py gains
    test_agent_paradigm_release_notes_blurb_documents_-
    distribution_path which pins the AGENT_PARADIGM.md draft's
    install-mcp.sh reference and the four-axis frame so a
    future edit cannot regress the install story silently.

Smoke-tested install-mcp.sh locally on darwin-arm64: platform
detection, install-dir resolution, URL building, and 404 error
handling all correct. The full end-to-end install path becomes
live the moment a Pulse release ships pulse-mcp binaries; the
next RC cut will exercise it.
2026-05-10 17:04:49 +01:00
rcourtman d6e96ebeca Fix v6 demo release signing key deployment 2026-05-05 21:40:14 +01:00
rcourtman 9ba0c3fa96 Retry release asset uploads 2026-05-03 10:26:51 +01:00
rcourtman 011d288cb4 Fix release asset validation workflow gates 2026-05-02 00:36:54 +01:00
rcourtman fb6b53268a Harden release Docker key embedding cache 2026-04-24 17:21:04 +01:00
rcourtman f58840e8a8 Guard forward release signing against trust-root drift 2026-04-22 19:59:18 +01:00
rcourtman c0f48b27ba Grant release validation workflow required permissions 2026-04-22 17:47:13 +01:00
rcourtman 9c2e3d5ffb Add historical backfill mode to create-release workflow 2026-04-22 17:43:37 +01:00
rcourtman f96abc5ee0 Publish signed release-packet SBOM assets 2026-04-22 16:49:29 +01:00
rcourtman 74df03c78c Pin workflow actions and CI image versions 2026-04-22 10:12:15 +01:00
rcourtman 4720807ae5 Require signed installer downloads and local release sidecars 2026-04-22 03:51:46 +01:00
rcourtman 96034f5e10 Attest release artifacts and harden image provenance 2026-04-22 03:22:29 +01:00
rcourtman 7be844f23a Require signed unified agent release assets 2026-04-22 02:00:29 +01:00
rcourtman a8d9051b15 Restrict default workflow token permissions 2026-04-22 01:21:24 +01:00
rcourtman fb7b9b01fc Update pinned Go toolchain to 1.25.9 2026-04-18 10:04:34 +01:00
rcourtman b19991f4ae Fix published release body rendering 2026-04-16 22:20:17 +01:00
rcourtman 6fcdcf8b8e Add pre-release Helm chart smoke gate 2026-04-16 21:48:35 +01:00
rcourtman 447280a0ce Fix release-line demo workflow dispatch and verification 2026-04-16 20:54:01 +01:00
rcourtman ef288b250b Reconcile draft release retries 2026-04-12 10:52:19 +01:00
rcourtman a48fb63cb3 Preserve draft release validation state 2026-04-11 17:35:14 +01:00
rcourtman 58ad221d47 Add governed v6 preview demo targets 2026-04-10 10:53:17 +01:00
rcourtman c6de686cb4 Fix release workflow branch policy env 2026-04-04 15:13:16 +01:00
rcourtman f34ec16138 fix(release): require explicit rollback targets in workflows 2026-03-26 13:03:24 +00:00
rcourtman cb41473018 Rename promotion RC wording to prerelease 2026-03-25 11:08:05 +00:00