2026-05-31 11:18:27 -04:00
# Releasing Dragon-ISO
2026-05-08 00:48:57 -04:00
The release workflow at `.forgejo/workflows/release.yml` runs on **annotated tag pushes
matching `v*.*.*` **. It builds, tests, publishes, packages an MSI, and uploads the
MSI as a release asset.
## Prerequisites
- A **Windows runner** registered to this Forgejo instance. WiX MSI builds require
Windows; the existing CI runs on Linux for unit tests, but releases need a
separate Windows runner. Register one with `forgejo-runner register` against a
Windows host that has the .NET 8 SDK + WiX SDK access (the WiX SDK pulls itself
via NuGet at build time, so no separate install).
2026-05-31 11:18:27 -04:00
- The repository's **Create release on tag push** setting on (default), or skip it —
2026-05-08 00:48:57 -04:00
the workflow will create the release if one doesn't exist.
## Cutting a release
```sh
# Bump the version in Directory.Build.props if you haven't already.
2026-05-31 11:18:27 -04:00
git tag -a v1.0.0 -m "Dragon-ISO 1.0.0"
2026-05-08 00:48:57 -04:00
git push origin v1.0.0
```
The workflow will:
2026-05-31 11:18:27 -04:00
1. Restore + build `Dragon-ISO.Windows.slnf` in Release with the tag's version.
2. Run unit tests (the `requires=ndi` integration tier is skipped — it needs a
2026-05-08 00:48:57 -04:00
real NDI runtime which a CI runner won't have).
2026-05-31 11:18:27 -04:00
3. Publish `Dragon-ISO.App` and `Dragon-ISO.Console` for `win-x64` ,
2026-05-08 00:48:57 -04:00
framework-dependent (.NET 8 Desktop runtime is the user's responsibility).
2026-05-31 11:18:27 -04:00
4. Build `installer/Dragon-ISO.Installer.wixproj` , producing
`Dragon-ISO-Setup-<version>.msi` .
2026-05-08 00:48:57 -04:00
5. Upload the MSI as a workflow artifact (downloadable from the run page).
6. Attach the MSI to the GitHub-style Release for the tag, creating the release
first if it doesn't exist. Pre-release flag is set automatically when the
tag contains `-alpha` , `-beta` , or `-rc` .
2026-05-10 09:41:28 -04:00
## Code signing
2026-05-08 00:48:57 -04:00
2026-05-10 09:41:28 -04:00
The release workflow has optional signtool integration. It runs only when the
2026-05-31 11:18:27 -04:00
signing-cert secrets are configured on the repository — without them, builds
2026-05-10 09:41:28 -04:00
remain unsigned and produce a SmartScreen warning on first launch.
2026-05-08 00:48:57 -04:00
2026-05-10 09:41:28 -04:00
### Enabling signing
2026-05-08 00:48:57 -04:00
2026-05-31 11:18:27 -04:00
Set these secrets on `forge.wilddragon.net/zgaetano/Dragon-ISO`
→ Settings → Actions → Secrets:
2026-05-10 09:41:28 -04:00
| Secret | Required | Notes |
| --- | --- | --- |
| `SIGN_CERT_PFX_BASE64` | yes | Base64 of your code-signing PFX file. Generate with `certutil -encode in.pfx out.b64` , then strip the `-----BEGIN/END CERTIFICATE-----` lines. |
| `SIGN_CERT_PASSWORD` | yes | The PFX password. |
| `SIGN_TIMESTAMP_URL` | no | RFC 3161 timestamp server. Defaults to `http://timestamp.digicert.com` . |
When all three are present, the workflow:
1. Decodes the PFX to a temp file on the runner before building.
2026-05-31 11:18:27 -04:00
2. Signs `publish/Dragon-ISO/Dragon-ISO.exe` after publish, before MSI build, so the
2026-05-10 09:41:28 -04:00
binary embedded in the MSI is signed too.
3. Signs the produced MSI itself after WiX builds it.
4. Wipes the temp PFX from disk.
Both signing steps use SHA-256 for both the file hash and the timestamp digest,
which is what current Microsoft / SmartScreen guidance requires.
### Cert types
- **OV (Organization Validation, ~$200/yr).** SmartScreen reputation is built
per-publisher over time; brand-new OV certs still trip the warning until
enough downloads accumulate.
- **EV (Extended Validation, ~$300/yr, hardware token).** SmartScreen-trusted
2026-05-31 11:18:27 -04:00
immediately. Token-based — to use one in CI you'll need to either (a) keep
2026-05-10 09:41:28 -04:00
the runner on a host with the token plugged in, or (b) move to a cloud
signing service like Azure Trusted Signing or DigiCert KeyLocker.
For v1.0 we recommend the Azure Trusted Signing route: replace the PFX block
in `release.yml` with `azure/trusted-signing-action` once an Azure subscription
is set up. The current PFX path is the simplest thing that works for now.