Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[![CodeQL](https://github.com/masarray/DigSubAnalyzer/actions/workflows/codeql.yml/badge.svg)](https://github.com/masarray/DigSubAnalyzer/actions/workflows/codeql.yml)
[![GitHub Pages](https://github.com/masarray/DigSubAnalyzer/actions/workflows/pages.yml/badge.svg)](https://github.com/masarray/DigSubAnalyzer/actions/workflows/pages.yml)
[![Release Package](https://github.com/masarray/DigSubAnalyzer/actions/workflows/release-package.yml/badge.svg)](https://github.com/masarray/DigSubAnalyzer/actions/workflows/release-package.yml)
[![Latest Release](https://img.shields.io/github/v/release/masarray/DigSubAnalyzer?include_prereleases&label=release)](https://github.com/masarray/DigSubAnalyzer/releases)
[![Latest Stable Release](https://img.shields.io/github/v/release/masarray/DigSubAnalyzer?label=stable)](https://github.com/masarray/DigSubAnalyzer/releases/latest)
[![License: GPL-3.0-or-later](https://img.shields.io/badge/license-GPL--3.0--or--later-blue.svg)](LICENSE)
[![Platform](https://img.shields.io/badge/platform-Windows%2010%2F11-0078d4)](#download-and-run)
[![.NET](https://img.shields.io/badge/.NET-8.0-512BD4)](#build-from-source)
Expand All @@ -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. |
Expand All @@ -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:

Expand Down
8 changes: 8 additions & 0 deletions docs/DEPLOYMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
69 changes: 69 additions & 0 deletions docs/app.js
Original file line number Diff line number Diff line change
@@ -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');
Expand Down
Loading
Loading