Sampled Values
Stream identity, APPID, svID, VLAN, continuity, waveform, RMS, phasor, and sequence context.
diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 9a54a6d1..1ee2943e 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -37,6 +37,13 @@ jobs: test -f docs/screenshot/analyzer-overview.webp grep -q 'Process Bus Insight' docs/index.html + - name: Validate latest stable EXE download contract + shell: bash + run: | + set -euo pipefail + python3 scripts/verify-landing-release.py + node --check docs/app.js + - name: Configure Pages uses: actions/configure-pages@v6 diff --git a/README.md b/README.md index f6dc2f75..67a4a0b6 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [](https://github.com/masarray/DigSubAnalyzer/actions/workflows/codeql.yml) [](https://github.com/masarray/DigSubAnalyzer/actions/workflows/pages.yml) [](https://github.com/masarray/DigSubAnalyzer/actions/workflows/release-package.yml) -[](https://github.com/masarray/DigSubAnalyzer/releases) +[](https://github.com/masarray/DigSubAnalyzer/releases/latest) [](LICENSE) [](#download-and-run) [](#build-from-source) @@ -28,7 +28,7 @@ Process Bus Insight is intentionally receive-only. It does not send IEC 61850 co | SV analyzer | Multi-stream discovery, APPID/svID/MAC/VLAN/confRev evidence, selected-stream workspace, decoded waveform, RMS, phasor, sequence diagnostics, shape/distortion indication, and selectable scope windows. | | Runtime snapshots | Immutable selected-stream generations containing copied identity, waveform, analog, phasor, shape, and diagnostic evidence for coherent consumer reads. | | PCAP replay | Bounded classic Ethernet PCAP replay through the same decoder/analyzer entry point used by live Npcap capture. | -| GOOSE inspector | Publisher discovery, stNum/sqNum tracking, event timeline, typed `allData` decoding, change summaries, and SCL-assisted semantic context. | +| GOOSE inspector | Stable multi-publisher selection, physical-key Messages filtering, bounded decoded-change timeline, Follow live switch, red unread notification dots, unified message acknowledgement, typed DataSet value-change tooltips, and SCL-assisted signal/quality context. | | PTP visibility | Passive PTPv2 context, grandmaster/domain evidence where available, freshness wording, and timestamp-confidence boundaries. | | SCL validation | Load SCD/ICD/CID files and compare expected publishers/streams against observed APPID, destination MAC, VLAN, svID, confRev, and related evidence. | | Evidence workflow | Copyable engineering evidence, cautious timing language, target-aware diagnostics, and screenshot-friendly workspaces. | @@ -46,14 +46,16 @@ The application can record what was configured in SCL, what the selected capture ## Download and run -1. Download the latest published **Windows Inno Setup installer** (v1.4.2 after its public release) from [GitHub Releases](https://github.com/masarray/DigSubAnalyzer/releases): `ProcessBusInsight-v1.4.2-win-x64-setup.exe`. +**[Download the latest stable installer (.exe) — v1.4.2](https://github.com/masarray/DigSubAnalyzer/releases/download/v1.4.2/ProcessBusInsight-v1.4.2-win-x64-setup.exe)** · [Landing page](https://masarray.github.io/DigSubAnalyzer/) · [Latest GitHub Release](https://github.com/masarray/DigSubAnalyzer/releases/latest) + +1. Download the public stable **Windows Inno Setup installer** directly from the link above. The landing page automatically resolves the newest stable Windows setup EXE and keeps v1.4.2 as a working fallback. 2. Run the installer. Its stable app identity supports in-place updates, same-version repair, Windows uninstall, and optional desktop shortcut. 3. **Offline manuals are installed directly inside the app folder** (`User Manual.pdf`, `Quick Start.pdf`, and `Install and Update.md`), with Start Menu shortcuts. 4. Install **Npcap separately** when live raw Ethernet capture is required; it is not bundled. Offline PCAP analysis remains available without it. 5. Launch Process Bus Insight, select an authorized TAP or mirror capture adapter, and start analysis. 6. To update, close the app and run the newer installer; no uninstall is needed for standard in-place upgrades. -An optional **portable ZIP** is also available for manual extraction. The community installer is currently unsigned, so verify its official source and SHA256; do not treat it as a background auto-updater. See [installation and update guidance](docs/INSTALLATION_AND_UPDATE.md). +An optional [**portable ZIP**](https://github.com/masarray/DigSubAnalyzer/releases/download/v1.4.2/ProcessBusInsight-v1.4.2-win-x64-portable.zip) is also available for manual extraction. Compare its checksum or the installer's checksum with [SHA256SUMS.txt](https://github.com/masarray/DigSubAnalyzer/releases/download/v1.4.2/SHA256SUMS.txt). The community installer is currently unsigned, so verify its official source and SHA256; do not treat it as a background auto-updater. See [installation and update guidance](docs/INSTALLATION_AND_UPDATE.md). Current Windows distribution naming: diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md index b25542ea..58312471 100644 --- a/docs/DEPLOYMENT.md +++ b/docs/DEPLOYMENT.md @@ -32,6 +32,14 @@ Or with GitHub CLI: gh repo edit masarray/DigSubAnalyzer --default-branch main --delete-branch-on-merge=true ``` +## Latest stable Windows installer + +The landing page must lead with a **direct installer .exe** link, never an Actions artifact or the portable ZIP. At deployment time, all three primary download links (header, hero, and Download card) have a stable `v1.4.2` asset fallback. `docs/app.js` queries GitHub `/releases/latest` client-side and upgrades the buttons to the latest non-draft, non-prerelease version **only if** its matching `ProcessBusInsight-vX.Y.Z-win-x64-setup.exe` asset exists. Missing API access retains the already-published fallback. + +The portable ZIP, SHA256 checksum, and release notes remain secondary links. `scripts/verify-landing-release.py` checks that the pinned fallback matches `Directory.Build.props`, that structured metadata/README are synchronized and that no primary CTA silently sends engineers to ZIP or the Releases list. The Pages workflow also runs `node --check docs/app.js` before deployment. When publishing a new stable version, update the pinned fallback URLs and version in the repository even though runtime discovery can follow the latest release automatically. + +Latest public stable release: https://github.com/masarray/DigSubAnalyzer/releases/latest + ## Deploy manually After pushing the latest repository content to `main`, run: diff --git a/docs/app.js b/docs/app.js index be559f1b..5a5d8828 100644 --- a/docs/app.js +++ b/docs/app.js @@ -1,3 +1,72 @@ + +// Public release discovery. GitHub /releases/latest excludes prereleases and +// drafts. Every anchor already has a working direct stable EXE fallback in HTML, +// so API outages, offline use, rate limits, and disabled JavaScript never send +// a user to an obsolete "portable ZIP" CTA or a CI artifact. +const releaseApi = 'https://api.github.com/repos/masarray/DigSubAnalyzer/releases/latest'; +const releaseAssetRoot = 'https://github.com/masarray/DigSubAnalyzer/releases/download/'; +const releaseFilename = /^ProcessBusInsight-v\d+\.\d+\.\d+-win-x64-(setup\.exe|portable\.zip)$/; +const checksumFilename = 'SHA256SUMS.txt'; + +function safeReleaseAsset(asset, tag) { + if (!asset || typeof asset.name !== 'string' || typeof asset.browser_download_url !== 'string') return false; + if (!(releaseFilename.test(asset.name) || asset.name === checksumFilename)) return false; + const prefix = `${releaseAssetRoot}${tag}/`; + return asset.browser_download_url === prefix + asset.name; +} + +function setReleaseLinks(kind, url) { + document.querySelectorAll(`[data-release-download="${kind}"]`).forEach((anchor) => { + anchor.href = url; + }); +} + +function applyLatestStableRelease(release) { + if (!release || release.draft || release.prerelease || + !/^v\d+\.\d+\.\d+$/.test(release.tag_name) || !Array.isArray(release.assets)) return; + + const tag = release.tag_name; + const assets = release.assets.filter((asset) => safeReleaseAsset(asset, tag)); + const exe = assets.find((asset) => asset.name === `ProcessBusInsight-${tag}-win-x64-setup.exe`); + if (!exe) return; // Never direct the primary button to ZIP or a nonexistent asset. + const portable = assets.find((asset) => asset.name === `ProcessBusInsight-${tag}-win-x64-portable.zip`); + const checksum = assets.find((asset) => asset.name === checksumFilename); + const releasePage = `https://github.com/masarray/DigSubAnalyzer/releases/tag/${tag}`; + + setReleaseLinks('installer', exe.browser_download_url); + if (portable) setReleaseLinks('portable', portable.browser_download_url); + if (checksum) setReleaseLinks('checksum', checksum.browser_download_url); + document.querySelectorAll('[data-release-page]').forEach((link) => { link.href = releasePage; }); + document.querySelectorAll('[data-release-version]').forEach((label) => { + label.textContent = `Stable ${tag}`; + }); + + // Keep structured download metadata coherent for crawlers that execute JS. + const structured = document.querySelector('script[type="application/ld+json"]'); + if (structured) { + try { + const data = JSON.parse(structured.textContent); + if (data['@type'] === 'SoftwareApplication') { + data.softwareVersion = tag.slice(1); + data.downloadUrl = exe.browser_download_url; + structured.textContent = JSON.stringify(data); + } + } catch { /* Noncritical metadata; keep the static stable fallback. */ } + } +} + +if (document.querySelector('[data-release-download="installer"]')) { + fetch(releaseApi, { + headers: { Accept: 'application/vnd.github+json' }, + cache: 'no-store' + }).then((response) => { + if (!response.ok) throw new Error('GitHub latest release not accessible'); + return response.json(); + }).then(applyLatestStableRelease).catch(() => { + // HTML already points directly to verified v1.4.2 EXE. + }); +} + const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; const header = document.querySelector('[data-header]'); const progressBar = document.querySelector('.scroll-progress'); diff --git a/docs/index.html b/docs/index.html index 3e80cef7..c0d1be50 100644 --- a/docs/index.html +++ b/docs/index.html @@ -4,7 +4,7 @@
Analyze live Sampled Values, GOOSE, PTP timing context, and SCL expected-vs-observed evidence. Reproduce sanitized classic PCAP captures through the same decoder path while keeping timing and evidence limitations visible.
Analyze live Sampled Values, GOOSE, PTP timing context, and SCL expected-vs-observed evidence. Reproduce sanitized classic PCAP captures through the same decoder path while keeping timing and evidence limitations visible.
Stable v1.4.2 · Windows 10/11 x64 · Free and open source
fullscreen PreviewUse an authorized observation path. Npcap is installed separately only when live raw Ethernet capture is required.
Stable v1.4.2 · self-contained Windows x64. Use the standard installer for in-place update and repair. Npcap is installed separately for live capture.
The application shortens the path from traffic to a reviewable finding without treating software capture as certified metrology.
Stream identity, APPID, svID, VLAN, continuity, waveform, RMS, phasor, and sequence context.
Publisher state, stNum, sqNum, dataset values, and event changes.
Stable multi-source selection, event timeline and Follow live, unread-change dots, unified acknowledgement, and decoded signal change tooltips.
Timing traffic and freshness with explicit timestamp-source limits.
Compare observed traffic with SCD, ICD, or CID expectations.
Reproduce sanitized classic Ethernet captures through the live decoder path.