Hotfix 8 - sign binaries and increase minimum Xcode version to 11 (#50291)

This commit is contained in:
Christopher Fujino 2020-02-10 09:59:22 -08:00 committed by GitHub
parent 9f5ff2306b
commit afb2006496
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 144 additions and 19 deletions

View File

@ -19,6 +19,7 @@ environment:
# TODO(amirha): remove once we've migrated to newer Gradle
CIRRUS_CHANGE_MESSAGE: ""
CIRRUS_COMMIT_MESSAGE: ""
FLUTTER_TESTS_PIN_HASH: 'f73542b1dcf6866948ca13d4f61c3557c7c3d4ad'
# LINUX SHARDS
task:
@ -283,6 +284,8 @@ task:
script:
- rm -rf bin/cache/pkg/tests
- git clone https://github.com/flutter/tests.git bin/cache/pkg/tests
# Hotfix only, this pins the flutter/tests repo
- (cd bin/cache/pkg/tests ; git checkout "$FLUTTER_TESTS_PIN_HASH")
- dart --enable-asserts dev/customer_testing/run_tests.dart --skip-on-fetch-failure --skip-template bin/cache/pkg/tests/registry/*.test
- name: firebase_test_lab_tests-linux # linux-only
@ -425,6 +428,8 @@ task:
script:
- CMD /S /C "IF EXIST "bin\cache\pkg\tests\" RMDIR /S /Q bin\cache\pkg\tests"
- git clone https://github.com/flutter/tests.git bin\cache\pkg\tests
# Hotfix only, this pins the flutter/tests repo
- CMD /S /C "CD bin\cache\pkg\tests & git checkout "%FLUTTER_TESTS_PIN_HASH%""
- dart --enable-asserts dev\customer_testing\run_tests.dart --skip-on-fetch-failure --skip-template bin/cache/pkg/tests/registry/*.test
# MACOS SHARDS
@ -548,6 +553,8 @@ task:
- ulimit -S -n 2048 # https://github.com/flutter/flutter/issues/2976
- rm -rf bin/cache/pkg/tests
- git clone https://github.com/flutter/tests.git bin/cache/pkg/tests
# Hotfix only, this pins the flutter/tests repo
- (cd bin/cache/pkg/tests ; git checkout "$FLUTTER_TESTS_PIN_HASH")
- dart --enable-asserts dev/customer_testing/run_tests.dart --skip-on-fetch-failure --skip-template bin/cache/pkg/tests/registry/*.test
- name: deploy_gallery-macos # linux- and macos- only
@ -577,6 +584,15 @@ task:
- 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

View File

@ -1 +1 @@
a67792536ca236a971d0efbcfd7af4efb8f6c119
e1e6ced81d029258d449bdec2ba3cddca9c2ca0c

105
dev/bots/codesign.dart Normal file
View File

@ -0,0 +1,105 @@
// 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 repoRoot => path.normalize(path.join(path.dirname(Platform.script.toFilePath()), '..', '..'));
String get cacheDirectory => path.normalize(path.join(repoRoot, 'bin', 'cache'));
/// Check mime-type of file at [filePath] to determine if it is binary
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');
}
/// Find every binary file in the given [rootDirectory]
List<String> findBinaryPaths([String rootDirectory]) {
rootDirectory ??= cacheDirectory;
final ProcessResult result = Process.runSync(
'find',
<String>[
rootDirectory,
'-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();
}
/// Given the path to a stamp file, read the contents.
///
/// Will throw if the file doesn't exist.
String readStamp(String filePath) {
final File file = File(filePath);
if (!file.existsSync()) {
throw 'Error! Stamp file $filePath does not exist!';
}
return file.readAsStringSync().trim();
}
/// Return whether or not the flutter cache is up to date.
bool checkCacheIsCurrent() {
try {
final String dartSdkStamp = readStamp(path.join(cacheDirectory, 'engine-dart-sdk.stamp'));
final String engineVersion = readStamp(path.join(repoRoot, 'bin', 'internal', 'engine.version'));
return dartSdkStamp == engineVersion;
} catch (e) {
print(e);
return false;
}
}
void main() {
final List<String> failures = <String>[];
if (!Platform.isMacOS) {
print('Error! Expected operating system "macos", actual operating system '
'is: "${Platform.operatingSystem}"');
exit(1);
}
if (!checkCacheIsCurrent()) {
print(
'Warning! Your cache is either not present or not matching your flutter\n'
'version. Run a `flutter` command to update your cache, and re-try this\n'
'test.');
exit(1);
}
for (final String binaryPath in findBinaryPaths(cacheDirectory)) {
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.');
}

View File

@ -12,8 +12,8 @@ import '../base/platform.dart';
import '../base/process.dart';
import '../ios/xcodeproj.dart';
const int kXcodeRequiredVersionMajor = 10;
const int kXcodeRequiredVersionMinor = 2;
const int kXcodeRequiredVersionMajor = 11;
const int kXcodeRequiredVersionMinor = 0;
Xcode get xcode => context.get<Xcode>();

View File

@ -79,8 +79,8 @@ void main() {
testUsingOsxContext('majorVersion returns major version', () {
when(mockProcessManager.runSync(<String>[xcodebuild, '-version']))
.thenReturn(ProcessResult(1, 0, 'Xcode 10.3.3\nBuild version 8E3004b', ''));
expect(xcodeProjectInterpreter.majorVersion, 10);
.thenReturn(ProcessResult(1, 0, 'Xcode 11.4.3\nBuild version 11N111s', ''));
expect(xcodeProjectInterpreter.majorVersion, 11);
});
testUsingOsxContext('majorVersion is null when version has unexpected format', () {

View File

@ -68,8 +68,9 @@ void main() {
testUsingContext('xcodeVersionSatisfactory is true when version meets minimum', () {
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(10);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(2);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(11);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
expect(xcode.isVersionSatisfactory, isTrue);
}, overrides: <Type, Generator>{
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
@ -77,8 +78,9 @@ void main() {
testUsingContext('xcodeVersionSatisfactory is true when major version exceeds minimum', () {
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(11);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(2);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(12);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
expect(xcode.isVersionSatisfactory, isTrue);
}, overrides: <Type, Generator>{
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
@ -86,7 +88,7 @@ void main() {
testUsingContext('xcodeVersionSatisfactory is true when minor version exceeds minimum', () {
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(10);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(11);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(3);
expect(xcode.isVersionSatisfactory, isTrue);
}, overrides: <Type, Generator>{
@ -123,8 +125,8 @@ void main() {
.thenReturn(ProcessResult(1, 127, '', 'ERROR'));
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(10);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(2);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(11);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
expect(xcode.isInstalledAndMeetsVersionCheck, isFalse);
}, overrides: <Type, Generator>{
@ -141,8 +143,9 @@ void main() {
.thenReturn(ProcessResult(1, 0, xcodePath, ''));
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(9);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(10);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(2);
expect(xcode.isInstalledAndMeetsVersionCheck, isFalse);
}, overrides: <Type, Generator>{
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
@ -158,8 +161,9 @@ void main() {
.thenReturn(ProcessResult(1, 0, xcodePath, ''));
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(10);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(2);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(11);
when(mockXcodeProjectInterpreter.minorVersion).thenReturn(0);
expect(xcode.isInstalledAndMeetsVersionCheck, isTrue);
}, overrides: <Type, Generator>{
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,

View File

@ -349,13 +349,13 @@ class FakeXcodeProjectInterpreter implements XcodeProjectInterpreter {
bool get isInstalled => true;
@override
String get versionText => 'Xcode 10.2';
String get versionText => 'Xcode 11.0';
@override
int get majorVersion => 10;
int get majorVersion => 11;
@override
int get minorVersion => 2;
int get minorVersion => 0;
@override
Future<Map<String, String>> getBuildSettings(