tests/integration/README.md and QUICK_START.md referenced the retired
.github/workflows/test-updates.yml; update-flow coverage now runs as
tests/79-update-flow.spec.ts inside the main suite via test-e2e.yml.
The Update Integration Tests workflow lost its Go test
(tests/integration/api) in the v6 release commit and was reduced to a
diagnostic smoke test that duplicated the test-e2e stack boot. Replace
it with tests/79-update-flow.spec.ts in the main suite, which runs via
test-e2e.yml on the same trigger paths:
- stable-channel check returns the mock v99.0.0 release and filters
the v99.1.0-rc.1 prerelease (regression guard for the auto-update
prerelease bug); rc-channel check surfaces the prerelease
- update plan reports honest manual instructions for the docker
deployment with readiness attached
- apply refuses prerelease download URLs on the stable channel (409)
- apply of an unsigned artifact fails closed at SSHSIG verification;
a completed update against the unsigned mock artifact would mean
the pinned-key trust root was bypassed
The old happy-path apply test is intentionally not revived: v6 made
SSHSIG verification against the pinned pulse-installer key mandatory,
so completing an apply would require shipping the real signing key to
the harness or weakening the trust root.
mock-github-server now serves v-prefixed asset names and download
paths like real Pulse releases (pulse-v99.0.0-linux-amd64.tar.gz);
the in-app updater only recognizes v-prefixed versions in download
URLs, so the old unprefixed shape made every apply fail validation
before reaching the paths under test. Unknown non-tarball sidecar
files (e.g. .sshsig) now 404 instead of falling back to tarball bytes.
The spec self-skips when the update check is not served by the mock
server, so managed-local-backend runs are unaffected.
golangci-lint was invoked from the repo root for every staged Go
package, so files in nested modules like
tests/integration/mock-github-server failed typechecking with 'main
module does not contain package' and could never be committed. Group
staged package dirs by their nearest enclosing go.mod and lint nested
modules from their own root.
.dockerignore only matched the root node_modules, so a locally
installed frontend-modern/node_modules entered the build context and
collided with the npm ci layer during COPY frontend-modern/, failing
local image builds. CI checkouts never hit this because they build
from a clean tree.
Settings > Alerts > Systems gains a 'Disk temperature by type' editor
(NVMe/SAS/SATA trigger degC) backing the existing per-type alert
thresholds that were previously hardcoded server-side. Saving alert
settings now round-trips diskTempByType and diskFillByType instead of
silently resetting them to defaults.
Disk temperature colors in the physical disks table, pool detail linked
disks, disk detail cards, and the Machines temperature fallback now
resolve from the live alert config per disk type (warning at trigger
minus the 5 degC hysteresis margin) instead of hardcoded 50/60 cutoffs.
Closes#1540
DiskTempByType unconditionally replaced the resolved host threshold, so a
host-level (or inherited linked-resource) diskTemperature override never
applied to nvme/sas/sata disks. Explicit overrides now win; the per-type
map still beats the global agent default.
Refs #1540
The workflow still invoked TestUpdateFlowIntegration from
tests/integration/api, but that package was removed in the v6 release
commit, and the remaining Playwright diagnostic spec skips itself
unless PULSE_E2E_DIAGNOSTIC is set, so the step ran zero tests and
then failed on the missing Go package. Enable the diagnostic spec so
the step actually exercises the pulse:test stack and drop the dead Go
test invocation.
Hosts (PVE nodes and host agents) were entirely outside the discovery
fingerprint model. Two consequences, one root:
1. collectFingerprints only covered docker/lxc/vm/k8s, so a host never
appeared in GetChangedResources and automatic discovery never ran for
it. Only the per-resource manual trigger worked, which is exactly the
v6.0.5-rc.3 behaviour reported in #1479.
2. cleanupOrphanedData built its keep-set from the same four types, so
CleanupOrphanedDiscoveries swept every agent:* discovery as an orphan
on the next fingerprint cycle (default 5 minutes). Manually discovered
hosts silently reverted to undiscovered.
Fix: add GenerateHostFingerprint (identity, OS, kernel, arch, tags;
status excluded so online/offline flapping cannot trigger rediscovery),
fingerprint snap.Hosts under the canonical agent:<id>:<id> key, and keep
host/node discovery keys (canonical, hostname-alias, and legacy host:
prefix forms) out of orphan cleanup. Also purge the store's in-memory
cache when an orphaned discovery file is removed, so deletions are not
masked for the cache TTL.
The RC3 memory bound for PBS backup polling summarized any group with
more than 8 snapshots into a single synthesized entry built from group
metadata. A synthesized entry has no verification, size, file, or
per-snapshot time data, so most real deployments saw every backup as
Unverified with no size, PBS files not listed, and a backup timeline
collapsed onto the latest backup day.
Keep the issue #1524 memory bounds but derive them from real data:
always fetch snapshots for stale groups, retain the newest bounded set
per group (limit raised from 8 to 100 to cover real keep policies), and
keep the newest-first global live-state cap. Remove the synthesized
group placeholder path entirely and update the monitoring subsystem
contract and tests to pin real-snapshot bounding.
Fixes#1541
Refs #1524
The release-control audits resolve repo identity from the checkout
directory name and expect evidence repos as siblings under one repos
root. The hosted runner checked the repo out at Pulse/Pulse, so
canonical_repo_id returned Pulse instead of pulse and the registry
audit treated every local file reference as untracked (2655 errors).
Check out the main repo at repos/pulse and the evidence repos as
repos/pulse-pro, repos/pulse-enterprise, and repos/pulse-mobile, run
all steps from repos/pulse, and point the PULSE_REPO_ROOT_* env vars
at the new paths.
The dual-key revert (1490a6e6e) removed the docker build line for the
pulse:test image instead of restoring the single-key version, leaving
the step with a bare cd and nothing building the image. Compose then
tried to pull pulse:test from Docker Hub and every run failed before
test execution. Build the runtime target the same way test-e2e.yml
does. The PULSE_LICENSE_PUBLIC_KEY env on the step was dead config:
env vars do not reach docker build and the Dockerfile no longer
declares that ARG.
The Canonical Governance workflow checked out the private pulse-pro,
pulse-enterprise, and pulse-mobile evidence repos with the default
workflow token, which cannot see other private repos, so every run
failed at the pulse-pro checkout. Use the existing WORKFLOW_PAT
secret (already used by create-release.yml to dispatch private Pro
workflows) and avoid persisting the credential in the checkout.
Empty allowedGroups, allowedDomains, allowedEmails, groupsClaim and
groupRoleMappings in a provider PUT were silently restored from the
existing config, so an admin could never clear them. The guards
shielded against lossy round-trips that no longer exist: the detail
GET and the flat list response both carry these fields, so an empty
value is an intentional clear. Nested OIDC/SAML config and the client
secret stay preserved since toggle payloads omit them and secrets are
never echoed in reads.
Also expose groupsClaim and groupRoleMappings in the shared extensions
list response so the enterprise list matches the core one, and make
the Settings enable/disable toggle send only writable fields; the old
list-item spread included computed response fields that the enterprise
strict PUT decoder rejects.
The MSP report scheduling form used raw native <select> elements,
failing the settings architecture guardrail that keeps Settings
selects on the shared labelled primitive. Cadence, Weekday, Format,
and Delivery now render through FormSelect, which also links each
label to its control.
Settings never rendered the oidc.scopes field, so admins could not
request an extra group scope and the authorization request stayed at
the default openid profile email. Adds the Scopes input to the OIDC
create/edit modal, points the Groups Claim help text at it, and covers
the create/edit round-trip with model and panel tests.
References #1535.
A Relay customer who enables Remote Access and generates a pairing QR
has nothing to scan it with: Pulse Mobile is early access and its
install links live on the authenticated download page, which nothing
in the pairing flow mentioned. Add the pointer to the pairing help
text, pin it in the panel contract test, and give docs/RELAY.md the
same install path instead of 'join early access when available'.
Make release validation resolve repository paths before entering external release directories, and execute extracted Linux release binaries through Docker when the host cannot run them directly.