Files
pbakaus_impeccable/tests/release-engine-workflow.test.js
T
Paul BakausandGitHub bb7663ecfb Sign Windows engine releases with Azure Artifact Signing (#742)
* Sign Windows engine releases with Azure Artifact Signing

Isolate OIDC signing behind a maintainer-approved release environment and publish only verified, timestamped company-signed Windows output.

AI assistance: implemented and verified with Codex under maintainer direction.

* Clarify same-run artifact permissions

Keep least-privilege tokens: the pinned artifact actions use ACTIONS_RUNTIME_TOKEN for same-run transfers. Guard against opting into cross-run downloads and use role-based reviewer wording.

AI assistance: prepared and verified with Codex under maintainer direction.
2026-09-05 15:38:55 -07:00

73 lines
4.0 KiB
JavaScript

import { describe, expect, test } from 'bun:test';
import { readFileSync } from 'node:fs';
const workflow = Bun.YAML.parse(readFileSync(new URL('../.github/workflows/release-engine.yml', import.meta.url), 'utf8'));
const action = (job, name) => job.steps.find(step => step.uses?.startsWith(`${name}@`));
describe('engine release signing boundary', () => {
test('only the protected signing job receives an OIDC token', () => {
expect(workflow.on).toEqual({ push: { tags: ['engine-v*'] } });
expect(workflow.permissions).toEqual({ contents: 'read' });
const sign = workflow.jobs['sign-windows'];
expect(sign.environment).toBe('windows-signing');
expect(sign.needs).toBe('build');
expect(sign.permissions).toEqual({ contents: 'read', 'id-token': 'write' });
expect(workflow.jobs.build.permissions?.['id-token']).toBeUndefined();
expect(workflow.jobs.publish.permissions).toEqual({ contents: 'write' });
expect(sign.steps.some(step => step.uses?.startsWith('actions/checkout@'))).toBe(false);
});
test('publication waits for signing and cannot collect the unsigned artifact', () => {
const unsignedName = 'unsigned-windows-x64';
expect(action(workflow.jobs.build, 'actions/upload-artifact').with.name).toContain(unsignedName);
const sign = workflow.jobs['sign-windows'];
expect(action(sign, 'actions/download-artifact').with.name).toBe(unsignedName);
expect(action(sign, 'actions/upload-artifact').with.name).toBe('impeccable-windows-x64');
expect(workflow.jobs.publish.needs).toEqual(['build', 'sign-windows']);
expect(action(workflow.jobs.publish, 'actions/download-artifact').with.pattern).toBe('impeccable-*');
expect(unsignedName.startsWith('impeccable-')).toBe(false);
expect(workflow.jobs.publish.steps.find(step => step.name === 'Lay out release assets with checksums').run).toContain('sha256sum');
});
test('artifact downloads stay on the same-run runtime-token path', () => {
for (const name of ['sign-windows', 'publish']) {
const download = action(workflow.jobs[name], 'actions/download-artifact');
// Supplying github-token opts into the public API path, which requires
// separate Actions permissions and can read other workflow runs.
for (const input of ['github-token', 'repository', 'run-id']) {
expect(download.with[input]).toBeUndefined();
}
}
});
test('signs exactly the engine with timestamping, then verifies before upload', () => {
const sign = workflow.jobs['sign-windows'];
const signing = action(sign, 'azure/artifact-signing-action');
expect(signing.with.files).toBe('${{ github.workspace }}\\unsigned\\impeccable.exe');
expect(signing.with['certificate-profile-name']).toBe('impeccable-windows');
expect(signing.with['signing-account-name']).toBe('impeccable-signing');
expect(signing.with['timestamp-rfc3161']).toBe('http://timestamp.acs.microsoft.com');
expect(signing.with['file-digest']).toBe('SHA256');
expect(signing.with['timestamp-digest']).toBe('SHA256');
expect(signing.with['exclude-environment-credential']).toBe(true);
expect(signing.with['cache-dependencies']).toBe(false);
const verify = sign.steps.find(step => step.name === 'Verify signed engine');
expect(sign.steps.indexOf(verify)).toBeGreaterThan(sign.steps.indexOf(signing));
expect(sign.steps.indexOf(verify)).toBeLessThan(sign.steps.indexOf(action(sign, 'actions/upload-artifact')));
expect(verify.run).toContain("$signature.Status -ne 'Valid'");
expect(verify.run).toContain("$publisher -cne 'Renaissance Geek, Inc.'");
expect(verify.run).toContain('$null -eq $signature.TimeStamperCertificate');
expect(verify.run).toContain('throw');
expect(sign.steps.some(step => step['continue-on-error'])).toBe(false);
expect(action(sign, 'actions/upload-artifact').if).toBeUndefined();
});
test('every third-party action is pinned to a commit', () => {
for (const job of Object.values(workflow.jobs)) {
for (const step of job.steps) {
if (step.uses) expect(step.uses).toMatch(/@[a-f0-9]{40}$/);
}
}
});
});