Skip to content

Commit 8a1a694

Browse files
author
David Imongirie
committed
chore(ci): attach checksums and publish release with artifacts; add distribution README
1 parent 8ed03ee commit 8a1a694

2 files changed

Lines changed: 158 additions & 25 deletions

File tree

.github/workflows/windows_build.yml

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ jobs:
1111
runs-on: windows-latest
1212

1313
steps:
14-
- name: Checkout repository
14+
- name: Checkout repository (full history)
1515
uses: actions/checkout@v4
16+
with:
17+
fetch-depth: 0
1618

1719
- name: Set up Python
1820
uses: actions/setup-python@v4
@@ -41,46 +43,73 @@ jobs:
4143
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
4244
.\build_windows.ps1 -CompileNSIS
4345
44-
- name: Upload EXE artifact
45-
if: always()
46-
uses: actions/upload-artifact@v4
47-
with:
48-
name: TestBuddy-exe
49-
path: dist/TestBuddy.exe
46+
- name: Compute checksums for artifacts
47+
shell: powershell
48+
run: |
49+
$files = @()
50+
if (Test-Path .\dist\TestBuddy.exe) { $files += Get-Item .\dist\TestBuddy.exe }
51+
if (Test-Path .\dist\TestBuddy-signed.exe) { $files += Get-Item .\dist\TestBuddy-signed.exe }
52+
if (Test-Path .\TestBuddy-Setup.exe) { $files += Get-Item .\TestBuddy-Setup.exe }
53+
if (Test-Path .\TestBuddy-Setup-signed.exe) { $files += Get-Item .\TestBuddy-Setup-signed.exe }
54+
if ($files.Count -eq 0) { Write-Host 'No build artifacts found to checksum.'; exit 0 }
55+
$out = "CHECKSUMS.txt"
56+
Remove-Item $out -ErrorAction SilentlyContinue
57+
foreach ($f in $files) {
58+
$sha = Get-FileHash -Algorithm SHA256 $f.FullName | Select-Object -ExpandProperty Hash
59+
"$sha $($f.Name)" | Out-File -FilePath $out -Encoding ascii -Append
60+
}
61+
Get-Content CHECKSUMS.txt
5062
51-
- name: Upload Installer artifact
52-
if: always()
63+
- name: Upload build artifacts and checksums
5364
uses: actions/upload-artifact@v4
5465
with:
55-
name: TestBuddy-installer
56-
path: TestBuddy-Setup.exe
66+
name: TestBuddy-artifacts
67+
path: |
68+
dist/TestBuddy*.exe
69+
TestBuddy-Setup*.exe
70+
CHECKSUMS.txt
5771
5872
- name: Optional: Sign artifacts (if PFX secret provided)
59-
if: ${{ secrets.SIGN_CERT_PFX != '' && secrets.SIGN_CERT_PASSWORD != '' }}
73+
if: ${{ secrets.SIGN_CERT_PFX && secrets.SIGN_CERT_PASSWORD }}
6074
shell: powershell
75+
env:
76+
PFX_BASE64: ${{ secrets.SIGN_CERT_PFX }}
77+
PFX_PASS: ${{ secrets.SIGN_CERT_PASSWORD }}
6178
run: |
62-
Write-Host "Writing PFX to file and attempting to sign artifacts..."
63-
$pfxBase64 = '${{ secrets.SIGN_CERT_PFX }}'
64-
[IO.File]::WriteAllBytes('cert.pfx', [Convert]::FromBase64String($pfxBase64))
65-
choco install osslsigncode -y || Write-Host 'osslsigncode install may have failed'
79+
Write-Host "Decoding PFX and writing to cert.pfx"
80+
[IO.File]::WriteAllBytes('cert.pfx', [Convert]::FromBase64String($env:PFX_BASE64))
81+
choco install osslsigncode -y || Write-Host 'osslsigncode may already be installed or install failed'
6682
if (Test-Path .\dist\TestBuddy.exe) {
67-
Write-Host 'Signing dist\\TestBuddy.exe'
68-
osslsigncode sign -pkcs12 cert.pfx -pass '${{ secrets.SIGN_CERT_PASSWORD }}' -n 'TestBuddy' -i 'http://testbuddy.local' -t 'http://timestamp.digicert.com' -in .\dist\TestBuddy.exe -out .\dist\TestBuddy-signed.exe || Write-Host 'Signing EXE failed'
83+
$in = Resolve-Path .\dist\TestBuddy.exe
84+
$out = Resolve-Path .\dist\TestBuddy-signed.exe
85+
Write-Host "Signing $in -> $out"
86+
osslsigncode sign -pkcs12 cert.pfx -pass $env:PFX_PASS -n 'TestBuddy' -i 'https://testbuddy.app' -t 'http://timestamp.digicert.com' -in $in -out $out
6987
}
7088
if (Test-Path .\TestBuddy-Setup.exe) {
71-
Write-Host 'Signing TestBuddy-Setup.exe'
72-
osslsigncode sign -pkcs12 cert.pfx -pass '${{ secrets.SIGN_CERT_PASSWORD }}' -n 'TestBuddy' -i 'http://testbuddy.local' -t 'http://timestamp.digicert.com' -in .\TestBuddy-Setup.exe -out .\TestBuddy-Setup-signed.exe || Write-Host 'Signing installer failed'
89+
$in = Resolve-Path .\TestBuddy-Setup.exe
90+
$out = Resolve-Path .\TestBuddy-Setup-signed.exe
91+
Write-Host "Signing $in -> $out"
92+
osslsigncode sign -pkcs12 cert.pfx -pass $env:PFX_PASS -n 'TestBuddy' -i 'https://testbuddy.app' -t 'http://timestamp.digicert.com' -in $in -out $out
7393
}
7494
95+
- name: Compute release tag
96+
id: tag
97+
uses: actions/github-script@v6
98+
with:
99+
script: |
100+
const date = new Date().toISOString().slice(0,10).replace(/-/g,'')
101+
const tag = `v${date}-${process.env.GITHUB_RUN_NUMBER}`
102+
return tag
103+
75104
- name: Create GitHub release and attach artifacts
76105
uses: ncipollo/release-action@v1
77106
with:
78-
tag: build-${{ github.run_number }}
79-
name: TestBuddy build ${{ github.run_number }}
107+
tag: ${{ steps.tag.outputs.result }}
108+
name: TestBuddy ${{ steps.tag.outputs.result }}
80109
body: |
81-
Automated build from commit ${{ github.sha }}
82-
- Runner: ${{ runner.os }}
83-
- Workflow: ${{ github.workflow }}
110+
Automated build for commit ${{ github.sha }}
111+
Artifacts include the executable(s) and installer. See attached CHECKSUMS.txt for SHA256 sums.
84112
files: |
85113
dist/TestBuddy*.exe
86114
TestBuddy-Setup*.exe
115+
CHECKSUMS.txt

README_DISTRIBUTION.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
TestBuddy - Distribution & Signing Guide
2+
========================================
3+
4+
Purpose
5+
-------
6+
This guide explains exactly how to produce signed, installable Windows artifacts for TestBuddy and how to configure the CI pipeline to produce release builds and signed installers.
7+
8+
What we added for you
9+
---------------------
10+
- `build_windows.ps1` / `build_windows.bat` — build the EXE (PyInstaller) and compile NSIS installer (if `makensis` is available).
11+
- `testbuddy_installer.nsi` — NSIS installer script (references `dist/TestBuddy.exe`).
12+
- GitHub Actions workflow: `.github/workflows/windows_build.yml` that:
13+
- Installs dependencies
14+
- Runs tests
15+
- Builds EXE and runs NSIS (on Windows runner)
16+
- Generates `CHECKSUMS.txt` (SHA256)
17+
- Uploads artifacts
18+
- Optionally signs artifacts if signing secrets are present
19+
- Creates a GitHub Release and attaches artifacts
20+
21+
Requirements before distribution
22+
--------------------------------
23+
1. Windows code signing certificate (PFX) with private key.
24+
- Obtain from a CA (DigiCert, Sectigo, GlobalSign). EV certificates are recommended for broad trust.
25+
2. GitHub repo-level secrets (to enable automatic signing):
26+
- `SIGN_CERT_PFX` — base64-encoded contents of the PFX file
27+
- `SIGN_CERT_PASSWORD` — password for the PFX
28+
29+
How to create the base64 PFX secret (PowerShell)
30+
------------------------------------------------
31+
Run locally and copy the output into the `SIGN_CERT_PFX` secret value in GitHub:
32+
33+
```powershell
34+
$bytes = [System.IO.File]::ReadAllBytes('C:\path\to\your-cert.pfx')
35+
$base64 = [Convert]::ToBase64String($bytes)
36+
# Save temporarily
37+
Set-Content -Path C:\tmp\cert.pfx.b64 -Value $base64
38+
# Open the file and copy-paste the single-line content into the repo secret
39+
notepad C:\tmp\cert.pfx.b64
40+
```
41+
42+
Add the PFX password as `SIGN_CERT_PASSWORD` in GitHub Secrets.
43+
44+
Signing options supported in the workflow
45+
----------------------------------------
46+
- `osslsigncode` (open-source): used on Windows runner (installed via Chocolatey). Works with PFX.
47+
- `signtool` (Microsoft): preferred for EV certs / MS recommended signing. If you prefer `signtool`, you can modify the workflow to call `signtool` instead; it requires the Windows SDK or a runner that has `signtool.exe` available.
48+
49+
How to trigger a release build
50+
------------------------------
51+
- Option A: Push a commit to `main` branch (workflow runs automatically)
52+
- Option B: Run `Build Windows` workflow manually from the Actions UI (workflow_dispatch)
53+
54+
How the workflow produces artifacts
55+
-----------------------------------
56+
1. `pyinstaller` creates `dist/TestBuddy.exe` (one-file, windowed).
57+
2. NSIS compiles `TestBuddy-Setup.exe` if `makensis` is available on the runner.
58+
3. `CHECKSUMS.txt` is produced with SHA256 lines for each artifact.
59+
4. Optional signing step (if secrets present) produces `*-signed.exe` variants.
60+
5. The release flow creates a tag like `vYYYYMMDD-<run_number>` and publishes a Release, attaching artifacts and `CHECKSUMS.txt`.
61+
62+
Manual verification steps (recommended)
63+
--------------------------------------
64+
- Download artifacts from the workflow run or Release.
65+
- Verify SHA256 matches the values in `CHECKSUMS.txt`:
66+
```powershell
67+
Get-FileHash .\TestBuddy-Setup.exe -Algorithm SHA256
68+
Get-Content CHECKSUMS.txt
69+
```
70+
- Install on a clean VM (Windows 10/11) and verify:
71+
- App launches
72+
- Sessions load
73+
- Export features work (PDF, DOCX, CSV, HTML, Markdown, JSON, TXT)
74+
- Document Intelligence analyze works (with Tesseract installed)
75+
- Uninstall removes program files
76+
77+
If you want to use `signtool` instead of `osslsigncode`
78+
------------------------------------------------------
79+
- Upload PFX as repo secret as above.
80+
- Modify the workflow step `Optional: Sign artifacts` to call `signtool.exe sign /f cert.pfx /p <password> /tr http://timestamp.digicert.com /td sha256 /fd sha256 <file>`
81+
- On hosted runners, `signtool` may not be present. You'll need either to install Windows SDK in the runner (adds time), or use a self-hosted Windows runner that has `signtool` installed and your signing cert available.
82+
83+
Recommended post-release steps
84+
------------------------------
85+
- Sign all binaries and installer before publishing to avoid "Unknown Publisher" warnings.
86+
- Consider using an official code-signing service or HSM for private key security.
87+
- Publish checksums on the website and in the release notes.
88+
- For automated distribution, consider pushing artifacts to a CDN or S3 bucket and use the installer to fetch updates.
89+
90+
Support and troubleshooting
91+
-------------------------
92+
If a workflow fails:
93+
- Open the Actions run and expand logs for the failing step.
94+
- For signing issues, ensure the PFX is valid and not password-protected with non-ASCII characters that could break environment handling.
95+
- For NSIS errors, ensure makensis is available and the path to the EXE referenced in `testbuddy_installer.nsi` matches the build output.
96+
97+
Contact
98+
-------
99+
If you'd like, I can:
100+
- Switch the workflow to use `signtool` and/or a self-hosted signing runner.
101+
- Add automatic changelog generation using Conventional Commits or `release-drafter`.
102+
- Add an auto-update server or mechanism.
103+
104+
*** End of guide ***

0 commit comments

Comments
 (0)