fix: resolve issues #8, #9, #10, #11 and bump to v2.2.0 #13
Workflow file for this run
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 Signed Binaries | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Release version (e.g., v2.0.8)' | |
| required: true | |
| default: 'v2.0.8' | |
| prerelease: | |
| description: 'Mark as pre-release' | |
| type: boolean | |
| default: false | |
| push: | |
| tags: | |
| - 'v*' | |
| permissions: | |
| contents: write | |
| id-token: write | |
| jobs: | |
| # Job 1: Windows Certificate Signing | |
| windows-sign: | |
| runs-on: windows-latest | |
| outputs: | |
| artifact-id: ${{ steps.upload.outputs.artifact-id }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup certificate | |
| env: | |
| CERTIFICATE_BASE64: ${{ secrets.CERTIFICATE_BASE64 }} | |
| CERTIFICATE_PASSWORD: ${{ secrets.CERTIFICATE_PASSWORD }} | |
| shell: pwsh | |
| run: | | |
| if ([string]::IsNullOrEmpty($env:CERTIFICATE_BASE64)) { | |
| Write-Host "❌ Certificate secrets missing - cannot sign" -ForegroundColor Red | |
| exit 1 | |
| } | |
| Write-Host "🔐 Setting up certificate..." -ForegroundColor Cyan | |
| $certBytes = [Convert]::FromBase64String($env:CERTIFICATE_BASE64) | |
| [IO.File]::WriteAllBytes("cert.pfx", $certBytes) | |
| - name: Sign executables with Windows Certificate | |
| env: | |
| CERTIFICATE_PASSWORD: ${{ secrets.CERTIFICATE_PASSWORD }} | |
| shell: pwsh | |
| run: | | |
| Write-Host "🔍 Finding executables to sign..." -ForegroundColor Cyan | |
| $files = Get-ChildItem -Recurse -Include "*.exe", "*.msi", "*.msix" | Where-Object { | |
| $_.Name -notlike "*build*" -and | |
| $_.Directory.Name -ne "node_modules" | |
| } | |
| $signtool = @( | |
| "${env:ProgramFiles(x86)}\Windows Kits\10\bin\10.0.22621.0\x64\signtool.exe", | |
| "${env:ProgramFiles(x86)}\Windows Kits\10\bin\10.0.22000.0\x64\signtool.exe", | |
| "${env:ProgramFiles(x86)}\Windows Kits\10\bin\10.0.19041.0\x64\signtool.exe" | |
| ) | Where-Object { Test-Path $_ } | Select-Object -First 1 | |
| foreach ($file in $files) { | |
| Write-Host "🔐 Signing: $($file.Name)" -ForegroundColor Yellow | |
| if ($signtool) { | |
| # Try with timestamp first, fallback without | |
| & $signtool sign /f "cert.pfx" /p $env:CERTIFICATE_PASSWORD /fd sha256 /tr "http://timestamp.digicert.com" /td sha256 /d "WindowsForum Diagnostic Tool" $file.FullName | |
| if ($LASTEXITCODE -ne 0) { | |
| & $signtool sign /f "cert.pfx" /p $env:CERTIFICATE_PASSWORD /fd sha256 /d "WindowsForum Diagnostic Tool" $file.FullName | |
| } | |
| if ($LASTEXITCODE -eq 0) { | |
| Write-Host "✅ Windows signature applied: $($file.Name)" -ForegroundColor Green | |
| } else { | |
| Write-Host "❌ Failed to sign: $($file.Name)" -ForegroundColor Red | |
| } | |
| } | |
| } | |
| - name: Upload Windows-signed artifacts | |
| id: upload | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: windows-signed-binaries | |
| path: | | |
| **/*.exe | |
| **/*.msi | |
| **/*.msix | |
| !node_modules/** | |
| !**/build/** | |
| !**/target/debug/** | |
| # Job 2: Sigstore Signing | |
| sigstore-sign: | |
| runs-on: ubuntu-latest | |
| needs: windows-sign | |
| outputs: | |
| artifact-id: ${{ steps.upload.outputs.artifact-id }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Download Windows-signed binaries | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: windows-signed-binaries | |
| - name: Install Cosign | |
| uses: sigstore/cosign-installer@v3 | |
| with: | |
| cosign-release: 'v2.2.4' | |
| - name: Sign with Sigstore | |
| run: | | |
| echo "🔐 Adding Sigstore signatures to Windows-signed binaries..." | |
| find . \( -name "*.exe" -o -name "*.msi" -o -name "*.msix" \) -type f | while read -r file; do | |
| if [ -f "$file" ]; then | |
| echo "🔐 Adding Sigstore signature: $file" | |
| cosign sign-blob --yes "$file" --output-signature "${file}.sig" --output-certificate "${file}.crt" | |
| echo "✅ Dual-signed: $file" | |
| fi | |
| done | |
| - name: Create release metadata | |
| run: | | |
| echo "# Release Metadata - Dual Signed Binaries" > RELEASE_INFO.md | |
| echo "Generated: $(date -u)" >> RELEASE_INFO.md | |
| echo "Commit: ${{ github.sha }}" >> RELEASE_INFO.md | |
| echo "" >> RELEASE_INFO.md | |
| echo "## Signing Status" >> RELEASE_INFO.md | |
| echo "✅ **Windows Certificate Signing**: Applied (embedded digital signatures)" >> RELEASE_INFO.md | |
| echo "✅ **Sigstore Keyless Signing**: Applied (verification files stored in workflow artifacts)" >> RELEASE_INFO.md | |
| echo "" >> RELEASE_INFO.md | |
| echo "## Files in this Release" >> RELEASE_INFO.md | |
| find . \( -name "*.exe" -o -name "*.msi" -o -name "*.msix" \) -type f | while read -r file; do | |
| echo "### $(basename "$file")" >> RELEASE_INFO.md | |
| echo "- **Path**: \`$file\`" >> RELEASE_INFO.md | |
| echo "- **Size**: $(stat -c%s "$file" | numfmt --to=iec) ($(stat -c%s "$file") bytes)" >> RELEASE_INFO.md | |
| echo "- **SHA256**: \`$(sha256sum "$file" | cut -d' ' -f1)\`" >> RELEASE_INFO.md | |
| echo "- **Windows Signature**: ✅ Embedded (WindowsForum Fara Technologies LLC)" >> RELEASE_INFO.md | |
| if [ -f "${file}.sig" ] && [ -f "${file}.crt" ]; then | |
| echo "- **Sigstore Signature**: ✅ \`$(basename "$file").sig\`" >> RELEASE_INFO.md | |
| echo "- **Sigstore Certificate**: ✅ \`$(basename "$file").crt\`" >> RELEASE_INFO.md | |
| fi | |
| echo "" >> RELEASE_INFO.md | |
| done | |
| - name: Upload dual-signed artifacts | |
| id: upload | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: dual-signed-release | |
| path: | | |
| **/*.exe | |
| **/*.msi | |
| **/*.msix | |
| **/*.sig | |
| **/*.crt | |
| RELEASE_INFO.md | |
| # Job 3: Create GitHub Release | |
| create-release: | |
| runs-on: ubuntu-latest | |
| needs: [windows-sign, sigstore-sign] | |
| if: github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/') | |
| steps: | |
| - name: Download dual-signed artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: dual-signed-release | |
| - name: Determine release version | |
| id: version | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| echo "version=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT | |
| echo "prerelease=${{ github.event.inputs.prerelease }}" >> $GITHUB_OUTPUT | |
| else | |
| echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT | |
| echo "prerelease=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Create GitHub Release | |
| uses: actions/create-release@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| tag_name: ${{ steps.version.outputs.version }} | |
| release_name: WFDiag ${{ steps.version.outputs.version }} - Dual Signed | |
| body: | | |
| ## WindowsForum Diagnostics ${{ steps.version.outputs.version }} | |
| ### Recommended Installation | |
| **[Get from Microsoft Store](https://apps.microsoft.com/detail/9nj59rh053pv)** - Signed by Microsoft, automatic updates | |
| ### Alternative Downloads | |
| - **MSIX Bundle**: Unsigned, for sideloading (requires developer mode or self-signed cert) | |
| - **Portable EXE**: Standalone executables for x64 and ARM64, no installation required | |
| ### Manual MSIX Installation | |
| ```powershell | |
| Add-AppxPackage -Path "WindowsForum_Diagnostics_${{ steps.version.outputs.version }}.msixbundle" | |
| ``` | |
| draft: false | |
| prerelease: ${{ steps.version.outputs.prerelease }} | |
| - name: Upload release assets | |
| run: | | |
| # Find the release ID | |
| RELEASE_ID=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ | |
| "https://api.github.com/repos/${{ github.repository }}/releases/tags/${{ steps.version.outputs.version }}" | \ | |
| jq -r '.id') | |
| # Upload only binary files (exclude .sig and .crt files from release downloads) | |
| find . \( -name "*.exe" -o -name "*.msi" -o -name "*.msix" \) -type f | while read -r file; do | |
| filename=$(basename "$file") | |
| echo "📤 Uploading: $filename" | |
| curl -s \ | |
| -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ | |
| -H "Content-Type: application/octet-stream" \ | |
| --data-binary @"$file" \ | |
| "https://uploads.github.com/repos/${{ github.repository }}/releases/${RELEASE_ID}/assets?name=${filename}" | |
| done | |
| # Note: RELEASE_INFO.md stays in workflow artifacts, not in release downloads | |
| - name: Release Summary | |
| run: | | |
| echo "🎉 Release ${{ steps.version.outputs.version }} created successfully!" | |
| echo "🔐 Includes both Windows Certificate and Sigstore signatures" | |
| echo "📦 All binaries and verification files uploaded" | |
| echo "🌐 Available at: https://github.com/${{ github.repository }}/releases/tag/${{ steps.version.outputs.version }}" |