mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
ci(windows): rehearse the orcad template reseal over SignPath-signed binaries (#34316)
* ci(windows): rehearse the orcad template reseal over SignPath-signed binaries * ci(windows): keep rehearsal template jobs on GitHub-hosted runners
This commit is contained in:
@@ -17,7 +17,19 @@ on:
|
||||
default: windows-inner-binaries-zip
|
||||
|
||||
jobs:
|
||||
# Ship the same qualified template as release-cut so the reseal over SignPath-rewritten binaries is rehearsed too.
|
||||
orcad-template:
|
||||
permissions:
|
||||
contents: read
|
||||
actions: read
|
||||
uses: ./.github/workflows/qualified-orcad-template.yml
|
||||
with:
|
||||
ref: ${{ github.sha }}
|
||||
# SignPath origin verification covers reusable-workflow jobs, so they stay GitHub-hosted.
|
||||
fast_runners: false
|
||||
|
||||
rehearse:
|
||||
needs: orcad-template
|
||||
# Why: SignPath origin verification requires GitHub-hosted runners, and
|
||||
# windows-2022 matches the real release job's build environment.
|
||||
runs-on: windows-2022
|
||||
@@ -25,6 +37,8 @@ jobs:
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
env:
|
||||
ORCA_REQUIRE_ORCAD_TEMPLATE: '1'
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -79,6 +93,13 @@ jobs:
|
||||
env:
|
||||
NODE_OPTIONS: --max-old-space-size=4096
|
||||
|
||||
# After the app build so nothing that cleans out/ can drop it; electron-builder ships it.
|
||||
- name: Download the orcad deployment template
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: orcad-template
|
||||
path: out/orcad-template
|
||||
|
||||
# Build full --win: --dir never creates the NSIS uninstaller needed for MDE evidence.
|
||||
- name: Package Windows app and export the NSIS uninstaller
|
||||
shell: pwsh
|
||||
@@ -111,6 +132,11 @@ jobs:
|
||||
Where-Object { $_.Extension -in '.exe', '.dll', '.node' } |
|
||||
ForEach-Object {
|
||||
$relative = [System.IO.Path]::GetRelativePath($root, $_.FullName)
|
||||
# The orcad template's Linux/macOS addons are data for SSH hosts, not PE files.
|
||||
if ($relative -match '^resources[\\/]orcad-template[\\/]targets[\\/](?!win32-)') {
|
||||
$skipped.Add("$relative <non-Windows orcad template payload>")
|
||||
return
|
||||
}
|
||||
$signature = Get-AuthenticodeSignature -FilePath $_.FullName
|
||||
if ($signature.Status -eq 'Valid') {
|
||||
$skipped.Add("$relative <already signed: $($signature.SignerCertificate.Subject)>")
|
||||
@@ -214,6 +240,10 @@ jobs:
|
||||
throw "Signed inner artifact did not round-trip cleanly ($($failures.Count) failures)."
|
||||
}
|
||||
|
||||
# Recompute template checksums over the signed bytes, then verify the template as release-cut does.
|
||||
- name: Reseal the orcad template over its signed binaries
|
||||
run: node config/scripts/packaged-orcad-template.cjs --reseal-signed dist/win-unpacked inner-signing-list.txt
|
||||
|
||||
- name: Restore signed uninstaller for the installer rebuild
|
||||
shell: pwsh
|
||||
env:
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { parse } from 'yaml'
|
||||
|
||||
// The rehearsal must sign and reseal the same template payload release-cut ships, or Windows reseal regressions only surface in a real release.
|
||||
function readWorkflow(name) {
|
||||
return parse(readFileSync(new URL(`../../.github/workflows/${name}`, import.meta.url), 'utf8'))
|
||||
}
|
||||
|
||||
const RESEAL_STEP = 'Reseal the orcad template over its signed binaries'
|
||||
const release = readWorkflow('release-cut.yml').jobs.build
|
||||
const { jobs } = readWorkflow('windows-signing-rehearsal.yml')
|
||||
const rehearse = jobs.rehearse
|
||||
const stepIndex = (name) => rehearse.steps.findIndex((step) => step.name === name)
|
||||
|
||||
describe('Windows signing rehearsal ships the orcad template', () => {
|
||||
it('packages the qualified template built from the dispatched commit', () => {
|
||||
expect(jobs['orcad-template'].uses).toBe('./.github/workflows/qualified-orcad-template.yml')
|
||||
expect(jobs['orcad-template'].with).toEqual({ ref: '${{ github.sha }}', fast_runners: false })
|
||||
expect(rehearse.needs).toBe('orcad-template')
|
||||
expect(rehearse.env.ORCA_REQUIRE_ORCAD_TEMPLATE).toBe('1')
|
||||
const download = stepIndex('Download the orcad deployment template')
|
||||
expect(download).toBeGreaterThan(stepIndex('Build app'))
|
||||
expect(download).toBeLessThan(stepIndex('Package Windows app and export the NSIS uninstaller'))
|
||||
expect(rehearse.steps[download].with).toEqual({
|
||||
name: 'orcad-template',
|
||||
path: 'out/orcad-template'
|
||||
})
|
||||
})
|
||||
|
||||
it('reseals the signed template exactly like release-cut, before the installer rebuild', () => {
|
||||
const releaseReseal = release.steps.find((step) => step.name === RESEAL_STEP)
|
||||
const reseal = stepIndex(RESEAL_STEP)
|
||||
expect(rehearse.steps[reseal].run).toBe(releaseReseal.run)
|
||||
expect(reseal).toBeGreaterThan(stepIndex('Restore signed inner binaries into unpacked app'))
|
||||
expect(reseal).toBeLessThan(stepIndex('Build NSIS installer from signed unpacked app'))
|
||||
})
|
||||
|
||||
it('keeps non-Windows template addons out of SignPath staging', () => {
|
||||
const filter = "'^resources[\\\\/]orcad-template[\\\\/]targets[\\\\/](?!win32-)'"
|
||||
const staging = (job) => job.steps.find((step) => step.id === 'stage-inner').run
|
||||
expect(staging(release)).toContain(filter)
|
||||
expect(staging(rehearse)).toContain(filter)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user