# Releasing ForgeFlow ForgeFlow releases are built only from a clean, reviewed commit on Node 22 LTS. ## Quality gate ```powershell npm ci npm run quality npm audit --omit=dev --audit-level=high ``` ## Signed Windows build Production signing is fail-closed. Configure electron-builder's Authenticode certificate through its supported CSC environment variables, then set: ```powershell $env:FORGEFLOW_SIGNED_RELEASE = '1' $env:FORGEFLOW_EXPECTED_PUBLISHER = 'CN=Exact Legal Publisher, O=Exact Legal Organization, C=BE' npm run dist:win:signed ``` The signed command requires signed-release mode, an exact publisher subject and either a classic `WIN_CSC_LINK` certificate configuration or complete Azure credentials. It enables electron-builder's `forceCodeSigning` gate, so missing signing material cannot silently produce a production candidate. ### Recommended: Azure Artifact Signing 1. Create an Azure Artifact Signing account and identity-validation certificate profile for the legal ForgeFlow publisher. 2. Create an Entra app registration and give its service principal the `Artifact Signing Certificate Profile Signer` role on that account. 3. Store the following as protected CI variables—never in Git: ```powershell $env:AZURE_TENANT_ID = '' $env:AZURE_CLIENT_ID = '' $env:AZURE_CLIENT_SECRET = '' $env:FORGEFLOW_AZURE_SIGNING_ENDPOINT = 'https://.codesigning.azure.net/' $env:FORGEFLOW_AZURE_SIGNING_ACCOUNT = '' $env:FORGEFLOW_AZURE_CERTIFICATE_PROFILE = '' $env:FORGEFLOW_SIGNED_RELEASE = '1' $env:FORGEFLOW_EXPECTED_PUBLISHER = 'CN=' npm run dist:win:signed ``` The generated configuration uses SHA-256 and Microsoft's RFC 3161 timestamp service. `FORGEFLOW_EXPECTED_PUBLISHER` must still contain the complete subject reported by the resulting certificate, even though Azure's builder option uses its CN component. ### Alternative: classic CA certificate When a CA supplies a CI-compatible PFX or hardware/cloud connector supported by electron-builder, configure its protected values and use the same command: ```powershell $env:WIN_CSC_LINK = 'C:\secure\forgeflow-signing.pfx' $env:WIN_CSC_KEY_PASSWORD = '' $env:FORGEFLOW_SIGNED_RELEASE = '1' $env:FORGEFLOW_EXPECTED_PUBLISHER = 'CN=, O=, C=BE' npm run dist:win:signed ``` Do not purchase a certificate before the CA or cloud service confirms the exact legal subject and that its key-storage method works with the intended Windows CI runner. An ordinary OV certificate can still accumulate SmartScreen reputation; EV or Azure Artifact Signing provides immediate publisher trust. Both installer and portable executable must have a valid Authenticode signature, the expected publisher and a timestamp. The build also creates SHA-256 files, a CycloneDX SBOM and a provenance document containing commit and build ID. Without `FORGEFLOW_SIGNED_RELEASE=1`, local builds may be unsigned for development testing but must never be published as production releases. ## Atomic publication `npm run release:binary` keeps the Gitea release in draft state while uploading the installer, portable executable, two checksums, provenance and SBOM. It only publishes after all six assets are present. A failed upload leaves a draft rather than exposing an incomplete updater target. The publisher check is an exact subject match, not a substring match. Before a production certificate is available, validate the complete local chain with: ```powershell npm run test:signing ``` This disposable fixture signs installer, portable, update-helper and uninstaller stand-ins, requires an RFC 3161 timestamp, and proves rejection of a missing timestamp, wrong publisher and a modified binary. Its certificate is removed from the current-user certificate store after the test. The production Authenticode certificate and exact legal publisher identity are `PENDING_HUMAN_INPUT`; all surrounding build and verification code is complete.