feat: harden release signing and coverage gate
ForgeFlow quality gate / quality (push) Canceled after 0s
ForgeFlow quality gate / quality (push) Canceled after 0s
This commit is contained in:
+9
-11
@@ -1,20 +1,18 @@
|
||||
# Coverage policy
|
||||
|
||||
ForgeFlow treats coverage as release evidence, not as a target to game. `npm run coverage`
|
||||
enforces 75% statements, 75% lines, 75% functions and 60% branches globally.
|
||||
enforces 75% statements, 75% lines, 75% functions and 65% branches globally.
|
||||
|
||||
The July 2026 hardening pass raised the measured baseline from 69.74% statements/lines,
|
||||
68.82% functions and 55.38% branches to at least 78% statements/lines, 79% functions and
|
||||
60% branches. The requested 65% global branch target was investigated but is not used as
|
||||
the release gate yet. Node/V8 discovers additional branch counters when previously
|
||||
unexecuted functions become covered; the denominator grew from 2,537 to more than 3,100
|
||||
while the new tests added hundreds of asserted branches. Raising the number by excluding
|
||||
command builders, platform guards or error adapters would make the result look better
|
||||
without increasing deployment safety.
|
||||
68.82% functions and 55.38% branches to 81.48% statements/lines, 82.07% functions and
|
||||
65.59% branches. Node/V8 discovered additional branch counters when previously unexecuted
|
||||
functions became covered; the denominator grew from 2,537 to 3,473 while the new tests
|
||||
added hundreds of asserted decisions. No command builders, platform guards or error
|
||||
adapters were excluded to improve the result cosmetically.
|
||||
|
||||
The 60% global gate is therefore paired with scenario-level evidence for the critical
|
||||
The 65% global gate is paired with scenario-level evidence for the critical
|
||||
boundaries: deploy-key rollback, deployment verification, Gitea authentication and
|
||||
redirects, SSH host identity and output limits, inventory reconciliation, stale plans,
|
||||
configuration recovery, release integrity and updater failure modes. New code must not
|
||||
reduce the global baseline. A future increase to 65% should come from additional asserted
|
||||
failure scenarios, not ignore comments or source exclusions.
|
||||
reduce the global baseline. Future increases must come from additional asserted failure
|
||||
scenarios, not ignore comments or source exclusions.
|
||||
|
||||
@@ -45,9 +45,8 @@ console events, DOM, fixture details and test identity.
|
||||
## 7. Coverage and dependencies
|
||||
|
||||
Coverage increased from 69.74% statements/lines, 68.82% functions and 55.38%
|
||||
branches to at least 78.75%, 79.68% and 59.25%, respectively, before the last
|
||||
ConfigStore tests. The enforced gates are 75/75/75/60; the rationale and 65%
|
||||
follow-up are in `COVERAGE_POLICY.md`. Production dependencies have zero known
|
||||
branches to 81.48%, 82.07% and 65.59%, respectively. The enforced gates are now
|
||||
75/75/75/65 and are documented in `COVERAGE_POLICY.md`. Production dependencies have zero known
|
||||
audit vulnerabilities. Remaining development findings belong to current upstream
|
||||
ESLint/electron-builder toolchains and are assessed in `DEPENDENCY_AUDIT.md`.
|
||||
|
||||
|
||||
+49
-1
@@ -18,9 +18,57 @@ 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
|
||||
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 = '<tenant id>'
|
||||
$env:AZURE_CLIENT_ID = '<application/client id>'
|
||||
$env:AZURE_CLIENT_SECRET = '<secret value>'
|
||||
$env:FORGEFLOW_AZURE_SIGNING_ENDPOINT = 'https://<region>.codesigning.azure.net/'
|
||||
$env:FORGEFLOW_AZURE_SIGNING_ACCOUNT = '<artifact signing account>'
|
||||
$env:FORGEFLOW_AZURE_CERTIFICATE_PROFILE = '<certificate profile>'
|
||||
$env:FORGEFLOW_SIGNED_RELEASE = '1'
|
||||
$env:FORGEFLOW_EXPECTED_PUBLISHER = 'CN=<exact subject from Get-AuthenticodeSignature>'
|
||||
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 = '<secret password>'
|
||||
$env:FORGEFLOW_SIGNED_RELEASE = '1'
|
||||
$env:FORGEFLOW_EXPECTED_PUBLISHER = 'CN=<exact legal subject>, O=<organization>, 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.
|
||||
|
||||
+3
-3
@@ -5,9 +5,9 @@
|
||||
The quality chain contains more than 230 Node and browser acceptance cases. The
|
||||
latest Windows source run completed without failures and retains one explicitly
|
||||
Bash-dependent skip. `npm run coverage` enforces 75% lines/statements/functions
|
||||
and 60% branches; the measured hardening baseline is 78.75% statements/lines,
|
||||
79.68% functions and 59.25% branches before the final ConfigStore additions.
|
||||
See `COVERAGE_POLICY.md` for the non-gamed branch policy.
|
||||
and 65% branches; the measured hardening baseline is 81.48% statements/lines,
|
||||
82.07% functions and 65.59% branches. See `COVERAGE_POLICY.md` for the
|
||||
non-gamed branch policy.
|
||||
|
||||
`npm run quality` is the local equivalent of `.gitea/workflows/quality.yml` and
|
||||
runs source verification, ESLint, the complete suite and coverage on Node 22 LTS.
|
||||
|
||||
Reference in New Issue
Block a user