Skip to content

Commit 39bb7a5

Browse files
committed
iOS,macOS: Skip codesigning files in unsigned_binaries.txt
This updates the code-signing workflow to account for iOS and macOS binaries in the artifact cache that are _expected_ to not be codesigned. In flutter/engine#54414 we started bundling dSYM (debugging symbols) within Flutter.xcframework, a requirement for App Store verification using Xcode 16. We did the same for macOS in flutter/engine#54696. Unlike the framework dylib, dSYM contents are not directly codesigned (though the xcframework containing them is). This skips code-signing for files found in `unsigned_binaries.txt`, which will be added in a followup patch to the framework artifact archive creation scripts in engine: * `sky/tools/create_ios_framework.py` * `sky/tools/create_macos_framework.py` Issue: flutter/flutter#154571
1 parent 8f96724 commit 39bb7a5

File tree

2 files changed

+62
-28
lines changed

2 files changed

+62
-28
lines changed

cipd_packages/codesign/lib/src/file_codesign_visitor.dart

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ enum CodesignType {
2929
withEntitlements(filename: 'entitlements.txt'),
3030

3131
/// Binaries requiring codesigning that DO NOT use APIs requiring entitlements.
32-
withoutEntitlements(filename: 'without_entitlements.txt');
32+
withoutEntitlements(filename: 'without_entitlements.txt'),
33+
34+
/// Binaries that do not require codesigning.
35+
unsigned(filename: 'unsigned_binaries.txt');
3336

3437
const CodesignType({required this.filename});
3538

@@ -87,6 +90,9 @@ class FileCodesignVisitor {
8790

8891
/// Files that require codesigning that DO NOT use APIs requiring entitlements.
8992
Set<String> withoutEntitlementsFiles = <String>{};
93+
94+
/// Files that do not require codesigning.
95+
Set<String> unsignedBinaryFiles = <String>{};
9096
Set<String> fileConsumed = <String>{};
9197
Set<String> directoriesVisited = <String>{};
9298
Map<String, String> availablePasswords = {
@@ -124,26 +130,30 @@ class FileCodesignVisitor {
124130
static final RegExp _notarytoolStatusCheckPattern = RegExp(r'[ ]*status: ([a-zA-z ]+)');
125131
static final RegExp _notarytoolRequestPattern = RegExp(r'id: ([a-z0-9-]+)');
126132

127-
static const String fixItInstructions = '''
133+
static final String fixItInstructions = '''
128134
Codesign test failed.
129135
130136
We compared binary files in engine artifacts with those listed in
131-
entitlement.txt and withoutEntitlements.txt, and the binary files do not match.
132-
*entitlements.txt is the configuration file encoded in engine artifact zip,
133-
built by BUILD.gn and Ninja, to detail the list of entitlement files.
134-
Either an expected file was not found in *entitlements.txt, or an unexpected
135-
file was found in entitlements.txt.
137+
* ${CodesignType.withEntitlements.filename}
138+
* ${CodesignType.withoutEntitlements.filename}
139+
* ${CodesignType.unsigned.filename}
140+
and the binary files do not match.
141+
142+
These are the configuration files encoded in engine artifact zip that detail
143+
the code-signing requirements of each of the binaries in the archive.
144+
Either an unexpected binary was listed in these files, or one of the expected
145+
binaries listed in these files was not found in the archive.
136146
137147
This usually happens during an engine roll.
138-
If this is a valid change, then BUILD.gn needs to be changed.
139-
Binaries that will run on a macOS host require entitlements, and
140-
binaries that run on an iOS device must NOT have entitlements.
148+
149+
If this is a valid change, then the BUILD.gn or the codesigning configuration
150+
files need to be changed. Binaries that will run on a macOS host require
151+
entitlements, and binaries that run on an iOS device must NOT have entitlements.
141152
For example, if this is a new binary that runs on macOS host, add it
142-
to [entitlements.txt] file inside the zip artifact produced by BUILD.gn.
143-
If this is a new binary that needs to be run on iOS device, add it
144-
to [withoutEntitlements.txt].
145-
If there are obsolete binaries in entitlements configuration files, please delete or
146-
update these file paths accordingly.
153+
to ${CodesignType.withEntitlements.filename} file inside the zip artifact produced by BUILD.gn.
154+
If this is a new binary that needs to be run on iOS device, add it to
155+
${CodesignType.withoutEntitlements.filename}. If there are obsolete binaries in entitlements
156+
configuration files, please delete or update these file paths accordingly.
147157
''';
148158

149159
/// Read a single line of password stored at [passwordFilePath].
@@ -202,8 +212,10 @@ update these file paths accordingly.
202212
// Read codesigning configuration files.
203213
withEntitlementsFiles = await parseCodesignConfig(parentDirectory, CodesignType.withEntitlements);
204214
withoutEntitlementsFiles = await parseCodesignConfig(parentDirectory, CodesignType.withoutEntitlements);
215+
unsignedBinaryFiles = await parseCodesignConfig(parentDirectory, CodesignType.unsigned);
205216
log.info('parsed binaries with entitlements are $withEntitlementsFiles');
206217
log.info('parsed binaries without entitlements are $withoutEntitlementsFiles');
218+
log.info('parsed binaries without codesigning $unsignedBinaryFiles');
207219

208220
// recursively visit extracted files
209221
await visitDirectory(directory: parentDirectory, parentVirtualPath: '');
@@ -319,17 +331,23 @@ update these file paths accordingly.
319331
final String entitlementCurrentPath = joinEntitlementPaths(parentVirtualPath, currentFileName);
320332

321333
if (!withEntitlementsFiles.contains(entitlementCurrentPath) &&
322-
!withoutEntitlementsFiles.contains(entitlementCurrentPath)) {
323-
log.severe('the binary file $currentFileName is causing an issue. \n'
334+
!withoutEntitlementsFiles.contains(entitlementCurrentPath) &&
335+
!unsignedBinaryFiles.contains(entitlementCurrentPath)) {
336+
log.severe('The binary file $currentFileName is causing an issue. \n'
324337
'This file is located at $entitlementCurrentPath in the flutter engine artifact.');
325338
log.severe('The system has detected a binary file at $entitlementCurrentPath. '
326-
'But it is not in the entitlements configuration files you provided. '
339+
'But it is not in the codesigning configuration files you provided. '
327340
'If this is a new engine artifact, please add it to one of the entitlements.txt files.');
328341
throw CodesignException(fixItInstructions);
329342
}
330-
log.info('signing file at path ${binaryFile.absolute.path}');
331-
log.info('the virtual entitlement path associated with file is $entitlementCurrentPath');
332-
log.info('the decision to sign with entitlement is ${withEntitlementsFiles.contains(entitlementCurrentPath)}');
343+
if (unsignedBinaryFiles.contains(entitlementCurrentPath)) {
344+
// No codesigning necessary.
345+
log.info('Not signing file at path ${binaryFile.absolute.path}');
346+
return;
347+
}
348+
log.info('Signing file at path ${binaryFile.absolute.path}');
349+
log.info('The virtual entitlement path associated with file is $entitlementCurrentPath');
350+
log.info('The decision to sign with entitlement is ${withEntitlementsFiles.contains(entitlementCurrentPath)}');
333351
fileConsumed.add(entitlementCurrentPath);
334352
if (dryrun) {
335353
return;

cipd_packages/codesign/test/file_codesign_visitor_test.dart

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -662,9 +662,11 @@ void main() {
662662
codesignVisitor.codesignTeamId = randomString;
663663
codesignVisitor.withEntitlementsFiles = <String>{'root/folder_a/file_a'};
664664
codesignVisitor.withoutEntitlementsFiles = <String>{'root/folder_b/file_b'};
665+
codesignVisitor.unsignedBinaryFiles = <String>{'root/folder_c/file_c'};
665666
fileSystem
666667
..file('${rootDirectory.path}/remote_zip_6/folder_a/file_a').createSync(recursive: true)
667-
..file('${rootDirectory.path}/remote_zip_6/folder_b/file_b').createSync(recursive: true);
668+
..file('${rootDirectory.path}/remote_zip_6/folder_b/file_b').createSync(recursive: true)
669+
..file('${rootDirectory.path}/remote_zip_6/folder_c/file_c').createSync(recursive: true);
668670
final Directory testDirectory = fileSystem.directory('${rootDirectory.path}/remote_zip_6');
669671
processManager.addCommands(<FakeCommand>[
670672
FakeCommand(
@@ -713,6 +715,15 @@ void main() {
713715
'--options=runtime',
714716
],
715717
),
718+
FakeCommand(
719+
command: <String>[
720+
'file',
721+
'--mime-type',
722+
'-b',
723+
'${rootDirectory.absolute.path}/remote_zip_6/folder_c/file_c',
724+
],
725+
stdout: 'application/x-mach-binary',
726+
),
716727
]);
717728
await codesignVisitor.visitDirectory(
718729
directory: testDirectory,
@@ -722,13 +733,18 @@ void main() {
722733
.where((LogRecord record) => record.level == Level.INFO)
723734
.map((LogRecord record) => record.message)
724735
.toList();
725-
expect(messages, contains('signing file at path ${rootDirectory.absolute.path}/remote_zip_6/folder_a/file_a'));
726-
expect(messages, contains('the virtual entitlement path associated with file is root/folder_a/file_a'));
727-
expect(messages, contains('the decision to sign with entitlement is true'));
736+
expect(messages, contains('Signing file at path ${rootDirectory.absolute.path}/remote_zip_6/folder_a/file_a'));
737+
expect(messages, contains('The virtual entitlement path associated with file is root/folder_a/file_a'));
738+
expect(messages, contains('The decision to sign with entitlement is true'));
739+
740+
expect(messages, contains('Signing file at path ${rootDirectory.absolute.path}/remote_zip_6/folder_b/file_b'));
741+
expect(messages, contains('The virtual entitlement path associated with file is root/folder_b/file_b'));
742+
expect(messages, contains('The decision to sign with entitlement is false'));
728743

729-
expect(messages, contains('signing file at path ${rootDirectory.absolute.path}/remote_zip_6/folder_b/file_b'));
730-
expect(messages, contains('the virtual entitlement path associated with file is root/folder_b/file_b'));
731-
expect(messages, contains('the decision to sign with entitlement is false'));
744+
expect(
745+
messages,
746+
contains('Not signing file at path ${rootDirectory.absolute.path}/remote_zip_6/folder_c/file_c'),
747+
);
732748
});
733749
});
734750

0 commit comments

Comments
 (0)