mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-07-09 16:00:59 +00:00
Prepare v6.0.5 RC1 release packet
Some checks are pending
Build and Test / Secret Scan (push) Waiting to run
Build and Test / Frontend & Backend (push) Waiting to run
Canonical Governance / governance (push) Waiting to run
Helm CI / Lint and Render Chart (push) Waiting to run
Core E2E Tests / Playwright Core E2E (push) Waiting to run
Some checks are pending
Build and Test / Secret Scan (push) Waiting to run
Build and Test / Frontend & Backend (push) Waiting to run
Canonical Governance / governance (push) Waiting to run
Helm CI / Lint and Render Chart (push) Waiting to run
Core E2E Tests / Playwright Core E2E (push) Waiting to run
Refs #1530 Refs #1531 Refs #1471
This commit is contained in:
parent
4b669ad9b5
commit
dded079297
13 changed files with 180 additions and 67 deletions
|
|
@ -6,7 +6,7 @@ set -euo pipefail
|
|||
|
||||
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
|
||||
DOCKER_IMAGE_REPO="${DOCKER_IMAGE_REPO:-rcourtman/pulse}"
|
||||
CANONICAL_DEFAULT_PULSE_VERSION="6.0.5"
|
||||
CANONICAL_DEFAULT_PULSE_VERSION="6.0.5-rc.1"
|
||||
|
||||
resolve_default_pulse_version() {
|
||||
if [ -n "${PULSE_IMAGE_VERSION:-}" ]; then
|
||||
|
|
|
|||
|
|
@ -308,6 +308,71 @@ func TestCurrentStablePatchReleasePacketTracksInstallMetadata(t *testing.T) {
|
|||
)
|
||||
}
|
||||
|
||||
func TestCurrentSupportPrereleasePacketTracksInstallMetadata(t *testing.T) {
|
||||
version := currentReleaseVersion(t)
|
||||
if !isPrereleaseVersion(version) {
|
||||
t.Skip("current release is stable")
|
||||
}
|
||||
previous, ok := previousStableForPrereleaseVersion(version)
|
||||
if !ok {
|
||||
t.Skip("current prerelease does not have a previous stable patch")
|
||||
}
|
||||
|
||||
releaseNotesPath := repoFile("docs", "releases", "RELEASE_NOTES_v"+version+".md")
|
||||
changelogPath := repoFile("docs", "releases", "V6_CHANGELOG_v"+version+".md")
|
||||
|
||||
assertFileContainsAllNormalized(t, releaseNotesPath,
|
||||
"`v"+version+"` is a release candidate",
|
||||
"stable `v"+previous+"`",
|
||||
"Patrol Gemini model readiness",
|
||||
"remembered-login submit persistence",
|
||||
"Proxmox SMART temperature fallback",
|
||||
"direct SATA/SAT disks",
|
||||
"rollback target for this release candidate is `v"+previous+"`",
|
||||
)
|
||||
assertFileContainsAll(t, changelogPath,
|
||||
"Version: `v"+version+"`",
|
||||
"Rollback target: `v"+previous+"`",
|
||||
"Promotion path: release candidate from `main`",
|
||||
"Gemini tool-call capability",
|
||||
"Remembered-login state now persists",
|
||||
"Proxmox SMART temperature collection",
|
||||
"explicit SAT probe",
|
||||
)
|
||||
assertFileContainsAll(t, repoFile("docs", "RELEASE_NOTES.md"),
|
||||
"docs/releases/RELEASE_NOTES_v"+version+".md",
|
||||
"docs/releases/V6_CHANGELOG_v"+version+".md",
|
||||
"current v6 support release candidate packet",
|
||||
)
|
||||
assertFileContainsAll(t, repoFile("docs", "UPGRADE_v6.md"),
|
||||
"docs/releases/RELEASE_NOTES_v"+version+".md",
|
||||
"docs/releases/V6_CHANGELOG_v"+version+".md",
|
||||
"current v6 support release candidate packet",
|
||||
)
|
||||
assertFileContainsAll(t, repoFile("deploy", "helm", "pulse", "Chart.yaml"),
|
||||
"version: "+version,
|
||||
`appVersion: "`+version+`"`,
|
||||
"raw.githubusercontent.com/rcourtman/Pulse/v"+version+"/docs/images/pulse-logo.svg",
|
||||
"blob/v"+version+"/docs/KUBERNETES.md",
|
||||
)
|
||||
assertFileContainsAll(t, repoFile("deploy", "helm", "pulse", "README.md"),
|
||||
"Version-"+shieldsBadgeMessage(version)+"-informational",
|
||||
"AppVersion-"+shieldsBadgeMessage(version)+"-informational",
|
||||
"Autogenerated from chart metadata using [helm-docs v1.14.2]",
|
||||
)
|
||||
assertFileContainsAll(t, repoFile("docker-compose.yml"),
|
||||
"image: ${PULSE_IMAGE:-rcourtman/pulse:"+version+"}",
|
||||
)
|
||||
assertFileContainsAll(t, repoFile("scripts", "install-docker.sh"),
|
||||
`CANONICAL_DEFAULT_PULSE_VERSION="`+version+`"`,
|
||||
)
|
||||
assertFileContainsAllNormalized(t, repoFile("docs", "release-control", "v6", "internal", "subsystems", "deployment-installability.md"),
|
||||
"The active support prerelease `v"+version+"` cut sets the repo-root `VERSION`, repo-root `docker-compose.yml` image default, `scripts/install-docker.sh` fallback, and Helm chart release metadata to the same `"+version+"` release version.",
|
||||
"This support prerelease keeps `rollback_version=v"+previous+"`, publishes a versioned public GitHub prerelease plus versioned Docker and Helm artifacts, and does not move stable/latest install pointers or stable semver aliases.",
|
||||
"For the active support prerelease `v"+version+"` cut, the repo-root compose default and `scripts/install-docker.sh` fallback must both pin `"+version+"` until the next governed stable cut moves them forward.",
|
||||
)
|
||||
}
|
||||
|
||||
func TestBackfillReleaseWorkflowRepairsPublishedAssetsWithoutRebuilds(t *testing.T) {
|
||||
scriptBytes, err := os.ReadFile(repoFile("scripts", "backfill-release-assets.sh"))
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ func TestInstallDockerProofTracksSupportPrereleaseContract(t *testing.T) {
|
|||
|
||||
assertFileContainsAllNormalized(t, repoFile("docs", "release-control", "v6", "internal", "subsystems", "deployment-installability.md"),
|
||||
"The active support prerelease `v"+version+"` cut sets the repo-root `VERSION`, repo-root `docker-compose.yml` image default, `scripts/install-docker.sh` fallback, and Helm chart release metadata to the same `"+version+"` release version.",
|
||||
"This support prerelease uses the private Pro support image path with a stable rollback reference `v"+previous+"`, no `latest` movement, no stable semver tag movement, no R2 manifest promotion, no broker download metadata promotion, and no public `rcourtman/pulse` image publication.",
|
||||
"This support prerelease keeps `rollback_version=v"+previous+"`, publishes a versioned public GitHub prerelease plus versioned Docker and Helm artifacts, and does not move stable/latest install pointers or stable semver aliases.",
|
||||
"For the active support prerelease `v"+version+"` cut, the repo-root compose default and `scripts/install-docker.sh` fallback must both pin `"+version+"` until the next governed stable cut moves them forward.",
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,6 +78,18 @@ def rc_packet_paths_for_version(version: str) -> tuple[str, str, str] | None:
|
|||
)
|
||||
|
||||
|
||||
def support_prerelease_packet_paths_for_version(version: str) -> tuple[str, str] | None:
|
||||
"""Return release-notes and changelog paths for post-GA support RC versions."""
|
||||
if not re.match(r"^6\.\d+\.\d+-rc\.\d+$", version):
|
||||
return None
|
||||
if version.startswith("6.0.0-rc."):
|
||||
return None
|
||||
return (
|
||||
f"docs/releases/RELEASE_NOTES_v{version}.md",
|
||||
f"docs/releases/V6_CHANGELOG_v{version}.md",
|
||||
)
|
||||
|
||||
|
||||
def stable_packet_paths_for_version(version: str) -> tuple[str, str] | None:
|
||||
"""Return the stable release-notes and changelog packet paths for a v6 stable VERSION."""
|
||||
if not re.match(r"^6\.\d+\.\d+$", version):
|
||||
|
|
@ -350,25 +362,40 @@ class ReleasePromotionPolicyTest(unittest.TestCase):
|
|||
self.assertIn(f"Pulse v{current_version}", changelog)
|
||||
else:
|
||||
packet_paths = rc_packet_paths_for_version(current_version)
|
||||
self.assertIsNotNone(
|
||||
packet_paths,
|
||||
f"VERSION={current_version} does not match the 6.0.0-rc.N pattern",
|
||||
support_packet_paths = support_prerelease_packet_paths_for_version(current_version)
|
||||
self.assertTrue(
|
||||
packet_paths is not None or support_packet_paths is not None,
|
||||
f"VERSION={current_version} does not match a governed v6 prerelease packet pattern",
|
||||
)
|
||||
release_notes_path, changelog_path, operator_pack_path = packet_paths
|
||||
if packet_paths is not None:
|
||||
release_notes_path, changelog_path, operator_pack_path = packet_paths
|
||||
|
||||
release_notes = read(release_notes_path)
|
||||
changelog = read(changelog_path)
|
||||
operator_pack = read(operator_pack_path)
|
||||
release_notes = read(release_notes_path)
|
||||
changelog = read(changelog_path)
|
||||
operator_pack = read(operator_pack_path)
|
||||
|
||||
self.assertIn(f"current in-repo v6 `rc.{current_version.rsplit('.', 1)[1]}` draft packet", release_index)
|
||||
self.assertIn(release_notes_path, release_index)
|
||||
self.assertIn(changelog_path, release_index)
|
||||
self.assertIn(operator_pack_path, release_index)
|
||||
self.assertNotIn("current stable v6 release packet", release_index)
|
||||
self.assertIn(f"Pulse v{current_version} Draft Release Notes", release_notes)
|
||||
self.assertIn(f"`v{current_version}`", release_notes)
|
||||
self.assertIn(f"Pulse v{current_version} Draft Changelog", changelog)
|
||||
self.assertIn(f"`v{current_version}`", operator_pack)
|
||||
self.assertIn(f"current in-repo v6 `rc.{current_version.rsplit('.', 1)[1]}` draft packet", release_index)
|
||||
self.assertIn(release_notes_path, release_index)
|
||||
self.assertIn(changelog_path, release_index)
|
||||
self.assertIn(operator_pack_path, release_index)
|
||||
self.assertNotIn("current stable v6 release packet", release_index)
|
||||
self.assertIn(f"Pulse v{current_version} Draft Release Notes", release_notes)
|
||||
self.assertIn(f"`v{current_version}`", release_notes)
|
||||
self.assertIn(f"Pulse v{current_version} Draft Changelog", changelog)
|
||||
self.assertIn(f"`v{current_version}`", operator_pack)
|
||||
else:
|
||||
assert support_packet_paths is not None
|
||||
release_notes_path, changelog_path = support_packet_paths
|
||||
|
||||
release_notes = read(release_notes_path)
|
||||
changelog = read(changelog_path)
|
||||
|
||||
self.assertIn("current v6 support release candidate packet", release_index)
|
||||
self.assertIn(release_notes_path, release_index)
|
||||
self.assertIn(changelog_path, release_index)
|
||||
self.assertIn(f"Pulse v{current_version} Release Notes", release_notes)
|
||||
self.assertIn(f"`v{current_version}`", release_notes)
|
||||
self.assertIn(f"Pulse v{current_version}", changelog)
|
||||
|
||||
def test_upgrade_guide_points_at_current_rc_support_pack(self) -> None:
|
||||
upgrade_guide = read("docs/UPGRADE_v6.md")
|
||||
|
|
@ -400,17 +427,27 @@ class ReleasePromotionPolicyTest(unittest.TestCase):
|
|||
self.assertNotIn("docs/releases/V6_RC_OPERATOR_SUPPORT_PACK.md", upgrade_guide)
|
||||
else:
|
||||
packet_paths = rc_packet_paths_for_version(current_version)
|
||||
self.assertIsNotNone(
|
||||
packet_paths,
|
||||
f"VERSION={current_version} does not match the 6.0.0-rc.N pattern",
|
||||
support_packet_paths = support_prerelease_packet_paths_for_version(current_version)
|
||||
self.assertTrue(
|
||||
packet_paths is not None or support_packet_paths is not None,
|
||||
f"VERSION={current_version} does not match a governed v6 prerelease packet pattern",
|
||||
)
|
||||
current_support_pack = packet_paths[2]
|
||||
self.assertIn(current_support_pack, upgrade_guide)
|
||||
for _, _, _, support_pack in discover_rc_draft_packets():
|
||||
if support_pack == current_support_pack:
|
||||
continue
|
||||
self.assertNotIn(support_pack, upgrade_guide)
|
||||
self.assertNotIn("docs/releases/V6_RC_OPERATOR_SUPPORT_PACK.md", upgrade_guide)
|
||||
if packet_paths is not None:
|
||||
current_support_pack = packet_paths[2]
|
||||
self.assertIn(current_support_pack, upgrade_guide)
|
||||
for _, _, _, support_pack in discover_rc_draft_packets():
|
||||
if support_pack == current_support_pack:
|
||||
continue
|
||||
self.assertNotIn(support_pack, upgrade_guide)
|
||||
self.assertNotIn("docs/releases/V6_RC_OPERATOR_SUPPORT_PACK.md", upgrade_guide)
|
||||
else:
|
||||
assert support_packet_paths is not None
|
||||
release_notes_path, changelog_path = support_packet_paths
|
||||
self.assertIn(release_notes_path, upgrade_guide)
|
||||
self.assertIn(changelog_path, upgrade_guide)
|
||||
for _, _, _, support_pack in discover_rc_draft_packets():
|
||||
self.assertNotIn(support_pack, upgrade_guide)
|
||||
self.assertNotIn("docs/releases/V6_RC_OPERATOR_SUPPORT_PACK.md", upgrade_guide)
|
||||
|
||||
def test_prerelease_feedback_template_uses_generic_current_rc_wording(self) -> None:
|
||||
template = read(".github/ISSUE_TEMPLATE/v6_rc_feedback.yml")
|
||||
|
|
@ -855,9 +892,10 @@ class ReleasePromotionPolicyTest(unittest.TestCase):
|
|||
if current_version != "6.0.0":
|
||||
self.assertNotIn(f"VERSION={current_version}", blocked)
|
||||
else:
|
||||
self.assertIsNotNone(
|
||||
rc_packet_paths_for_version(current_version),
|
||||
f"VERSION={current_version} does not match the 6.0.0-rc.N pattern",
|
||||
self.assertTrue(
|
||||
rc_packet_paths_for_version(current_version) is not None
|
||||
or support_prerelease_packet_paths_for_version(current_version) is not None,
|
||||
f"VERSION={current_version} does not match a governed v6 prerelease packet pattern",
|
||||
)
|
||||
self.assertIn("VERSION=6.0.0", blocked)
|
||||
self.assertNotIn(f"VERSION={current_version}", blocked)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue