Bigquery access for autosubmit bot to record processed pull requests (#2112)

diff --git a/auto_submit/lib/exception/bigquery_exception.dart b/auto_submit/lib/exception/bigquery_exception.dart
new file mode 100644
index 0000000..2c79f63
--- /dev/null
+++ b/auto_submit/lib/exception/bigquery_exception.dart
@@ -0,0 +1,13 @@
+// Copyright 2022 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.
+
+class BigQueryException implements Exception {
+  /// Create a custom exception for Big Query Errors.
+  BigQueryException(this.cause);
+
+  final String cause;
+
+  @override
+  String toString() => cause;
+}
diff --git a/auto_submit/lib/exception/retryable_merge_exception.dart b/auto_submit/lib/exception/retryable_merge_exception.dart
index 0de89e0..c9e0495 100644
--- a/auto_submit/lib/exception/retryable_merge_exception.dart
+++ b/auto_submit/lib/exception/retryable_merge_exception.dart
@@ -12,7 +12,5 @@
   final List<GraphQLError> graphQLErrors;
 
   @override
-  String toString() {
-    return cause;
-  }
+  String toString() => cause;
 }
diff --git a/auto_submit/lib/model/big_query_pull_request_record.dart b/auto_submit/lib/model/big_query_pull_request_record.dart
new file mode 100644
index 0000000..b435f34
--- /dev/null
+++ b/auto_submit/lib/model/big_query_pull_request_record.dart
@@ -0,0 +1,41 @@
+// Copyright 2022 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:convert';
+
+import 'package:json_annotation/json_annotation.dart';
+import 'package:meta/meta.dart';
+
+part 'big_query_pull_request_record.g.dart';
+
+@immutable
+@JsonSerializable()
+class PullRequestRecord {
+  const PullRequestRecord({
+    this.prCreatedTimestamp,
+    this.prLandedTimestamp,
+    this.organization,
+    this.repository,
+    this.author,
+    this.prNumber,
+    this.prCommit,
+    this.prRequestType,
+  });
+
+  final DateTime? prCreatedTimestamp;
+  final DateTime? prLandedTimestamp;
+  final String? organization;
+  final String? repository;
+  final String? author;
+  final int? prNumber;
+  final String? prCommit;
+  final String? prRequestType;
+
+  @override
+  String toString() => jsonEncode(toJson());
+
+  factory PullRequestRecord.fromJson(Map<String, dynamic> json) => _$PullRequestRecordFromJson(json);
+
+  Map<String, dynamic> toJson() => _$PullRequestRecordToJson(this);
+}
diff --git a/auto_submit/lib/model/big_query_pull_request_record.g.dart b/auto_submit/lib/model/big_query_pull_request_record.g.dart
new file mode 100644
index 0000000..a898c80
--- /dev/null
+++ b/auto_submit/lib/model/big_query_pull_request_record.g.dart
@@ -0,0 +1,31 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'big_query_pull_request_record.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+PullRequestRecord _$PullRequestRecordFromJson(Map<String, dynamic> json) => PullRequestRecord(
+      prCreatedTimestamp:
+          json['pr_created_timestamp'] == null ? null : DateTime.parse(json['pr_created_timestamp'] as String),
+      prLandedTimestamp:
+          json['pr_landed_timestamp'] == null ? null : DateTime.parse(json['pr_landed_timestamp'] as String),
+      organization: json['organization'] as String?,
+      repository: json['repository'] as String?,
+      author: json['author'] as String?,
+      prNumber: json['pr_number'] as int?,
+      prCommit: json['pr_commit'] as String?,
+      prRequestType: json['pr_request_type'] as String?,
+    );
+
+Map<String, dynamic> _$PullRequestRecordToJson(PullRequestRecord instance) => <String, dynamic>{
+      'pr_created_timestamp': instance.prCreatedTimestamp?.toIso8601String(),
+      'pr_landed_timestamp': instance.prLandedTimestamp?.toIso8601String(),
+      'organization': instance.organization,
+      'repository': instance.repository,
+      'author': instance.author,
+      'pr_number': instance.prNumber,
+      'pr_commit': instance.prCommit,
+      'pr_request_type': instance.prRequestType,
+    };
diff --git a/auto_submit/lib/model/big_query_revert_request_record.dart b/auto_submit/lib/model/big_query_revert_request_record.dart
new file mode 100644
index 0000000..c9573ca
--- /dev/null
+++ b/auto_submit/lib/model/big_query_revert_request_record.dart
@@ -0,0 +1,50 @@
+// Copyright 2022 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:convert';
+
+import 'package:auto_submit/model/big_query_pull_request_record.dart';
+import 'package:json_annotation/json_annotation.dart';
+
+part 'big_query_revert_request_record.g.dart';
+
+@JsonSerializable()
+class RevertRequestRecord extends PullRequestRecord {
+  const RevertRequestRecord({
+    super.organization,
+    super.repository,
+    super.author,
+    super.prNumber,
+    super.prCommit,
+    super.prCreatedTimestamp,
+    super.prLandedTimestamp,
+    this.originalPrAuthor,
+    this.originalPrNumber,
+    this.originalPrCommit,
+    this.originalPrCreatedTimestamp,
+    this.originalPrLandedTimestamp,
+    this.reviewIssueAssignee,
+    this.reviewIssueNumber,
+    this.reviewIssueCreatedTimestamp,
+    this.reviewIssueLandedTimestamp,
+  });
+
+  final String? originalPrAuthor;
+  final int? originalPrNumber;
+  final String? originalPrCommit;
+  final DateTime? originalPrCreatedTimestamp;
+  final DateTime? originalPrLandedTimestamp;
+  final String? reviewIssueAssignee;
+  final int? reviewIssueNumber;
+  final DateTime? reviewIssueCreatedTimestamp;
+  final DateTime? reviewIssueLandedTimestamp;
+
+  @override
+  String toString() => jsonEncode(toJson());
+
+  factory RevertRequestRecord.fromJson(Map<String, dynamic> json) => _$RevertRequestRecordFromJson(json);
+
+  @override
+  Map<String, dynamic> toJson() => _$RevertRequestRecordToJson(this);
+}
diff --git a/auto_submit/lib/model/big_query_revert_request_record.g.dart b/auto_submit/lib/model/big_query_revert_request_record.g.dart
new file mode 100644
index 0000000..b05750e
--- /dev/null
+++ b/auto_submit/lib/model/big_query_revert_request_record.g.dart
@@ -0,0 +1,55 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'big_query_revert_request_record.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+RevertRequestRecord _$RevertRequestRecordFromJson(Map<String, dynamic> json) => RevertRequestRecord(
+      organization: json['organization'] as String?,
+      repository: json['repository'] as String?,
+      author: json['author'] as String?,
+      prNumber: json['pr_number'] as int?,
+      prCommit: json['pr_commit'] as String?,
+      prCreatedTimestamp:
+          json['pr_created_timestamp'] == null ? null : DateTime.parse(json['pr_created_timestamp'] as String),
+      prLandedTimestamp:
+          json['pr_landed_timestamp'] == null ? null : DateTime.parse(json['pr_landed_timestamp'] as String),
+      originalPrAuthor: json['original_pr_author'] as String?,
+      originalPrNumber: json['original_pr_number'] as int?,
+      originalPrCommit: json['original_pr_commit'] as String?,
+      originalPrCreatedTimestamp: json['original_pr_created_timestamp'] == null
+          ? null
+          : DateTime.parse(json['original_pr_created_timestamp'] as String),
+      originalPrLandedTimestamp: json['original_pr_landed_timestamp'] == null
+          ? null
+          : DateTime.parse(json['original_pr_landed_timestamp'] as String),
+      reviewIssueAssignee: json['review_issue_assignee'] as String?,
+      reviewIssueNumber: json['review_issue_number'] as int?,
+      reviewIssueCreatedTimestamp: json['review_issue_created_timestamp'] == null
+          ? null
+          : DateTime.parse(json['review_issue_created_timestamp'] as String),
+      reviewIssueLandedTimestamp: json['review_issue_landed_timestamp'] == null
+          ? null
+          : DateTime.parse(json['review_issue_landed_timestamp'] as String),
+    );
+
+Map<String, dynamic> _$RevertRequestRecordToJson(RevertRequestRecord instance) => <String, dynamic>{
+      'pr_created_timestamp': instance.prCreatedTimestamp?.toIso8601String(),
+      'pr_landed_timestamp': instance.prLandedTimestamp?.toIso8601String(),
+      'organization': instance.organization,
+      'repository': instance.repository,
+      'author': instance.author,
+      'pr_number': instance.prNumber,
+      'pr_commit': instance.prCommit,
+      'original_pr_author': instance.originalPrAuthor,
+      'original_pr_number': instance.originalPrNumber,
+      'original_pr_commit': instance.originalPrCommit,
+      'original_pr_created_timestamp': instance.originalPrCreatedTimestamp?.toIso8601String(),
+      'original_pr_landed_timestamp': instance.originalPrLandedTimestamp?.toIso8601String(),
+      'review_issue_assignee': instance.reviewIssueAssignee,
+      'review_issue_number': instance.reviewIssueNumber,
+      'review_issue_created_timestamp': instance.reviewIssueCreatedTimestamp?.toIso8601String(),
+      'review_issue_landed_timestamp': instance.reviewIssueLandedTimestamp?.toIso8601String(),
+    };
diff --git a/auto_submit/lib/model/pull_request_change_type.dart b/auto_submit/lib/model/pull_request_change_type.dart
new file mode 100644
index 0000000..8a7b5e7
--- /dev/null
+++ b/auto_submit/lib/model/pull_request_change_type.dart
@@ -0,0 +1,12 @@
+// Copyright 2022 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.
+
+/// The type of the change in the pull request we have processed.
+enum PullRequestChangeType {
+  /// Merge is any submitted pull request change that does not undo previous changes.
+  change,
+
+  /// Revert is specifically for undoing changes.
+  revert,
+}
diff --git a/auto_submit/lib/service/access_client_provider.dart b/auto_submit/lib/service/access_client_provider.dart
new file mode 100644
index 0000000..eb60463
--- /dev/null
+++ b/auto_submit/lib/service/access_client_provider.dart
@@ -0,0 +1,15 @@
+// Copyright 2022 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 'package:googleapis_auth/auth_io.dart';
+import 'package:http/http.dart';
+
+class AccessClientProvider {
+  /// Returns an OAuth 2.0 authenticated access client for the device lab service account.
+  Future<Client> createAccessClient({
+    List<String> scopes = const <String>['https://www.googleapis.com/auth/cloud-platform'],
+  }) async {
+    return clientViaApplicationDefaultCredentials(scopes: scopes);
+  }
+}
diff --git a/auto_submit/lib/service/bigquery.dart b/auto_submit/lib/service/bigquery.dart
new file mode 100644
index 0000000..df5d418
--- /dev/null
+++ b/auto_submit/lib/service/bigquery.dart
@@ -0,0 +1,511 @@
+// Copyright 2022 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:async';
+
+import 'package:auto_submit/exception/bigquery_exception.dart';
+import 'package:auto_submit/model/big_query_pull_request_record.dart';
+import 'package:auto_submit/model/big_query_revert_request_record.dart';
+import 'package:googleapis/bigquery/v2.dart';
+import 'package:http/http.dart';
+
+import 'access_client_provider.dart';
+
+const String selectRevertRequestDml = r'''
+SELECT organization,
+       repository,
+       reverting_pr_author,
+       reverting_pr_number,
+       reverting_pr_commit,
+       reverting_pr_created_timestamp,
+       reverting_pr_landed_timestamp,
+       original_pr_author,
+       original_pr_number,
+       original_pr_commit,
+       original_pr_created_timestamp,
+       original_pr_landed_timestamp,
+       review_issue_assignee,
+       review_issue_number,
+       review_issue_created_timestamp,
+       review_issue_landed_timestamp
+FROM `flutter-dashboard.revert.revert_requests`
+WHERE reverting_pr_number=@REVERTING_PR_NUMBER AND repository=@REPOSITORY
+''';
+
+const String insertRevertRequestDml = r'''
+INSERT INTO `flutter-dashboard.revert.revert_requests` (
+  organization,
+  repository,
+  reverting_pr_author,
+  reverting_pr_number,
+  reverting_pr_commit,
+  reverting_pr_created_timestamp,
+  reverting_pr_landed_timestamp,
+  original_pr_author,
+  original_pr_number,
+  original_pr_commit,
+  original_pr_created_timestamp,
+  original_pr_landed_timestamp,
+  review_issue_assignee,
+  review_issue_number,
+  review_issue_created_timestamp,
+  review_issue_landed_timestamp
+) VALUES (
+  @ORGANIZATION,
+  @REPOSITORY,
+  @REVERTING_PR_AUTHOR,
+  @REVERTING_PR_NUMBER,
+  @REVERTING_PR_COMMIT,
+  @REVERTING_PR_CREATED_TIMESTAMP,
+  @REVERTING_PR_LANDED_TIMESTAMP,
+  @ORIGINAL_PR_AUTHOR,
+  @ORIGINAL_PR_NUMBER,
+  @ORIGINAL_PR_COMMIT,
+  @ORIGINAL_PR_CREATED_TIMESTAMP,
+  @ORIGINAL_PR_LANDED_TIMESTAMP,
+  @REVIEW_ISSUE_ASSIGNEE,
+  @REVIEW_ISSUE_NUMBER,
+  @REVIEW_ISSUE_CREATED_TIMESTAMP,
+  @REVIEW_ISSUE_LANDED_TIMESTAMP
+)
+''';
+
+const String deleteRevertRequestDml = r'''
+DELETE FROM `flutter-dashboard.revert.revert_requests`
+WHERE reverting_pr_number=@REVERTING_PR_NUMBER AND repository=@REPOSITORY
+''';
+
+const String insertPullRequestDml = r'''
+INSERT INTO `flutter-dashboard.autosubmit.pull_requests` (
+  pr_created_timestamp,
+  pr_landed_timestamp,
+  organization,
+  repository,
+  author,
+  pr_number,
+  pr_commit,
+  pr_request_type
+) VALUES (
+  @PR_CREATED_TIMESTAMP,
+  @PR_LANDED_TIMESTAMP,
+  @ORGANIZATION,
+  @REPOSITORY,
+  @AUTHOR,
+  @PR_NUMBER,
+  @PR_COMMIT,
+  @PR_REQUEST_TYPE
+)
+''';
+
+const String selectPullRequestDml = r'''
+SELECT pr_created_timestamp,
+       pr_landed_timestamp,
+       organization,
+       repository,
+       author,
+       pr_number,
+       pr_commit,
+       pr_request_type
+FROM `flutter-dashboard.autosubmit.pull_requests`
+WHERE pr_number=@PR_NUMBER AND repository=@REPOSITORY
+''';
+
+const String deletePullRequestDml = r'''
+DELETE FROM `flutter-dashboard.autosubmit.pull_requests`
+WHERE pr_number=@PR_NUMBER AND repository=@REPOSITORY
+''';
+
+class BigqueryService {
+  const BigqueryService(this.accessClientProvider);
+
+  /// AccessClientProvider for OAuth 2.0 authenticated access client
+  final AccessClientProvider accessClientProvider;
+
+  /// Return a [TabledataResource] with an authenticated [client]
+  Future<TabledataResource> defaultTabledata() async {
+    final Client client = await accessClientProvider.createAccessClient(
+      scopes: const <String>[BigqueryApi.bigqueryScope],
+    );
+    return BigqueryApi(client).tabledata;
+  }
+
+  /// Return a [JobsResource] with an authenticated [client]
+  Future<JobsResource> defaultJobs() async {
+    final Client client = await accessClientProvider.createAccessClient(
+      scopes: const <String>[BigqueryApi.bigqueryScope],
+    );
+    return BigqueryApi(client).jobs;
+  }
+
+  /// Insert a new revert request into the database.
+  Future<void> insertRevertRequestRecord({
+    required String projectId,
+    required RevertRequestRecord revertRequestRecord,
+  }) async {
+    final JobsResource jobsResource = await defaultJobs();
+
+    final QueryRequest queryRequest = QueryRequest(
+      query: insertRevertRequestDml,
+      queryParameters: <QueryParameter>[
+        _createStringQueryParameter(
+          'ORGANIZATION',
+          revertRequestRecord.organization,
+        ),
+        _createStringQueryParameter(
+          'REPOSITORY',
+          revertRequestRecord.repository,
+        ),
+        _createStringQueryParameter(
+          'REVERTING_PR_AUTHOR',
+          revertRequestRecord.author,
+        ),
+        _createIntegerQueryParameter(
+          'REVERTING_PR_NUMBER',
+          revertRequestRecord.prNumber!,
+        ),
+        _createStringQueryParameter(
+          'REVERTING_PR_COMMIT',
+          revertRequestRecord.prCommit,
+        ),
+        _createIntegerQueryParameter(
+          'REVERTING_PR_CREATED_TIMESTAMP',
+          revertRequestRecord.prCreatedTimestamp!.millisecondsSinceEpoch,
+        ),
+        _createIntegerQueryParameter(
+          'REVERTING_PR_LANDED_TIMESTAMP',
+          revertRequestRecord.prLandedTimestamp!.millisecondsSinceEpoch,
+        ),
+        _createStringQueryParameter(
+          'ORIGINAL_PR_AUTHOR',
+          revertRequestRecord.originalPrAuthor,
+        ),
+        _createIntegerQueryParameter(
+          'ORIGINAL_PR_NUMBER',
+          revertRequestRecord.originalPrNumber!,
+        ),
+        _createStringQueryParameter(
+          'ORIGINAL_PR_COMMIT',
+          revertRequestRecord.originalPrCommit,
+        ),
+        _createIntegerQueryParameter(
+          'ORIGINAL_PR_CREATED_TIMESTAMP',
+          revertRequestRecord.originalPrCreatedTimestamp!.millisecondsSinceEpoch,
+        ),
+        _createIntegerQueryParameter(
+          'ORIGINAL_PR_LANDED_TIMESTAMP',
+          revertRequestRecord.originalPrLandedTimestamp!.millisecondsSinceEpoch,
+        ),
+        _createStringQueryParameter(
+          'REVIEW_ISSUE_ASSIGNEE',
+          revertRequestRecord.reviewIssueAssignee,
+        ),
+        _createIntegerQueryParameter(
+          'REVIEW_ISSUE_NUMBER',
+          revertRequestRecord.reviewIssueNumber,
+        ),
+        _createIntegerQueryParameter(
+          'REVIEW_ISSUE_CREATED_TIMESTAMP',
+          revertRequestRecord.reviewIssueCreatedTimestamp!.millisecondsSinceEpoch,
+        ),
+        // This could not possibly be landed at the time of entry into the database but we should check for null.
+        _createIntegerQueryParameter(
+          'REVIEW_ISSUE_LANDED_TIMESTAMP',
+          (revertRequestRecord.reviewIssueLandedTimestamp != null)
+              ? revertRequestRecord.reviewIssueLandedTimestamp!.millisecondsSinceEpoch
+              : 0,
+        ),
+      ],
+      useLegacySql: false,
+    );
+
+    final QueryResponse queryResponse = await jobsResource.query(queryRequest, projectId);
+    if (!queryResponse.jobComplete!) {
+      throw BigQueryException(
+        'Insert revert request $revertRequestRecord did not complete.',
+      );
+    }
+
+    if (queryResponse.numDmlAffectedRows != null && int.parse(queryResponse.numDmlAffectedRows!) != 1) {
+      throw BigQueryException(
+        'There was an error inserting $revertRequestRecord into the table.',
+      );
+    }
+  }
+
+  /// Select a specific revert request from the database.
+  Future<RevertRequestRecord> selectRevertRequestByRevertPrNumber({
+    required String projectId,
+    required int prNumber,
+    required String repository,
+  }) async {
+    final JobsResource jobsResource = await defaultJobs();
+
+    final QueryRequest queryRequest = QueryRequest(
+      query: selectRevertRequestDml,
+      queryParameters: <QueryParameter>[
+        _createIntegerQueryParameter('REVERTING_PR_NUMBER', prNumber),
+        _createStringQueryParameter('REPOSITORY', repository),
+      ],
+      useLegacySql: false,
+    );
+
+    final QueryResponse queryResponse = await jobsResource.query(queryRequest, projectId);
+    if (!queryResponse.jobComplete!) {
+      throw BigQueryException(
+        'Get revert request with pr# $prNumber in repository $repository did not complete.',
+      );
+    }
+
+    final List<TableRow>? tableRows = queryResponse.rows;
+    if (tableRows == null || tableRows.isEmpty) {
+      throw BigQueryException(
+        'Could not find an entry for revert request with pr# $prNumber in repository $repository.',
+      );
+    }
+
+    if (tableRows.length != 1) {
+      throw BigQueryException(
+        'More than one record was returned for revert request with pr# $prNumber in repository $repository.',
+      );
+    }
+
+    final TableRow tableRow = tableRows.first;
+
+    return RevertRequestRecord(
+      organization: tableRow.f![0].v as String,
+      repository: tableRow.f![1].v as String,
+      author: tableRow.f![2].v as String,
+      prNumber: int.parse(tableRow.f![3].v as String),
+      prCommit: tableRow.f![4].v as String,
+      prCreatedTimestamp: (tableRow.f![5].v != null)
+          ? DateTime.fromMillisecondsSinceEpoch(int.parse(tableRow.f![5].v as String))
+          : null,
+      prLandedTimestamp: (tableRow.f![6].v != null)
+          ? DateTime.fromMillisecondsSinceEpoch(int.parse(tableRow.f![6].v as String))
+          : null,
+      originalPrAuthor: tableRow.f![7].v as String,
+      originalPrNumber: int.parse(tableRow.f![8].v as String),
+      originalPrCommit: tableRow.f![9].v as String,
+      originalPrCreatedTimestamp: (tableRow.f![10].v != null)
+          ? DateTime.fromMillisecondsSinceEpoch(int.parse(tableRow.f![10].v as String))
+          : null,
+      originalPrLandedTimestamp: (tableRow.f![11].v != null)
+          ? DateTime.fromMillisecondsSinceEpoch(int.parse(tableRow.f![11].v as String))
+          : null,
+      reviewIssueAssignee: tableRow.f![12].v as String,
+      reviewIssueNumber: int.parse(tableRow.f![13].v as String),
+      reviewIssueCreatedTimestamp: (tableRow.f![14].v != null)
+          ? DateTime.fromMillisecondsSinceEpoch(int.parse(tableRow.f![14].v as String))
+          : null,
+      reviewIssueLandedTimestamp: (tableRow.f![15].v != null)
+          ? DateTime.fromMillisecondsSinceEpoch(int.parse(tableRow.f![15].v as String))
+          : null,
+    );
+  }
+
+  Future<void> deleteRevertRequestRecord({
+    required String projectId,
+    required int prNumber,
+    required String repository,
+  }) async {
+    final JobsResource jobsResource = await defaultJobs();
+
+    final QueryRequest queryRequest = QueryRequest(
+      query: deleteRevertRequestDml,
+      queryParameters: <QueryParameter>[
+        _createIntegerQueryParameter('REVERTING_PR_NUMBER', prNumber),
+        _createStringQueryParameter('REPOSITORY', repository),
+      ],
+      useLegacySql: false,
+    );
+
+    final QueryResponse queryResponse = await jobsResource.query(queryRequest, projectId);
+    if (!queryResponse.jobComplete!) {
+      throw BigQueryException(
+        'Delete revert request with pr# $prNumber in repository $repository did not complete.',
+      );
+    }
+
+    if (queryResponse.numDmlAffectedRows == null || int.parse(queryResponse.numDmlAffectedRows!) == 0) {
+      throw BigQueryException(
+        'Could not find revert request with pr# $prNumber in repository $repository to delete.',
+      );
+    }
+
+    if (int.parse(queryResponse.numDmlAffectedRows!) != 1) {
+      throw BigQueryException(
+        'More than one row was deleted from the database for revert request with pr# $prNumber in repository $repository.',
+      );
+    }
+  }
+
+  /// Insert a new pull request record into the database.
+  Future<void> insertPullRequestRecord({
+    required String projectId,
+    required PullRequestRecord pullRequestRecord,
+  }) async {
+    final JobsResource jobsResource = await defaultJobs();
+
+    final QueryRequest queryRequest = QueryRequest(
+      query: insertPullRequestDml,
+      queryParameters: <QueryParameter>[
+        _createIntegerQueryParameter(
+          'PR_CREATED_TIMESTAMP',
+          pullRequestRecord.prCreatedTimestamp!.millisecondsSinceEpoch,
+        ),
+        _createIntegerQueryParameter(
+          'PR_LANDED_TIMESTAMP',
+          pullRequestRecord.prLandedTimestamp!.millisecondsSinceEpoch,
+        ),
+        _createStringQueryParameter(
+          'ORGANIZATION',
+          pullRequestRecord.organization,
+        ),
+        _createStringQueryParameter(
+          'REPOSITORY',
+          pullRequestRecord.repository,
+        ),
+        _createStringQueryParameter(
+          'AUTHOR',
+          pullRequestRecord.author,
+        ),
+        _createIntegerQueryParameter(
+          'PR_NUMBER',
+          pullRequestRecord.prNumber,
+        ),
+        _createStringQueryParameter(
+          'PR_COMMIT',
+          pullRequestRecord.prCommit,
+        ),
+        _createStringQueryParameter(
+          'PR_REQUEST_TYPE',
+          pullRequestRecord.prRequestType,
+        ),
+      ],
+      useLegacySql: false,
+    );
+
+    final QueryResponse queryResponse = await jobsResource.query(queryRequest, projectId);
+    if (!queryResponse.jobComplete!) {
+      throw BigQueryException(
+        'Insert pull request $pullRequestRecord did not complete.',
+      );
+    }
+
+    if (queryResponse.numDmlAffectedRows != null && int.parse(queryResponse.numDmlAffectedRows!) != 1) {
+      throw BigQueryException(
+        'There was an error inserting $pullRequestRecord into the table.',
+      );
+    }
+  }
+
+  /// Select a specific pull request form the database.
+  Future<PullRequestRecord> selectPullRequestRecordByPrNumber({
+    required String projectId,
+    required int prNumber,
+    required String repository,
+  }) async {
+    final JobsResource jobsResource = await defaultJobs();
+
+    final QueryRequest queryRequest = QueryRequest(
+      query: selectPullRequestDml,
+      queryParameters: <QueryParameter>[
+        _createIntegerQueryParameter('PR_NUMBER', prNumber),
+        _createStringQueryParameter('REPOSITORY', repository),
+      ],
+      useLegacySql: false,
+    );
+
+    final QueryResponse queryResponse = await jobsResource.query(queryRequest, projectId);
+    if (!queryResponse.jobComplete!) {
+      throw BigQueryException(
+        'Get pull request by pr# $prNumber in repository $repository did not complete.',
+      );
+    }
+
+    final List<TableRow>? tableRows = queryResponse.rows;
+    if (tableRows == null || tableRows.isEmpty) {
+      throw BigQueryException(
+        'Could not find an entry for pull request with pr# $prNumber in repository $repository.',
+      );
+    }
+
+    if (tableRows.length != 1) {
+      throw BigQueryException(
+        'More than one record was returned for pull request with pr# $prNumber in repository $repository.',
+      );
+    }
+
+    final TableRow tableRow = tableRows.first;
+
+    return PullRequestRecord(
+      prCreatedTimestamp: (tableRow.f![0].v != null)
+          ? DateTime.fromMillisecondsSinceEpoch(int.parse(tableRow.f![0].v as String))
+          : null,
+      prLandedTimestamp: (tableRow.f![1].v != null)
+          ? DateTime.fromMillisecondsSinceEpoch(int.parse(tableRow.f![1].v as String))
+          : null,
+      organization: tableRow.f![2].v as String,
+      repository: tableRow.f![3].v as String,
+      author: tableRow.f![4].v as String,
+      prNumber: int.parse(tableRow.f![5].v as String),
+      prCommit: tableRow.f![6].v as String,
+      prRequestType: tableRow.f![7].v as String,
+    );
+  }
+
+  Future<void> deletePullRequestRecord({
+    required String projectId,
+    required int prNumber,
+    required String repository,
+  }) async {
+    final JobsResource jobsResource = await defaultJobs();
+
+    final QueryRequest queryRequest = QueryRequest(
+      query: deletePullRequestDml,
+      queryParameters: <QueryParameter>[
+        _createIntegerQueryParameter('PR_NUMBER', prNumber),
+        _createStringQueryParameter('REPOSITORY', repository),
+      ],
+      useLegacySql: false,
+    );
+
+    final QueryResponse queryResponse = await jobsResource.query(queryRequest, projectId);
+    if (!queryResponse.jobComplete!) {
+      throw BigQueryException(
+        'Delete pull request with pr# $prNumber in repository $repository did not complete.',
+      );
+    }
+
+    if (queryResponse.numDmlAffectedRows == null || int.parse(queryResponse.numDmlAffectedRows!) == 0) {
+      throw BigQueryException(
+        'Could not find pull request with pr# $prNumber in repository $repository to delete.',
+      );
+    }
+
+    if (int.parse(queryResponse.numDmlAffectedRows!) != 1) {
+      throw BigQueryException(
+        'More than one row was deleted from the database for pull request with pr# $prNumber in repository $repository.',
+      );
+    }
+  }
+
+  /// Create an int parameter for query substitution.
+  QueryParameter _createIntegerQueryParameter(String name, int? value) {
+    return QueryParameter(
+      name: name,
+      parameterType: QueryParameterType(type: 'INT64'),
+      parameterValue: QueryParameterValue(value: value.toString()),
+    );
+  }
+
+  /// Create a String parameter for query substitution.
+  QueryParameter _createStringQueryParameter(String name, String? value) {
+    return QueryParameter(
+      name: name,
+      parameterType: QueryParameterType(type: 'STRING'),
+      parameterValue: QueryParameterValue(value: value),
+    );
+  }
+}
diff --git a/auto_submit/lib/service/config.dart b/auto_submit/lib/service/config.dart
index bb59526..9837db9 100644
--- a/auto_submit/lib/service/config.dart
+++ b/auto_submit/lib/service/config.dart
@@ -7,6 +7,7 @@
 
 import 'package:corsac_jwt/corsac_jwt.dart';
 import 'package:github/github.dart';
+import 'package:googleapis/bigquery/v2.dart';
 import 'package:graphql/client.dart';
 import 'package:http/http.dart' as http;
 import 'package:neat_cache/cache_provider.dart';
@@ -14,6 +15,8 @@
 
 import '../foundation/providers.dart';
 import '../service/secrets.dart';
+import 'access_client_provider.dart';
+import 'bigquery.dart';
 import 'github_service.dart';
 import 'log.dart';
 
@@ -113,6 +116,15 @@
     );
   }
 
+  Future<BigqueryService> createBigQueryService() async {
+    final AccessClientProvider accessClientProvider = AccessClientProvider();
+    return BigqueryService(accessClientProvider);
+  }
+
+  Future<TabledataResource> createTabledataResourceApi() async {
+    return (await createBigQueryService()).defaultTabledata();
+  }
+
   Future<Uint8List> _generateGithubToken(RepositorySlug slug) async {
     final String jwt = await _generateGithubJwt();
     final Map<String, String> headers = <String, String>{
diff --git a/auto_submit/lib/service/revert_review_template.dart b/auto_submit/lib/service/revert_review_template.dart
index c32a973..37ada80 100644
--- a/auto_submit/lib/service/revert_review_template.dart
+++ b/auto_submit/lib/service/revert_review_template.dart
@@ -38,9 +38,7 @@
 1. Add the reviewer of revert pull request as the assignee of this issue.
 2. Close only when the review has been completed.
 
-
-DO NOT EDIT, REVERT METADATA
-<!--
+<!-- DO NOT EDIT, REVERT METADATA
 {
   'originalPrLink': '$originalPrLink',
   'revertPrLink': '$repositorySlug#$revertPrNumber',
diff --git a/auto_submit/lib/service/validation_service.dart b/auto_submit/lib/service/validation_service.dart
index 5ab2d34..e7a59d0 100644
--- a/auto_submit/lib/service/validation_service.dart
+++ b/auto_submit/lib/service/validation_service.dart
@@ -2,11 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'package:auto_submit/exception/bigquery_exception.dart';
+import 'package:auto_submit/model/big_query_pull_request_record.dart';
+import 'package:auto_submit/model/big_query_revert_request_record.dart';
+import 'package:auto_submit/model/pull_request_change_type.dart';
 import 'dart:async';
 
 import 'package:auto_submit/exception/retryable_merge_exception.dart';
 import 'package:auto_submit/requests/check_pull_request_queries.dart';
-import 'package:auto_submit/service/approver_service.dart';
+import 'package:auto_submit/service/bigquery.dart';
 import 'package:auto_submit/service/config.dart';
 import 'package:auto_submit/service/github_service.dart';
 import 'package:auto_submit/service/graphql_service.dart';
@@ -27,6 +31,7 @@
 import '../validations/conflicting.dart';
 import '../validations/empty_checks.dart';
 import '../validations/validation.dart';
+import 'approver_service.dart';
 
 /// Provides an extensible and standardized way to validate different aspects of
 /// a commit to ensure it is ready to land, it has been reviewed, and it has been
@@ -204,6 +209,14 @@
       );
 
       log.info(message);
+    } else {
+      log.info('Attempting to insert a pull request record into the database for $prNumber');
+
+      await insertPullRequestRecord(
+        config: config,
+        pullRequest: messagePullRequest,
+        pullRequestType: PullRequestChangeType.change,
+      );
     }
 
     log.info('Ack the processed message : $ackId.');
@@ -250,12 +263,27 @@
             title: revertReviewTemplate.title!,
             body: revertReviewTemplate.body!,
             labels: <String>['P1'],
+            assignee: result.repository!.pullRequest!.author!.login!,
           );
-          log.info('Issue #${issue.id} was created to track the review for $prNumber in ${slug.fullName}');
+          log.info('Issue #${issue.id} was created to track the review for pr# $prNumber in ${slug.fullName}');
+
+          log.info('Attempting to insert a revert pull request record into the database for pr# $prNumber');
+          await insertPullRequestRecord(
+            config: config,
+            pullRequest: messagePullRequest,
+            pullRequestType: PullRequestChangeType.revert,
+          );
+
+          log.info('Attempting to insert a revert tracking request record into the database for pr# $prNumber');
+          await insertRevertRequestRecord(
+            config: config,
+            revertPullRequest: messagePullRequest,
+            reviewIssue: issue,
+          );
         } on github.GitHubError catch (exception) {
           // We have merged but failed to create follow up issue.
           final String errorMessage = '''
-An exception has occurred while attempting to create the follow up review issue for $prNumber.
+An exception has occurred while attempting to create the follow up review issue for pr# $prNumber.
 Please create a follow up issue to track a review for this pull request.
 Exception: ${exception.message}
 ''';
@@ -263,7 +291,7 @@
           await gitHubService.createComment(slug, prNumber, errorMessage);
         }
       } else {
-        final String message = 'revert label is removed for ${slug.fullName}, pr: $prNumber, ${processed.message}.';
+        final String message = 'revert label is removed for ${slug.fullName}, pr#: $prNumber, ${processed.message}.';
 
         await removeLabelAndComment(
           githubService: gitHubService,
@@ -351,6 +379,90 @@
     await githubService.removeLabel(repositorySlug, prNumber, prLabel);
     await githubService.createComment(repositorySlug, prNumber, message);
   }
+
+  /// Insert a merged pull request record into the database.
+  Future<void> insertPullRequestRecord({
+    required Config config,
+    required github.PullRequest pullRequest,
+    required PullRequestChangeType pullRequestType,
+  }) async {
+    final github.RepositorySlug slug = pullRequest.base!.repo!.slug();
+    final GithubService gitHubService = await config.createGithubService(slug);
+    // We need the updated time fields for the merged request from github.
+    final github.PullRequest currentPullRequest = await gitHubService.getPullRequest(slug, pullRequest.number!);
+
+    log.info('Updated pull request info: ${currentPullRequest.toString()}');
+
+    // add a record for the pull request into our metrics tracking
+    PullRequestRecord pullRequestRecord = PullRequestRecord(
+      organization: currentPullRequest.base!.repo!.slug().owner,
+      repository: currentPullRequest.base!.repo!.slug().name,
+      author: currentPullRequest.user!.login,
+      prNumber: pullRequest.number!,
+      prCommit: currentPullRequest.head!.sha,
+      prRequestType: pullRequestType.name,
+      prCreatedTimestamp: currentPullRequest.createdAt!,
+      prLandedTimestamp: currentPullRequest.closedAt!,
+    );
+
+    log.info('Created pull request record: ${pullRequestRecord.toString()}');
+
+    try {
+      BigqueryService bigqueryService = await config.createBigQueryService();
+      await bigqueryService.insertPullRequestRecord(
+        projectId: 'flutter-dashboard',
+        pullRequestRecord: pullRequestRecord,
+      );
+      log.info('Record inserted for pull request pr# ${pullRequest.number} successfully.');
+    } on BigQueryException catch (exception) {
+      log.severe('Unable to insert pull request record due to: ${exception.toString()}');
+    }
+  }
+
+  Future<void> insertRevertRequestRecord({
+    required Config config,
+    required github.PullRequest revertPullRequest,
+    required github.Issue reviewIssue,
+  }) async {
+    final github.RepositorySlug slug = revertPullRequest.base!.repo!.slug();
+    final GithubService gitHubService = await config.createGithubService(slug);
+    // Get the updated revert issue.
+    final github.PullRequest currentPullRequest = await gitHubService.getPullRequest(slug, revertPullRequest.number!);
+    // Get the original pull request issue.
+    String originalPullRequestLink = revertValidation!.extractLinkFromText(revertPullRequest.body)!;
+    int originalPullRequestNumber = int.parse(originalPullRequestLink.split('#').elementAt(1));
+    // return int.parse(linkSplit.elementAt(1));
+    final github.PullRequest originalPullRequest = await gitHubService.getPullRequest(slug, originalPullRequestNumber);
+
+    RevertRequestRecord revertRequestRecord = RevertRequestRecord(
+      organization: currentPullRequest.base!.repo!.slug().owner,
+      repository: currentPullRequest.base!.repo!.slug().name,
+      author: currentPullRequest.user!.login,
+      prNumber: revertPullRequest.number,
+      prCommit: currentPullRequest.head!.sha,
+      prCreatedTimestamp: currentPullRequest.createdAt,
+      prLandedTimestamp: currentPullRequest.closedAt,
+      originalPrAuthor: originalPullRequest.user!.login,
+      originalPrNumber: originalPullRequest.number,
+      originalPrCommit: originalPullRequest.head!.sha,
+      originalPrCreatedTimestamp: originalPullRequest.createdAt,
+      originalPrLandedTimestamp: originalPullRequest.closedAt,
+      reviewIssueAssignee: reviewIssue.assignee!.login,
+      reviewIssueNumber: reviewIssue.number,
+      reviewIssueCreatedTimestamp: reviewIssue.createdAt,
+    );
+
+    try {
+      BigqueryService bigqueryService = await config.createBigQueryService();
+      await bigqueryService.insertRevertRequestRecord(
+        projectId: 'flutter-dashboard',
+        revertRequestRecord: revertRequestRecord,
+      );
+      log.info('Record inserted for revert tracking request for pr# ${revertPullRequest.number} successfully.');
+    } on BigQueryException catch (exception) {
+      log.severe(exception.toString());
+    }
+  }
 }
 
 /// Small wrapper class to allow us to capture and create a comment in the PR with
diff --git a/auto_submit/lib/validations/revert.dart b/auto_submit/lib/validations/revert.dart
index 38517ba..c7e3932 100644
--- a/auto_submit/lib/validations/revert.dart
+++ b/auto_submit/lib/validations/revert.dart
@@ -47,7 +47,7 @@
 
     github.RepositorySlug repositorySlug = _getSlugFromLink(revertLink);
     GithubService githubService = await config.createGithubService(repositorySlug);
-    int pullRequestId = _getPullRequestIdFromLink(revertLink);
+    int pullRequestId = _getPullRequestNumberFromLink(revertLink);
     github.PullRequest requestToRevert = await githubService.getPullRequest(repositorySlug, pullRequestId);
 
     bool requestsMatch = await githubService.comparePullRequests(repositorySlug, requestToRevert, messagePullRequest);
@@ -96,7 +96,7 @@
 
   /// Split a reverts link on the '#' to get the id part of the link.
   /// It is assumed that the link has the format flutter/repo#id.
-  int _getPullRequestIdFromLink(String link) {
+  int _getPullRequestNumberFromLink(String link) {
     List<String> linkSplit = link.split('#');
     return int.parse(linkSplit.elementAt(1));
   }
diff --git a/auto_submit/test/model/pull_request_change_type.dart b/auto_submit/test/model/pull_request_change_type.dart
new file mode 100644
index 0000000..1545501
--- /dev/null
+++ b/auto_submit/test/model/pull_request_change_type.dart
@@ -0,0 +1,17 @@
+// Copyright 2022 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 'package:auto_submit/model/pull_request_change_type.dart';
+import 'package:test/test.dart';
+
+void main() {
+  List<String> expectedNames = ['change', 'revert'];
+
+  test('Expected string value for enum is returned.', () {
+    for (PullRequestChangeType prChangeType in PullRequestChangeType.values) {
+      assert(expectedNames.contains(prChangeType.name));
+    }
+    expect(PullRequestChangeType.values.length, 2);
+  });
+}
diff --git a/auto_submit/test/requests/check_pull_request_test.dart b/auto_submit/test/requests/check_pull_request_test.dart
index 3617bc2..b66c5de 100644
--- a/auto_submit/test/requests/check_pull_request_test.dart
+++ b/auto_submit/test/requests/check_pull_request_test.dart
@@ -4,18 +4,22 @@
 
 // ignore_for_file: constant_identifier_names
 import 'dart:async';
+import 'dart:convert';
 import 'package:auto_submit/service/config.dart';
 
 import 'package:auto_submit/requests/check_pull_request.dart';
 import 'package:auto_submit/requests/check_pull_request_queries.dart';
 import 'package:auto_submit/service/log.dart';
 import 'package:github/github.dart';
+import 'package:googleapis/bigquery/v2.dart';
 import 'package:googleapis/pubsub/v1.dart' as pub;
 import 'package:graphql/client.dart' hide Request, Response;
 import 'package:logging/logging.dart';
 import 'package:mockito/mockito.dart';
 import 'package:test/test.dart';
 
+import '../service/bigquery_test.dart';
+import '../src/service/fake_bigquery_service.dart';
 import './github_webhook_test_data.dart';
 import '../src/request_handling/fake_pubsub.dart';
 import '../src/request_handling/fake_authentication.dart';
@@ -35,6 +39,8 @@
     late FakeCronAuthProvider auth;
     late FakeGraphQLClient githubGraphQLClient;
     final FakeGithubService githubService = FakeGithubService();
+    late MockJobsResource jobsResource;
+    late FakeBigqueryService bigqueryService;
     late MockPullRequestsService pullRequests;
     final MockGitHub gitHub = MockGitHub();
     late FakePubSub pubsub;
@@ -93,10 +99,19 @@
       githubService.successMergeData = successMergeMock;
       githubService.createCommentData = createCommentMock;
       githubService.commitData = commitMock;
+      jobsResource = MockJobsResource();
+      bigqueryService = FakeBigqueryService(jobsResource);
       config = FakeConfig(githubService: githubService, githubGraphQLClient: githubGraphQLClient, githubClient: gitHub);
+      config.bigqueryService = bigqueryService;
       pullRequests = MockPullRequestsService();
       when(gitHub.pullRequests).thenReturn(pullRequests);
       when(pullRequests.get(any, any)).thenAnswer((_) async => PullRequest(number: 123, state: 'open'));
+
+      when(jobsResource.query(captureAny, any)).thenAnswer((Invocation invocation) {
+        return Future<QueryResponse>.value(
+          QueryResponse.fromJson(jsonDecode(insertDeleteSuccessResponse) as Map<dynamic, dynamic>),
+        );
+      });
     });
 
     void verifyQueries(List<QueryOptions> expectedOptions) {
diff --git a/auto_submit/test/requests/github_webhook_test_data.dart b/auto_submit/test/requests/github_webhook_test_data.dart
index 1bef666..fd1fd2e 100644
--- a/auto_submit/test/requests/github_webhook_test_data.dart
+++ b/auto_submit/test/requests/github_webhook_test_data.dart
@@ -108,6 +108,7 @@
         }
       ],
       "created_at": "2011-01-26T19:01:12Z",
+      "closed_at": "2011-01-26T19:10:12Z",
       "head": {
         "label": "octocat:new-topic",
         "ref": "new-topic",
diff --git a/auto_submit/test/service/bigquery_test.dart b/auto_submit/test/service/bigquery_test.dart
new file mode 100644
index 0000000..60b3045
--- /dev/null
+++ b/auto_submit/test/service/bigquery_test.dart
@@ -0,0 +1,675 @@
+// Copyright 2022 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:convert';
+
+import 'package:auto_submit/exception/bigquery_exception.dart';
+import 'package:auto_submit/model/big_query_pull_request_record.dart';
+import 'package:auto_submit/model/big_query_revert_request_record.dart';
+import 'package:googleapis/bigquery/v2.dart';
+import 'package:mockito/mockito.dart';
+import 'package:test/expect.dart';
+import 'package:test/scaffolding.dart';
+
+import '../src/service/fake_bigquery_service.dart';
+import '../utilities/mocks.dart';
+
+const String revertRequestRecordResponse = '''
+{
+  "jobComplete": true,
+  "rows": [
+    { "f": [
+        { "v": "flutter"},
+        { "v": "cocoon" },
+        { "v": "ricardoamador" },
+        { "v": "1024" },
+        { "v": "123f124" },
+        { "v": "123456789" },
+        { "v": "123456999" },
+        { "v": "ricardoamador" },
+        { "v": "2048" },
+        { "v": "ce345dc" },
+        { "v": "234567890" },
+        { "v": "234567999" },
+        { "v": "ricardoamador" },
+        { "v": "11304" },
+        { "v": "1640979000000" },
+        { "v": null }
+      ]
+    }
+  ]
+}
+''';
+
+const String pullRequestRecordResponse = '''
+{
+  "jobComplete": true,
+  "rows": [
+    { "f": [
+        { "v": "123456789"},
+        { "v": "234567890" },
+        { "v": "flutter" },
+        { "v": "cocoon" },
+        { "v": "ricardoamador" },
+        { "v": "345" },
+        { "v": "ade456" },
+        { "v": "merge" }
+      ]
+    }
+  ]
+}
+''';
+
+const String successResponseNoRowsAffected = '''
+{
+  "jobComplete": true
+}
+''';
+
+const String insertDeleteSuccessResponse = '''
+{
+  "jobComplete": true,
+  "numDmlAffectedRows": "1"
+}
+''';
+
+const String insertDeleteSuccessTooManyRows = '''
+{
+  "jobComplete": true,
+  "numDmlAffectedRows": "2"
+}
+''';
+
+const String selectPullRequestTooManyRowsResponse = '''
+{
+  "jobComplete": true,
+  "numDmlAffectedRows": "2",
+  "rows": [
+    { "f": [
+        { "v": "123456789"},
+        { "v": "234567890" },
+        { "v": "flutter" },
+        { "v": "cocoon" },
+        { "v": "ricardoamador" },
+        { "v": "345" },
+        { "v": "ade456" },
+        { "v": "merge" }
+      ]
+    },
+    { "f": [
+        { "v": "123456789"},
+        { "v": "234567890" },
+        { "v": "flutter" },
+        { "v": "cocoon" },
+        { "v": "ricardoamador" },
+        { "v": "345" },
+        { "v": "ade456" },
+        { "v": "merge" }
+      ]
+    }
+  ]
+}
+''';
+
+const String selectRevertRequestTooManyRowsResponse = '''
+{
+  "jobComplete": true,
+  "numDmlAffectedRows": "2",
+  "rows": [
+    { "f": [
+        { "v": "flutter"},
+        { "v": "cocoon" },
+        { "v": "ricardoamador" },
+        { "v": "1024" },
+        { "v": "123f124" },
+        { "v": "123456789" },
+        { "v": "123456999" },
+        { "v": "ricardoamador" },
+        { "v": "2048" },
+        { "v": "ce345dc" },
+        { "v": "234567890" },
+        { "v": "234567999" }
+      ]
+    },
+    { "f": [
+        { "v": "flutter"},
+        { "v": "cocoon" },
+        { "v": "ricardoamador" },
+        { "v": "1024" },
+        { "v": "123f124" },
+        { "v": "123456789" },
+        { "v": "123456999" },
+        { "v": "ricardoamador" },
+        { "v": "2048" },
+        { "v": "ce345dc" },
+        { "v": "234567890" },
+        { "v": "234567999" }
+      ]
+    }
+  ]
+}
+''';
+
+const String errorResponse = '''
+{
+  "jobComplete": false
+}
+''';
+
+const String expectedProjectId = 'flutter-dashboard';
+
+void main() {
+  late FakeBigqueryService service;
+  late MockJobsResource jobsResource;
+
+  setUp(() {
+    jobsResource = MockJobsResource();
+    service = FakeBigqueryService(jobsResource);
+  });
+
+  test('Insert pull request record is successful.', () async {
+    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
+      return Future<QueryResponse>.value(
+        QueryResponse.fromJson(jsonDecode(insertDeleteSuccessResponse) as Map<dynamic, dynamic>),
+      );
+    });
+
+    PullRequestRecord pullRequestRecord = PullRequestRecord(
+      prCreatedTimestamp: DateTime.fromMillisecondsSinceEpoch(123456789),
+      prLandedTimestamp: DateTime.fromMillisecondsSinceEpoch(234567890),
+      organization: 'flutter',
+      repository: 'cocoon',
+      author: 'ricardoamador',
+      prNumber: 345,
+      prCommit: 'ade456',
+      prRequestType: 'merge',
+    );
+
+    bool hasError = false;
+    try {
+      await service.insertPullRequestRecord(
+        projectId: expectedProjectId,
+        pullRequestRecord: pullRequestRecord,
+      );
+    } on BigQueryException {
+      hasError = true;
+    }
+    expect(hasError, isFalse);
+  });
+
+  test('Insert pull request record handles unsuccessful job complete error.', () async {
+    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
+      return Future<QueryResponse>.value(
+        QueryResponse.fromJson(jsonDecode(errorResponse) as Map<dynamic, dynamic>),
+      );
+    });
+
+    bool hasError = false;
+    PullRequestRecord pullRequestRecord = PullRequestRecord(
+      prCreatedTimestamp: DateTime.fromMillisecondsSinceEpoch(123456789),
+      prLandedTimestamp: DateTime.fromMillisecondsSinceEpoch(234567890),
+      organization: 'flutter',
+      repository: 'cocoon',
+      author: 'ricardoamador',
+      prNumber: 345,
+      prCommit: 'ade456',
+      prRequestType: 'merge',
+    );
+
+    try {
+      await service.insertPullRequestRecord(
+        projectId: expectedProjectId,
+        pullRequestRecord: pullRequestRecord,
+      );
+    } on BigQueryException catch (exception) {
+      expect(exception.cause, 'Insert pull request $pullRequestRecord did not complete.');
+      hasError = true;
+    }
+    expect(hasError, isTrue);
+  });
+
+  test('Insert pull request fails when multiple rows are returned.', () async {
+    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
+      return Future<QueryResponse>.value(
+        QueryResponse.fromJson(jsonDecode(selectPullRequestTooManyRowsResponse) as Map<dynamic, dynamic>),
+      );
+    });
+
+    bool hasError = false;
+    PullRequestRecord pullRequestRecord = PullRequestRecord(
+      prCreatedTimestamp: DateTime.fromMillisecondsSinceEpoch(123456789),
+      prLandedTimestamp: DateTime.fromMillisecondsSinceEpoch(234567890),
+      organization: 'flutter',
+      repository: 'cocoon',
+      author: 'ricardoamador',
+      prNumber: 345,
+      prCommit: 'ade456',
+      prRequestType: 'merge',
+    );
+
+    try {
+      await service.insertPullRequestRecord(
+        projectId: expectedProjectId,
+        pullRequestRecord: pullRequestRecord,
+      );
+    } on BigQueryException catch (exception) {
+      expect(exception.cause, 'There was an error inserting $pullRequestRecord into the table.');
+      hasError = true;
+    }
+    expect(hasError, isTrue);
+  });
+
+  test('Select pull request is successful.', () async {
+    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
+      return Future<QueryResponse>.value(
+        QueryResponse.fromJson(jsonDecode(pullRequestRecordResponse) as Map<dynamic, dynamic>),
+      );
+    });
+
+    PullRequestRecord pullRequestRecord = await service.selectPullRequestRecordByPrNumber(
+      projectId: expectedProjectId,
+      prNumber: 345,
+      repository: 'cocoon',
+    );
+
+    expect(pullRequestRecord, isNotNull);
+    expect(pullRequestRecord.prCreatedTimestamp, equals(DateTime.fromMillisecondsSinceEpoch(123456789)));
+    expect(pullRequestRecord.prLandedTimestamp, equals(DateTime.fromMillisecondsSinceEpoch(234567890)));
+    expect(pullRequestRecord.organization, equals('flutter'));
+    expect(pullRequestRecord.repository, equals('cocoon'));
+    expect(pullRequestRecord.author, equals('ricardoamador'));
+    expect(pullRequestRecord.prNumber, 345);
+    expect(pullRequestRecord.prCommit, equals('ade456'));
+    expect(pullRequestRecord.prRequestType, equals('merge'));
+  });
+
+  test('Select pull request handles unsuccessful job failure.', () async {
+    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
+      return Future<QueryResponse>.value(QueryResponse.fromJson(jsonDecode(errorResponse) as Map<dynamic, dynamic>));
+    });
+
+    bool hasError = false;
+    try {
+      await service.selectPullRequestRecordByPrNumber(
+        projectId: expectedProjectId,
+        prNumber: 345,
+        repository: 'cocoon',
+      );
+    } on BigQueryException catch (exception) {
+      hasError = true;
+      expect(exception.cause, 'Get pull request by pr# 345 in repository cocoon did not complete.');
+    }
+    expect(hasError, isTrue);
+  });
+
+  test('Select pull request handles no rows returned failure.', () async {
+    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
+      return Future<QueryResponse>.value(
+        QueryResponse.fromJson(jsonDecode(successResponseNoRowsAffected) as Map<dynamic, dynamic>),
+      );
+    });
+
+    bool hasError = false;
+    try {
+      await service.selectPullRequestRecordByPrNumber(
+        projectId: expectedProjectId,
+        prNumber: 345,
+        repository: 'cocoon',
+      );
+    } on BigQueryException catch (exception) {
+      hasError = true;
+      expect(
+        exception.cause,
+        'Could not find an entry for pull request with pr# 345 in repository cocoon.',
+      );
+    }
+    expect(hasError, isTrue);
+  });
+
+  test('Select pull request handles too many rows returned failure.', () async {
+    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
+      return Future<QueryResponse>.value(
+        QueryResponse.fromJson(jsonDecode(selectPullRequestTooManyRowsResponse) as Map<dynamic, dynamic>),
+      );
+    });
+
+    bool hasError = false;
+    try {
+      await service.selectPullRequestRecordByPrNumber(
+        projectId: expectedProjectId,
+        prNumber: 345,
+        repository: 'cocoon',
+      );
+    } on BigQueryException catch (exception) {
+      hasError = true;
+      expect(
+        exception.cause,
+        'More than one record was returned for pull request with pr# 345 in repository cocoon.',
+      );
+    }
+    expect(hasError, isTrue);
+  });
+
+  test('Delete pull request record handles failure to complete job.', () async {
+    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
+      return Future<QueryResponse>.value(QueryResponse.fromJson(jsonDecode(errorResponse) as Map<dynamic, dynamic>));
+    });
+
+    bool hasError = false;
+    try {
+      await service.deletePullRequestRecord(
+        projectId: expectedProjectId,
+        prNumber: 345,
+        repository: 'cocoon',
+      );
+    } on BigQueryException catch (exception) {
+      hasError = true;
+      expect(
+        exception.cause,
+        'Delete pull request with pr# 345 in repository cocoon did not complete.',
+      );
+    }
+    expect(hasError, isTrue);
+  });
+
+  test('Delete pull request record handles success but no affected rows.', () async {
+    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
+      return Future<QueryResponse>.value(
+        QueryResponse.fromJson(jsonDecode(successResponseNoRowsAffected) as Map<dynamic, dynamic>),
+      );
+    });
+
+    bool hasError = false;
+    try {
+      await service.deletePullRequestRecord(
+        projectId: expectedProjectId,
+        prNumber: 345,
+        repository: 'cocoon',
+      );
+    } on BigQueryException catch (exception) {
+      hasError = true;
+      expect(
+        exception.cause,
+        'Could not find pull request with pr# 345 in repository cocoon to delete.',
+      );
+    }
+    expect(hasError, isTrue);
+  });
+
+  test('Delete pull request record handles success but wrong number of affected rows.', () async {
+    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
+      return Future<QueryResponse>.value(
+        QueryResponse.fromJson(jsonDecode(insertDeleteSuccessTooManyRows) as Map<dynamic, dynamic>),
+      );
+    });
+
+    bool hasError = false;
+    try {
+      await service.deletePullRequestRecord(
+        projectId: expectedProjectId,
+        prNumber: 345,
+        repository: 'cocoon',
+      );
+    } on BigQueryException catch (exception) {
+      hasError = true;
+      expect(
+        exception.cause,
+        'More than one row was deleted from the database for pull request with pr# 345 in repository cocoon.',
+      );
+    }
+    expect(hasError, isTrue);
+  });
+
+  test('Insert revert request record is successful.', () async {
+    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
+      return Future<QueryResponse>.value(
+        QueryResponse.fromJson(jsonDecode(insertDeleteSuccessResponse) as Map<dynamic, dynamic>),
+      );
+    });
+
+    RevertRequestRecord revertRequestRecord = RevertRequestRecord(
+      organization: 'flutter',
+      repository: 'cocoon',
+      author: 'ricardoamador',
+      prNumber: 1024,
+      prCommit: '123f124',
+      prCreatedTimestamp: DateTime.fromMillisecondsSinceEpoch(123456789),
+      prLandedTimestamp: DateTime.fromMillisecondsSinceEpoch(123456999),
+      originalPrAuthor: 'ricardoamador',
+      originalPrNumber: 1000,
+      originalPrCommit: 'ce345dc',
+      originalPrCreatedTimestamp: DateTime.fromMillisecondsSinceEpoch(234567890),
+      originalPrLandedTimestamp: DateTime.fromMillisecondsSinceEpoch(234567999),
+      reviewIssueAssignee: 'ricardoamador',
+      reviewIssueNumber: 11304,
+      reviewIssueCreatedTimestamp: DateTime.fromMillisecondsSinceEpoch(1640979000000),
+    );
+
+    bool hasError = false;
+    try {
+      await service.insertRevertRequestRecord(
+        projectId: expectedProjectId,
+        revertRequestRecord: revertRequestRecord,
+      );
+    } on BigQueryException {
+      hasError = true;
+    }
+    expect(hasError, isFalse);
+  });
+
+  test('Insert revert request record handles unsuccessful job complete error.', () async {
+    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
+      return Future<QueryResponse>.value(
+        QueryResponse.fromJson(jsonDecode(errorResponse) as Map<dynamic, dynamic>),
+      );
+    });
+
+    bool hasError = false;
+    RevertRequestRecord revertRequestRecord = RevertRequestRecord(
+      organization: 'flutter',
+      repository: 'cocoon',
+      author: 'ricardoamador',
+      prNumber: 1024,
+      prCommit: '123f124',
+      prCreatedTimestamp: DateTime.fromMillisecondsSinceEpoch(123456789),
+      prLandedTimestamp: DateTime.fromMillisecondsSinceEpoch(123456999),
+      originalPrAuthor: 'ricardoamador',
+      originalPrNumber: 1000,
+      originalPrCommit: 'ce345dc',
+      originalPrCreatedTimestamp: DateTime.fromMillisecondsSinceEpoch(234567890),
+      originalPrLandedTimestamp: DateTime.fromMillisecondsSinceEpoch(234567999),
+      reviewIssueAssignee: 'ricardoamador',
+      reviewIssueNumber: 11304,
+      reviewIssueCreatedTimestamp: DateTime.fromMillisecondsSinceEpoch(1640979000000),
+    );
+
+    try {
+      await service.insertRevertRequestRecord(
+        projectId: expectedProjectId,
+        revertRequestRecord: revertRequestRecord,
+      );
+    } on BigQueryException catch (e) {
+      expect(e.cause, 'Insert revert request $revertRequestRecord did not complete.');
+      hasError = true;
+    }
+    expect(hasError, isTrue);
+  });
+
+  test('Select revert request is successful.', () async {
+    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
+      return Future<QueryResponse>.value(
+        QueryResponse.fromJson(jsonDecode(revertRequestRecordResponse) as Map<dynamic, dynamic>),
+      );
+    });
+
+    RevertRequestRecord revertRequestRecord = await service.selectRevertRequestByRevertPrNumber(
+      projectId: expectedProjectId,
+      prNumber: 2048,
+      repository: 'cocoon',
+    );
+
+    expect(revertRequestRecord, isNotNull);
+    expect(revertRequestRecord.organization, equals('flutter'));
+    expect(revertRequestRecord.repository, equals('cocoon'));
+    expect(revertRequestRecord.author, equals('ricardoamador'));
+    expect(revertRequestRecord.prNumber, equals(1024));
+    expect(revertRequestRecord.prCommit, equals('123f124'));
+    expect(revertRequestRecord.prCreatedTimestamp, equals(DateTime.fromMillisecondsSinceEpoch(123456789)));
+    expect(revertRequestRecord.prLandedTimestamp, equals(DateTime.fromMillisecondsSinceEpoch(123456999)));
+    expect(revertRequestRecord.originalPrAuthor, equals('ricardoamador'));
+    expect(revertRequestRecord.originalPrNumber, equals(2048));
+    expect(revertRequestRecord.originalPrCommit, equals('ce345dc'));
+    expect(revertRequestRecord.originalPrCreatedTimestamp, equals(DateTime.fromMillisecondsSinceEpoch(234567890)));
+    expect(revertRequestRecord.originalPrLandedTimestamp, equals(DateTime.fromMillisecondsSinceEpoch(234567999)));
+    // { "v": "ricardoamador" },
+    //     { "v": "11304" },
+    //     { "v": "1640979000000" },
+    //     { "v": null },
+    expect(revertRequestRecord.reviewIssueAssignee, equals('ricardoamador'));
+    expect(revertRequestRecord.reviewIssueNumber, equals(11304));
+    expect(revertRequestRecord.reviewIssueCreatedTimestamp, equals(DateTime.fromMillisecondsSinceEpoch(1640979000000)));
+    expect(revertRequestRecord.reviewIssueLandedTimestamp, isNull);
+  });
+
+  test('Select revert request is unsuccessful with job did not complete error.', () async {
+    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
+      return Future<QueryResponse>.value(
+        QueryResponse.fromJson(jsonDecode(errorResponse) as Map<dynamic, dynamic>),
+      );
+    });
+
+    bool hasError = false;
+    try {
+      await service.selectRevertRequestByRevertPrNumber(
+        projectId: expectedProjectId,
+        prNumber: 2048,
+        repository: 'cocoon',
+      );
+    } on BigQueryException catch (exception) {
+      hasError = true;
+      expect(exception.cause, 'Get revert request with pr# 2048 in repository cocoon did not complete.');
+    }
+    expect(hasError, isTrue);
+  });
+
+  test('Select revert request is successful but does not return any rows.', () async {
+    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
+      return Future<QueryResponse>.value(
+        QueryResponse.fromJson(jsonDecode(successResponseNoRowsAffected) as Map<dynamic, dynamic>),
+      );
+    });
+
+    bool hasError = false;
+    try {
+      await service.selectRevertRequestByRevertPrNumber(
+        projectId: expectedProjectId,
+        prNumber: 2048,
+        repository: 'cocoon',
+      );
+    } on BigQueryException catch (exception) {
+      hasError = true;
+      expect(
+        exception.cause,
+        'Could not find an entry for revert request with pr# 2048 in repository cocoon.',
+      );
+    }
+    expect(hasError, isTrue);
+  });
+
+  test('Select is successful but returns more than one row in the request.', () async {
+    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
+      return Future<QueryResponse>.value(
+        QueryResponse.fromJson(jsonDecode(selectRevertRequestTooManyRowsResponse) as Map<dynamic, dynamic>),
+      );
+    });
+
+    bool hasError = false;
+    try {
+      await service.selectRevertRequestByRevertPrNumber(
+        projectId: expectedProjectId,
+        prNumber: 2048,
+        repository: 'cocoon',
+      );
+    } on BigQueryException catch (exception) {
+      hasError = true;
+      expect(
+        exception.cause,
+        'More than one record was returned for revert request with pr# 2048 in repository cocoon.',
+      );
+    }
+    expect(hasError, isTrue);
+  });
+
+  test('Delete revert request record handles failure to complete job.', () async {
+    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
+      return Future<QueryResponse>.value(
+        QueryResponse.fromJson(jsonDecode(errorResponse) as Map<dynamic, dynamic>),
+      );
+    });
+
+    bool hasError = false;
+    try {
+      await service.deleteRevertRequestRecord(
+        projectId: expectedProjectId,
+        prNumber: 2048,
+        repository: 'cocoon',
+      );
+    } on BigQueryException catch (exception) {
+      hasError = true;
+      expect(
+        exception.cause,
+        'Delete revert request with pr# 2048 in repository cocoon did not complete.',
+      );
+    }
+    expect(hasError, isTrue);
+  });
+
+  test('Delete revert request record handles success but no affected rows.', () async {
+    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
+      return Future<QueryResponse>.value(
+        QueryResponse.fromJson(jsonDecode(successResponseNoRowsAffected) as Map<dynamic, dynamic>),
+      );
+    });
+
+    bool hasError = false;
+    try {
+      await service.deleteRevertRequestRecord(
+        projectId: expectedProjectId,
+        prNumber: 2048,
+        repository: 'cocoon',
+      );
+    } on BigQueryException catch (exception) {
+      hasError = true;
+      expect(
+        exception.cause,
+        'Could not find revert request with pr# 2048 in repository cocoon to delete.',
+      );
+    }
+    expect(hasError, isTrue);
+  });
+
+  test('Delete revert request record handles success but wrong number of affected rows.', () async {
+    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
+      return Future<QueryResponse>.value(
+        QueryResponse.fromJson(jsonDecode(insertDeleteSuccessTooManyRows) as Map<dynamic, dynamic>),
+      );
+    });
+
+    bool hasError = false;
+    try {
+      await service.deleteRevertRequestRecord(
+        projectId: expectedProjectId,
+        prNumber: 2048,
+        repository: 'cocoon',
+      );
+    } on BigQueryException catch (exception) {
+      hasError = true;
+      expect(
+        exception.cause,
+        'More than one row was deleted from the database for revert request with pr# 2048 in repository cocoon.',
+      );
+    }
+    expect(hasError, isTrue);
+  });
+}
diff --git a/auto_submit/test/service/validation_service_test.dart b/auto_submit/test/service/validation_service_test.dart
index a0537de..2ed3fbd 100644
--- a/auto_submit/test/service/validation_service_test.dart
+++ b/auto_submit/test/service/validation_service_test.dart
@@ -3,25 +3,30 @@
 // found in the LICENSE file.
 
 import 'dart:async';
+import 'dart:convert';
 
 import 'package:auto_submit/model/auto_submit_query_result.dart' as auto hide PullRequest;
 import 'package:auto_submit/service/process_method.dart';
 import 'package:auto_submit/service/validation_service.dart';
 import 'package:auto_submit/validations/validation.dart';
 import 'package:github/github.dart';
+import 'package:googleapis/bigquery/v2.dart';
 import 'package:graphql/client.dart';
+import 'package:mockito/mockito.dart';
 import 'package:retry/retry.dart';
 import 'package:test/test.dart';
 
 import '../requests/github_webhook_test_data.dart';
 import '../src/request_handling/fake_pubsub.dart';
 import '../src/service/fake_approver_service.dart';
+import '../src/service/fake_bigquery_service.dart';
 import '../src/service/fake_config.dart';
 import '../src/service/fake_graphql_client.dart';
 import '../src/service/fake_github_service.dart';
 import '../src/validations/fake_revert.dart';
 import '../utilities/utils.dart';
 import '../utilities/mocks.dart';
+import 'bigquery_test.dart';
 
 void main() {
   late ValidationService validationService;
@@ -30,12 +35,25 @@
   late FakeGraphQLClient githubGraphQLClient;
   late RepositorySlug slug;
 
+  late MockJobsResource jobsResource;
+  late FakeBigqueryService bigqueryService;
+
   setUp(() {
     githubGraphQLClient = FakeGraphQLClient();
     githubService = FakeGithubService(client: MockGitHub());
     config = FakeConfig(githubService: githubService, githubGraphQLClient: githubGraphQLClient);
     validationService = ValidationService(config);
     slug = RepositorySlug('flutter', 'cocoon');
+
+    jobsResource = MockJobsResource();
+    bigqueryService = FakeBigqueryService(jobsResource);
+    config.bigqueryService = bigqueryService;
+
+    when(jobsResource.query(captureAny, any)).thenAnswer((Invocation invocation) {
+      return Future<QueryResponse>.value(
+        QueryResponse.fromJson(jsonDecode(insertDeleteSuccessResponse) as Map<dynamic, dynamic>),
+      );
+    });
   });
 
   test('Removes label and post comment when no approval', () async {
@@ -121,8 +139,11 @@
 
       final Issue issue = Issue(
         id: 1234,
+        assignee: User(login: 'keyonghan'),
+        createdAt: DateTime.now(),
       );
       githubService.githubIssueMock = issue;
+      githubService.pullRequestMock = pullRequest;
 
       unawaited(pubsub.publish('auto-submit-queue-sub', pullRequest));
       final auto.QueryResult queryResult = createQueryResult(flutterRequest);
@@ -312,6 +333,8 @@
 
       final Issue issue = Issue(
         id: 1234,
+        assignee: User(login: 'keyonghan'),
+        createdAt: DateTime.now(),
       );
       githubService.githubIssueMock = issue;
 
@@ -367,6 +390,8 @@
 
       final Issue issue = Issue(
         id: 1234,
+        assignee: User(login: 'keyonghan'),
+        createdAt: DateTime.now(),
       );
       githubService.githubIssueMock = issue;
 
@@ -427,6 +452,8 @@
 
       final Issue issue = Issue(
         id: 1234,
+        assignee: User(login: 'keyonghan'),
+        createdAt: DateTime.now(),
       );
       githubService.githubIssueMock = issue;
 
@@ -498,8 +525,11 @@
 
       final Issue issue = Issue(
         id: 1234,
+        assignee: User(login: 'keyonghan'),
+        createdAt: DateTime.now(),
       );
       githubService.githubIssueMock = issue;
+      githubService.pullRequestMock = pullRequest;
 
       unawaited(pubsub.publish('auto-submit-queue-sub', pullRequest));
       final auto.QueryResult queryResult = createQueryResult(flutterRequest);
diff --git a/auto_submit/test/src/service/fake_bigquery_service.dart b/auto_submit/test/src/service/fake_bigquery_service.dart
new file mode 100644
index 0000000..d9cbd3a
--- /dev/null
+++ b/auto_submit/test/src/service/fake_bigquery_service.dart
@@ -0,0 +1,19 @@
+// Copyright 2022 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 'package:auto_submit/service/bigquery.dart';
+import 'package:googleapis/bigquery/v2.dart';
+
+import '../../utilities/mocks.mocks.dart';
+
+class FakeBigqueryService extends BigqueryService {
+  FakeBigqueryService(this.jobsResource) : super(MockAccessClientProvider());
+
+  JobsResource jobsResource;
+
+  @override
+  Future<JobsResource> defaultJobs() async {
+    return jobsResource;
+  }
+}
diff --git a/auto_submit/test/src/service/fake_config.dart b/auto_submit/test/src/service/fake_config.dart
index 6193be0..b2a698e 100644
--- a/auto_submit/test/src/service/fake_config.dart
+++ b/auto_submit/test/src/service/fake_config.dart
@@ -4,6 +4,7 @@
 
 import 'dart:async';
 
+import 'package:auto_submit/service/bigquery.dart';
 import 'package:auto_submit/service/config.dart';
 import 'package:auto_submit/service/github_service.dart';
 import 'package:auto_submit/service/secrets.dart';
@@ -35,6 +36,7 @@
   String? overrideTreeStatusLabelValue;
   String? webhookKey;
   int? kPubsubPullNumberValue;
+  BigqueryService? bigqueryService;
 
   @override
   int get kPubsubPullNumber => kPubsubPullNumberValue ?? 1;
@@ -72,4 +74,7 @@
   Future<String> getFlutterGitHubBotToken() async {
     return 'not_a_real_token';
   }
+
+  @override
+  Future<BigqueryService> createBigQueryService() async => bigqueryService!;
 }
diff --git a/auto_submit/test/src/service/fake_github_service.dart b/auto_submit/test/src/service/fake_github_service.dart
index 9483275..ae5eccc 100644
--- a/auto_submit/test/src/service/fake_github_service.dart
+++ b/auto_submit/test/src/service/fake_github_service.dart
@@ -114,11 +114,13 @@
 
   @override
   Future<PullRequest> getPullRequest(RepositorySlug slug, int pullRequestNumber) async {
-    PullRequest pullRequest = pullRequestMock!;
+    PullRequest pullRequest;
     if (usePullRequestList && pullRequestMockList.isNotEmpty) {
       pullRequest = pullRequestMockList.removeAt(0)!;
     } else if (usePullRequestList && pullRequestMockList.isEmpty) {
       throw Exception('List is empty.');
+    } else {
+      pullRequest = pullRequestMock!;
     }
     return pullRequest;
   }
diff --git a/auto_submit/test/utilities/mocks.dart b/auto_submit/test/utilities/mocks.dart
index 544567f..06dafe0 100644
--- a/auto_submit/test/utilities/mocks.dart
+++ b/auto_submit/test/utilities/mocks.dart
@@ -2,14 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'package:auto_submit/service/access_client_provider.dart';
 import 'package:auto_submit/service/approver_service.dart';
 import 'package:github/github.dart';
+import 'package:googleapis/bigquery/v2.dart';
 import 'package:mockito/annotations.dart';
 import 'package:http/http.dart' as http;
 
 export 'mocks.mocks.dart';
 
 @GenerateMocks(<Type>[
+  AccessClientProvider,
+  JobsResource,
   ApproverService,
   GitHub,
   PullRequestsService,
diff --git a/auto_submit/test/utilities/mocks.mocks.dart b/auto_submit/test/utilities/mocks.mocks.dart
index b69010b..9be1dbe 100644
--- a/auto_submit/test/utilities/mocks.mocks.dart
+++ b/auto_submit/test/utilities/mocks.mocks.dart
@@ -3,14 +3,17 @@
 // Do not manually edit this file.
 
 // ignore_for_file: no_leading_underscores_for_library_prefixes
-import 'dart:async' as _i6;
-import 'dart:typed_data' as _i8;
+import 'dart:async' as _i7;
+import 'dart:typed_data' as _i11;
 
-import 'package:auto_submit/model/auto_submit_query_result.dart' as _i7;
-import 'package:auto_submit/service/approver_service.dart' as _i5;
-import 'package:auto_submit/service/config.dart' as _i2;
-import 'package:github/github.dart' as _i4;
-import 'package:http/http.dart' as _i3;
+import 'package:_discoveryapis_commons/_discoveryapis_commons.dart' as _i8;
+import 'package:auto_submit/model/auto_submit_query_result.dart' as _i10;
+import 'package:auto_submit/service/access_client_provider.dart' as _i6;
+import 'package:auto_submit/service/approver_service.dart' as _i9;
+import 'package:auto_submit/service/config.dart' as _i4;
+import 'package:github/github.dart' as _i5;
+import 'package:googleapis/bigquery/v2.dart' as _i3;
+import 'package:http/http.dart' as _i2;
 import 'package:mockito/mockito.dart' as _i1;
 
 // ignore_for_file: type=lint
@@ -24,262 +27,421 @@
 // ignore_for_file: camel_case_types
 // ignore_for_file: subtype_of_sealed_class
 
-class _FakeConfig_0 extends _i1.SmartFake implements _i2.Config {
-  _FakeConfig_0(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeClient_0 extends _i1.SmartFake implements _i2.Client {
+  _FakeClient_0(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeClient_1 extends _i1.SmartFake implements _i3.Client {
-  _FakeClient_1(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeJobCancelResponse_1 extends _i1.SmartFake implements _i3.JobCancelResponse {
+  _FakeJobCancelResponse_1(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeActivityService_2 extends _i1.SmartFake implements _i4.ActivityService {
-  _FakeActivityService_2(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeJob_2 extends _i1.SmartFake implements _i3.Job {
+  _FakeJob_2(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeAuthorizationsService_3 extends _i1.SmartFake implements _i4.AuthorizationsService {
-  _FakeAuthorizationsService_3(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeGetQueryResultsResponse_3 extends _i1.SmartFake implements _i3.GetQueryResultsResponse {
+  _FakeGetQueryResultsResponse_3(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeGistsService_4 extends _i1.SmartFake implements _i4.GistsService {
-  _FakeGistsService_4(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeJobList_4 extends _i1.SmartFake implements _i3.JobList {
+  _FakeJobList_4(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeGitService_5 extends _i1.SmartFake implements _i4.GitService {
-  _FakeGitService_5(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeQueryResponse_5 extends _i1.SmartFake implements _i3.QueryResponse {
+  _FakeQueryResponse_5(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeIssuesService_6 extends _i1.SmartFake implements _i4.IssuesService {
-  _FakeIssuesService_6(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeConfig_6 extends _i1.SmartFake implements _i4.Config {
+  _FakeConfig_6(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeMiscService_7 extends _i1.SmartFake implements _i4.MiscService {
-  _FakeMiscService_7(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeActivityService_7 extends _i1.SmartFake implements _i5.ActivityService {
+  _FakeActivityService_7(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeOrganizationsService_8 extends _i1.SmartFake implements _i4.OrganizationsService {
-  _FakeOrganizationsService_8(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeAuthorizationsService_8 extends _i1.SmartFake implements _i5.AuthorizationsService {
+  _FakeAuthorizationsService_8(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakePullRequestsService_9 extends _i1.SmartFake implements _i4.PullRequestsService {
-  _FakePullRequestsService_9(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeGistsService_9 extends _i1.SmartFake implements _i5.GistsService {
+  _FakeGistsService_9(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeRepositoriesService_10 extends _i1.SmartFake implements _i4.RepositoriesService {
-  _FakeRepositoriesService_10(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeGitService_10 extends _i1.SmartFake implements _i5.GitService {
+  _FakeGitService_10(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeSearchService_11 extends _i1.SmartFake implements _i4.SearchService {
-  _FakeSearchService_11(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeIssuesService_11 extends _i1.SmartFake implements _i5.IssuesService {
+  _FakeIssuesService_11(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeUrlShortenerService_12 extends _i1.SmartFake implements _i4.UrlShortenerService {
-  _FakeUrlShortenerService_12(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeMiscService_12 extends _i1.SmartFake implements _i5.MiscService {
+  _FakeMiscService_12(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeUsersService_13 extends _i1.SmartFake implements _i4.UsersService {
-  _FakeUsersService_13(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeOrganizationsService_13 extends _i1.SmartFake implements _i5.OrganizationsService {
+  _FakeOrganizationsService_13(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeChecksService_14 extends _i1.SmartFake implements _i4.ChecksService {
-  _FakeChecksService_14(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakePullRequestsService_14 extends _i1.SmartFake implements _i5.PullRequestsService {
+  _FakePullRequestsService_14(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeResponse_15 extends _i1.SmartFake implements _i3.Response {
-  _FakeResponse_15(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeRepositoriesService_15 extends _i1.SmartFake implements _i5.RepositoriesService {
+  _FakeRepositoriesService_15(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeGitHub_16 extends _i1.SmartFake implements _i4.GitHub {
-  _FakeGitHub_16(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeSearchService_16 extends _i1.SmartFake implements _i5.SearchService {
+  _FakeSearchService_16(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakePullRequest_17 extends _i1.SmartFake implements _i4.PullRequest {
-  _FakePullRequest_17(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeUrlShortenerService_17 extends _i1.SmartFake implements _i5.UrlShortenerService {
+  _FakeUrlShortenerService_17(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakePullRequestMerge_18 extends _i1.SmartFake implements _i4.PullRequestMerge {
-  _FakePullRequestMerge_18(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeUsersService_18 extends _i1.SmartFake implements _i5.UsersService {
+  _FakeUsersService_18(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakePullRequestComment_19 extends _i1.SmartFake implements _i4.PullRequestComment {
-  _FakePullRequestComment_19(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeChecksService_19 extends _i1.SmartFake implements _i5.ChecksService {
+  _FakeChecksService_19(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakePullRequestReview_20 extends _i1.SmartFake implements _i4.PullRequestReview {
-  _FakePullRequestReview_20(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeResponse_20 extends _i1.SmartFake implements _i2.Response {
+  _FakeResponse_20(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeRepository_21 extends _i1.SmartFake implements _i4.Repository {
-  _FakeRepository_21(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeGitHub_21 extends _i1.SmartFake implements _i5.GitHub {
+  _FakeGitHub_21(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeLicenseDetails_22 extends _i1.SmartFake implements _i4.LicenseDetails {
-  _FakeLicenseDetails_22(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakePullRequest_22 extends _i1.SmartFake implements _i5.PullRequest {
+  _FakePullRequest_22(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeLanguageBreakdown_23 extends _i1.SmartFake implements _i4.LanguageBreakdown {
-  _FakeLanguageBreakdown_23(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakePullRequestMerge_23 extends _i1.SmartFake implements _i5.PullRequestMerge {
+  _FakePullRequestMerge_23(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeBranch_24 extends _i1.SmartFake implements _i4.Branch {
-  _FakeBranch_24(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakePullRequestComment_24 extends _i1.SmartFake implements _i5.PullRequestComment {
+  _FakePullRequestComment_24(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeCommitComment_25 extends _i1.SmartFake implements _i4.CommitComment {
-  _FakeCommitComment_25(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakePullRequestReview_25 extends _i1.SmartFake implements _i5.PullRequestReview {
+  _FakePullRequestReview_25(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeRepositoryCommit_26 extends _i1.SmartFake implements _i4.RepositoryCommit {
-  _FakeRepositoryCommit_26(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeRepository_26 extends _i1.SmartFake implements _i5.Repository {
+  _FakeRepository_26(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeGitHubComparison_27 extends _i1.SmartFake implements _i4.GitHubComparison {
-  _FakeGitHubComparison_27(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeLicenseDetails_27 extends _i1.SmartFake implements _i5.LicenseDetails {
+  _FakeLicenseDetails_27(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeGitHubFile_28 extends _i1.SmartFake implements _i4.GitHubFile {
-  _FakeGitHubFile_28(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeLanguageBreakdown_28 extends _i1.SmartFake implements _i5.LanguageBreakdown {
+  _FakeLanguageBreakdown_28(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeRepositoryContents_29 extends _i1.SmartFake implements _i4.RepositoryContents {
-  _FakeRepositoryContents_29(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeBranch_29 extends _i1.SmartFake implements _i5.Branch {
+  _FakeBranch_29(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeContentCreation_30 extends _i1.SmartFake implements _i4.ContentCreation {
-  _FakeContentCreation_30(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeCommitComment_30 extends _i1.SmartFake implements _i5.CommitComment {
+  _FakeCommitComment_30(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeHook_31 extends _i1.SmartFake implements _i4.Hook {
-  _FakeHook_31(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeRepositoryCommit_31 extends _i1.SmartFake implements _i5.RepositoryCommit {
+  _FakeRepositoryCommit_31(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakePublicKey_32 extends _i1.SmartFake implements _i4.PublicKey {
-  _FakePublicKey_32(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeGitHubComparison_32 extends _i1.SmartFake implements _i5.GitHubComparison {
+  _FakeGitHubComparison_32(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeRepositoryPages_33 extends _i1.SmartFake implements _i4.RepositoryPages {
-  _FakeRepositoryPages_33(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeGitHubFile_33 extends _i1.SmartFake implements _i5.GitHubFile {
+  _FakeGitHubFile_33(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakePageBuild_34 extends _i1.SmartFake implements _i4.PageBuild {
-  _FakePageBuild_34(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeRepositoryContents_34 extends _i1.SmartFake implements _i5.RepositoryContents {
+  _FakeRepositoryContents_34(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeRelease_35 extends _i1.SmartFake implements _i4.Release {
-  _FakeRelease_35(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeContentCreation_35 extends _i1.SmartFake implements _i5.ContentCreation {
+  _FakeContentCreation_35(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeReleaseAsset_36 extends _i1.SmartFake implements _i4.ReleaseAsset {
-  _FakeReleaseAsset_36(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeHook_36 extends _i1.SmartFake implements _i5.Hook {
+  _FakeHook_36(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeContributorParticipation_37 extends _i1.SmartFake implements _i4.ContributorParticipation {
-  _FakeContributorParticipation_37(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakePublicKey_37 extends _i1.SmartFake implements _i5.PublicKey {
+  _FakePublicKey_37(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeRepositoryStatus_38 extends _i1.SmartFake implements _i4.RepositoryStatus {
-  _FakeRepositoryStatus_38(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeRepositoryPages_38 extends _i1.SmartFake implements _i5.RepositoryPages {
+  _FakeRepositoryPages_38(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeCombinedRepositoryStatus_39 extends _i1.SmartFake implements _i4.CombinedRepositoryStatus {
-  _FakeCombinedRepositoryStatus_39(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakePageBuild_39 extends _i1.SmartFake implements _i5.PageBuild {
+  _FakePageBuild_39(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
 }
 
-class _FakeReleaseNotes_40 extends _i1.SmartFake implements _i4.ReleaseNotes {
-  _FakeReleaseNotes_40(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+class _FakeRelease_40 extends _i1.SmartFake implements _i5.Release {
+  _FakeRelease_40(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
+
+class _FakeReleaseAsset_41 extends _i1.SmartFake implements _i5.ReleaseAsset {
+  _FakeReleaseAsset_41(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
+
+class _FakeContributorParticipation_42 extends _i1.SmartFake implements _i5.ContributorParticipation {
+  _FakeContributorParticipation_42(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
+
+class _FakeRepositoryStatus_43 extends _i1.SmartFake implements _i5.RepositoryStatus {
+  _FakeRepositoryStatus_43(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
+
+class _FakeCombinedRepositoryStatus_44 extends _i1.SmartFake implements _i5.CombinedRepositoryStatus {
+  _FakeCombinedRepositoryStatus_44(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
+
+class _FakeReleaseNotes_45 extends _i1.SmartFake implements _i5.ReleaseNotes {
+  _FakeReleaseNotes_45(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
+
+/// A class which mocks [AccessClientProvider].
+///
+/// See the documentation for Mockito's code generation for more information.
+class MockAccessClientProvider extends _i1.Mock implements _i6.AccessClientProvider {
+  MockAccessClientProvider() {
+    _i1.throwOnMissingStub(this);
+  }
+
+  @override
+  _i7.Future<_i2.Client> createAccessClient(
+          {List<String>? scopes = const [r'https://www.googleapis.com/auth/cloud-platform']}) =>
+      (super.noSuchMethod(Invocation.method(#createAccessClient, [], {#scopes: scopes}),
+              returnValue: _i7.Future<_i2.Client>.value(
+                  _FakeClient_0(this, Invocation.method(#createAccessClient, [], {#scopes: scopes}))))
+          as _i7.Future<_i2.Client>);
+}
+
+/// A class which mocks [JobsResource].
+///
+/// See the documentation for Mockito's code generation for more information.
+class MockJobsResource extends _i1.Mock implements _i3.JobsResource {
+  MockJobsResource() {
+    _i1.throwOnMissingStub(this);
+  }
+
+  @override
+  _i7.Future<_i3.JobCancelResponse> cancel(String? projectId, String? jobId, {String? location, String? $fields}) =>
+      (super.noSuchMethod(Invocation.method(#cancel, [projectId, jobId], {#location: location, #$fields: $fields}),
+              returnValue: _i7.Future<_i3.JobCancelResponse>.value(_FakeJobCancelResponse_1(
+                  this, Invocation.method(#cancel, [projectId, jobId], {#location: location, #$fields: $fields}))))
+          as _i7.Future<_i3.JobCancelResponse>);
+  @override
+  _i7.Future<void> delete(String? projectId, String? jobId, {String? location, String? $fields}) =>
+      (super.noSuchMethod(Invocation.method(#delete, [projectId, jobId], {#location: location, #$fields: $fields}),
+          returnValue: _i7.Future<void>.value(),
+          returnValueForMissingStub: _i7.Future<void>.value()) as _i7.Future<void>);
+  @override
+  _i7.Future<_i3.Job> get(String? projectId, String? jobId, {String? location, String? $fields}) => (super.noSuchMethod(
+          Invocation.method(#get, [projectId, jobId], {#location: location, #$fields: $fields}),
+          returnValue: _i7.Future<_i3.Job>.value(
+              _FakeJob_2(this, Invocation.method(#get, [projectId, jobId], {#location: location, #$fields: $fields}))))
+      as _i7.Future<_i3.Job>);
+  @override
+  _i7.Future<_i3.GetQueryResultsResponse> getQueryResults(String? projectId, String? jobId,
+          {String? location,
+          int? maxResults,
+          String? pageToken,
+          String? startIndex,
+          int? timeoutMs,
+          String? $fields}) =>
+      (super.noSuchMethod(
+          Invocation.method(#getQueryResults, [
+            projectId,
+            jobId
+          ], {
+            #location: location,
+            #maxResults: maxResults,
+            #pageToken: pageToken,
+            #startIndex: startIndex,
+            #timeoutMs: timeoutMs,
+            #$fields: $fields
+          }),
+          returnValue: _i7.Future<_i3.GetQueryResultsResponse>.value(_FakeGetQueryResultsResponse_3(
+              this,
+              Invocation.method(#getQueryResults, [
+                projectId,
+                jobId
+              ], {
+                #location: location,
+                #maxResults: maxResults,
+                #pageToken: pageToken,
+                #startIndex: startIndex,
+                #timeoutMs: timeoutMs,
+                #$fields: $fields
+              })))) as _i7.Future<_i3.GetQueryResultsResponse>);
+  @override
+  _i7.Future<_i3.Job> insert(_i3.Job? request, String? projectId,
+          {String? $fields,
+          _i8.UploadOptions? uploadOptions = _i8.UploadOptions.defaultOptions,
+          _i8.Media? uploadMedia}) =>
+      (super.noSuchMethod(Invocation.method(#insert, [request, projectId], {#$fields: $fields, #uploadOptions: uploadOptions, #uploadMedia: uploadMedia}),
+          returnValue: _i7.Future<_i3.Job>.value(_FakeJob_2(
+              this,
+              Invocation.method(#insert, [
+                request,
+                projectId
+              ], {
+                #$fields: $fields,
+                #uploadOptions: uploadOptions,
+                #uploadMedia: uploadMedia
+              })))) as _i7.Future<_i3.Job>);
+  @override
+  _i7.Future<_i3.JobList> list(String? projectId,
+          {bool? allUsers,
+          String? maxCreationTime,
+          int? maxResults,
+          String? minCreationTime,
+          String? pageToken,
+          String? parentJobId,
+          String? projection,
+          List<String>? stateFilter,
+          String? $fields}) =>
+      (super.noSuchMethod(
+          Invocation.method(#list, [
+            projectId
+          ], {
+            #allUsers: allUsers,
+            #maxCreationTime: maxCreationTime,
+            #maxResults: maxResults,
+            #minCreationTime: minCreationTime,
+            #pageToken: pageToken,
+            #parentJobId: parentJobId,
+            #projection: projection,
+            #stateFilter: stateFilter,
+            #$fields: $fields
+          }),
+          returnValue: _i7.Future<_i3.JobList>.value(_FakeJobList_4(
+              this,
+              Invocation.method(#list, [
+                projectId
+              ], {
+                #allUsers: allUsers,
+                #maxCreationTime: maxCreationTime,
+                #maxResults: maxResults,
+                #minCreationTime: minCreationTime,
+                #pageToken: pageToken,
+                #parentJobId: parentJobId,
+                #projection: projection,
+                #stateFilter: stateFilter,
+                #$fields: $fields
+              })))) as _i7.Future<_i3.JobList>);
+  @override
+  _i7.Future<_i3.QueryResponse> query(_i3.QueryRequest? request, String? projectId, {String? $fields}) =>
+      (super.noSuchMethod(Invocation.method(#query, [request, projectId], {#$fields: $fields}),
+              returnValue: _i7.Future<_i3.QueryResponse>.value(
+                  _FakeQueryResponse_5(this, Invocation.method(#query, [request, projectId], {#$fields: $fields}))))
+          as _i7.Future<_i3.QueryResponse>);
 }
 
 /// A class which mocks [ApproverService].
 ///
 /// See the documentation for Mockito's code generation for more information.
-class MockApproverService extends _i1.Mock implements _i5.ApproverService {
+class MockApproverService extends _i1.Mock implements _i9.ApproverService {
   MockApproverService() {
     _i1.throwOnMissingStub(this);
   }
 
   @override
-  _i2.Config get config =>
-      (super.noSuchMethod(Invocation.getter(#config), returnValue: _FakeConfig_0(this, Invocation.getter(#config)))
-          as _i2.Config);
+  _i4.Config get config =>
+      (super.noSuchMethod(Invocation.getter(#config), returnValue: _FakeConfig_6(this, Invocation.getter(#config)))
+          as _i4.Config);
   @override
-  _i6.Future<void> autoApproval(_i4.PullRequest? pullRequest) =>
+  _i7.Future<void> autoApproval(_i5.PullRequest? pullRequest) =>
       (super.noSuchMethod(Invocation.method(#autoApproval, [pullRequest]),
-          returnValue: _i6.Future<void>.value(),
-          returnValueForMissingStub: _i6.Future<void>.value()) as _i6.Future<void>);
+          returnValue: _i7.Future<void>.value(),
+          returnValueForMissingStub: _i7.Future<void>.value()) as _i7.Future<void>);
   @override
-  _i6.Future<void> revertApproval(_i7.QueryResult? queryResult, _i4.PullRequest? pullRequest) =>
+  _i7.Future<void> revertApproval(_i10.QueryResult? queryResult, _i5.PullRequest? pullRequest) =>
       (super.noSuchMethod(Invocation.method(#revertApproval, [queryResult, pullRequest]),
-          returnValue: _i6.Future<void>.value(),
-          returnValueForMissingStub: _i6.Future<void>.value()) as _i6.Future<void>);
+          returnValue: _i7.Future<void>.value(),
+          returnValueForMissingStub: _i7.Future<void>.value()) as _i7.Future<void>);
 }
 
 /// A class which mocks [GitHub].
 ///
 /// See the documentation for Mockito's code generation for more information.
-class MockGitHub extends _i1.Mock implements _i4.GitHub {
+class MockGitHub extends _i1.Mock implements _i5.GitHub {
   MockGitHub() {
     _i1.throwOnMissingStub(this);
   }
 
   @override
-  set auth(_i4.Authentication? _auth) =>
+  set auth(_i5.Authentication? _auth) =>
       super.noSuchMethod(Invocation.setter(#auth, _auth), returnValueForMissingStub: null);
   @override
   String get endpoint => (super.noSuchMethod(Invocation.getter(#endpoint), returnValue: '') as String);
   @override
-  _i3.Client get client =>
-      (super.noSuchMethod(Invocation.getter(#client), returnValue: _FakeClient_1(this, Invocation.getter(#client)))
-          as _i3.Client);
+  _i2.Client get client =>
+      (super.noSuchMethod(Invocation.getter(#client), returnValue: _FakeClient_0(this, Invocation.getter(#client)))
+          as _i2.Client);
   @override
-  _i4.ActivityService get activity => (super.noSuchMethod(Invocation.getter(#activity),
-      returnValue: _FakeActivityService_2(this, Invocation.getter(#activity))) as _i4.ActivityService);
+  _i5.ActivityService get activity => (super.noSuchMethod(Invocation.getter(#activity),
+      returnValue: _FakeActivityService_7(this, Invocation.getter(#activity))) as _i5.ActivityService);
   @override
-  _i4.AuthorizationsService get authorizations => (super.noSuchMethod(Invocation.getter(#authorizations),
-          returnValue: _FakeAuthorizationsService_3(this, Invocation.getter(#authorizations)))
-      as _i4.AuthorizationsService);
+  _i5.AuthorizationsService get authorizations => (super.noSuchMethod(Invocation.getter(#authorizations),
+          returnValue: _FakeAuthorizationsService_8(this, Invocation.getter(#authorizations)))
+      as _i5.AuthorizationsService);
   @override
-  _i4.GistsService get gists =>
-      (super.noSuchMethod(Invocation.getter(#gists), returnValue: _FakeGistsService_4(this, Invocation.getter(#gists)))
-          as _i4.GistsService);
+  _i5.GistsService get gists =>
+      (super.noSuchMethod(Invocation.getter(#gists), returnValue: _FakeGistsService_9(this, Invocation.getter(#gists)))
+          as _i5.GistsService);
   @override
-  _i4.GitService get git =>
-      (super.noSuchMethod(Invocation.getter(#git), returnValue: _FakeGitService_5(this, Invocation.getter(#git)))
-          as _i4.GitService);
+  _i5.GitService get git =>
+      (super.noSuchMethod(Invocation.getter(#git), returnValue: _FakeGitService_10(this, Invocation.getter(#git)))
+          as _i5.GitService);
   @override
-  _i4.IssuesService get issues => (super.noSuchMethod(Invocation.getter(#issues),
-      returnValue: _FakeIssuesService_6(this, Invocation.getter(#issues))) as _i4.IssuesService);
+  _i5.IssuesService get issues => (super.noSuchMethod(Invocation.getter(#issues),
+      returnValue: _FakeIssuesService_11(this, Invocation.getter(#issues))) as _i5.IssuesService);
   @override
-  _i4.MiscService get misc =>
-      (super.noSuchMethod(Invocation.getter(#misc), returnValue: _FakeMiscService_7(this, Invocation.getter(#misc)))
-          as _i4.MiscService);
+  _i5.MiscService get misc =>
+      (super.noSuchMethod(Invocation.getter(#misc), returnValue: _FakeMiscService_12(this, Invocation.getter(#misc)))
+          as _i5.MiscService);
   @override
-  _i4.OrganizationsService get organizations => (super.noSuchMethod(Invocation.getter(#organizations),
-      returnValue: _FakeOrganizationsService_8(this, Invocation.getter(#organizations))) as _i4.OrganizationsService);
+  _i5.OrganizationsService get organizations => (super.noSuchMethod(Invocation.getter(#organizations),
+      returnValue: _FakeOrganizationsService_13(this, Invocation.getter(#organizations))) as _i5.OrganizationsService);
   @override
-  _i4.PullRequestsService get pullRequests => (super.noSuchMethod(Invocation.getter(#pullRequests),
-      returnValue: _FakePullRequestsService_9(this, Invocation.getter(#pullRequests))) as _i4.PullRequestsService);
+  _i5.PullRequestsService get pullRequests => (super.noSuchMethod(Invocation.getter(#pullRequests),
+      returnValue: _FakePullRequestsService_14(this, Invocation.getter(#pullRequests))) as _i5.PullRequestsService);
   @override
-  _i4.RepositoriesService get repositories => (super.noSuchMethod(Invocation.getter(#repositories),
-      returnValue: _FakeRepositoriesService_10(this, Invocation.getter(#repositories))) as _i4.RepositoriesService);
+  _i5.RepositoriesService get repositories => (super.noSuchMethod(Invocation.getter(#repositories),
+      returnValue: _FakeRepositoriesService_15(this, Invocation.getter(#repositories))) as _i5.RepositoriesService);
   @override
-  _i4.SearchService get search => (super.noSuchMethod(Invocation.getter(#search),
-      returnValue: _FakeSearchService_11(this, Invocation.getter(#search))) as _i4.SearchService);
+  _i5.SearchService get search => (super.noSuchMethod(Invocation.getter(#search),
+      returnValue: _FakeSearchService_16(this, Invocation.getter(#search))) as _i5.SearchService);
   @override
-  _i4.UrlShortenerService get urlShortener => (super.noSuchMethod(Invocation.getter(#urlShortener),
-      returnValue: _FakeUrlShortenerService_12(this, Invocation.getter(#urlShortener))) as _i4.UrlShortenerService);
+  _i5.UrlShortenerService get urlShortener => (super.noSuchMethod(Invocation.getter(#urlShortener),
+      returnValue: _FakeUrlShortenerService_17(this, Invocation.getter(#urlShortener))) as _i5.UrlShortenerService);
   @override
-  _i4.UsersService get users =>
-      (super.noSuchMethod(Invocation.getter(#users), returnValue: _FakeUsersService_13(this, Invocation.getter(#users)))
-          as _i4.UsersService);
+  _i5.UsersService get users =>
+      (super.noSuchMethod(Invocation.getter(#users), returnValue: _FakeUsersService_18(this, Invocation.getter(#users)))
+          as _i5.UsersService);
   @override
-  _i4.ChecksService get checks => (super.noSuchMethod(Invocation.getter(#checks),
-      returnValue: _FakeChecksService_14(this, Invocation.getter(#checks))) as _i4.ChecksService);
+  _i5.ChecksService get checks => (super.noSuchMethod(Invocation.getter(#checks),
+      returnValue: _FakeChecksService_19(this, Invocation.getter(#checks))) as _i5.ChecksService);
   @override
-  _i6.Future<T> getJSON<S, T>(String? path,
+  _i7.Future<T> getJSON<S, T>(String? path,
           {int? statusCode,
-          void Function(_i3.Response)? fail,
+          void Function(_i2.Response)? fail,
           Map<String, String>? headers,
           Map<String, String>? params,
-          _i4.JSONConverter<S, T>? convert,
+          _i5.JSONConverter<S, T>? convert,
           String? preview}) =>
       (super.noSuchMethod(
           Invocation.method(#getJSON, [
@@ -292,14 +454,14 @@
             #convert: convert,
             #preview: preview
           }),
-          returnValue: _i6.Future<T>.value(null)) as _i6.Future<T>);
+          returnValue: _i7.Future<T>.value(null)) as _i7.Future<T>);
   @override
-  _i6.Future<T> postJSON<S, T>(String? path,
+  _i7.Future<T> postJSON<S, T>(String? path,
           {int? statusCode,
-          void Function(_i3.Response)? fail,
+          void Function(_i2.Response)? fail,
           Map<String, String>? headers,
           Map<String, dynamic>? params,
-          _i4.JSONConverter<S, T>? convert,
+          _i5.JSONConverter<S, T>? convert,
           dynamic body,
           String? preview}) =>
       (super.noSuchMethod(
@@ -314,14 +476,14 @@
             #body: body,
             #preview: preview
           }),
-          returnValue: _i6.Future<T>.value(null)) as _i6.Future<T>);
+          returnValue: _i7.Future<T>.value(null)) as _i7.Future<T>);
   @override
-  _i6.Future<T> putJSON<S, T>(String? path,
+  _i7.Future<T> putJSON<S, T>(String? path,
           {int? statusCode,
-          void Function(_i3.Response)? fail,
+          void Function(_i2.Response)? fail,
           Map<String, String>? headers,
           Map<String, dynamic>? params,
-          _i4.JSONConverter<S, T>? convert,
+          _i5.JSONConverter<S, T>? convert,
           dynamic body,
           String? preview}) =>
       (super.noSuchMethod(
@@ -336,14 +498,14 @@
             #body: body,
             #preview: preview
           }),
-          returnValue: _i6.Future<T>.value(null)) as _i6.Future<T>);
+          returnValue: _i7.Future<T>.value(null)) as _i7.Future<T>);
   @override
-  _i6.Future<T> patchJSON<S, T>(String? path,
+  _i7.Future<T> patchJSON<S, T>(String? path,
           {int? statusCode,
-          void Function(_i3.Response)? fail,
+          void Function(_i2.Response)? fail,
           Map<String, String>? headers,
           Map<String, dynamic>? params,
-          _i4.JSONConverter<S, T>? convert,
+          _i5.JSONConverter<S, T>? convert,
           dynamic body,
           String? preview}) =>
       (super.noSuchMethod(
@@ -358,14 +520,14 @@
             #body: body,
             #preview: preview
           }),
-          returnValue: _i6.Future<T>.value(null)) as _i6.Future<T>);
+          returnValue: _i7.Future<T>.value(null)) as _i7.Future<T>);
   @override
-  _i6.Future<T> requestJson<S, T>(String? method, String? path,
+  _i7.Future<T> requestJson<S, T>(String? method, String? path,
           {int? statusCode,
-          void Function(_i3.Response)? fail,
+          void Function(_i2.Response)? fail,
           Map<String, String>? headers,
           Map<String, dynamic>? params,
-          _i4.JSONConverter<S, T?>? convert,
+          _i5.JSONConverter<S, T?>? convert,
           dynamic body,
           String? preview}) =>
       (super.noSuchMethod(
@@ -381,17 +543,17 @@
             #body: body,
             #preview: preview
           }),
-          returnValue: _i6.Future<T>.value(null)) as _i6.Future<T>);
+          returnValue: _i7.Future<T>.value(null)) as _i7.Future<T>);
   @override
-  _i6.Future<_i3.Response> request(String? method, String? path,
+  _i7.Future<_i2.Response> request(String? method, String? path,
           {Map<String, String>? headers,
           Map<String, dynamic>? params,
           dynamic body,
           int? statusCode,
-          void Function(_i3.Response)? fail,
+          void Function(_i2.Response)? fail,
           String? preview}) =>
       (super.noSuchMethod(Invocation.method(#request, [method, path], {#headers: headers, #params: params, #body: body, #statusCode: statusCode, #fail: fail, #preview: preview}),
-          returnValue: _i6.Future<_i3.Response>.value(_FakeResponse_15(
+          returnValue: _i7.Future<_i2.Response>.value(_FakeResponse_20(
               this,
               Invocation.method(#request, [
                 method,
@@ -403,9 +565,9 @@
                 #statusCode: statusCode,
                 #fail: fail,
                 #preview: preview
-              })))) as _i6.Future<_i3.Response>);
+              })))) as _i7.Future<_i2.Response>);
   @override
-  void handleStatusCode(_i3.Response? response) =>
+  void handleStatusCode(_i2.Response? response) =>
       super.noSuchMethod(Invocation.method(#handleStatusCode, [response]), returnValueForMissingStub: null);
   @override
   void dispose() => super.noSuchMethod(Invocation.method(#dispose, []), returnValueForMissingStub: null);
@@ -414,17 +576,17 @@
 /// A class which mocks [PullRequestsService].
 ///
 /// See the documentation for Mockito's code generation for more information.
-class MockPullRequestsService extends _i1.Mock implements _i4.PullRequestsService {
+class MockPullRequestsService extends _i1.Mock implements _i5.PullRequestsService {
   MockPullRequestsService() {
     _i1.throwOnMissingStub(this);
   }
 
   @override
-  _i4.GitHub get github =>
-      (super.noSuchMethod(Invocation.getter(#github), returnValue: _FakeGitHub_16(this, Invocation.getter(#github)))
-          as _i4.GitHub);
+  _i5.GitHub get github =>
+      (super.noSuchMethod(Invocation.getter(#github), returnValue: _FakeGitHub_21(this, Invocation.getter(#github)))
+          as _i5.GitHub);
   @override
-  _i6.Stream<_i4.PullRequest> list(_i4.RepositorySlug? slug,
+  _i7.Stream<_i5.PullRequest> list(_i5.RepositorySlug? slug,
           {int? pages,
           String? base,
           String? direction = r'desc',
@@ -434,126 +596,126 @@
       (super.noSuchMethod(
           Invocation.method(#list, [slug],
               {#pages: pages, #base: base, #direction: direction, #head: head, #sort: sort, #state: state}),
-          returnValue: _i6.Stream<_i4.PullRequest>.empty()) as _i6.Stream<_i4.PullRequest>);
+          returnValue: _i7.Stream<_i5.PullRequest>.empty()) as _i7.Stream<_i5.PullRequest>);
   @override
-  _i6.Future<_i4.PullRequest> get(_i4.RepositorySlug? slug, int? number) =>
+  _i7.Future<_i5.PullRequest> get(_i5.RepositorySlug? slug, int? number) =>
       (super.noSuchMethod(Invocation.method(#get, [slug, number]),
               returnValue:
-                  _i6.Future<_i4.PullRequest>.value(_FakePullRequest_17(this, Invocation.method(#get, [slug, number]))))
-          as _i6.Future<_i4.PullRequest>);
+                  _i7.Future<_i5.PullRequest>.value(_FakePullRequest_22(this, Invocation.method(#get, [slug, number]))))
+          as _i7.Future<_i5.PullRequest>);
   @override
-  _i6.Future<_i4.PullRequest> create(_i4.RepositorySlug? slug, _i4.CreatePullRequest? request) => (super.noSuchMethod(
+  _i7.Future<_i5.PullRequest> create(_i5.RepositorySlug? slug, _i5.CreatePullRequest? request) => (super.noSuchMethod(
           Invocation.method(#create, [slug, request]),
           returnValue:
-              _i6.Future<_i4.PullRequest>.value(_FakePullRequest_17(this, Invocation.method(#create, [slug, request]))))
-      as _i6.Future<_i4.PullRequest>);
+              _i7.Future<_i5.PullRequest>.value(_FakePullRequest_22(this, Invocation.method(#create, [slug, request]))))
+      as _i7.Future<_i5.PullRequest>);
   @override
-  _i6.Future<_i4.PullRequest> edit(_i4.RepositorySlug? slug, int? number,
+  _i7.Future<_i5.PullRequest> edit(_i5.RepositorySlug? slug, int? number,
           {String? title, String? body, String? state, String? base}) =>
       (super.noSuchMethod(
               Invocation.method(#edit, [slug, number], {#title: title, #body: body, #state: state, #base: base}),
-              returnValue: _i6.Future<_i4.PullRequest>.value(_FakePullRequest_17(this,
+              returnValue: _i7.Future<_i5.PullRequest>.value(_FakePullRequest_22(this,
                   Invocation.method(#edit, [slug, number], {#title: title, #body: body, #state: state, #base: base}))))
-          as _i6.Future<_i4.PullRequest>);
+          as _i7.Future<_i5.PullRequest>);
   @override
-  _i6.Stream<_i4.RepositoryCommit> listCommits(_i4.RepositorySlug? slug, int? number) =>
+  _i7.Stream<_i5.RepositoryCommit> listCommits(_i5.RepositorySlug? slug, int? number) =>
       (super.noSuchMethod(Invocation.method(#listCommits, [slug, number]),
-          returnValue: _i6.Stream<_i4.RepositoryCommit>.empty()) as _i6.Stream<_i4.RepositoryCommit>);
+          returnValue: _i7.Stream<_i5.RepositoryCommit>.empty()) as _i7.Stream<_i5.RepositoryCommit>);
   @override
-  _i6.Stream<_i4.PullRequestFile> listFiles(_i4.RepositorySlug? slug, int? number) =>
+  _i7.Stream<_i5.PullRequestFile> listFiles(_i5.RepositorySlug? slug, int? number) =>
       (super.noSuchMethod(Invocation.method(#listFiles, [slug, number]),
-          returnValue: _i6.Stream<_i4.PullRequestFile>.empty()) as _i6.Stream<_i4.PullRequestFile>);
+          returnValue: _i7.Stream<_i5.PullRequestFile>.empty()) as _i7.Stream<_i5.PullRequestFile>);
   @override
-  _i6.Stream<_i4.PullRequestReview> listReviews(_i4.RepositorySlug? slug, int? number) =>
+  _i7.Stream<_i5.PullRequestReview> listReviews(_i5.RepositorySlug? slug, int? number) =>
       (super.noSuchMethod(Invocation.method(#listReviews, [slug, number]),
-          returnValue: _i6.Stream<_i4.PullRequestReview>.empty()) as _i6.Stream<_i4.PullRequestReview>);
+          returnValue: _i7.Stream<_i5.PullRequestReview>.empty()) as _i7.Stream<_i5.PullRequestReview>);
   @override
-  _i6.Future<bool> isMerged(_i4.RepositorySlug? slug, int? number) =>
-      (super.noSuchMethod(Invocation.method(#isMerged, [slug, number]), returnValue: _i6.Future<bool>.value(false))
-          as _i6.Future<bool>);
+  _i7.Future<bool> isMerged(_i5.RepositorySlug? slug, int? number) =>
+      (super.noSuchMethod(Invocation.method(#isMerged, [slug, number]), returnValue: _i7.Future<bool>.value(false))
+          as _i7.Future<bool>);
   @override
-  _i6.Future<_i4.PullRequestMerge> merge(_i4.RepositorySlug? slug, int? number, {String? message}) =>
+  _i7.Future<_i5.PullRequestMerge> merge(_i5.RepositorySlug? slug, int? number, {String? message}) =>
       (super.noSuchMethod(Invocation.method(#merge, [slug, number], {#message: message}),
-              returnValue: _i6.Future<_i4.PullRequestMerge>.value(
-                  _FakePullRequestMerge_18(this, Invocation.method(#merge, [slug, number], {#message: message}))))
-          as _i6.Future<_i4.PullRequestMerge>);
+              returnValue: _i7.Future<_i5.PullRequestMerge>.value(
+                  _FakePullRequestMerge_23(this, Invocation.method(#merge, [slug, number], {#message: message}))))
+          as _i7.Future<_i5.PullRequestMerge>);
   @override
-  _i6.Stream<_i4.PullRequestComment> listCommentsByPullRequest(_i4.RepositorySlug? slug, int? number) =>
+  _i7.Stream<_i5.PullRequestComment> listCommentsByPullRequest(_i5.RepositorySlug? slug, int? number) =>
       (super.noSuchMethod(Invocation.method(#listCommentsByPullRequest, [slug, number]),
-          returnValue: _i6.Stream<_i4.PullRequestComment>.empty()) as _i6.Stream<_i4.PullRequestComment>);
+          returnValue: _i7.Stream<_i5.PullRequestComment>.empty()) as _i7.Stream<_i5.PullRequestComment>);
   @override
-  _i6.Stream<_i4.PullRequestComment> listComments(_i4.RepositorySlug? slug) =>
+  _i7.Stream<_i5.PullRequestComment> listComments(_i5.RepositorySlug? slug) =>
       (super.noSuchMethod(Invocation.method(#listComments, [slug]),
-          returnValue: _i6.Stream<_i4.PullRequestComment>.empty()) as _i6.Stream<_i4.PullRequestComment>);
+          returnValue: _i7.Stream<_i5.PullRequestComment>.empty()) as _i7.Stream<_i5.PullRequestComment>);
   @override
-  _i6.Future<_i4.PullRequestComment> createComment(
-          _i4.RepositorySlug? slug, int? number, _i4.CreatePullRequestComment? comment) =>
+  _i7.Future<_i5.PullRequestComment> createComment(
+          _i5.RepositorySlug? slug, int? number, _i5.CreatePullRequestComment? comment) =>
       (super.noSuchMethod(Invocation.method(#createComment, [slug, number, comment]),
-              returnValue: _i6.Future<_i4.PullRequestComment>.value(
-                  _FakePullRequestComment_19(this, Invocation.method(#createComment, [slug, number, comment]))))
-          as _i6.Future<_i4.PullRequestComment>);
+              returnValue: _i7.Future<_i5.PullRequestComment>.value(
+                  _FakePullRequestComment_24(this, Invocation.method(#createComment, [slug, number, comment]))))
+          as _i7.Future<_i5.PullRequestComment>);
   @override
-  _i6.Future<_i4.PullRequestReview> createReview(_i4.RepositorySlug? slug, _i4.CreatePullRequestReview? review) =>
+  _i7.Future<_i5.PullRequestReview> createReview(_i5.RepositorySlug? slug, _i5.CreatePullRequestReview? review) =>
       (super.noSuchMethod(Invocation.method(#createReview, [slug, review]),
-              returnValue: _i6.Future<_i4.PullRequestReview>.value(
-                  _FakePullRequestReview_20(this, Invocation.method(#createReview, [slug, review]))))
-          as _i6.Future<_i4.PullRequestReview>);
+              returnValue: _i7.Future<_i5.PullRequestReview>.value(
+                  _FakePullRequestReview_25(this, Invocation.method(#createReview, [slug, review]))))
+          as _i7.Future<_i5.PullRequestReview>);
 }
 
 /// A class which mocks [RepositoriesService].
 ///
 /// See the documentation for Mockito's code generation for more information.
-class MockRepositoriesService extends _i1.Mock implements _i4.RepositoriesService {
+class MockRepositoriesService extends _i1.Mock implements _i5.RepositoriesService {
   MockRepositoriesService() {
     _i1.throwOnMissingStub(this);
   }
 
   @override
-  _i4.GitHub get github =>
-      (super.noSuchMethod(Invocation.getter(#github), returnValue: _FakeGitHub_16(this, Invocation.getter(#github)))
-          as _i4.GitHub);
+  _i5.GitHub get github =>
+      (super.noSuchMethod(Invocation.getter(#github), returnValue: _FakeGitHub_21(this, Invocation.getter(#github)))
+          as _i5.GitHub);
   @override
-  _i6.Stream<_i4.Repository> listRepositories(
+  _i7.Stream<_i5.Repository> listRepositories(
           {String? type = r'owner', String? sort = r'full_name', String? direction = r'asc'}) =>
       (super.noSuchMethod(Invocation.method(#listRepositories, [], {#type: type, #sort: sort, #direction: direction}),
-          returnValue: _i6.Stream<_i4.Repository>.empty()) as _i6.Stream<_i4.Repository>);
+          returnValue: _i7.Stream<_i5.Repository>.empty()) as _i7.Stream<_i5.Repository>);
   @override
-  _i6.Stream<_i4.Repository> listUserRepositories(String? user,
+  _i7.Stream<_i5.Repository> listUserRepositories(String? user,
           {String? type = r'owner', String? sort = r'full_name', String? direction = r'asc'}) =>
       (super.noSuchMethod(
           Invocation.method(#listUserRepositories, [user], {#type: type, #sort: sort, #direction: direction}),
-          returnValue: _i6.Stream<_i4.Repository>.empty()) as _i6.Stream<_i4.Repository>);
+          returnValue: _i7.Stream<_i5.Repository>.empty()) as _i7.Stream<_i5.Repository>);
   @override
-  _i6.Stream<_i4.Repository> listOrganizationRepositories(String? org, {String? type = r'all'}) =>
+  _i7.Stream<_i5.Repository> listOrganizationRepositories(String? org, {String? type = r'all'}) =>
       (super.noSuchMethod(Invocation.method(#listOrganizationRepositories, [org], {#type: type}),
-          returnValue: _i6.Stream<_i4.Repository>.empty()) as _i6.Stream<_i4.Repository>);
+          returnValue: _i7.Stream<_i5.Repository>.empty()) as _i7.Stream<_i5.Repository>);
   @override
-  _i6.Stream<_i4.Repository> listPublicRepositories({int? limit = 50, DateTime? since}) =>
+  _i7.Stream<_i5.Repository> listPublicRepositories({int? limit = 50, DateTime? since}) =>
       (super.noSuchMethod(Invocation.method(#listPublicRepositories, [], {#limit: limit, #since: since}),
-          returnValue: _i6.Stream<_i4.Repository>.empty()) as _i6.Stream<_i4.Repository>);
+          returnValue: _i7.Stream<_i5.Repository>.empty()) as _i7.Stream<_i5.Repository>);
   @override
-  _i6.Future<_i4.Repository> createRepository(_i4.CreateRepository? repository, {String? org}) =>
+  _i7.Future<_i5.Repository> createRepository(_i5.CreateRepository? repository, {String? org}) =>
       (super.noSuchMethod(Invocation.method(#createRepository, [repository], {#org: org}),
-              returnValue: _i6.Future<_i4.Repository>.value(
-                  _FakeRepository_21(this, Invocation.method(#createRepository, [repository], {#org: org}))))
-          as _i6.Future<_i4.Repository>);
+              returnValue: _i7.Future<_i5.Repository>.value(
+                  _FakeRepository_26(this, Invocation.method(#createRepository, [repository], {#org: org}))))
+          as _i7.Future<_i5.Repository>);
   @override
-  _i6.Future<_i4.LicenseDetails> getLicense(_i4.RepositorySlug? slug) =>
+  _i7.Future<_i5.LicenseDetails> getLicense(_i5.RepositorySlug? slug) =>
       (super.noSuchMethod(Invocation.method(#getLicense, [slug]),
-          returnValue: _i6.Future<_i4.LicenseDetails>.value(
-              _FakeLicenseDetails_22(this, Invocation.method(#getLicense, [slug])))) as _i6.Future<_i4.LicenseDetails>);
+          returnValue: _i7.Future<_i5.LicenseDetails>.value(
+              _FakeLicenseDetails_27(this, Invocation.method(#getLicense, [slug])))) as _i7.Future<_i5.LicenseDetails>);
   @override
-  _i6.Future<_i4.Repository> getRepository(_i4.RepositorySlug? slug) =>
+  _i7.Future<_i5.Repository> getRepository(_i5.RepositorySlug? slug) =>
       (super.noSuchMethod(Invocation.method(#getRepository, [slug]),
               returnValue:
-                  _i6.Future<_i4.Repository>.value(_FakeRepository_21(this, Invocation.method(#getRepository, [slug]))))
-          as _i6.Future<_i4.Repository>);
+                  _i7.Future<_i5.Repository>.value(_FakeRepository_26(this, Invocation.method(#getRepository, [slug]))))
+          as _i7.Future<_i5.Repository>);
   @override
-  _i6.Stream<_i4.Repository> getRepositories(List<_i4.RepositorySlug>? slugs) =>
-      (super.noSuchMethod(Invocation.method(#getRepositories, [slugs]), returnValue: _i6.Stream<_i4.Repository>.empty())
-          as _i6.Stream<_i4.Repository>);
+  _i7.Stream<_i5.Repository> getRepositories(List<_i5.RepositorySlug>? slugs) =>
+      (super.noSuchMethod(Invocation.method(#getRepositories, [slugs]), returnValue: _i7.Stream<_i5.Repository>.empty())
+          as _i7.Stream<_i5.Repository>);
   @override
-  _i6.Future<_i4.Repository> editRepository(_i4.RepositorySlug? slug,
+  _i7.Future<_i5.Repository> editRepository(_i5.RepositorySlug? slug,
           {String? name,
           String? description,
           String? homepage,
@@ -573,7 +735,7 @@
             #hasWiki: hasWiki,
             #hasDownloads: hasDownloads
           }),
-          returnValue: _i6.Future<_i4.Repository>.value(_FakeRepository_21(
+          returnValue: _i7.Future<_i5.Repository>.value(_FakeRepository_26(
               this,
               Invocation.method(#editRepository, [
                 slug
@@ -585,169 +747,169 @@
                 #hasIssues: hasIssues,
                 #hasWiki: hasWiki,
                 #hasDownloads: hasDownloads
-              })))) as _i6.Future<_i4.Repository>);
+              })))) as _i7.Future<_i5.Repository>);
   @override
-  _i6.Future<bool> deleteRepository(_i4.RepositorySlug? slug) =>
-      (super.noSuchMethod(Invocation.method(#deleteRepository, [slug]), returnValue: _i6.Future<bool>.value(false))
-          as _i6.Future<bool>);
+  _i7.Future<bool> deleteRepository(_i5.RepositorySlug? slug) =>
+      (super.noSuchMethod(Invocation.method(#deleteRepository, [slug]), returnValue: _i7.Future<bool>.value(false))
+          as _i7.Future<bool>);
   @override
-  _i6.Stream<_i4.Contributor> listContributors(_i4.RepositorySlug? slug, {bool? anon = false}) =>
+  _i7.Stream<_i5.Contributor> listContributors(_i5.RepositorySlug? slug, {bool? anon = false}) =>
       (super.noSuchMethod(Invocation.method(#listContributors, [slug], {#anon: anon}),
-          returnValue: _i6.Stream<_i4.Contributor>.empty()) as _i6.Stream<_i4.Contributor>);
+          returnValue: _i7.Stream<_i5.Contributor>.empty()) as _i7.Stream<_i5.Contributor>);
   @override
-  _i6.Stream<_i4.Team> listTeams(_i4.RepositorySlug? slug) =>
-      (super.noSuchMethod(Invocation.method(#listTeams, [slug]), returnValue: _i6.Stream<_i4.Team>.empty())
-          as _i6.Stream<_i4.Team>);
+  _i7.Stream<_i5.Team> listTeams(_i5.RepositorySlug? slug) =>
+      (super.noSuchMethod(Invocation.method(#listTeams, [slug]), returnValue: _i7.Stream<_i5.Team>.empty())
+          as _i7.Stream<_i5.Team>);
   @override
-  _i6.Future<_i4.LanguageBreakdown> listLanguages(_i4.RepositorySlug? slug) =>
+  _i7.Future<_i5.LanguageBreakdown> listLanguages(_i5.RepositorySlug? slug) =>
       (super.noSuchMethod(Invocation.method(#listLanguages, [slug]),
-              returnValue: _i6.Future<_i4.LanguageBreakdown>.value(
-                  _FakeLanguageBreakdown_23(this, Invocation.method(#listLanguages, [slug]))))
-          as _i6.Future<_i4.LanguageBreakdown>);
+              returnValue: _i7.Future<_i5.LanguageBreakdown>.value(
+                  _FakeLanguageBreakdown_28(this, Invocation.method(#listLanguages, [slug]))))
+          as _i7.Future<_i5.LanguageBreakdown>);
   @override
-  _i6.Stream<_i4.Tag> listTags(_i4.RepositorySlug? slug, {int? page = 1, int? pages, int? perPage = 30}) =>
+  _i7.Stream<_i5.Tag> listTags(_i5.RepositorySlug? slug, {int? page = 1, int? pages, int? perPage = 30}) =>
       (super.noSuchMethod(Invocation.method(#listTags, [slug], {#page: page, #pages: pages, #perPage: perPage}),
-          returnValue: _i6.Stream<_i4.Tag>.empty()) as _i6.Stream<_i4.Tag>);
+          returnValue: _i7.Stream<_i5.Tag>.empty()) as _i7.Stream<_i5.Tag>);
   @override
-  _i6.Stream<_i4.Branch> listBranches(_i4.RepositorySlug? slug) =>
-      (super.noSuchMethod(Invocation.method(#listBranches, [slug]), returnValue: _i6.Stream<_i4.Branch>.empty())
-          as _i6.Stream<_i4.Branch>);
+  _i7.Stream<_i5.Branch> listBranches(_i5.RepositorySlug? slug) =>
+      (super.noSuchMethod(Invocation.method(#listBranches, [slug]), returnValue: _i7.Stream<_i5.Branch>.empty())
+          as _i7.Stream<_i5.Branch>);
   @override
-  _i6.Future<_i4.Branch> getBranch(_i4.RepositorySlug? slug, String? branch) =>
+  _i7.Future<_i5.Branch> getBranch(_i5.RepositorySlug? slug, String? branch) =>
       (super.noSuchMethod(Invocation.method(#getBranch, [slug, branch]),
               returnValue:
-                  _i6.Future<_i4.Branch>.value(_FakeBranch_24(this, Invocation.method(#getBranch, [slug, branch]))))
-          as _i6.Future<_i4.Branch>);
+                  _i7.Future<_i5.Branch>.value(_FakeBranch_29(this, Invocation.method(#getBranch, [slug, branch]))))
+          as _i7.Future<_i5.Branch>);
   @override
-  _i6.Stream<_i4.Collaborator> listCollaborators(_i4.RepositorySlug? slug) =>
+  _i7.Stream<_i5.Collaborator> listCollaborators(_i5.RepositorySlug? slug) =>
       (super.noSuchMethod(Invocation.method(#listCollaborators, [slug]),
-          returnValue: _i6.Stream<_i4.Collaborator>.empty()) as _i6.Stream<_i4.Collaborator>);
+          returnValue: _i7.Stream<_i5.Collaborator>.empty()) as _i7.Stream<_i5.Collaborator>);
   @override
-  _i6.Future<bool> isCollaborator(_i4.RepositorySlug? slug, String? user) =>
-      (super.noSuchMethod(Invocation.method(#isCollaborator, [slug, user]), returnValue: _i6.Future<bool>.value(false))
-          as _i6.Future<bool>);
+  _i7.Future<bool> isCollaborator(_i5.RepositorySlug? slug, String? user) =>
+      (super.noSuchMethod(Invocation.method(#isCollaborator, [slug, user]), returnValue: _i7.Future<bool>.value(false))
+          as _i7.Future<bool>);
   @override
-  _i6.Future<bool> addCollaborator(_i4.RepositorySlug? slug, String? user) =>
-      (super.noSuchMethod(Invocation.method(#addCollaborator, [slug, user]), returnValue: _i6.Future<bool>.value(false))
-          as _i6.Future<bool>);
+  _i7.Future<bool> addCollaborator(_i5.RepositorySlug? slug, String? user) =>
+      (super.noSuchMethod(Invocation.method(#addCollaborator, [slug, user]), returnValue: _i7.Future<bool>.value(false))
+          as _i7.Future<bool>);
   @override
-  _i6.Future<bool> removeCollaborator(_i4.RepositorySlug? slug, String? user) =>
+  _i7.Future<bool> removeCollaborator(_i5.RepositorySlug? slug, String? user) =>
       (super.noSuchMethod(Invocation.method(#removeCollaborator, [slug, user]),
-          returnValue: _i6.Future<bool>.value(false)) as _i6.Future<bool>);
+          returnValue: _i7.Future<bool>.value(false)) as _i7.Future<bool>);
   @override
-  _i6.Stream<_i4.CommitComment> listSingleCommitComments(_i4.RepositorySlug? slug, _i4.RepositoryCommit? commit) =>
+  _i7.Stream<_i5.CommitComment> listSingleCommitComments(_i5.RepositorySlug? slug, _i5.RepositoryCommit? commit) =>
       (super.noSuchMethod(Invocation.method(#listSingleCommitComments, [slug, commit]),
-          returnValue: _i6.Stream<_i4.CommitComment>.empty()) as _i6.Stream<_i4.CommitComment>);
+          returnValue: _i7.Stream<_i5.CommitComment>.empty()) as _i7.Stream<_i5.CommitComment>);
   @override
-  _i6.Stream<_i4.CommitComment> listCommitComments(_i4.RepositorySlug? slug) =>
+  _i7.Stream<_i5.CommitComment> listCommitComments(_i5.RepositorySlug? slug) =>
       (super.noSuchMethod(Invocation.method(#listCommitComments, [slug]),
-          returnValue: _i6.Stream<_i4.CommitComment>.empty()) as _i6.Stream<_i4.CommitComment>);
+          returnValue: _i7.Stream<_i5.CommitComment>.empty()) as _i7.Stream<_i5.CommitComment>);
   @override
-  _i6.Future<_i4.CommitComment> createCommitComment(_i4.RepositorySlug? slug, _i4.RepositoryCommit? commit,
+  _i7.Future<_i5.CommitComment> createCommitComment(_i5.RepositorySlug? slug, _i5.RepositoryCommit? commit,
           {String? body, String? path, int? position, int? line}) =>
       (super
           .noSuchMethod(Invocation.method(#createCommitComment, [slug, commit], {#body: body, #path: path, #position: position, #line: line}),
-              returnValue: _i6.Future<_i4.CommitComment>.value(_FakeCommitComment_25(
+              returnValue: _i7.Future<_i5.CommitComment>.value(_FakeCommitComment_30(
                   this,
                   Invocation.method(#createCommitComment, [slug, commit],
-                      {#body: body, #path: path, #position: position, #line: line})))) as _i6.Future<_i4.CommitComment>);
+                      {#body: body, #path: path, #position: position, #line: line})))) as _i7.Future<_i5.CommitComment>);
   @override
-  _i6.Future<_i4.CommitComment> getCommitComment(_i4.RepositorySlug? slug, {int? id}) =>
+  _i7.Future<_i5.CommitComment> getCommitComment(_i5.RepositorySlug? slug, {int? id}) =>
       (super.noSuchMethod(Invocation.method(#getCommitComment, [slug], {#id: id}),
-              returnValue: _i6.Future<_i4.CommitComment>.value(
-                  _FakeCommitComment_25(this, Invocation.method(#getCommitComment, [slug], {#id: id}))))
-          as _i6.Future<_i4.CommitComment>);
+              returnValue: _i7.Future<_i5.CommitComment>.value(
+                  _FakeCommitComment_30(this, Invocation.method(#getCommitComment, [slug], {#id: id}))))
+          as _i7.Future<_i5.CommitComment>);
   @override
-  _i6.Future<_i4.CommitComment> updateCommitComment(_i4.RepositorySlug? slug, {int? id, String? body}) =>
+  _i7.Future<_i5.CommitComment> updateCommitComment(_i5.RepositorySlug? slug, {int? id, String? body}) =>
       (super.noSuchMethod(Invocation.method(#updateCommitComment, [slug], {#id: id, #body: body}),
-              returnValue: _i6.Future<_i4.CommitComment>.value(
-                  _FakeCommitComment_25(this, Invocation.method(#updateCommitComment, [slug], {#id: id, #body: body}))))
-          as _i6.Future<_i4.CommitComment>);
+              returnValue: _i7.Future<_i5.CommitComment>.value(
+                  _FakeCommitComment_30(this, Invocation.method(#updateCommitComment, [slug], {#id: id, #body: body}))))
+          as _i7.Future<_i5.CommitComment>);
   @override
-  _i6.Future<bool> deleteCommitComment(_i4.RepositorySlug? slug, {int? id}) =>
+  _i7.Future<bool> deleteCommitComment(_i5.RepositorySlug? slug, {int? id}) =>
       (super.noSuchMethod(Invocation.method(#deleteCommitComment, [slug], {#id: id}),
-          returnValue: _i6.Future<bool>.value(false)) as _i6.Future<bool>);
+          returnValue: _i7.Future<bool>.value(false)) as _i7.Future<bool>);
   @override
-  _i6.Stream<_i4.RepositoryCommit> listCommits(_i4.RepositorySlug? slug) => (super
-          .noSuchMethod(Invocation.method(#listCommits, [slug]), returnValue: _i6.Stream<_i4.RepositoryCommit>.empty())
-      as _i6.Stream<_i4.RepositoryCommit>);
+  _i7.Stream<_i5.RepositoryCommit> listCommits(_i5.RepositorySlug? slug) => (super
+          .noSuchMethod(Invocation.method(#listCommits, [slug]), returnValue: _i7.Stream<_i5.RepositoryCommit>.empty())
+      as _i7.Stream<_i5.RepositoryCommit>);
   @override
-  _i6.Future<_i4.RepositoryCommit> getCommit(_i4.RepositorySlug? slug, String? sha) =>
+  _i7.Future<_i5.RepositoryCommit> getCommit(_i5.RepositorySlug? slug, String? sha) =>
       (super.noSuchMethod(Invocation.method(#getCommit, [slug, sha]),
-              returnValue: _i6.Future<_i4.RepositoryCommit>.value(
-                  _FakeRepositoryCommit_26(this, Invocation.method(#getCommit, [slug, sha]))))
-          as _i6.Future<_i4.RepositoryCommit>);
+              returnValue: _i7.Future<_i5.RepositoryCommit>.value(
+                  _FakeRepositoryCommit_31(this, Invocation.method(#getCommit, [slug, sha]))))
+          as _i7.Future<_i5.RepositoryCommit>);
   @override
-  _i6.Future<String> getCommitDiff(_i4.RepositorySlug? slug, String? sha) =>
-      (super.noSuchMethod(Invocation.method(#getCommitDiff, [slug, sha]), returnValue: _i6.Future<String>.value(''))
-          as _i6.Future<String>);
+  _i7.Future<String> getCommitDiff(_i5.RepositorySlug? slug, String? sha) =>
+      (super.noSuchMethod(Invocation.method(#getCommitDiff, [slug, sha]), returnValue: _i7.Future<String>.value(''))
+          as _i7.Future<String>);
   @override
-  _i6.Future<_i4.GitHubComparison> compareCommits(_i4.RepositorySlug? slug, String? refBase, String? refHead) =>
+  _i7.Future<_i5.GitHubComparison> compareCommits(_i5.RepositorySlug? slug, String? refBase, String? refHead) =>
       (super.noSuchMethod(Invocation.method(#compareCommits, [slug, refBase, refHead]),
-              returnValue: _i6.Future<_i4.GitHubComparison>.value(
-                  _FakeGitHubComparison_27(this, Invocation.method(#compareCommits, [slug, refBase, refHead]))))
-          as _i6.Future<_i4.GitHubComparison>);
+              returnValue: _i7.Future<_i5.GitHubComparison>.value(
+                  _FakeGitHubComparison_32(this, Invocation.method(#compareCommits, [slug, refBase, refHead]))))
+          as _i7.Future<_i5.GitHubComparison>);
   @override
-  _i6.Future<_i4.GitHubFile> getReadme(_i4.RepositorySlug? slug, {String? ref}) => (super.noSuchMethod(
+  _i7.Future<_i5.GitHubFile> getReadme(_i5.RepositorySlug? slug, {String? ref}) => (super.noSuchMethod(
       Invocation.method(#getReadme, [slug], {#ref: ref}),
-      returnValue: _i6.Future<_i4.GitHubFile>.value(
-          _FakeGitHubFile_28(this, Invocation.method(#getReadme, [slug], {#ref: ref})))) as _i6.Future<_i4.GitHubFile>);
+      returnValue: _i7.Future<_i5.GitHubFile>.value(
+          _FakeGitHubFile_33(this, Invocation.method(#getReadme, [slug], {#ref: ref})))) as _i7.Future<_i5.GitHubFile>);
   @override
-  _i6.Future<_i4.RepositoryContents> getContents(_i4.RepositorySlug? slug, String? path, {String? ref}) =>
+  _i7.Future<_i5.RepositoryContents> getContents(_i5.RepositorySlug? slug, String? path, {String? ref}) =>
       (super.noSuchMethod(Invocation.method(#getContents, [slug, path], {#ref: ref}),
-              returnValue: _i6.Future<_i4.RepositoryContents>.value(
-                  _FakeRepositoryContents_29(this, Invocation.method(#getContents, [slug, path], {#ref: ref}))))
-          as _i6.Future<_i4.RepositoryContents>);
+              returnValue: _i7.Future<_i5.RepositoryContents>.value(
+                  _FakeRepositoryContents_34(this, Invocation.method(#getContents, [slug, path], {#ref: ref}))))
+          as _i7.Future<_i5.RepositoryContents>);
   @override
-  _i6.Future<_i4.ContentCreation> createFile(_i4.RepositorySlug? slug, _i4.CreateFile? file) =>
+  _i7.Future<_i5.ContentCreation> createFile(_i5.RepositorySlug? slug, _i5.CreateFile? file) =>
       (super.noSuchMethod(Invocation.method(#createFile, [slug, file]),
-              returnValue: _i6.Future<_i4.ContentCreation>.value(
-                  _FakeContentCreation_30(this, Invocation.method(#createFile, [slug, file]))))
-          as _i6.Future<_i4.ContentCreation>);
+              returnValue: _i7.Future<_i5.ContentCreation>.value(
+                  _FakeContentCreation_35(this, Invocation.method(#createFile, [slug, file]))))
+          as _i7.Future<_i5.ContentCreation>);
   @override
-  _i6.Future<_i4.ContentCreation> updateFile(
-          _i4.RepositorySlug? slug, String? path, String? message, String? content, String? sha, {String? branch}) =>
+  _i7.Future<_i5.ContentCreation> updateFile(
+          _i5.RepositorySlug? slug, String? path, String? message, String? content, String? sha, {String? branch}) =>
       (super.noSuchMethod(Invocation.method(#updateFile, [slug, path, message, content, sha], {#branch: branch}),
-              returnValue: _i6.Future<_i4.ContentCreation>.value(_FakeContentCreation_30(
+              returnValue: _i7.Future<_i5.ContentCreation>.value(_FakeContentCreation_35(
                   this, Invocation.method(#updateFile, [slug, path, message, content, sha], {#branch: branch}))))
-          as _i6.Future<_i4.ContentCreation>);
+          as _i7.Future<_i5.ContentCreation>);
   @override
-  _i6.Future<_i4.ContentCreation> deleteFile(
-          _i4.RepositorySlug? slug, String? path, String? message, String? sha, String? branch) =>
+  _i7.Future<_i5.ContentCreation> deleteFile(
+          _i5.RepositorySlug? slug, String? path, String? message, String? sha, String? branch) =>
       (super.noSuchMethod(Invocation.method(#deleteFile, [slug, path, message, sha, branch]),
-              returnValue: _i6.Future<_i4.ContentCreation>.value(
-                  _FakeContentCreation_30(this, Invocation.method(#deleteFile, [slug, path, message, sha, branch]))))
-          as _i6.Future<_i4.ContentCreation>);
+              returnValue: _i7.Future<_i5.ContentCreation>.value(
+                  _FakeContentCreation_35(this, Invocation.method(#deleteFile, [slug, path, message, sha, branch]))))
+          as _i7.Future<_i5.ContentCreation>);
   @override
-  _i6.Future<String?> getArchiveLink(_i4.RepositorySlug? slug, String? ref, {String? format = r'tarball'}) =>
+  _i7.Future<String?> getArchiveLink(_i5.RepositorySlug? slug, String? ref, {String? format = r'tarball'}) =>
       (super.noSuchMethod(Invocation.method(#getArchiveLink, [slug, ref], {#format: format}),
-          returnValue: _i6.Future<String?>.value()) as _i6.Future<String?>);
+          returnValue: _i7.Future<String?>.value()) as _i7.Future<String?>);
   @override
-  _i6.Stream<_i4.Repository> listForks(_i4.RepositorySlug? slug) =>
-      (super.noSuchMethod(Invocation.method(#listForks, [slug]), returnValue: _i6.Stream<_i4.Repository>.empty())
-          as _i6.Stream<_i4.Repository>);
+  _i7.Stream<_i5.Repository> listForks(_i5.RepositorySlug? slug) =>
+      (super.noSuchMethod(Invocation.method(#listForks, [slug]), returnValue: _i7.Stream<_i5.Repository>.empty())
+          as _i7.Stream<_i5.Repository>);
   @override
-  _i6.Future<_i4.Repository> createFork(_i4.RepositorySlug? slug, [_i4.CreateFork? fork]) => (super.noSuchMethod(
+  _i7.Future<_i5.Repository> createFork(_i5.RepositorySlug? slug, [_i5.CreateFork? fork]) => (super.noSuchMethod(
           Invocation.method(#createFork, [slug, fork]),
           returnValue:
-              _i6.Future<_i4.Repository>.value(_FakeRepository_21(this, Invocation.method(#createFork, [slug, fork]))))
-      as _i6.Future<_i4.Repository>);
+              _i7.Future<_i5.Repository>.value(_FakeRepository_26(this, Invocation.method(#createFork, [slug, fork]))))
+      as _i7.Future<_i5.Repository>);
   @override
-  _i6.Stream<_i4.Hook> listHooks(_i4.RepositorySlug? slug) =>
-      (super.noSuchMethod(Invocation.method(#listHooks, [slug]), returnValue: _i6.Stream<_i4.Hook>.empty())
-          as _i6.Stream<_i4.Hook>);
+  _i7.Stream<_i5.Hook> listHooks(_i5.RepositorySlug? slug) =>
+      (super.noSuchMethod(Invocation.method(#listHooks, [slug]), returnValue: _i7.Stream<_i5.Hook>.empty())
+          as _i7.Stream<_i5.Hook>);
   @override
-  _i6.Future<_i4.Hook> getHook(_i4.RepositorySlug? slug, int? id) =>
+  _i7.Future<_i5.Hook> getHook(_i5.RepositorySlug? slug, int? id) =>
       (super.noSuchMethod(Invocation.method(#getHook, [slug, id]),
-              returnValue: _i6.Future<_i4.Hook>.value(_FakeHook_31(this, Invocation.method(#getHook, [slug, id]))))
-          as _i6.Future<_i4.Hook>);
+              returnValue: _i7.Future<_i5.Hook>.value(_FakeHook_36(this, Invocation.method(#getHook, [slug, id]))))
+          as _i7.Future<_i5.Hook>);
   @override
-  _i6.Future<_i4.Hook> createHook(_i4.RepositorySlug? slug, _i4.CreateHook? hook) =>
+  _i7.Future<_i5.Hook> createHook(_i5.RepositorySlug? slug, _i5.CreateHook? hook) =>
       (super.noSuchMethod(Invocation.method(#createHook, [slug, hook]),
-              returnValue: _i6.Future<_i4.Hook>.value(_FakeHook_31(this, Invocation.method(#createHook, [slug, hook]))))
-          as _i6.Future<_i4.Hook>);
+              returnValue: _i7.Future<_i5.Hook>.value(_FakeHook_36(this, Invocation.method(#createHook, [slug, hook]))))
+          as _i7.Future<_i5.Hook>);
   @override
-  _i6.Future<_i4.Hook> editHook(_i4.RepositorySlug? slug, _i4.Hook? hookToEdit,
+  _i7.Future<_i5.Hook> editHook(_i5.RepositorySlug? slug, _i5.Hook? hookToEdit,
           {String? configUrl,
           String? configContentType,
           String? configSecret,
@@ -770,7 +932,7 @@
             #removeEvents: removeEvents,
             #active: active
           }),
-          returnValue: _i6.Future<_i4.Hook>.value(_FakeHook_31(
+          returnValue: _i7.Future<_i5.Hook>.value(_FakeHook_36(
               this,
               Invocation.method(#editHook, [
                 slug,
@@ -784,91 +946,91 @@
                 #addEvents: addEvents,
                 #removeEvents: removeEvents,
                 #active: active
-              })))) as _i6.Future<_i4.Hook>);
+              })))) as _i7.Future<_i5.Hook>);
   @override
-  _i6.Future<bool> testPushHook(_i4.RepositorySlug? slug, int? id) =>
-      (super.noSuchMethod(Invocation.method(#testPushHook, [slug, id]), returnValue: _i6.Future<bool>.value(false))
-          as _i6.Future<bool>);
+  _i7.Future<bool> testPushHook(_i5.RepositorySlug? slug, int? id) =>
+      (super.noSuchMethod(Invocation.method(#testPushHook, [slug, id]), returnValue: _i7.Future<bool>.value(false))
+          as _i7.Future<bool>);
   @override
-  _i6.Future<bool> pingHook(_i4.RepositorySlug? slug, int? id) =>
-      (super.noSuchMethod(Invocation.method(#pingHook, [slug, id]), returnValue: _i6.Future<bool>.value(false))
-          as _i6.Future<bool>);
+  _i7.Future<bool> pingHook(_i5.RepositorySlug? slug, int? id) =>
+      (super.noSuchMethod(Invocation.method(#pingHook, [slug, id]), returnValue: _i7.Future<bool>.value(false))
+          as _i7.Future<bool>);
   @override
-  _i6.Future<bool> deleteHook(_i4.RepositorySlug? slug, int? id) =>
-      (super.noSuchMethod(Invocation.method(#deleteHook, [slug, id]), returnValue: _i6.Future<bool>.value(false))
-          as _i6.Future<bool>);
+  _i7.Future<bool> deleteHook(_i5.RepositorySlug? slug, int? id) =>
+      (super.noSuchMethod(Invocation.method(#deleteHook, [slug, id]), returnValue: _i7.Future<bool>.value(false))
+          as _i7.Future<bool>);
   @override
-  _i6.Stream<_i4.PublicKey> listDeployKeys(_i4.RepositorySlug? slug) =>
-      (super.noSuchMethod(Invocation.method(#listDeployKeys, [slug]), returnValue: _i6.Stream<_i4.PublicKey>.empty())
-          as _i6.Stream<_i4.PublicKey>);
+  _i7.Stream<_i5.PublicKey> listDeployKeys(_i5.RepositorySlug? slug) =>
+      (super.noSuchMethod(Invocation.method(#listDeployKeys, [slug]), returnValue: _i7.Stream<_i5.PublicKey>.empty())
+          as _i7.Stream<_i5.PublicKey>);
   @override
-  _i6.Future<_i4.PublicKey> getDeployKey(_i4.RepositorySlug? slug, {int? id}) => (super.noSuchMethod(
+  _i7.Future<_i5.PublicKey> getDeployKey(_i5.RepositorySlug? slug, {int? id}) => (super.noSuchMethod(
       Invocation.method(#getDeployKey, [slug], {#id: id}),
-      returnValue: _i6.Future<_i4.PublicKey>.value(
-          _FakePublicKey_32(this, Invocation.method(#getDeployKey, [slug], {#id: id})))) as _i6.Future<_i4.PublicKey>);
+      returnValue: _i7.Future<_i5.PublicKey>.value(
+          _FakePublicKey_37(this, Invocation.method(#getDeployKey, [slug], {#id: id})))) as _i7.Future<_i5.PublicKey>);
   @override
-  _i6.Future<_i4.PublicKey> createDeployKey(_i4.RepositorySlug? slug, _i4.CreatePublicKey? key) =>
+  _i7.Future<_i5.PublicKey> createDeployKey(_i5.RepositorySlug? slug, _i5.CreatePublicKey? key) =>
       (super.noSuchMethod(Invocation.method(#createDeployKey, [slug, key]),
-          returnValue: _i6.Future<_i4.PublicKey>.value(
-              _FakePublicKey_32(this, Invocation.method(#createDeployKey, [slug, key])))) as _i6.Future<_i4.PublicKey>);
+          returnValue: _i7.Future<_i5.PublicKey>.value(
+              _FakePublicKey_37(this, Invocation.method(#createDeployKey, [slug, key])))) as _i7.Future<_i5.PublicKey>);
   @override
-  _i6.Future<bool> deleteDeployKey({_i4.RepositorySlug? slug, _i4.PublicKey? key}) =>
+  _i7.Future<bool> deleteDeployKey({_i5.RepositorySlug? slug, _i5.PublicKey? key}) =>
       (super.noSuchMethod(Invocation.method(#deleteDeployKey, [], {#slug: slug, #key: key}),
-          returnValue: _i6.Future<bool>.value(false)) as _i6.Future<bool>);
+          returnValue: _i7.Future<bool>.value(false)) as _i7.Future<bool>);
   @override
-  _i6.Future<_i4.RepositoryCommit> merge(_i4.RepositorySlug? slug, _i4.CreateMerge? merge) =>
+  _i7.Future<_i5.RepositoryCommit> merge(_i5.RepositorySlug? slug, _i5.CreateMerge? merge) =>
       (super.noSuchMethod(Invocation.method(#merge, [slug, merge]),
-              returnValue: _i6.Future<_i4.RepositoryCommit>.value(
-                  _FakeRepositoryCommit_26(this, Invocation.method(#merge, [slug, merge]))))
-          as _i6.Future<_i4.RepositoryCommit>);
+              returnValue: _i7.Future<_i5.RepositoryCommit>.value(
+                  _FakeRepositoryCommit_31(this, Invocation.method(#merge, [slug, merge]))))
+          as _i7.Future<_i5.RepositoryCommit>);
   @override
-  _i6.Future<_i4.RepositoryPages> getPagesInfo(_i4.RepositorySlug? slug) => (super.noSuchMethod(
+  _i7.Future<_i5.RepositoryPages> getPagesInfo(_i5.RepositorySlug? slug) => (super.noSuchMethod(
       Invocation.method(#getPagesInfo, [slug]),
-      returnValue: _i6.Future<_i4.RepositoryPages>.value(
-          _FakeRepositoryPages_33(this, Invocation.method(#getPagesInfo, [slug])))) as _i6.Future<_i4.RepositoryPages>);
+      returnValue: _i7.Future<_i5.RepositoryPages>.value(
+          _FakeRepositoryPages_38(this, Invocation.method(#getPagesInfo, [slug])))) as _i7.Future<_i5.RepositoryPages>);
   @override
-  _i6.Stream<_i4.PageBuild> listPagesBuilds(_i4.RepositorySlug? slug) =>
-      (super.noSuchMethod(Invocation.method(#listPagesBuilds, [slug]), returnValue: _i6.Stream<_i4.PageBuild>.empty())
-          as _i6.Stream<_i4.PageBuild>);
+  _i7.Stream<_i5.PageBuild> listPagesBuilds(_i5.RepositorySlug? slug) =>
+      (super.noSuchMethod(Invocation.method(#listPagesBuilds, [slug]), returnValue: _i7.Stream<_i5.PageBuild>.empty())
+          as _i7.Stream<_i5.PageBuild>);
   @override
-  _i6.Future<_i4.PageBuild> getLatestPagesBuild(_i4.RepositorySlug? slug) => (super.noSuchMethod(
+  _i7.Future<_i5.PageBuild> getLatestPagesBuild(_i5.RepositorySlug? slug) => (super.noSuchMethod(
           Invocation.method(#getLatestPagesBuild, [slug]),
           returnValue:
-              _i6.Future<_i4.PageBuild>.value(_FakePageBuild_34(this, Invocation.method(#getLatestPagesBuild, [slug]))))
-      as _i6.Future<_i4.PageBuild>);
+              _i7.Future<_i5.PageBuild>.value(_FakePageBuild_39(this, Invocation.method(#getLatestPagesBuild, [slug]))))
+      as _i7.Future<_i5.PageBuild>);
   @override
-  _i6.Stream<_i4.Release> listReleases(_i4.RepositorySlug? slug) =>
-      (super.noSuchMethod(Invocation.method(#listReleases, [slug]), returnValue: _i6.Stream<_i4.Release>.empty())
-          as _i6.Stream<_i4.Release>);
+  _i7.Stream<_i5.Release> listReleases(_i5.RepositorySlug? slug) =>
+      (super.noSuchMethod(Invocation.method(#listReleases, [slug]), returnValue: _i7.Stream<_i5.Release>.empty())
+          as _i7.Stream<_i5.Release>);
   @override
-  _i6.Future<_i4.Release> getLatestRelease(_i4.RepositorySlug? slug) =>
+  _i7.Future<_i5.Release> getLatestRelease(_i5.RepositorySlug? slug) =>
       (super.noSuchMethod(Invocation.method(#getLatestRelease, [slug]),
               returnValue:
-                  _i6.Future<_i4.Release>.value(_FakeRelease_35(this, Invocation.method(#getLatestRelease, [slug]))))
-          as _i6.Future<_i4.Release>);
+                  _i7.Future<_i5.Release>.value(_FakeRelease_40(this, Invocation.method(#getLatestRelease, [slug]))))
+          as _i7.Future<_i5.Release>);
   @override
-  _i6.Future<_i4.Release> getReleaseById(_i4.RepositorySlug? slug, int? id) =>
+  _i7.Future<_i5.Release> getReleaseById(_i5.RepositorySlug? slug, int? id) =>
       (super.noSuchMethod(Invocation.method(#getReleaseById, [slug, id]),
               returnValue:
-                  _i6.Future<_i4.Release>.value(_FakeRelease_35(this, Invocation.method(#getReleaseById, [slug, id]))))
-          as _i6.Future<_i4.Release>);
+                  _i7.Future<_i5.Release>.value(_FakeRelease_40(this, Invocation.method(#getReleaseById, [slug, id]))))
+          as _i7.Future<_i5.Release>);
   @override
-  _i6.Future<_i4.Release> getReleaseByTagName(_i4.RepositorySlug? slug, String? tagName) => (super.noSuchMethod(
+  _i7.Future<_i5.Release> getReleaseByTagName(_i5.RepositorySlug? slug, String? tagName) => (super.noSuchMethod(
       Invocation.method(#getReleaseByTagName, [slug, tagName]),
-      returnValue: _i6.Future<_i4.Release>.value(
-          _FakeRelease_35(this, Invocation.method(#getReleaseByTagName, [slug, tagName])))) as _i6.Future<_i4.Release>);
+      returnValue: _i7.Future<_i5.Release>.value(
+          _FakeRelease_40(this, Invocation.method(#getReleaseByTagName, [slug, tagName])))) as _i7.Future<_i5.Release>);
   @override
-  _i6.Future<_i4.Release> createRelease(_i4.RepositorySlug? slug, _i4.CreateRelease? createRelease,
+  _i7.Future<_i5.Release> createRelease(_i5.RepositorySlug? slug, _i5.CreateRelease? createRelease,
           {bool? getIfExists = true}) =>
       (super.noSuchMethod(Invocation.method(#createRelease, [slug, createRelease], {#getIfExists: getIfExists}),
-              returnValue: _i6.Future<_i4.Release>.value(_FakeRelease_35(
+              returnValue: _i7.Future<_i5.Release>.value(_FakeRelease_40(
                   this, Invocation.method(#createRelease, [slug, createRelease], {#getIfExists: getIfExists}))))
-          as _i6.Future<_i4.Release>);
+          as _i7.Future<_i5.Release>);
   @override
-  _i6.Future<_i4.Release> editRelease(_i4.RepositorySlug? slug, _i4.Release? releaseToEdit,
+  _i7.Future<_i5.Release> editRelease(_i5.RepositorySlug? slug, _i5.Release? releaseToEdit,
           {String? tagName, String? targetCommitish, String? name, String? body, bool? draft, bool? preRelease}) =>
       (super.noSuchMethod(Invocation.method(#editRelease, [slug, releaseToEdit], {#tagName: tagName, #targetCommitish: targetCommitish, #name: name, #body: body, #draft: draft, #preRelease: preRelease}),
-          returnValue: _i6.Future<_i4.Release>.value(_FakeRelease_35(
+          returnValue: _i7.Future<_i5.Release>.value(_FakeRelease_40(
               this,
               Invocation.method(#editRelease, [
                 slug,
@@ -880,89 +1042,89 @@
                 #body: body,
                 #draft: draft,
                 #preRelease: preRelease
-              })))) as _i6.Future<_i4.Release>);
+              })))) as _i7.Future<_i5.Release>);
   @override
-  _i6.Future<bool> deleteRelease(_i4.RepositorySlug? slug, _i4.Release? release) => (super
-          .noSuchMethod(Invocation.method(#deleteRelease, [slug, release]), returnValue: _i6.Future<bool>.value(false))
-      as _i6.Future<bool>);
+  _i7.Future<bool> deleteRelease(_i5.RepositorySlug? slug, _i5.Release? release) => (super
+          .noSuchMethod(Invocation.method(#deleteRelease, [slug, release]), returnValue: _i7.Future<bool>.value(false))
+      as _i7.Future<bool>);
   @override
-  _i6.Stream<_i4.ReleaseAsset> listReleaseAssets(_i4.RepositorySlug? slug, _i4.Release? release) =>
+  _i7.Stream<_i5.ReleaseAsset> listReleaseAssets(_i5.RepositorySlug? slug, _i5.Release? release) =>
       (super.noSuchMethod(Invocation.method(#listReleaseAssets, [slug, release]),
-          returnValue: _i6.Stream<_i4.ReleaseAsset>.empty()) as _i6.Stream<_i4.ReleaseAsset>);
+          returnValue: _i7.Stream<_i5.ReleaseAsset>.empty()) as _i7.Stream<_i5.ReleaseAsset>);
   @override
-  _i6.Future<_i4.ReleaseAsset> getReleaseAsset(_i4.RepositorySlug? slug, _i4.Release? release, {int? assetId}) =>
+  _i7.Future<_i5.ReleaseAsset> getReleaseAsset(_i5.RepositorySlug? slug, _i5.Release? release, {int? assetId}) =>
       (super.noSuchMethod(Invocation.method(#getReleaseAsset, [slug, release], {#assetId: assetId}),
-              returnValue: _i6.Future<_i4.ReleaseAsset>.value(_FakeReleaseAsset_36(
+              returnValue: _i7.Future<_i5.ReleaseAsset>.value(_FakeReleaseAsset_41(
                   this, Invocation.method(#getReleaseAsset, [slug, release], {#assetId: assetId}))))
-          as _i6.Future<_i4.ReleaseAsset>);
+          as _i7.Future<_i5.ReleaseAsset>);
   @override
-  _i6.Future<_i4.ReleaseAsset> editReleaseAsset(_i4.RepositorySlug? slug, _i4.ReleaseAsset? assetToEdit,
+  _i7.Future<_i5.ReleaseAsset> editReleaseAsset(_i5.RepositorySlug? slug, _i5.ReleaseAsset? assetToEdit,
           {String? name, String? label}) =>
       (super.noSuchMethod(Invocation.method(#editReleaseAsset, [slug, assetToEdit], {#name: name, #label: label}),
-              returnValue: _i6.Future<_i4.ReleaseAsset>.value(_FakeReleaseAsset_36(
+              returnValue: _i7.Future<_i5.ReleaseAsset>.value(_FakeReleaseAsset_41(
                   this, Invocation.method(#editReleaseAsset, [slug, assetToEdit], {#name: name, #label: label}))))
-          as _i6.Future<_i4.ReleaseAsset>);
+          as _i7.Future<_i5.ReleaseAsset>);
   @override
-  _i6.Future<bool> deleteReleaseAsset(_i4.RepositorySlug? slug, _i4.ReleaseAsset? asset) =>
+  _i7.Future<bool> deleteReleaseAsset(_i5.RepositorySlug? slug, _i5.ReleaseAsset? asset) =>
       (super.noSuchMethod(Invocation.method(#deleteReleaseAsset, [slug, asset]),
-          returnValue: _i6.Future<bool>.value(false)) as _i6.Future<bool>);
+          returnValue: _i7.Future<bool>.value(false)) as _i7.Future<bool>);
   @override
-  _i6.Future<List<_i4.ReleaseAsset>> uploadReleaseAssets(
-          _i4.Release? release, Iterable<_i4.CreateReleaseAsset>? createReleaseAssets) =>
+  _i7.Future<List<_i5.ReleaseAsset>> uploadReleaseAssets(
+          _i5.Release? release, Iterable<_i5.CreateReleaseAsset>? createReleaseAssets) =>
       (super.noSuchMethod(Invocation.method(#uploadReleaseAssets, [release, createReleaseAssets]),
-              returnValue: _i6.Future<List<_i4.ReleaseAsset>>.value(<_i4.ReleaseAsset>[]))
-          as _i6.Future<List<_i4.ReleaseAsset>>);
+              returnValue: _i7.Future<List<_i5.ReleaseAsset>>.value(<_i5.ReleaseAsset>[]))
+          as _i7.Future<List<_i5.ReleaseAsset>>);
   @override
-  _i6.Future<List<_i4.ContributorStatistics>> listContributorStats(_i4.RepositorySlug? slug) =>
+  _i7.Future<List<_i5.ContributorStatistics>> listContributorStats(_i5.RepositorySlug? slug) =>
       (super.noSuchMethod(Invocation.method(#listContributorStats, [slug]),
-              returnValue: _i6.Future<List<_i4.ContributorStatistics>>.value(<_i4.ContributorStatistics>[]))
-          as _i6.Future<List<_i4.ContributorStatistics>>);
+              returnValue: _i7.Future<List<_i5.ContributorStatistics>>.value(<_i5.ContributorStatistics>[]))
+          as _i7.Future<List<_i5.ContributorStatistics>>);
   @override
-  _i6.Stream<_i4.YearCommitCountWeek> listCommitActivity(_i4.RepositorySlug? slug) =>
+  _i7.Stream<_i5.YearCommitCountWeek> listCommitActivity(_i5.RepositorySlug? slug) =>
       (super.noSuchMethod(Invocation.method(#listCommitActivity, [slug]),
-          returnValue: _i6.Stream<_i4.YearCommitCountWeek>.empty()) as _i6.Stream<_i4.YearCommitCountWeek>);
+          returnValue: _i7.Stream<_i5.YearCommitCountWeek>.empty()) as _i7.Stream<_i5.YearCommitCountWeek>);
   @override
-  _i6.Stream<_i4.WeeklyChangesCount> listCodeFrequency(_i4.RepositorySlug? slug) =>
+  _i7.Stream<_i5.WeeklyChangesCount> listCodeFrequency(_i5.RepositorySlug? slug) =>
       (super.noSuchMethod(Invocation.method(#listCodeFrequency, [slug]),
-          returnValue: _i6.Stream<_i4.WeeklyChangesCount>.empty()) as _i6.Stream<_i4.WeeklyChangesCount>);
+          returnValue: _i7.Stream<_i5.WeeklyChangesCount>.empty()) as _i7.Stream<_i5.WeeklyChangesCount>);
   @override
-  _i6.Future<_i4.ContributorParticipation> getParticipation(_i4.RepositorySlug? slug) =>
+  _i7.Future<_i5.ContributorParticipation> getParticipation(_i5.RepositorySlug? slug) =>
       (super.noSuchMethod(Invocation.method(#getParticipation, [slug]),
-              returnValue: _i6.Future<_i4.ContributorParticipation>.value(
-                  _FakeContributorParticipation_37(this, Invocation.method(#getParticipation, [slug]))))
-          as _i6.Future<_i4.ContributorParticipation>);
+              returnValue: _i7.Future<_i5.ContributorParticipation>.value(
+                  _FakeContributorParticipation_42(this, Invocation.method(#getParticipation, [slug]))))
+          as _i7.Future<_i5.ContributorParticipation>);
   @override
-  _i6.Stream<_i4.PunchcardEntry> listPunchcard(_i4.RepositorySlug? slug) => (super
-          .noSuchMethod(Invocation.method(#listPunchcard, [slug]), returnValue: _i6.Stream<_i4.PunchcardEntry>.empty())
-      as _i6.Stream<_i4.PunchcardEntry>);
+  _i7.Stream<_i5.PunchcardEntry> listPunchcard(_i5.RepositorySlug? slug) => (super
+          .noSuchMethod(Invocation.method(#listPunchcard, [slug]), returnValue: _i7.Stream<_i5.PunchcardEntry>.empty())
+      as _i7.Stream<_i5.PunchcardEntry>);
   @override
-  _i6.Stream<_i4.RepositoryStatus> listStatuses(_i4.RepositorySlug? slug, String? ref) =>
+  _i7.Stream<_i5.RepositoryStatus> listStatuses(_i5.RepositorySlug? slug, String? ref) =>
       (super.noSuchMethod(Invocation.method(#listStatuses, [slug, ref]),
-          returnValue: _i6.Stream<_i4.RepositoryStatus>.empty()) as _i6.Stream<_i4.RepositoryStatus>);
+          returnValue: _i7.Stream<_i5.RepositoryStatus>.empty()) as _i7.Stream<_i5.RepositoryStatus>);
   @override
-  _i6.Future<_i4.RepositoryStatus> createStatus(_i4.RepositorySlug? slug, String? ref, _i4.CreateStatus? request) =>
+  _i7.Future<_i5.RepositoryStatus> createStatus(_i5.RepositorySlug? slug, String? ref, _i5.CreateStatus? request) =>
       (super.noSuchMethod(Invocation.method(#createStatus, [slug, ref, request]),
-              returnValue: _i6.Future<_i4.RepositoryStatus>.value(
-                  _FakeRepositoryStatus_38(this, Invocation.method(#createStatus, [slug, ref, request]))))
-          as _i6.Future<_i4.RepositoryStatus>);
+              returnValue: _i7.Future<_i5.RepositoryStatus>.value(
+                  _FakeRepositoryStatus_43(this, Invocation.method(#createStatus, [slug, ref, request]))))
+          as _i7.Future<_i5.RepositoryStatus>);
   @override
-  _i6.Future<_i4.CombinedRepositoryStatus> getCombinedStatus(_i4.RepositorySlug? slug, String? ref) =>
+  _i7.Future<_i5.CombinedRepositoryStatus> getCombinedStatus(_i5.RepositorySlug? slug, String? ref) =>
       (super.noSuchMethod(Invocation.method(#getCombinedStatus, [slug, ref]),
-              returnValue: _i6.Future<_i4.CombinedRepositoryStatus>.value(
-                  _FakeCombinedRepositoryStatus_39(this, Invocation.method(#getCombinedStatus, [slug, ref]))))
-          as _i6.Future<_i4.CombinedRepositoryStatus>);
+              returnValue: _i7.Future<_i5.CombinedRepositoryStatus>.value(
+                  _FakeCombinedRepositoryStatus_44(this, Invocation.method(#getCombinedStatus, [slug, ref]))))
+          as _i7.Future<_i5.CombinedRepositoryStatus>);
   @override
-  _i6.Future<_i4.ReleaseNotes> generateReleaseNotes(_i4.CreateReleaseNotes? crn) =>
+  _i7.Future<_i5.ReleaseNotes> generateReleaseNotes(_i5.CreateReleaseNotes? crn) =>
       (super.noSuchMethod(Invocation.method(#generateReleaseNotes, [crn]),
-              returnValue: _i6.Future<_i4.ReleaseNotes>.value(
-                  _FakeReleaseNotes_40(this, Invocation.method(#generateReleaseNotes, [crn]))))
-          as _i6.Future<_i4.ReleaseNotes>);
+              returnValue: _i7.Future<_i5.ReleaseNotes>.value(
+                  _FakeReleaseNotes_45(this, Invocation.method(#generateReleaseNotes, [crn]))))
+          as _i7.Future<_i5.ReleaseNotes>);
 }
 
 /// A class which mocks [GitHubComparison].
 ///
 /// See the documentation for Mockito's code generation for more information.
-class MockGitHubComparison extends _i1.Mock implements _i4.GitHubComparison {
+class MockGitHubComparison extends _i1.Mock implements _i5.GitHubComparison {
   MockGitHubComparison() {
     _i1.throwOnMissingStub(this);
   }
@@ -975,14 +1137,14 @@
 /// A class which mocks [Response].
 ///
 /// See the documentation for Mockito's code generation for more information.
-class MockResponse extends _i1.Mock implements _i3.Response {
+class MockResponse extends _i1.Mock implements _i2.Response {
   MockResponse() {
     _i1.throwOnMissingStub(this);
   }
 
   @override
-  _i8.Uint8List get bodyBytes =>
-      (super.noSuchMethod(Invocation.getter(#bodyBytes), returnValue: _i8.Uint8List(0)) as _i8.Uint8List);
+  _i11.Uint8List get bodyBytes =>
+      (super.noSuchMethod(Invocation.getter(#bodyBytes), returnValue: _i11.Uint8List(0)) as _i11.Uint8List);
   @override
   String get body => (super.noSuchMethod(Invocation.getter(#body), returnValue: '') as String);
   @override