blob: 84bdbd42ab49e32990d60a3e18ff110e4f910680 [file] [log] [blame]
// Copyright 2019 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:args/args.dart';
import 'package:codesign/codesign.dart';
import 'package:file/file.dart';
import 'package:file/local.dart';
import 'package:platform/platform.dart';
import 'package:process/process.dart';
/// Definitions of variables are included in help texts below.
const String kHelpFlag = 'help';
const String kCommitOption = 'commit';
const String kProductionFlag = 'production';
const String kCodesignCertNameOption = 'codesign-cert-name';
const String kCodesignUserNameOption = 'codesign-username';
const String kAppSpecificPasswordOption = 'app-specific-password';
const String kCodesignAppStoreIdOption = 'codesign-appstore-id';
const String kCodesignTeamIdOption = 'codesign-team-id';
const String kCodesignFilepathOption = 'filepath';
/// Perform Mac code signing based on file paths.
///
/// If [kProductionFlag] is set to true, code signed artifacts will be uploaded
/// back to google cloud storage.
/// Otherwise, nothing will be uploaded back for production. default value is
/// false.
///
/// For [kCommitOption], provides the engine commit to be code signed.
///
/// For [kCodesignFilepathOption], provides the artifacts zip paths to be code signed.
///
/// Usage:
/// ```shell
/// dart run bin/main.dart --commit=$commitSha
/// --filepath=darwin-x64/FlutterMacOS.framework.zip --filepath=ios/artifacts.zip
/// --filepath=dart-sdk-darwin-arm64.zip
/// ( add `--production` if this is intended for production)
/// ```
Future<void> main(List<String> args) async {
final ArgParser parser = ArgParser();
parser
..addFlag(kHelpFlag, help: 'Prints usage info.', callback: (bool value) {
if (value) {
stdout.write('${parser.usage}\n');
exit(1);
}
})
..addOption(
kCodesignCertNameOption,
help: 'The name of the codesign certificate to be used when codesigning.'
'the name of the certificate for flutter, for example, is: FLUTTER.IO LLC',
)
..addOption(
kAppSpecificPasswordOption,
help: 'Unique password specifically for codesigning the given application.',
)
..addOption(
kCodesignAppStoreIdOption,
help: 'Apple developer account email used for authentication with notary service.',
)
..addOption(
kCodesignTeamIdOption,
help: 'Team-id is used by notary service for xcode version 13+.',
)
..addOption(
kCommitOption,
help: 'the Flutter engine commit revision for which Google Cloud Storage binary artifacts should be codesigned.',
)
..addMultiOption(
kCodesignFilepathOption,
help: 'The zip file paths to be codesigned. Pass this option multiple'
'times to codesign multiple zip files',
valueHelp: 'darwin-x64/font-subset.zip',
)
..addFlag(
kProductionFlag,
help: 'whether we are going to upload the artifacts back to GCS for production',
);
final ArgResults argResults = parser.parse(args);
const Platform platform = LocalPlatform();
final String commit = getValueFromEnvOrArgs(kCommitOption, argResults, platform.environment)!;
final String codesignCertName = getValueFromEnvOrArgs(kCodesignCertNameOption, argResults, platform.environment)!;
final String codesignUserName = getValueFromEnvOrArgs(kCodesignUserNameOption, argResults, platform.environment)!;
final String appSpecificPassword =
getValueFromEnvOrArgs(kAppSpecificPasswordOption, argResults, platform.environment)!;
final String codesignAppstoreId = getValueFromEnvOrArgs(kCodesignAppStoreIdOption, argResults, platform.environment)!;
final String codesignTeamId = getValueFromEnvOrArgs(kCodesignTeamIdOption, argResults, platform.environment)!;
final List<String> codesignFilepaths = argResults[kCodesignFilepathOption]! as List<String>;
final bool production = argResults[kProductionFlag] as bool;
if (!platform.isMacOS) {
throw CodesignException(
'Error! Expected operating system "macos", actual operating system is: '
'"${platform.operatingSystem}"',
);
}
const FileSystem fileSystem = LocalFileSystem();
final Directory tempDir = fileSystem.systemTempDirectory.createTempSync('conductor_codesign');
const ProcessManager processManager = LocalProcessManager();
return FileCodesignVisitor(
codesignCertName: codesignCertName,
codesignUserName: codesignUserName,
commitHash: commit,
appSpecificPassword: appSpecificPassword,
codesignAppstoreId: codesignAppstoreId,
codesignTeamId: codesignTeamId,
codesignFilepaths: codesignFilepaths,
fileSystem: fileSystem,
tempDir: tempDir,
processManager: processManager,
production: production,
).validateAll();
}