feat(FN-5609): add macOS desktop signing configuration and entitlements

Adds macOS code signing and notarization infrastructure (FN-5609), introducing hardened runtime entitlements, electron-builder config for signed builds, and signing-enabled release workflows, with tests validating the configuration and docs covering the signing flow.

Fusion-Task-Id: FN-5609

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5609
This commit is contained in:
gsxdsm
2026-05-27 05:21:56 -07:00
parent 925a466043
commit 7d2cf330db
8 changed files with 199 additions and 13 deletions

View File

@@ -106,6 +106,31 @@ describe("electron-builder desktop config", () => {
expect(linuxArchByTarget.get("deb")).toEqual(["arm64", "x64"]);
expect(linuxArchByTarget.get("tar.gz")).toEqual(["arm64", "x64"]);
});
it("locks mac signing and notarization configuration", async () => {
const builderConfig = await readDesktopFile("electron-builder.yml");
expect(builderConfig).toMatch(/mac:\s*[\s\S]*?hardenedRuntime:\s*true/m);
expect(builderConfig).toMatch(/mac:\s*[\s\S]*?gatekeeperAssess:\s*false/m);
expect(builderConfig).toMatch(/mac:\s*[\s\S]*?entitlements:\s*build\/entitlements\.mac\.plist/m);
expect(builderConfig).toMatch(/mac:\s*[\s\S]*?entitlementsInherit:\s*build\/entitlements\.mac\.plist/m);
expect(builderConfig).toMatch(/mac:\s*[\s\S]*?notarize:\s*true/m);
expect(builderConfig).not.toContain("mac.identity:");
expect(builderConfig).not.toContain("appleId:");
expect(builderConfig).not.toContain("teamId:");
});
it("ships the expected hardened-runtime entitlements plist", async () => {
const entitlements = await readDesktopFile("build/entitlements.mac.plist");
expect(entitlements).toContain("<?xml");
expect(entitlements).toContain("</plist>");
expect(entitlements).toContain("com.apple.security.cs.allow-jit");
expect(entitlements).toContain("com.apple.security.cs.allow-unsigned-executable-memory");
expect(entitlements).toContain("com.apple.security.cs.allow-dyld-environment-variables");
expect(entitlements).toContain("com.apple.security.cs.disable-library-validation");
expect(entitlements).toContain("com.apple.security.inherit");
});
});
describe("desktop windows workflow signing guards", () => {

View File

@@ -69,6 +69,39 @@ describe("desktop release workflow wiring", () => {
});
});
describe("desktop macos signing wiring", () => {
it("wires signed and unsigned macOS packaging paths with verification", async () => {
const release = await readRepoFile(".github/workflows/release.yml");
const testRelease = await readRepoFile(".github/workflows/test-release.yml");
for (const workflow of [release, testRelease]) {
expect(workflow).toContain("Package signed macOS desktop DMG/ZIP");
expect(workflow).toContain("Package unsigned macOS desktop DMG/ZIP");
expect(workflow).toContain("Verify signed and notarized macOS artifacts");
expect(workflow).toContain("secrets.APPLE_CERTIFICATE_BASE64");
expect(workflow).toContain("secrets.APPLE_CERTIFICATE_PASSWORD");
expect(workflow).toContain("secrets.APPLE_ID");
expect(workflow).toContain("secrets.APPLE_TEAM_ID");
expect(workflow).toContain("secrets.APPLE_APP_PASSWORD");
expect(workflow).toContain("CSC_LINK:");
expect(workflow).toContain("CSC_KEY_PASSWORD:");
expect(workflow).toContain("APPLE_APP_SPECIFIC_PASSWORD:");
expect(workflow).toContain("APPLE_TEAM_ID:");
expect(workflow).toContain("APPLE_CERTIFICATE_BASE64 != ''");
expect(workflow).toContain("APPLE_CERTIFICATE_BASE64 == ''");
expect(workflow).toContain("codesign --verify");
expect(workflow).toContain("spctl --assess");
expect(workflow).toContain("xcrun stapler validate");
expect(workflow).toContain("-c.mac.notarize=false");
}
});
});
describe("desktop linux signing wiring", () => {
it("wires Linux GPG secret-guarded signing and asc uploads in both workflows", async () => {
const release = await readRepoFile(".github/workflows/release.yml");