diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 0f9921f99..2897cee00 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -897,14 +897,18 @@ jobs: --unsigned-windows-exception "${{ needs.prepare.outputs.unsigned_windows_exception }}" \ --unsigned-windows-reason "${{ needs.prepare.outputs.unsigned_windows_reason }}" - # The in-app "What's New" banner only fires when the release body has - # a Highlights section (see frontend-modern/src/components/whatsNewModel.ts). - # Surface which way this release will behave so silence is a choice, - # not an accident. + # Highlights provide the compact pre-update preview. The post-update + # dialog uses categorized changelog entries instead of that summary. if grep -qiE '^#{1,6}[[:space:]]+highlights\b' "$RENDERED_NOTES_FILE"; then - echo "::notice::Release notes include a Highlights section — the in-app What's New banner will show it after users update." + echo "::notice::Release notes include Highlights — the update banner can preview them before users update." else - echo "::notice::Release notes have no Highlights section — the in-app What's New banner stays silent for this release (expected for maintenance releases)." + echo "::notice::Release notes have no Highlights — the update banner will not show a summary preview." + fi + + if grep -qiE '^#{1,6}[[:space:]]+(added|new features|improved|improvements|changed|fixed|bug fixes|security|breaking changes|deprecated|removed)[[:space:]]*$' "$RENDERED_NOTES_FILE"; then + echo "::notice::Release notes include categorized changes — the post-update changelog dialog will show them." + else + echo "::notice::Release notes have no categorized changes — the post-update changelog dialog stays silent." fi echo "notes_file=${RENDERED_NOTES_FILE}" >> $GITHUB_OUTPUT diff --git a/docs/release-control/v6/internal/subsystems/deployment-installability.md b/docs/release-control/v6/internal/subsystems/deployment-installability.md index 89820bdee..474c62758 100644 --- a/docs/release-control/v6/internal/subsystems/deployment-installability.md +++ b/docs/release-control/v6/internal/subsystems/deployment-installability.md @@ -689,14 +689,16 @@ upgrade, update, release, or artifact-selection behavior. unavailable for source/development builds, and return the canonical release body without inventing a second changelog source. The update banner may preview only the curated `Highlights` section from update-check metadata, - while the post-update card may show that same section once per later - installed release and must stay silent for a first baseline, malformed or - development versions, missing releases, and releases without highlights. - When present, `Highlights` is the complete in-app overview: release - rendering must keep it to at most three short plain-text bullets of no more - than 140 characters each, with links, code, issue references, nested - structure, and implementation-oriented detail reserved for the full release - notes. + while the post-update card must render the release's categorized user-facing + change sections (`Added`, `Improved`/`Changed`, `Fixed`, `Security`, + `Breaking changes`, `Deprecated`, or `Removed`) as a changelog once per + later installed release. It must not reuse the Highlights summary as the + post-update content, and must stay silent for a first baseline, malformed or + development versions, missing releases, and releases without categorized + changes. `Highlights` remains a pre-update overview only: release rendering + keeps it to at most three short plain-text bullets of no more than 140 + characters each, with links, code, issue references, and nested structure + reserved for the categorized or full release notes. The same post-update communication boundary owns the one-time schema-v2 telemetry payload notice. It must use a non-blocking shared notice banner, appear only for existing installations on a published build, stay silent @@ -1591,14 +1593,15 @@ serves their route, scope, payload, pairing, and push requirements, including the relay-mobile Patrol attention scopes corrected after rc.4. No companion build upload or public mobile-store rollout is part of this server release. The same release boundary now provides one canonical in-app release-note -experience. Update checks can preview a curated `Highlights` section, and an -authenticated running-version endpoint lets the update surface show those -same published highlights once after a later upgrade. Missing highlights stay -quiet by design, and source or development builds never masquerade as -published releases. Post-update highlights are limited to three short, -plain-text user outcomes and use the shared dialog so the overview stays easy -to scan without pushing the dashboard down; every close path still records the -running release as seen. +experience. Update checks can preview a curated `Highlights` section before an +update, while the authenticated running-version endpoint lets the post-update +surface extract the published `Added`, `Improved`/`Changed`, `Fixed`, +`Security`, `Breaking changes`, `Deprecated`, and `Removed` sections into a +categorized changelog after an upgrade. Summary-only or uncategorized releases +stay quiet in the post-update dialog, and source or development builds never +masquerade as published releases. The shared scrollable dialog keeps the +categories readable without pushing the dashboard down; every close path still +records the running release as seen. The initial GA promotion metadata remains `promoted_from_tag=v6.0.0-rc.7`, `rollback_version=v5.1.35`, diff --git a/frontend-modern/browser-verification.json b/frontend-modern/browser-verification.json index 79b01c0f3..a08e401f7 100644 --- a/frontend-modern/browser-verification.json +++ b/frontend-modern/browser-verification.json @@ -1,34 +1,23 @@ { "version": 1, - "base_sha": "c45a950a74c11d299b1be6277a8b552e87f9c5d9", - "verified_at": "2026-08-11T10:30:03Z", + "base_sha": "3826316eec488cef2561eb64397f225979a0adc1", + "verified_at": "2026-08-11T14:57:15Z", "result": "passed", "changed_paths": [ - "frontend-modern/src/api/resourceOperatorState.ts", - "frontend-modern/src/components/Infrastructure/ResourceDetailDrawerOverviewTab.tsx", - "frontend-modern/src/components/Infrastructure/ResourceOperatorStateSection.tsx", - "frontend-modern/src/components/Workloads/GuestDrawerOverview.tsx", - "frontend-modern/src/features/alerts/AlertOverviewAlertCard.tsx", - "frontend-modern/src/features/alerts/ResourceMonitoringPolicyAction.tsx", - "frontend-modern/src/utils/resourceMonitoringPolicy.ts" + "frontend-modern/src/components/WhatsNewCard.tsx", + "frontend-modern/src/components/whatsNewModel.ts" ], "content_sha256": { - "frontend-modern/src/api/resourceOperatorState.ts": "2b27d3dcc3415cc2a57b9bd201d06f04150ede3b29d91816ce3715a065eb8459", - "frontend-modern/src/components/Infrastructure/ResourceDetailDrawerOverviewTab.tsx": "9b757063cbd6c0b97ab0057754d45ad2e2067ad58f4ec0b388c7ae28e51d8239", - "frontend-modern/src/components/Infrastructure/ResourceOperatorStateSection.tsx": "3c5008b4db7027a7a08c8dff796a7546b5b343a522bf7439361467c0031318f3", - "frontend-modern/src/components/Workloads/GuestDrawerOverview.tsx": "f0339dc3c3fdd2e08f2c5fea75a62a0a5ecdfab833970653bf9f74982c4ba891", - "frontend-modern/src/features/alerts/AlertOverviewAlertCard.tsx": "83081abb871d76e5531bf66ddcddb47171c05c86c1d91249a0e9c6ef5dad73dd", - "frontend-modern/src/features/alerts/ResourceMonitoringPolicyAction.tsx": "287ff35169c4082f9cb8cac3e36bcbaaab9e343801c497e89da8602d9af276d2", - "frontend-modern/src/utils/resourceMonitoringPolicy.ts": "ba5133bbdeb57a236845f3ee946f0f0c13518e293810eec1ae7e4fab2ab3e2d5" + "frontend-modern/src/components/WhatsNewCard.tsx": "f7f905d0e08b56c98b908653ec663332dc9d140d4e82b6d20c9428be6bbd5b15", + "frontend-modern/src/components/whatsNewModel.ts": "d6aaf56335e9cb1505e5f574c51f2d396636db850f2162fbc56cf61330df5cc5" }, "routes": [ - "/alerts", "/proxmox/overview" ], "viewports": [ { - "width": 1280, - "height": 800 + "width": 1440, + "height": 900 }, { "width": 390, @@ -36,17 +25,18 @@ } ], "states": [ - "Active powered-off Proxmox guest alert with the Monitoring policy menu open and provider ownership copy visible.", - "Normal monitoring restored, powered-off detector alert reactivated, then Expected offline applied from that alert and the alert removed immediately.", - "Proxmox guest drawer with Monitoring and Lifecycle controls showing Expected offline and provider-owned retirement guidance.", - "Retired lifecycle selected with monitoring disabled and the retained-inventory, history, attention, and automation notice visible.", - "Mobile Alerts overview with the policy menu open, all four choices reachable, and main content clientWidth and scrollWidth both 362 pixels." + "Post-update Pulse v6.2.2 changelog open with Added, Improved, and Fixed sections while Highlights and Release Qualification are absent.", + "Desktop dialog fully visible with all categorized entries fitting without page clipping or horizontal overflow.", + "Mobile dialog open at the top with internal vertical scrolling and no horizontal overflow.", + "Mobile dialog scrolled to the final Fixed entry with the close action still reachable.", + "Dialog dismissed with Escape, reopened, and dismissed by clicking the backdrop." ], "interactions": [ - "Opened the Monitoring menu from a live powered-off alert and confirmed Proxmox remains the inventory owner.", - "Applied Expected offline from the alert, observed the success notification, and confirmed the alert disappeared immediately while the active count decreased.", - "Opened dev-portal-01 in the Proxmox guest drawer, changed Monitoring between Normal and Expected offline, and saved through the canonical resource policy.", - "Changed Lifecycle to Retired, confirmed the retirement notice and disabled monitoring control, then restored Active while preserving Expected offline.", - "Repeated the Alerts policy-menu inspection at 390 by 844 pixels and confirmed there was no horizontal content overflow." + "Triggered the post-update dialog from a simulated completed v6.2.2 update and inspected the rendered changelog content.", + "Resized from 1440 by 900 pixels to 390 by 844 pixels and confirmed responsive containment.", + "Scrolled the changelog body to the bottom and confirmed the final entry remained readable.", + "Dismissed with Escape and confirmed page scrolling was restored.", + "Reopened the dialog and dismissed it by clicking outside the panel.", + "Inspected browser warning and error logs and found none." ] } diff --git a/frontend-modern/src/components/WhatsNewCard.tsx b/frontend-modern/src/components/WhatsNewCard.tsx index 23c746593..b04e16165 100644 --- a/frontend-modern/src/components/WhatsNewCard.tsx +++ b/frontend-modern/src/components/WhatsNewCard.tsx @@ -10,7 +10,7 @@ import { Dialog } from '@/components/shared/Dialog'; import { ExternalTextLink } from '@/components/shared/ExternalTextLink'; import { InlineNotice } from '@/components/shared/InlineNotice'; import { buildReleaseNotesUrl, normalizeReleaseVersion } from '@/components/updateVersion'; -import { extractHighlights, isReleaseVersion } from '@/components/whatsNewModel'; +import { extractChangelog, isReleaseVersion } from '@/components/whatsNewModel'; import { renderMarkdown } from '@/components/AI/aiChatUtils'; import { t } from '@/i18n'; import { PRIVACY_DOC_URL } from '@/utils/docsLinks'; @@ -56,9 +56,9 @@ const markTelemetryPayloadNoticeSeen = () => { /** * Post-update "What's New" dialog. Shows once after the running version - * changes, and only when that release has a curated `## Highlights` section - * in its GitHub release notes. Dismissing (or a highlights-free release) - * records the version so the dialog stays quiet until the next update. + * changes, and only when that release has categorized user-facing changelog + * entries in its GitHub release notes. Dismissing (or a release without those + * entries) records the version so the dialog stays quiet until the next update. * * This release communication boundary also owns the one-time, non-blocking * telemetry schema v2 notice. Existing installations see it once; fresh @@ -69,7 +69,7 @@ export function WhatsNewCard() { const [visible, setVisible] = createSignal(false); const [telemetryNoticeVisible, setTelemetryNoticeVisible] = createSignal(false); const [version, setVersion] = createSignal(''); - const [highlightsHtml, setHighlightsHtml] = createSignal(''); + const [changelogHtml, setChangelogHtml] = createSignal(''); const hadPriorReleaseBaseline = readLastSeenVersion() !== null; let checked = false; let telemetryNoticeChecked = false; @@ -82,12 +82,12 @@ export function WhatsNewCard() { if (normalizeReleaseVersion(notes.version) !== currentVersion) { return; } - const highlights = extractHighlights(notes.releaseNotes); - if (!highlights) { + const changelog = extractChangelog(notes.releaseNotes); + if (!changelog) { markVersionSeen(currentVersion); return; } - setHighlightsHtml(renderMarkdown(highlights)); + setChangelogHtml(renderMarkdown(changelog)); setVersion(currentVersion); setVisible(true); } catch (error) { @@ -244,9 +244,9 @@ export function WhatsNewCard() { id="whats-new-title" class="text-lg font-semibold text-base-content truncate" > - What's new in v{version()} + Pulse v{version()} changelog -
Pulse updated successfully
+What changed in this release