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
114 changes: 114 additions & 0 deletions .github/workflows/processbus-dual-stable-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
name: Process Bus Dual Firmware Stable Promotion

# Repackage tested RC1. NO firmware or Qt compilation.
on:
push:
branches: [main]
paths:
- docs/releases/PROCESSBUS_DUAL_STABLE_LAUNCH.md

permissions:
contents: write

concurrency:
group: arstack-dual-stable-20261105
cancel-in-progress: false

env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RC_TAG: processbus-sim-dual-rc1-20261105
STABLE_TAG: processbus-sim-dual-stable-20261105
RC_MERGED_MAIN: 525902548504aa997f868c43f51208fb13beecaf

jobs:
verified-stable-publication:
runs-on: windows-2022
timeout-minutes: 40
steps:
- name: Checkout verified stable Inno script
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Download pinned tested RC1 and verify exact firmware Studio Linux
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
$rc = Join-Path $env:RUNNER_TEMP 'arstack-dual-rc1'
New-Item -ItemType Directory -Force -Path $rc | Out-Null
& gh release download $env:RC_TAG --repo $env:GITHUB_REPOSITORY --dir $rc
if ($LASTEXITCODE -ne 0) { throw 'RC1 download failed' }
$meta = Join-Path $env:RUNNER_TEMP 'arstack-rc1-release.json'
& gh api "repos/$env:GITHUB_REPOSITORY/releases/tags/$env:RC_TAG" | Out-File -LiteralPath $meta -Encoding utf8
if ($LASTEXITCODE -ne 0) { throw 'RC1 metadata failed' }
python scripts/promote_processbus_dual_stable.py prepare --rc $rc --release-meta $meta --stage (Join-Path $env:RUNNER_TEMP 'arstack-stable-stage') --out (Join-Path $PWD 'dist-stable')
if ($LASTEXITCODE -ne 0) { throw 'Provenance / dual-revision validation failed' }

- name: Compile Stable Inno installer from identical tested RC1 binaries
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
choco install innosetup --version 6.7.1 -y --no-progress
if ($LASTEXITCODE -ne 0) { throw 'Inno Setup unavailable' }
$compiler = Join-Path ([Environment]::GetFolderPath('ProgramFilesX86')) 'Inno Setup 6\ISCC.exe'
$iss = (Resolve-Path 'apps\arstack_studio\packaging\ARStackStudio.iss').Path
$stage = Join-Path $env:RUNNER_TEMP 'arstack-stable-stage'
$out = Join-Path $PWD 'dist-stable'
& $compiler '/DSTUDIO_VERSION=0.1.1' "/DSTAGE_DIR=$stage" "/O$out" $iss
if ($LASTEXITCODE -ne 0 -or -not (Test-Path (Join-Path $out 'ARStack-Studio-win-x64-setup.exe'))) {
throw 'Stable-channel installer missing'
}

- name: Windows Stable AppId install firmware contract and clean uninstall
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
$installer = Join-Path $PWD 'dist-stable\ARStack-Studio-win-x64-setup.exe'
$target = Join-Path $env:RUNNER_TEMP 'ARStackStableInstall'
$arguments = @('/VERYSILENT','/SUPPRESSMSGBOXES','/NORESTART','/CLOSEAPPLICATIONS',("/DIR=" + $target))
$process = Start-Process -FilePath $installer -ArgumentList $arguments -Wait -PassThru
if ($process.ExitCode -ne 0) { throw 'Stable installer execution failed' }
$app = Join-Path $target 'ARStackStudio.exe'
$stableKey = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\ARStack61850.Studio.Stable_is1'
$previewKey = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\ARStack61850.Studio.Preview_is1'
if (-not (Test-Path $app) -or -not (Test-Path $stableKey) -or (Test-Path $previewKey)) {
throw 'Stable installer AppId is incorrect'
}
$source = Join-Path $env:RUNNER_TEMP 'arstack-stable-stage\ARStackStudio.exe'
if ((Get-FileHash $app -Algorithm SHA256).Hash -ne (Get-FileHash $source -Algorithm SHA256).Hash) {
throw 'Installed executable is not the RC1 executable'
}
$env:ARSTACK_STUDIO_FIRMWARE_DIR = Join-Path $target 'firmware'
$env:ARSTACK_STUDIO_ESPFLASH = Join-Path $target 'tools\espflash.exe'
$env:ESPFLASH_SKIP_UPDATE_CHECK = 'true'
foreach ($check in @('--check-firmware-contract','--check-p0-policy','--check-reference-template','--check-app-lifecycle')) {
$probe = Start-Process -FilePath $app -ArgumentList $check -Wait -PassThru
if ($probe.ExitCode -ne 0) { throw "Stable Studio failed $check" }
}
$remover = Join-Path $target 'unins000.exe'
$gone = Start-Process -FilePath $remover -ArgumentList @('/VERYSILENT','/SUPPRESSMSGBOXES','/NORESTART') -Wait -PassThru
if ($gone.ExitCode -ne 0 -or (Test-Path $app) -or (Test-Path $stableKey)) { throw 'Stable uninstall failed' }
Write-Host 'STABLE_INSTALL_SMOKE: PASS'

- name: Create preferred Setup ZIP and verify all release hashes
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
python scripts/promote_processbus_dual_stable.py finish --rc (Join-Path $env:RUNNER_TEMP 'arstack-dual-rc1') --release-meta (Join-Path $env:RUNNER_TEMP 'arstack-rc1-release.json') --stage (Join-Path $env:RUNNER_TEMP 'arstack-stable-stage') --out (Join-Path $PWD 'dist-stable')
if ($LASTEXITCODE -ne 0) { throw 'Preferred ZIP hash verification failed' }

- name: Publish immutable stable GitHub release as latest
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
$out = Join-Path $PWD 'dist-stable'
$assets = @(Get-ChildItem -LiteralPath $out -File | ForEach-Object { $_.FullName })
if ($assets.Count -lt 11) { throw 'Incomplete stable assets' }
$arguments = @('release','create',$env:STABLE_TAG) + $assets + @('--repo',$env:GITHUB_REPOSITORY,'--target',$env:RC_MERGED_MAIN,'--title','ARStack Process Bus Simulator - Dual Firmware Stable','--notes-file',(Join-Path $out 'RELEASE_NOTES.md'),'--latest')
& gh @arguments
if ($LASTEXITCODE -ne 0) { throw 'Stable publishing failed or immutable tag already exists' }
$published = (& gh api "repos/$env:GITHUB_REPOSITORY/releases/tags/$env:STABLE_TAG" | ConvertFrom-Json)
if ($published.draft -or $published.prerelease -or $published.assets.Count -ne $assets.Count) {
throw 'Stable release not fully published'
}
Write-Host "STABLE_RELEASE_URL=$($published.html_url)"
21 changes: 21 additions & 0 deletions docs/releases/PROCESSBUS_DUAL_STABLE_LAUNCH.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Process Bus Simulator Dual Firmware — Stable Release Promotion

**Release tag:** `processbus-sim-dual-stable-20261105`
**Source accepted by operator:** Public RC1 `processbus-sim-dual-rc1-20261105`
**Exact RC1 firmware/Studio source:** `ab646b58da601569c956f2d19ff45100129f19a0`
**RC1 integrated main SHA:** `525902548504aa997f868c43f51208fb13beecaf`

This file is a one-time, post-merge trigger for the existing-artifact stable promotion
in `.github/workflows/processbus-dual-stable-publish.yml`.

## Product release contract

- ARStack61850 is an IEC 61850 Process Bus **Merging Unit + GPS-style PTP Grandmaster simulator** for isolated laboratory current/voltage SV injection and SCL-driven engineering. Emulated PTP and SV must work as though genuine process-bus devices were connected.
- **No C++ Studio, Qt, ESP-IDF, SV encoder, PTP runtime, or firmware rebuild.** Promote the exact operator-tested public RC1 binaries, matching the two distinct ESP32-P4 pre-v3 and v3.x images and catalog by pinned SHA256.
- The one necessary packaging change: compile the already-gated Inno Setup source **without ARSTACK_PREVIEW**, using the stable AppId and installer identity. Run fresh Windows stable install, exact Studio binary/firmware contract, and clean uninstall checks.
- Package `ARStack-Studio-win-x64-setup.zip` containing only `ARStack-Studio-win-x64-setup.exe` as the **preferred browser download**. Provide portable ZIP, Setup EXE, Linux AppImage, firmware images, revision catalog, manifest, release notes, SHA256SUMS and source provenance separately.
- Create a **new public non-prerelease stable release** and make it latest. Do not edit the accepted RC1 tag or historic M3.H.3 stable tag/assets. Publication must fail closed on provenance/hash mismatch or CI/package test failure.
- ZIP helps with browser download handling but does **not** bypass Microsoft SmartScreen or security checks. Keep unsigned EXE provenance and installation instructions clear.
- Stable release reflects operator-tested RC1 behavior; avoid making unsupported claims that 3x4000fps physical HIL on every PCB or certified UTC/GPS hardware were proven.

**Gate:** Merge this release PR only after static validation and no outstanding review issues; the merge starts the single Windows packaging/publishing job without reopening expensive firmware CI.
14 changes: 10 additions & 4 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ <h1>Your own <em>IEC 61850 Process Bus</em> lab.</h1>
<div class="schematic" aria-label="Process bus simulator topology"><div class="unit">ARStack Studio<small>Windows setup · autonomous board state</small></div><span class="wire" aria-hidden="true"></span><div class="unit">ESP32-P4 Ethernet<small>EMAC hardware timestamp + 4 kHz SV grid</small></div><span class="wire" aria-hidden="true"></span><div class="streams"><div>PTP · Announce / Sync / Follow_Up</div><div>SV · 4I+4V · smpSynch AUTO</div></div></div>
<p class="small">M3.H.3 on-wire lab capture: <strong>4,705,090 SV frames over 19 min 36 s</strong>, 3,999.886 fps, zero missing/duplicate/reordered/malformed SV; 3,528 PTP packets observed and smpSynch=2 on the received stream. <a href="https://github.com/masarray/arstack61850/blob/main/docs/releases/PROCESSBUS_AUTONOMOUS_M3H3_OFFICIAL_20261025.md">View the engineering capture results</a>.</p>
</section>
<section class="shell content" id="roadmap"><h2>Next: multiple virtual Merging Units from one board.</h2><p class="sectionintro">ARStack is built for practical digital-substation engineers. Our next priority is <strong>Multi-SV on one ESP32-P4</strong> plus <strong>SCL-driven Merging Unit simulation</strong>: open an SCD/CID/IID, select supported SV streams and deploy their identities and DataSet layouts without building a rack of physical MUs.</p><div class="cards"><article class="card"><h3>Multiple SV publishers</h3><p>One ESP32-P4, multiple independently configured SV streams, each with its own identity and sample counter.</p></article><article class="card"><h3>SCL file-based configuration</h3><p>Choose Merging Unit streams from IEC 61850 engineering files and map supported DataSet leaves to generated waveforms.</p></article><article class="card"><h3>Engineer-first workflow</h3><p>Open file → select stream(s) → assign values → Start → observe real traffic in a relay/BCU test network.</p></article></div><p class="small">Multi-stream publishing and the full SCL-driven MU workflow are planned next; M3.H.3 currently ships the proven single 4I+4V SV stream. <a href="https://github.com/masarray/arstack61850/blob/main/docs/PROCESS_BUS_MULTI_SV_SCL_NEXT_PHASE.md">See the engineering roadmap</a>.</p></section>
<section class="shell content" id="roadmap"><h2>Next: multiple virtual Merging Units from one board.</h2><p class="sectionintro">ARStack is built for practical digital-substation engineers. Our next priority is <strong>Multi-SV on one ESP32-P4</strong> plus <strong>SCL-driven Merging Unit simulation</strong>: open an SCD/CID/IID, select supported SV streams and deploy their identities and DataSet layouts without building a rack of physical MUs.</p><div class="cards"><article class="card"><h3>Multiple SV publishers</h3><p>One ESP32-P4, multiple independently configured SV streams, each with its own identity and sample counter.</p></article><article class="card"><h3>SCL file-based configuration</h3><p>Choose Merging Unit streams from IEC 61850 engineering files and map supported DataSet leaves to generated waveforms.</p></article><article class="card"><h3>Engineer-first workflow</h3><p>Open file → select stream(s) → assign values → Start → observe real traffic in a relay/BCU test network.</p></article></div><p class="small">M4 software supports SCL-driven virtual MU streams on one ESP32-P4; extended three-stream physical load acceptance is still being gathered. The M3.H.3 measurements above refer to the historical single-stream release. <a href="https://github.com/masarray/arstack61850/blob/main/docs/PROCESS_BUS_MULTI_SV_SCL_NEXT_PHASE.md">See the engineering roadmap</a>.</p></section>
<section class="shell content" id="studio-preview"><h2>See ARStack Studio in action.</h2><p class="sectionintro">Configure IEC 61850 waveform scenarios, inspect phasors, and prepare process-bus experiments in one native desktop workspace.</p>
<figure class="studio-preview"><img src="assets/screenshots/arstack-studio-windows.png" alt="ARStack Studio Windows engineering interface with 4I+4V signal controls, voltage and current phasors and waveform preview" width="960" height="680" loading="lazy" decoding="async"><figcaption>Real Windows Qt application screenshot · 960 × 680</figcaption></figure>
</section>
<section class="shell content" id="getting-started"><h2>First packet in four steps.</h2><div class="setup"><div class="step"><b>Install Studio</b>Use Windows Setup or Portable; both include the matched firmware and flashing tool.</div><div class="step"><b>Flash ESP32-P4</b>Connect USB OTG and install the matching firmware from the release.</div><div class="step"><b>Select lab timing</b>Use PTP SOURCE / INTERNAL_GM_ONLY and smpSynch AUTO on an isolated Ethernet LAN.</div><div class="step"><b>Start and capture</b>Run 4I+4V, then inspect SV 0x88BA and PTP 0x88F7 in ARSAS, DigSubAnalyzer or Wireshark.</div></div><p class="footnote">Safety boundary: Never attach the lab PTP GM or SV publisher to a live substation process bus. Use an isolated test LAN or VLAN. ARStack is an <strong>open-source IEC 61850 engineering lab tool</strong>; no external GPS or protection relay is needed for the basic simulation.</p></section>
<section class="shell content" id="downloads"><h2>Download the latest release.</h2><p class="sectionintro">Choose the installer, portable application or matched board firmware from the latest stable GitHub release. Downloads update automatically when a new verified release is published.</p>
<section class="shell content" id="downloads"><h2>Download the latest release.</h2><p class="sectionintro">Prefer the Windows Setup ZIP, extract it and run the installer. Portable ZIP requires no installation; select revision-matched ESP32-P4 firmware from the latest release catalog. Downloads update automatically when a new verified release is published.</p>
<div class="downloads"><article class="download"><div><h3>Windows Installer</h3><p>Windows x64 · setup and bundled dependencies</p></div><a data-asset="windows" href="https://github.com/masarray/arstack61850/releases/download/processbus-sim-m3h3-20261025/ARStack-Studio-M3H3-win-x64-setup.exe">Setup EXE ↗</a></article>
<article class="download"><div><h3>Portable ZIP</h3><p>Windows x64 · run without a separate installation</p></div><a data-asset="portable" href="https://github.com/masarray/arstack61850/releases/download/processbus-sim-m3h3-20261025/ARStack-Studio-M3H3-win-x64-portable.zip">Portable ZIP ↗</a></article>
<article class="download"><div><h3>ESP32-P4 Firmware</h3><p>Match the firmware to your installed Studio release</p></div><a data-asset="firmware" href="https://github.com/masarray/arstack61850/releases/download/processbus-sim-m3h3-20261025/ARStack-ESP32P4-M3H3-firmware.bin">Firmware BIN ↗</a></article>
Expand All @@ -89,9 +89,9 @@ <h1>Your own <em>IEC 61850 Process Bus</em> lab.</h1>
typeof x.browser_download_url==='string' &&
x.browser_download_url.startsWith('https://github.com/masarray/arstack61850/releases/download/'));
const resolved={
windows:find(/(?:win|windows).*setup\.exe$/i),
windows:find(/(?:win|windows).*setup\.zip$/i) || find(/(?:win|windows).*setup\.exe$/i),
portable:find(/(?:win|windows).*portable\.zip$/i),
firmware:find(/firmware.*\.bin$/i),
firmware:assets.some(x=>x.name==='firmware-catalog.json') ? null : find(/firmware.*\.bin$/i),
linux:find(/linux.*\.AppImage$/i)
};
for(const [key,asset] of Object.entries(resolved)){
Expand All @@ -100,6 +100,12 @@ <h1>Your own <em>IEC 61850 Process Bus</em> lab.</h1>
if(!asset) link.title='View available files in the latest release';
});
}
document.querySelectorAll('[data-asset="windows"]').forEach(link=>{
const preferredZip=resolved.windows && /setup\.zip$/i.test(resolved.windows.name);
link.textContent=link.classList.contains('btn')
? (preferredZip ? 'Download Windows Setup ZIP ↓' : 'Download latest Windows Setup ↓')
: (preferredZip ? 'Setup ZIP ↗' : 'Setup EXE ↗');
});
if(resolved.linux) document.getElementById('linux-download').hidden=false;
const label=document.querySelector('[data-latest-label]');
if(label) label.textContent='Latest stable release · '+release.tag_name;
Expand Down
Loading
Loading