add test to verify binaries are signed on release branches (#50074)
diff --git a/.cirrus.yml b/.cirrus.yml
index 5436a5d..6f444cf 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -652,6 +652,15 @@
- ulimit -S -n 2048 # https://github.com/flutter/flutter/issues/2976
- ./dev/bots/deploy_gallery.sh
+ - name: verify_binaries_codesigned-macos # macos-only
+ # TODO(fujino): remove this `only_if` after https://github.com/flutter/flutter/issues/44372
+ only_if: "$CIRRUS_BRANCH == 'dev' || $CIRRUS_BRANCH == 'beta' || $CIRRUS_BRANCH == 'stable' || $CIRRUS_BRANCH =~ '.*hotfix.*'"
+ depends_on:
+ - analyze-linux
+ script:
+ - ulimit -S -n 2048 # https://github.com/flutter/flutter/issues/2976
+ - dart --enable-asserts ./dev/bots/codesign.dart
+
docker_builder:
# Only build a new docker image when we tag a release (for dev, beta, or
# stable). Note: tagging a commit and pushing to a release branch are
diff --git a/dev/bots/codesign.dart b/dev/bots/codesign.dart
new file mode 100644
index 0000000..129d5ab
--- /dev/null
+++ b/dev/bots/codesign.dart
@@ -0,0 +1,67 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:io';
+import 'package:path/path.dart' as path;
+
+String get cacheDirectory {
+ final String flutterRepoRoot = path.normalize(path.join(path.dirname(Platform.script.path), '..', '..'));
+ return path.normalize(path.join(flutterRepoRoot, 'bin', 'cache'));
+}
+
+bool isBinary(String filePath) {
+ final ProcessResult result = Process.runSync(
+ 'file',
+ <String>[
+ '--mime-type',
+ '-b', // is binary
+ filePath,
+ ],
+ );
+ return (result.stdout as String).contains('application/x-mach-binary');
+}
+
+List<String> findBinaryPaths() {
+ final ProcessResult result = Process.runSync(
+ 'find',
+ <String>[
+ cacheDirectory,
+ '-type',
+ 'f',
+ '-perm',
+ '+111', // is executable
+ ],
+ );
+ final List<String> allFiles = (result.stdout as String).split('\n').where((String s) => s.isNotEmpty).toList();
+ return allFiles.where(isBinary).toList();
+}
+
+void main() {
+ final List<String> failures = <String>[];
+
+ for (final String binaryPath in findBinaryPaths()) {
+ print('Verifying the code signature of $binaryPath');
+ final ProcessResult result = Process.runSync(
+ 'codesign',
+ <String>[
+ '-vvv',
+ binaryPath,
+ ],
+ );
+ if (result.exitCode != 0) {
+ failures.add(binaryPath);
+ print('File "$binaryPath" does not appear to be codesigned.\n'
+ 'The `codesign` command failed with exit code ${result.exitCode}:\n'
+ '${result.stderr}\n');
+ }
+ }
+
+ if (failures.isNotEmpty) {
+ print('Found ${failures.length} unsigned binaries.');
+ failures.forEach(print);
+ exit(1);
+ }
+
+ print('Verified that binaries are codesigned.');
+}