feat(KAN-65): add signed macOS updates and DMG distribution
CI/CD / preconditions (pull_request) Successful in 2s
Native JavaScript checks / Native launcher and release tests (pull_request) Successful in 1m0s
CI/CD / test_and_check_app (pull_request) Successful in 7m2s
CI/CD / Publish immutable image (pull_request) Skipped
macOS checks / Native Rust tests and unsigned build (pull_request) Successful in 1m35s

This commit is contained in:
2026-09-27 21:40:23 +02:00
parent 3e5c316b8f
commit 20f9314659
28 changed files with 2454 additions and 130 deletions
+34 -8
View File
@@ -40,6 +40,7 @@ function fixture(t, overrides = {}) {
arch: 'arm64',
log() {},
env: {
TAURI_SIGNING_PRIVATE_KEY: 'test-private-key',
APPLE_SIGNING_IDENTITY: identity,
APPLE_NOTARY_KEYCHAIN_PROFILE: 'kanbangit-notary',
},
@@ -57,7 +58,11 @@ function fixture(t, overrides = {}) {
);
}
if (command === 'pnpm' && !overrides.missingApp) {
if (
command === 'pnpm' &&
args.includes('build') &&
!overrides.missingApp
) {
const target = args[args.indexOf('--target') + 1];
mkdirSync(
join(
@@ -137,7 +142,16 @@ function fixture(t, overrides = {}) {
stapled = true;
}
if (command === 'ditto') {
if (command === 'pnpm' && args.includes('signer')) {
writeFileSync(`${args.at(-1)}.sig`, 'signature');
}
if (command === 'tar') {
writeFileSync(args[1], 'updater with stapled ticket');
}
if (
(command === 'hdiutil' && args[0] === 'create') ||
command === 'ditto'
) {
writeFileSync(
args.at(-1),
stapled
@@ -171,11 +185,14 @@ test('publishes only the stapled app archive with its exact SHA-256 checksum aft
);
assert.equal(
readFileSync(`${result.archive}.sha256`, 'utf8'),
`${result.checksum} KanbanGit-1.2.3-aarch64-apple-darwin.zip\n`,
`${result.checksum} KanbanGit-1.2.3-aarch64-apple-darwin.dmg\n`,
);
assert.deepEqual(readdirSync(f.destination).sort(), [
'KanbanGit-1.2.3-aarch64-apple-darwin.zip',
'KanbanGit-1.2.3-aarch64-apple-darwin.zip.sha256',
'KanbanGit-1.2.3-aarch64-apple-darwin.app.tar.gz',
'KanbanGit-1.2.3-aarch64-apple-darwin.app.tar.gz.sha256',
'KanbanGit-1.2.3-aarch64-apple-darwin.app.tar.gz.sig',
'KanbanGit-1.2.3-aarch64-apple-darwin.dmg',
'KanbanGit-1.2.3-aarch64-apple-darwin.dmg.sha256',
]);
assert.deepEqual(readdirSync(f.releaseDirectory), [
'1.2.3-aarch64-apple-darwin',
@@ -195,6 +212,11 @@ test('publishes only the stapled app archive with its exact SHA-256 checksum aft
});
for (const [name, env, expected] of [
[
'missing updater signing key',
{ TAURI_SIGNING_PRIVATE_KEY: '' },
/TAURI_SIGNING_PRIVATE_KEY/,
],
[
'missing identity',
{ APPLE_SIGNING_IDENTITY: '' },
@@ -343,7 +365,7 @@ test('supports an explicit Intel target with distinct output naming', (t) => {
assert.equal(result.target, 'x86_64-apple-darwin');
assert.match(
result.archive,
/1\.2\.3-x86_64-apple-darwin\/KanbanGit-1\.2\.3-x86_64-apple-darwin\.zip$/,
/1\.2\.3-x86_64-apple-darwin\/KanbanGit-1\.2\.3-x86_64-apple-darwin\.dmg$/,
);
});
@@ -454,7 +476,9 @@ test('persists submission ID on timeout and resumes the same app without rebuild
);
assert.equal(
f.calls.some(
(call) => call.command === 'pnpm' || call.args[1] === 'submit',
(call) =>
(call.command === 'pnpm' && call.args.includes('build')) ||
call.args[1] === 'submit',
),
false,
);
@@ -481,7 +505,9 @@ test('resume never rebuilds a missing previously submitted app', (t) => {
);
assert.equal(
f.calls.some(
(call) => call.command === 'pnpm' || call.args[1] === 'submit',
(call) =>
(call.command === 'pnpm' && call.args.includes('build')) ||
call.args[1] === 'submit',
),
false,
);