prepare method

Future<void> prepare()

Implementation

Future<void> prepare() async {
  await ensureInstalled('fastlane');

  if (!(await File('$_fastlaneDirectory/Appfile').exists())) {
    await runProcess(
      'fastlane',
      [
        'release',
      ],
      workingDirectory: _iosDirectory,
    );
    _logger.info('Created fastlane config in `ios` directory.');
  }

  final iosDir = Directory(_iosDirectory);
  final entities = await iosDir.list().toList();

  // Handle APIs private key file
  FileSystemEntity? apiPrivateKeyFile = entities.singleWhereOrNull((file) {
    final fileName = file.uri.pathSegments.last;
    return fileName.startsWith('AuthKey_') && fileName.endsWith('.p8');
  });

  if (apiPrivateKeyFile == null) {
    throw 'Please generate an App Store connect API Team key and copy it into the `ios` folder, see https://appstoreconnect.apple.com/access/integrations/api .';
  }

  print(
      'Enter your personal apple ID / username (apple_id, exported as IOS_APPLE_USERNAME):');
  final appleUsername = readInput();

  final apiPrivateKeyFileName = apiPrivateKeyFile.uri.pathSegments.last;
  final apiKeyId = apiPrivateKeyFileName.substring(
      'AuthKey_'.length, apiPrivateKeyFileName.indexOf('.p8'));
  print(
      'The API Key id is (api-key-id, exported as IOS_API_KEY_ID):\n$apiKeyId\n');

  print(
      'Enter the issuer id of the API key (api-issuer-id, exported as IOS_API_ISSUER_ID):');
  final apiIssuerId = readInput();

  print('Is the team enterprise y/n (team-enterprise, default:"n"):');
  final teamEnterpriseStr = readInput();
  var isTeamEnterprise = false;
  if (teamEnterpriseStr.toLowerCase().startsWith('y')) {
    isTeamEnterprise = true;
  }

  final apiPrivateKeyBase64 =
      base64Encode(await File.fromUri(apiPrivateKeyFile.uri).readAsBytes());

  final absoluteApiKeyJsonPath = await generateApiKeyJson(
    apiPrivateKeyBase64: apiPrivateKeyBase64,
    apiKeyId: apiKeyId,
    apiIssuerId: apiIssuerId,
    isTeamEnterprise: isTeamEnterprise,
    workingDirectory: _iosDirectory,
  );

  print(
      'Enter your content provider id (team_id, exported as IOS_TEAM_ID), see https://developer.apple.com/account#MembershipDetailsCard:');
  final teamId = readInput();

  print(
      'Enter your content provider id (itc_team_id, exported as IOS_CONTENT_PROVIDER_ID), see https://appstoreconnect.apple.com/WebObjects/iTunesConnect.woa/ra/user/detail:');
  final contentProviderId = readInput();

  print(
      'Base64 Private Key for App Store connect API (api-private-key-base64, exported as IOS_API_PRIVATE_KEY):\n');
  print('$apiPrivateKeyBase64\n');

  final (p12PrivateKeyBase64, certBase64) = await createCertificate(
      isDevelopment: false, apiKeyJsonPath: absoluteApiKeyJsonPath);

  print('Example command to publish the iOS app via flutter_release:\n');

  var exampleCommand = '''
export \\
  IOS_DISTRIBUTION_PRIVATE_KEY=$p12PrivateKeyBase64 \\
  IOS_DISTRIBUTION_CERT=$certBase64 \\
  IOS_APPLE_USERNAME=$appleUsername \\
  IOS_API_KEY_ID=$apiKeyId \\
  IOS_API_ISSUER_ID=$apiIssuerId \\
  IOS_API_PRIVATE_KEY=$apiPrivateKeyBase64 \\
  IOS_CONTENT_PROVIDER_ID=$contentProviderId \\
  IOS_TEAM_ID=$teamId\n\n
  ''';

  exampleCommand += r'''
flutter_release publish ios-app-store \
--dry-run \
--app-name my_app \ # Optional
--app-version v0.0.1-alpha.1 \ # Optional
--stage internal \
--apple-username=$IOS_APPLE_USERNAME \
--api-key-id=$IOS_API_KEY_ID \
--api-issuer-id=$IOS_API_ISSUER_ID \
--api-private-key-base64=$IOS_API_PRIVATE_KEY \
--content-provider-id=$IOS_CONTENT_PROVIDER_ID \
--team-id=$IOS_TEAM_ID \
--distribution-private-key-base64=$IOS_DISTRIBUTION_PRIVATE_KEY \
--distribution-cert-base64=$IOS_DISTRIBUTION_CERT''';
  if (isTeamEnterprise) {
    exampleCommand += ' --team-enterprise';
  }
  print(exampleCommand);
}