buildAndroid function
Future<void>
buildAndroid(
- ExecContext context, {
- required String gh,
- required String appName,
- required int defaultIncrementNumber,
Gibhut Actions build for Android.
Android用のGibhut Actionsのビルド。
Implementation
Future<void> buildAndroid(
ExecContext context, {
required String gh,
required String appName,
required int defaultIncrementNumber,
}) async {
final github = context.yaml.getAsMap("github");
final action = github.getAsMap("action");
final android = action.getAsMap("android");
final changesNotSentForReview =
android.get("changes_not_sent_for_review", nullOfBool);
final status = android.get("status", "draft");
final secretGithub = context.secrets.getAsMap("github");
final slack = secretGithub.getAsMap("slack");
final slackIncomingWebhookUrl = slack.get("incoming_webhook_url", "");
final useEnvironment = AndroidSigningEnvironment.isConfigured();
if (!isLocalApply && !useEnvironment) {
final keystoreFile = File("android/app/appkey.keystore");
if (!keystoreFile.existsSync()) {
error(
"Cannot find `android/app/appkey.keystore`. Run `katana app keystore` to create the keystore file. `android/app/appkey.keystore`が見つかりません。`katana app keystore`を実行しキーストアのファイルを作成してください。",
);
return;
}
final keyPropertiesFile = File("android/key.properties");
if (!keyPropertiesFile.existsSync()) {
error(
"Cannot find `android/key.properties`. Run `katana app keystore` to create the keystore file. `android/key.properties`が見つかりません。`katana app keystore`を実行しキーストアのファイルを作成してください。",
);
return;
}
final serviceAccountFile = await find(
Directory("android"),
RegExp("([a-z0-9_-]+).json"),
recursive: false,
);
if (serviceAccountFile == null) {
error(
"Json for service account not found, please refer to https://mathru.notion.site/Google-Play-Developer-df655aff2dfb49988b82feb7aae3c61b to set it up. サービスアカウント用のJsonが見つかりません。https://mathru.notion.site/Google-Play-Developer-df655aff2dfb49988b82feb7aae3c61b を参考に設定してください。",
);
return;
}
}
if (!isLocalApply && useEnvironment) {
if (AndroidSigningEnvironment.value(
AndroidSigningEnvironment.serviceAccountVariable,
) ==
null &&
await find(
Directory("android"),
RegExp("([a-z0-9_-]+).json"),
recursive: false,
) ==
null) {
error(
"Json for service account not found. Set `${AndroidSigningEnvironment.serviceAccountVariable}` or place the json in `android/`. サービスアカウント用のJsonが見つかりません。`${AndroidSigningEnvironment.serviceAccountVariable}`を設定するか`android/`にJsonを配置してください。",
);
return;
}
}
final gradle = AppGradle();
await gradle.load();
final packageName = gradle.android?.defaultConfig.applicationId;
if (packageName == null) {
error(
"Cannot find [android]->[defaultConfig]->[applicationId] in `android/app/build.gradle`.",
);
return;
}
if (useEnvironment &&
!gradle.rawData.contains(AndroidSigningEnvironment.beginMarker)) {
error(
"The Gradle file does not read the keystore from environment variables. Set [app]->[keystore]->[enable] to `true` and run `katana apply`. Gradleファイルが環境変数からキーストアを読み込む設定になっていません。[app]->[keystore]->[enable]を`true`にして`katana apply`を実行してください。",
);
return;
}
final appSuffix = appName.toUpperCase();
if (!isLocalApply && useEnvironment) {
final keystore = _normalizeBase64(
AndroidSigningEnvironment.value(
AndroidSigningEnvironment.keystoreVariable,
)!,
AndroidSigningEnvironment.keystoreVariable,
);
final serviceAccountValue = AndroidSigningEnvironment.value(
AndroidSigningEnvironment.serviceAccountVariable,
);
final serviceAccount = serviceAccountValue != null
? _normalizeBase64(
serviceAccountValue,
AndroidSigningEnvironment.serviceAccountVariable,
)
: base64.encode(
await (await find(
Directory("android"),
RegExp("([a-z0-9_-]+).json"),
recursive: false,
))!
.readAsBytes(),
);
if (keystore == null || serviceAccount == null) {
return;
}
await githubSecret(
"Store `${AndroidSigningEnvironment.keystoreVariable}` in `secrets.ANDROID_KEYSTORE_B64_$appSuffix`.",
gh: gh,
name: "ANDROID_KEYSTORE_B64_$appSuffix",
value: keystore,
);
await githubSecret(
"Store `${AndroidSigningEnvironment.passwordVariable}` in `secrets.ANDROID_KEYSTORE_PASSWORD_$appSuffix`.",
gh: gh,
name: "ANDROID_KEYSTORE_PASSWORD_$appSuffix",
value: AndroidSigningEnvironment.value(
AndroidSigningEnvironment.passwordVariable,
)!,
);
final alias = AndroidSigningEnvironment.value(
AndroidSigningEnvironment.aliasVariable,
);
if (alias != null) {
await githubSecret(
"Store `${AndroidSigningEnvironment.aliasVariable}` in `secrets.ANDROID_KEYSTORE_ALIAS_$appSuffix`.",
gh: gh,
name: "ANDROID_KEYSTORE_ALIAS_$appSuffix",
value: alias,
);
}
await githubSecret(
"Store the service account key in `secrets.ANDROID_SERVICE_ACCOUNT_KEY_JSON_$appSuffix`.",
gh: gh,
name: "ANDROID_SERVICE_ACCOUNT_KEY_JSON_$appSuffix",
value: serviceAccount,
);
} else if (!isLocalApply) {
final keystoreFile = File("android/app/appkey.keystore");
final keyPropertiesFile = File("android/key.properties");
final serviceAccountFile = await find(
Directory("android"),
RegExp("([a-z0-9_-]+).json"),
recursive: false,
);
final keystore = base64.encode(await keystoreFile.readAsBytes());
final keyProperties = base64.encode(await keyPropertiesFile.readAsBytes());
final serviceAccount =
base64.encode(await serviceAccountFile!.readAsBytes());
await githubSecret(
"Store `appkey.keystore` in `secrets.ANDROID_KEYSTORE_$appSuffix`.",
gh: gh,
name: "ANDROID_KEYSTORE_$appSuffix",
value: keystore,
);
await githubSecret(
"Store `key.properties` in `secrets.ANDROID_KEY_PROPERTIES_$appSuffix`.",
gh: gh,
name: "ANDROID_KEY_PROPERTIES_$appSuffix",
value: keyProperties,
);
await githubSecret(
"Store `service_account.json` in `secrets.ANDROID_SERVICE_ACCOUNT_KEY_JSON_$appSuffix`.",
gh: gh,
name: "ANDROID_SERVICE_ACCOUNT_KEY_JSON_$appSuffix",
value: serviceAccount,
);
}
if (!isLocalApply) {
if (!await registerDartDefinesSecrets(
gh: gh,
path: kProductionDartDefinesFile,
suffix: appName.toUpperCase(),
)) {
return;
}
if (!await registerDartDefinesSecrets(
gh: gh,
path: kDevelopmentDartDefinesFile,
)) {
return;
}
}
final gitDir = await findGitDirectory(Directory.current);
await GitStatusCheckActionCliCode(
workingDirectory: gitDir,
).generateFile("action.yaml");
final androidCode = GithubActionsAndroidCliCode(
workingDirectory: gitDir,
defaultIncrementNumber: defaultIncrementNumber,
changesNotSentForReview: changesNotSentForReview,
status: status,
useEnvironmentSigning: useEnvironment,
);
await androidCode.generateFile(
"build_android_${appName.toLowerCase()}.yaml",
filter: (value) {
return androidCode._additionalSlackFilter(
applyDartDefinesToWorkflow(
value,
buildNames: dartDefinesEnvironmentNames(kProductionDartDefinesFile),
statusCheckNames:
dartDefinesEnvironmentNames(kDevelopmentDartDefinesFile),
suffix: appName.toUpperCase(),
)
.replaceAll(
"#### REPLACE_ANDROID_PACKAGE_NAME ####",
packageName.replaceAll('"', ""),
)
.replaceAll(
"#### REPLACE_APP_NAME ####",
appName.toUpperCase(),
),
slackIncomingWebhookUrl,
);
},
);
label("Rewrite `.gitignore`.");
final gitignore = File("android/.gitignore");
if (!gitignore.existsSync()) {
error("Cannot find `android/.gitignore`. Project is broken.");
return;
}
final gitignores = await gitignore.readAsLines();
if (context.yaml.getAsMap("git").get("ignore_secure_file", true)) {
if (!gitignores.any((e) => e.startsWith("key.properties"))) {
gitignores.add("key.properties");
}
if (!gitignores.any((e) => e.startsWith("**/*.keystore"))) {
gitignores.add("**/*.keystore");
}
if (!gitignores.any((e) => e.startsWith("**/*.jks"))) {
gitignores.add("**/*.jks");
}
if (!gitignores.any((e) => e.startsWith("**/*.p12"))) {
gitignores.add("**/*.p12");
}
if (!gitignores.any((e) => e.startsWith("*.json"))) {
gitignores.add("*.json");
}
if (!gitignores.any((e) => e.startsWith("**/appkey_fingerprint.txt"))) {
gitignores.add("**/appkey_fingerprint.txt");
}
if (!gitignores.any((e) => e.startsWith("**/appkey_password.key"))) {
gitignores.add("**/appkey_password.key");
}
} else {
gitignores.removeWhere((e) => e.startsWith("**/*.p12"));
gitignores.removeWhere((e) => e.startsWith("*.json"));
gitignores.removeWhere((e) => e.startsWith("**/appkey_fingerprint.txt"));
gitignores.removeWhere((e) => e.startsWith("**/appkey_password.key"));
gitignores.removeWhere((e) => e.startsWith("key.properties"));
gitignores.removeWhere((e) => e.startsWith("**/*.keystore"));
gitignores.removeWhere((e) => e.startsWith("**/*.jks"));
}
await gitignore.writeAsString(gitignores.join("\n"));
}