Skip to content

Commit 9716df2

Browse files
unity-xcode-builder@v1.3.3 (#21)
- fix applying entitlements to app bundles on sign step - verify signed entitlements for app bundles
1 parent 51ddcc0 commit 9716df2

File tree

6 files changed

+139
-6
lines changed

6 files changed

+139
-6
lines changed

dist/index.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58316,6 +58316,7 @@ exports.XcodeProject = XcodeProject;
5831658316

5831758317
Object.defineProperty(exports, "__esModule", ({ value: true }));
5831858318
exports.log = log;
58319+
exports.DeepEqual = DeepEqual;
5831958320
const core = __nccwpck_require__(2186);
5832058321
function log(message, type = 'info') {
5832158322
if (type == 'info' && !core.isDebug()) {
@@ -58345,6 +58346,36 @@ function log(message, type = 'info') {
5834558346
}
5834658347
}
5834758348
}
58349+
function DeepEqual(a, b) {
58350+
if (a === b)
58351+
return true;
58352+
if (typeof a !== typeof b)
58353+
return false;
58354+
if (typeof a !== 'object' || a === null || b === null)
58355+
return false;
58356+
if (Array.isArray(a) !== Array.isArray(b))
58357+
return false;
58358+
if (Array.isArray(a)) {
58359+
if (a.length !== b.length)
58360+
return false;
58361+
for (let i = 0; i < a.length; i++) {
58362+
if (!DeepEqual(a[i], b[i]))
58363+
return false;
58364+
}
58365+
return true;
58366+
}
58367+
const keysA = Object.keys(a);
58368+
const keysB = Object.keys(b);
58369+
if (keysA.length !== keysB.length)
58370+
return false;
58371+
for (const key of keysA) {
58372+
if (!keysB.includes(key))
58373+
return false;
58374+
if (!DeepEqual(a[key], b[key]))
58375+
return false;
58376+
}
58377+
return true;
58378+
}
5834858379

5834958380

5835058381
/***/ }),
@@ -58906,13 +58937,25 @@ async function signMacOSAppBundle(projectRef) {
5890658937
if (!developerIdApplicationSigningIdentity) {
5890758938
throw new Error(`Failed to find the Developer ID Application signing identity!`);
5890858939
}
58940+
if (projectRef.entitlementsPath) {
58941+
if (projectRef.entitlementsPath.trim().length === 0) {
58942+
throw new Error(`Entitlements path is empty!`);
58943+
}
58944+
if (!fs.existsSync(projectRef.entitlementsPath)) {
58945+
throw new Error(`Entitlements file not found at: ${projectRef.entitlementsPath}`);
58946+
}
58947+
}
58948+
else {
58949+
throw new Error(`Entitlements path is not set! Please provide a valid entitlements plist file.`);
58950+
}
5890958951
const codesignArgs = [
5891058952
'--force',
5891158953
'--verify',
5891258954
'--timestamp',
5891358955
'--options', 'runtime',
5891458956
'--keychain', projectRef.credential.keychainPath,
5891558957
'--sign', developerIdApplicationSigningIdentity,
58958+
'--entitlements', projectRef.entitlementsPath,
5891658959
];
5891758960
if (core.isDebug()) {
5891858961
codesignArgs.unshift('--verbose');
@@ -58944,6 +58987,32 @@ async function signMacOSAppBundle(projectRef) {
5894458987
if (verifyExitCode !== 0) {
5894558988
throw new Error('App bundle codesign verification failed!');
5894658989
}
58990+
let entitlementsOutput = '';
58991+
const entitlementsExitCode = await (0, exec_1.exec)('codesign', [
58992+
'--display',
58993+
'--entitlements', '-', '--xml',
58994+
appPath
58995+
], {
58996+
listeners: {
58997+
stdout: (data) => {
58998+
entitlementsOutput += data.toString();
58999+
}
59000+
},
59001+
ignoreReturnCode: true
59002+
});
59003+
if (entitlementsExitCode !== 0) {
59004+
(0, utilities_1.log)(entitlementsOutput, 'error');
59005+
throw new Error('Failed to display signed entitlements!');
59006+
}
59007+
const expectedEntitlementsContent = await fs.promises.readFile(projectRef.entitlementsPath, 'utf8');
59008+
const expectedEntitlements = plist.parse(expectedEntitlementsContent);
59009+
if (!entitlementsOutput.trim()) {
59010+
throw new Error('Signed entitlements output is empty!');
59011+
}
59012+
const signedEntitlements = plist.parse(entitlementsOutput);
59013+
if (!(0, utilities_1.DeepEqual)(expectedEntitlements, signedEntitlements)) {
59014+
throw new Error('Signed entitlements do not match the expected entitlements!');
59015+
}
5894759016
}
5894859017
async function createMacOSInstallerPkg(projectRef) {
5894959018
core.info('Creating macOS installer pkg...');

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "unity-xcode-builder",
3-
"version": "1.3.2",
3+
"version": "1.3.3",
44
"description": "A GitHub Action to build, archive, and upload Unity exported xcode projects.",
55
"author": "buildalon",
66
"license": "MIT",

src/utilities.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,27 @@ export function log(message: string, type: 'info' | 'warning' | 'error' = 'info'
2626
}
2727
}
2828
}
29+
30+
export function DeepEqual(a: any, b: any): boolean {
31+
if (a === b) return true;
32+
if (typeof a !== typeof b) return false;
33+
if (typeof a !== 'object' || a === null || b === null) return false;
34+
if (Array.isArray(a) !== Array.isArray(b)) return false;
35+
36+
if (Array.isArray(a)) {
37+
if (a.length !== b.length) return false;
38+
for (let i = 0; i < a.length; i++) {
39+
if (!DeepEqual(a[i], b[i])) return false;
40+
}
41+
return true;
42+
}
43+
44+
const keysA = Object.keys(a);
45+
const keysB = Object.keys(b);
46+
if (keysA.length !== keysB.length) return false;
47+
for (const key of keysA) {
48+
if (!keysB.includes(key)) return false;
49+
if (!DeepEqual(a[key], b[key])) return false;
50+
}
51+
return true;
52+
}

src/xcode.ts

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import plist = require('plist');
77
import path = require('path');
88
import fs = require('fs');
99
import semver = require('semver');
10-
import { log } from './utilities';
10+
import {
11+
DeepEqual,
12+
log
13+
} from './utilities';
1114
import { SemVer } from 'semver';
1215
import core = require('@actions/core');
1316
import {
@@ -560,13 +563,24 @@ async function signMacOSAppBundle(projectRef: XcodeProject): Promise<void> {
560563
if (!developerIdApplicationSigningIdentity) {
561564
throw new Error(`Failed to find the Developer ID Application signing identity!`);
562565
}
566+
if (projectRef.entitlementsPath) {
567+
if (projectRef.entitlementsPath.trim().length === 0) {
568+
throw new Error(`Entitlements path is empty!`);
569+
}
570+
if (!fs.existsSync(projectRef.entitlementsPath)) {
571+
throw new Error(`Entitlements file not found at: ${projectRef.entitlementsPath}`);
572+
}
573+
} else {
574+
throw new Error(`Entitlements path is not set! Please provide a valid entitlements plist file.`);
575+
}
563576
const codesignArgs = [
564577
'--force',
565578
'--verify',
566579
'--timestamp',
567580
'--options', 'runtime',
568581
'--keychain', projectRef.credential.keychainPath,
569582
'--sign', developerIdApplicationSigningIdentity,
583+
'--entitlements', projectRef.entitlementsPath,
570584
];
571585
if (core.isDebug()) {
572586
codesignArgs.unshift('--verbose');
@@ -598,6 +612,32 @@ async function signMacOSAppBundle(projectRef: XcodeProject): Promise<void> {
598612
if (verifyExitCode !== 0) {
599613
throw new Error('App bundle codesign verification failed!');
600614
}
615+
let entitlementsOutput = '';
616+
const entitlementsExitCode = await exec('codesign', [
617+
'--display',
618+
'--entitlements', '-', '--xml',
619+
appPath
620+
], {
621+
listeners: {
622+
stdout: (data: Buffer) => {
623+
entitlementsOutput += data.toString();
624+
}
625+
},
626+
ignoreReturnCode: true
627+
});
628+
if (entitlementsExitCode !== 0) {
629+
log(entitlementsOutput, 'error');
630+
throw new Error('Failed to display signed entitlements!');
631+
}
632+
const expectedEntitlementsContent = await fs.promises.readFile(projectRef.entitlementsPath, 'utf8');
633+
const expectedEntitlements = plist.parse(expectedEntitlementsContent);
634+
if (!entitlementsOutput.trim()) {
635+
throw new Error('Signed entitlements output is empty!');
636+
}
637+
const signedEntitlements = plist.parse(entitlementsOutput);
638+
if (!DeepEqual(expectedEntitlements, signedEntitlements)) {
639+
throw new Error('Signed entitlements do not match the expected entitlements!');
640+
}
601641
}
602642

603643
async function createMacOSInstallerPkg(projectRef: XcodeProject): Promise<string> {
@@ -1110,4 +1150,4 @@ async function execGit(args: string[]): Promise<string> {
11101150
throw new Error(`Git failed with exit code: ${exitCode}`);
11111151
}
11121152
return output;
1113-
}
1153+
}

0 commit comments

Comments
 (0)