Release #1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| jobs: | |
| package: | |
| name: Build portable Windows release | |
| runs-on: windows-latest | |
| timeout-minutes: 40 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '8.0.x' | |
| - name: Restore | |
| run: dotnet restore .\PtpLabClock.sln | |
| - name: Test | |
| run: dotnet test .\PtpLabClock.sln -c Release --no-restore --logger trx --results-directory TestResults | |
| - name: Protocol smoke validation | |
| run: dotnet run --project .\src\PtpLabClock.Console --configuration Release -- --validate-protocol --domain 0 --export-pcap .\TestResults\ptp-validation.pcap | |
| - name: Publish portable single EXE files | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| $publishRoot = Resolve-Path "." | |
| New-Item -ItemType Directory -Path .\artifacts -Force | Out-Null | |
| New-Item -ItemType Directory -Path .\publish\app -Force | Out-Null | |
| New-Item -ItemType Directory -Path .\publish\console -Force | Out-Null | |
| $singleFileProps = @( | |
| "-p:PublishSingleFile=true", | |
| "-p:SelfContained=true", | |
| "-p:IncludeNativeLibrariesForSelfExtract=true", | |
| "-p:EnableCompressionInSingleFile=true", | |
| "-p:PublishReadyToRun=false", | |
| "-p:PublishTrimmed=false", | |
| "-p:DebugType=None", | |
| "-p:DebugSymbols=false" | |
| ) | |
| dotnet publish .\src\PtpLabClock.App\PtpLabClock.App.csproj -c Release -r win-x64 --self-contained true @singleFileProps -o .\publish\app | |
| dotnet publish .\src\PtpLabClock.Console\PtpLabClock.Console.csproj -c Release -r win-x64 --self-contained true @singleFileProps -o .\publish\console | |
| Copy-Item .\publish\app\PtpLabClock.App.exe .\artifacts\PtpLabClock.App.win-x64.portable.exe -Force | |
| Copy-Item .\publish\console\PtpLabClock.Console.exe .\artifacts\PtpLabClock.Console.win-x64.portable.exe -Force | |
| if (-not (Test-Path .\artifacts\PtpLabClock.App.win-x64.portable.exe)) { throw "App portable EXE was not created." } | |
| if (-not (Test-Path .\artifacts\PtpLabClock.Console.win-x64.portable.exe)) { throw "Console portable EXE was not created." } | |
| - name: Create optional ZIP packages with notices | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| $packages = @( | |
| @{ Name = "PtpLabClock.App.win-x64.portable"; Exe = ".\artifacts\PtpLabClock.App.win-x64.portable.exe" }, | |
| @{ Name = "PtpLabClock.Console.win-x64.portable"; Exe = ".\artifacts\PtpLabClock.Console.win-x64.portable.exe" } | |
| ) | |
| foreach ($package in $packages) { | |
| $dir = Join-Path ".\artifacts" $package.Name | |
| New-Item -ItemType Directory -Path $dir -Force | Out-Null | |
| Copy-Item $package.Exe (Join-Path $dir (Split-Path $package.Exe -Leaf)) -Force | |
| Copy-Item .\LICENSE $dir -Force | |
| Copy-Item .\NOTICE $dir -Force | |
| Copy-Item .\THIRD-PARTY-NOTICES.md $dir -Force | |
| Copy-Item .\docs\release-readme.md (Join-Path $dir "README-FIRST.md") -Force | |
| Compress-Archive -Path (Join-Path $dir "*") -DestinationPath ".\artifacts\$($package.Name).zip" -Force | |
| } | |
| - name: Generate checksums and SPDX-style release manifest | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| $releaseFiles = Get-ChildItem .\artifacts -File | Where-Object { $_.Extension -in ".exe", ".zip" } | Sort-Object Name | |
| $checksums = foreach ($file in $releaseFiles) { | |
| $hash = Get-FileHash $file.FullName -Algorithm SHA256 | |
| "$($hash.Hash.ToLowerInvariant()) $($file.Name)" | |
| } | |
| $checksums | Set-Content .\artifacts\checksums.txt -Encoding UTF8 | |
| $sbom = [ordered]@{ | |
| spdxVersion = "SPDX-2.3" | |
| dataLicense = "CC0-1.0" | |
| SPDXID = "SPDXRef-DOCUMENT" | |
| name = "Process Bus Timing Lab portable Windows release manifest" | |
| documentNamespace = "https://github.com/masarray/PtpLabClock/releases/$env:GITHUB_RUN_ID" | |
| creationInfo = [ordered]@{ | |
| created = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") | |
| creators = @("Tool: GitHub Actions", "Organization: Process Bus Timing Lab") | |
| } | |
| packages = @( | |
| [ordered]@{ SPDXID = "SPDXRef-Package-PtpLabClock"; name = "PtpLabClock"; downloadLocation = "NOASSERTION"; filesAnalyzed = $false; licenseConcluded = "Apache-2.0"; licenseDeclared = "Apache-2.0"; copyrightText = "Copyright (C) 2026 Ari Sulistiono" }, | |
| [ordered]@{ SPDXID = "SPDXRef-Package-SharpPcap"; name = "SharpPcap"; versionInfo = "6.3.1"; downloadLocation = "https://www.nuget.org/packages/SharpPcap/6.3.1"; filesAnalyzed = $false; licenseConcluded = "MIT"; licenseDeclared = "MIT"; copyrightText = "NOASSERTION" } | |
| ) | |
| releaseArtifacts = @($releaseFiles | ForEach-Object { [ordered]@{ name = $_.Name; sha256 = (Get-FileHash $_.FullName -Algorithm SHA256).Hash.ToLowerInvariant(); size = $_.Length } }) | |
| } | |
| $sbom | ConvertTo-Json -Depth 8 | Set-Content .\artifacts\PtpLabClock.release-sbom.spdx.json -Encoding UTF8 | |
| - name: Upload release build artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: portable-release-packages | |
| path: | | |
| .\artifacts\*.exe | |
| .\artifacts\*.zip | |
| .\artifacts\checksums.txt | |
| .\artifacts\PtpLabClock.release-sbom.spdx.json | |
| .\TestResults\ptp-validation.pcap | |
| - name: Publish GitHub Release | |
| if: startsWith(github.ref, 'refs/tags/') | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: | | |
| .\artifacts\*.exe | |
| .\artifacts\*.zip | |
| .\artifacts\checksums.txt | |
| .\artifacts\PtpLabClock.release-sbom.spdx.json | |
| .\TestResults\ptp-validation.pcap | |
| generate_release_notes: true | |
| body: | | |
| ## Process Bus Timing Lab portable release | |
| Download the direct portable EXE when you want the fastest Windows start: | |
| - `PtpLabClock.App.win-x64.portable.exe` - WPF dashboard, self-contained single-file app. | |
| - `PtpLabClock.Console.win-x64.portable.exe` - CLI validation, RAW self-test, passive monitor, and scripts. | |
| ZIP packages are also provided for users who want license notices and README files bundled beside the EXE. | |
| RAW NIC mode requires Npcap and may require Administrator privileges. This software is a lab simulator and diagnostic companion, not a certified grandmaster or relay-acceptance timing reference. |