uploadBuild method

Future<void> uploadBuild({
  1. required AutoRefreshingAuthClient authClient,
  2. required String filePath,
  3. required List<String> testerGroups,
})

Implementation

Future<void> uploadBuild({
  required final AutoRefreshingAuthClient authClient,
  required final String filePath,
  required final List<String> testerGroups,
}) async {
  final request = http.MultipartRequest(
    'POST',
    Uri.parse(
      'https://firebaseappdistribution.googleapis.com/upload/v1/projects/$_projectId/apps/$_appId/releases:upload',
    ),
  )..files.add(await http.MultipartFile.fromPath('file', filePath));

  final uploadResponse =
      await http.Response.fromStream(await authClient.send(request));

  if (uploadResponse.statusCode != 200) {
    logHttpResponse(uploadResponse);
    throw Exception('Error uploading build to firebase app distribution.');
  }
  final operationUrl =
      (jsonDecode(uploadResponse.body) as Map?)?['name'] as String?;
  String? releaseId;
  while (true) {
    await Future<void>.delayed(const Duration(seconds: 2));
    final uploadBuildUrl = await authClient.get(
      Uri.parse(
        'https://firebaseappdistribution.googleapis.com/v1/$operationUrl',
      ),
    );
    if (uploadBuildUrl.statusCode == 200) {
      final data = jsonDecode(uploadBuildUrl.body) as Map<String, dynamic>?;
      final done = data?['done'] as bool?;
      final error = data?['error'] as Map<String, dynamic>?;
      final release = (data?['response'] as Map<String, dynamic>?)?['release']
          as Map<String, dynamic>?;
      if (done != null && done) {
        if (release != null) {
          releaseId = (release['name'] as String?)?.split('/').last;
          stdout.writeln('Release completed successfully');
          if (releaseId == null) {
            throw Exception('Release ID not found.');
          }
          stdout.writeln('Release ID: $releaseId');
        } else if (error != null) {
          throw Exception(
            'Error uploading build to firebase app distribution. '
            '${error['message']}',
          );
        }
        break;
      }
      stdout.writeln('Polling... Operation still in progress.');
    } else {
      logHttpResponse(uploadBuildUrl);
      throw Exception('Error polling operation.');
    }
  }
  stdout.writeln('Uploaded to firebase app distribution successfully.');

  final latestCommitResult =
      await Process.run('git', ['log', '-1', '--pretty=%B']);

  if (latestCommitResult.exitCode == 0) {
    stdout.writeln('Latest commit message: ${latestCommitResult.stdout}');
  } else {
    stderr.writeln(
      'Error fetching commit message: ${latestCommitResult.stderr}',
    );
  }

  final updateReleaseResponse = await authClient.patch(
    Uri.parse(
      'https://firebaseappdistribution.googleapis.com/v1/projects/$_projectId/apps/$_appId/releases/$releaseId',
    ),
    body: jsonEncode({
      'releaseNotes': {'text': latestCommitResult.stdout},
    }),
  );

  if (updateReleaseResponse.statusCode != 200) {
    logHttpResponse(updateReleaseResponse);
    throw Exception('Error updating release notes.');
  }
  stdout.writeln('Updated release notes successfully.');

  final distributeReleaseResponse = await authClient.post(
    Uri.parse(
      'https://firebaseappdistribution.googleapis.com/v1/projects/$_projectId/apps/$_appId/releases/$releaseId:distribute',
    ),
    body: jsonEncode({'groupAliases': testerGroups}),
  );

  if (distributeReleaseResponse.statusCode != 200) {
    logHttpResponse(distributeReleaseResponse);
    throw Exception('Error distributing release.');
  }
  stdout.writeln('Distributed release successfully.');
}