diff --git a/app_dart/lib/cocoon_service.dart b/app_dart/lib/cocoon_service.dart index 8e0720972..9cd66123a 100644 --- a/app_dart/lib/cocoon_service.dart +++ b/app_dart/lib/cocoon_service.dart @@ -7,8 +7,8 @@ export 'src/foundation/utils.dart'; export 'src/model/firestore/base.dart' hide AppDocument; export 'src/model/firestore/commit.dart'; export 'src/model/firestore/pr_check_runs.dart'; -export 'src/model/firestore/presubmit_check.dart'; export 'src/model/firestore/presubmit_guard.dart'; +export 'src/model/firestore/presubmit_job.dart'; export 'src/model/firestore/suppressed_test.dart'; export 'src/model/firestore/task.dart'; export 'src/model/firestore/tree_status_change.dart'; diff --git a/app_dart/lib/server.dart b/app_dart/lib/server.dart index a05106575..3979a15ac 100644 --- a/app_dart/lib/server.dart +++ b/app_dart/lib/server.dart @@ -6,9 +6,9 @@ import 'dart:math'; import 'cocoon_service.dart'; import 'src/request_handlers/get_engine_artifacts_ready.dart'; -import 'src/request_handlers/get_presubmit_checks.dart'; import 'src/request_handlers/get_presubmit_guard.dart'; import 'src/request_handlers/get_presubmit_guard_summaries.dart'; +import 'src/request_handlers/get_presubmit_jobs.dart'; import 'src/request_handlers/get_tree_status_changes.dart'; import 'src/request_handlers/github_webhook_replay.dart'; import 'src/request_handlers/lookup_hash.dart'; @@ -207,7 +207,7 @@ Server createServer({ config: config, firestore: firestore, ), - '/api/public/get-presubmit-checks': GetPresubmitChecks( + '/api/public/get-presubmit-jobs': GetPresubmitJobs( config: config, firestore: firestore, ), diff --git a/app_dart/lib/src/generated_config.dart b/app_dart/lib/src/generated_config.dart index e9ca5e239..6152ab3c3 100644 --- a/app_dart/lib/src/generated_config.dart +++ b/app_dart/lib/src/generated_config.dart @@ -31,5 +31,5 @@ unifiedCheckRunFlow: useForAll: false useForUsers: - ievdokdm - - matanlurey + - eyebrowsoffire '''; diff --git a/app_dart/lib/src/model/common/failed_presubmit_checks.dart b/app_dart/lib/src/model/common/failed_presubmit_jobs.dart similarity index 54% rename from app_dart/lib/src/model/common/failed_presubmit_checks.dart rename to app_dart/lib/src/model/common/failed_presubmit_jobs.dart index e12aee144..bbe7e7ec6 100644 --- a/app_dart/lib/src/model/common/failed_presubmit_checks.dart +++ b/app_dart/lib/src/model/common/failed_presubmit_jobs.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -/// @docImport 'failed_presubmit_checks.dart'; +/// @docImport 'failed_presubmit_jobs.dart'; library; import 'package:collection/collection.dart'; @@ -11,40 +11,37 @@ import 'package:github/github.dart'; import '../firestore/base.dart'; -/// Contains the list of failed checks that are proposed to be re-run. +/// Contains the list of failed jobs that are proposed to be re-run. /// -/// See: [UnifiedCheckRun.reInitializeFailedChecks] -class FailedChecksForRerun { +/// See: [UnifiedCheckRun.reInitializeFailedJobs] +class FailedJobsForRerun { final CheckRun checkRunGuard; final CiStage stage; - final Map checkRetries; + final Map jobRetries; - const FailedChecksForRerun({ + const FailedJobsForRerun({ required this.checkRunGuard, required this.stage, - required this.checkRetries, + required this.jobRetries, }); @override bool operator ==(Object other) => identical(this, other) || - (other is FailedChecksForRerun && + (other is FailedJobsForRerun && other.checkRunGuard == checkRunGuard && other.stage == stage && - const DeepCollectionEquality().equals( - other.checkRetries, - checkRetries, - )); + const DeepCollectionEquality().equals(other.jobRetries, jobRetries)); @override int get hashCode => Object.hashAll([ checkRunGuard, stage, - ...checkRetries.keys, - ...checkRetries.values, + ...jobRetries.keys, + ...jobRetries.values, ]); @override String toString() => - 'FailedChecksForRerun("$checkRunGuard", "$stage", "$checkRetries")'; + 'FailedChecksForRerun("$checkRunGuard", "$stage", "$jobRetries")'; } diff --git a/app_dart/lib/src/model/common/presubmit_completed_check.dart b/app_dart/lib/src/model/common/presubmit_completed_check.dart index 23a5d010b..5ce9ac3dd 100644 --- a/app_dart/lib/src/model/common/presubmit_completed_check.dart +++ b/app_dart/lib/src/model/common/presubmit_completed_check.dart @@ -16,14 +16,14 @@ import '../firestore/base.dart'; import '../firestore/presubmit_guard.dart'; import '../github/checks.dart' as cocoon_checks; import 'checks_extension.dart'; -import 'presubmit_check_state.dart'; +import 'presubmit_job_state.dart'; -/// Unified representation of a completed presubmit check. +/// Unified representation of a completed presubmit job. /// -/// This class abstracts away the source of the check (GitHub CheckRun or BuildBucket Build) +/// This class abstracts away the source of the job (GitHub CheckRun or BuildBucket Build) /// to allow unified processing logic. @immutable -class PresubmitCompletedCheck { +class PresubmitCompletedJob { final String name; final String sha; final RepositorySlug slug; @@ -35,14 +35,14 @@ class PresubmitCompletedCheck { final String? headBranch; final bool isUnifiedCheckRun; final CiStage? stage; - final int? pullRequestNumber; + final int? prNum; final int attempt; final int? startTime; final int? endTime; final String? summary; final int? buildNumber; - const PresubmitCompletedCheck({ + const PresubmitCompletedJob({ required this.name, required this.sha, required this.slug, @@ -53,7 +53,7 @@ class PresubmitCompletedCheck { required this.headBranch, required this.isUnifiedCheckRun, this.stage, - this.pullRequestNumber, + this.prNum, this.attempt = 1, this.startTime, this.endTime, @@ -61,12 +61,12 @@ class PresubmitCompletedCheck { this.buildNumber, }); - /// Creates a [PresubmitCompletedCheck] from a GitHub [CheckRun]. - factory PresubmitCompletedCheck.fromCheckRun( + /// Creates a [PresubmitCompletedJob] from a GitHub [CheckRun]. + factory PresubmitCompletedJob.fromCheckRun( cocoon_checks.CheckRun checkRun, RepositorySlug slug, ) { - return PresubmitCompletedCheck( + return PresubmitCompletedJob( name: checkRun.name!, sha: checkRun.headSha!, slug: slug, @@ -84,13 +84,13 @@ class PresubmitCompletedCheck { ); } - /// Creates a [PresubmitCompletedCheck] from a BuildBucket [Build]. - factory PresubmitCompletedCheck.fromBuild( + /// Creates a [PresubmitCompletedJob] from a BuildBucket [Build]. + factory PresubmitCompletedJob.fromBuild( Build build, PresubmitUserData userData, { TaskStatus? status, }) { - return PresubmitCompletedCheck( + return PresubmitCompletedJob( name: build.builder.builder, sha: userData.commit.sha, slug: userData.commit.slug, @@ -101,7 +101,7 @@ class PresubmitCompletedCheck { headBranch: userData.commit.branch, isUnifiedCheckRun: userData.guardCheckRunId != null, stage: userData.stage, - pullRequestNumber: userData.pullRequestNumber, + prNum: userData.pullRequestNumber, attempt: _getAttempt(build), startTime: build.startTime.toDateTime().microsecondsSinceEpoch, endTime: build.endTime.toDateTime().microsecondsSinceEpoch, @@ -134,15 +134,15 @@ class PresubmitCompletedCheck { PresubmitGuardId get guardId { return PresubmitGuardId( slug: slug, - pullRequestId: pullRequestNumber ?? 0, + prNum: prNum ?? 0, checkRunId: checkRunId, stage: stage ?? CiStage.fusionTests, ); } - PresubmitCheckState get state { - return PresubmitCheckState( - buildName: name, + PresubmitJobState get state { + return PresubmitJobState( + jobName: name, status: status, attemptNumber: attempt, startTime: startTime, diff --git a/app_dart/lib/src/model/common/presubmit_check_state.dart b/app_dart/lib/src/model/common/presubmit_job_state.dart similarity index 77% rename from app_dart/lib/src/model/common/presubmit_check_state.dart rename to app_dart/lib/src/model/common/presubmit_job_state.dart index 13eeb2a50..120430d0d 100644 --- a/app_dart/lib/src/model/common/presubmit_check_state.dart +++ b/app_dart/lib/src/model/common/presubmit_job_state.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -/// @docImport 'presubmit_check_state.dart'; +/// @docImport 'presubmit_job_state.dart'; library; import 'package:buildbucket/buildbucket_pb.dart' as bbv2; @@ -12,8 +12,8 @@ import '../../service/luci_build_service/build_tags.dart'; import '../bbv2_extension.dart'; /// Represents the current state of a check run. -class PresubmitCheckState { - final String buildName; +class PresubmitJobState { + final String jobName; final TaskStatus status; final int attemptNumber; //static int _currentAttempt(BuildTags buildTags) final int? startTime; @@ -21,8 +21,8 @@ class PresubmitCheckState { final String? summary; final int? buildNumber; - const PresubmitCheckState({ - required this.buildName, + const PresubmitJobState({ + required this.jobName, required this.status, required this.attemptNumber, this.startTime, @@ -32,9 +32,9 @@ class PresubmitCheckState { }); } -extension BuildToPresubmitCheckState on bbv2.Build { - PresubmitCheckState toPresubmitCheckState() => PresubmitCheckState( - buildName: builder.builder, +extension BuildToPresubmitJobState on bbv2.Build { + PresubmitJobState toPresubmitJobState() => PresubmitJobState( + jobName: builder.builder, status: status.toTaskStatus(), attemptNumber: BuildTags.fromStringPairs(tags).currentAttempt, startTime: startTime.toDateTime().microsecondsSinceEpoch, diff --git a/app_dart/lib/src/model/firestore/presubmit_guard.dart b/app_dart/lib/src/model/firestore/presubmit_guard.dart index 5b2e48214..8f260d499 100644 --- a/app_dart/lib/src/model/firestore/presubmit_guard.dart +++ b/app_dart/lib/src/model/firestore/presubmit_guard.dart @@ -18,7 +18,7 @@ import 'base.dart'; final class PresubmitGuardId extends AppDocumentId { PresubmitGuardId({ required this.slug, - required this.pullRequestId, + required this.prNum, required this.checkRunId, required this.stage, }); @@ -26,8 +26,8 @@ final class PresubmitGuardId extends AppDocumentId { /// The repository owner/name. final RepositorySlug slug; - /// The pull request id. - final int pullRequestId; + /// The pull request number. + final int prNum; /// The Check Run Id. final int checkRunId; @@ -37,7 +37,7 @@ final class PresubmitGuardId extends AppDocumentId { @override String get documentId => - [slug.owner, slug.name, pullRequestId, checkRunId, stage].join('_'); + [slug.owner, slug.name, prNum, checkRunId, stage].join('_'); @override AppDocumentMetadata get runtimeMetadata => @@ -48,25 +48,25 @@ final class PresubmitGuard extends AppDocument { static const collectionId = 'presubmit_guards'; static const fieldCheckRun = 'check_run'; static const fieldCheckRunId = 'check_run_id'; - static const fieldPullRequestId = 'pull_request_id'; + static const fieldPrNum = 'pr_num'; static const fieldSlug = 'slug'; static const fieldStage = 'stage'; - static const fieldCommitSha = 'commit_sha'; + static const fieldHeadSha = 'head_sha'; static const fieldAuthor = 'author'; static const fieldCreationTime = 'creation_time'; - static const fieldRemainingBuilds = 'remaining_builds'; - static const fieldFailedBuilds = 'failed_builds'; - static const fieldBuilds = 'builds'; + static const fieldRemainingJobs = 'remaining_jobs'; + static const fieldFailedJobs = 'failed_jobs'; + static const fieldJobs = 'jobs'; static AppDocumentId documentIdFor({ required RepositorySlug slug, - required int pullRequestId, + required int prNum, required int checkRunId, required CiStage stage, }) { return PresubmitGuardId( slug: slug, - pullRequestId: pullRequestId, + prNum: prNum, checkRunId: checkRunId, stage: stage, ); @@ -75,14 +75,14 @@ final class PresubmitGuard extends AppDocument { /// Returns a firebase documentName used in [fromFirestore]. static String documentNameFor({ required RepositorySlug slug, - required int pullRequestId, + required int prNum, required int checkRunId, required CiStage stage, }) { // Document names cannot cannot have '/' in the document id. final docId = documentIdFor( slug: slug, - pullRequestId: pullRequestId, + prNum: prNum, checkRunId: checkRunId, stage: stage, ); @@ -92,11 +92,11 @@ final class PresubmitGuard extends AppDocument { /// Returns the document ID for the given parameters. // static String documentId({ // required RepositorySlug slug, - // required int pullRequestId, + // required int prNum, // required int checkRunId, // required CiStage stage, // }) => - // '${slug.owner}_${slug.name}_${pullRequestId}_${checkRunId}_${stage.name}'; + // '${slug.owner}_${slug.name}_${prNum}_${checkRunId}_${stage.name}'; @override AppDocumentMetadata get runtimeMetadata => metadata; @@ -108,24 +108,24 @@ final class PresubmitGuard extends AppDocument { factory PresubmitGuard.init({ required RepositorySlug slug, - required int pullRequestId, + required int prNum, required CheckRun checkRun, required CiStage stage, - required String commitSha, + required String headSha, required int creationTime, required String author, - required int buildCount, + required int jobCount, }) { return PresubmitGuard( checkRun: checkRun, - commitSha: commitSha, + headSha: headSha, slug: slug, - pullRequestId: pullRequestId, + prNum: prNum, stage: stage, author: author, creationTime: creationTime, - remainingBuilds: buildCount, - failedBuilds: 0, + remainingJobs: jobCount, + failedJobs: 0, ); } @@ -135,38 +135,38 @@ final class PresubmitGuard extends AppDocument { factory PresubmitGuard({ required CheckRun checkRun, - required String commitSha, + required String headSha, required RepositorySlug slug, - required int pullRequestId, + required int prNum, required CiStage stage, required int creationTime, required String author, - required int remainingBuilds, - required int failedBuilds, - Map? builds, + required int remainingJobs, + required int failedJobs, + Map? jobs, }) { return PresubmitGuard._( { fieldCheckRunId: checkRun.id!.toValue(), - fieldPullRequestId: pullRequestId.toValue(), + fieldPrNum: prNum.toValue(), fieldSlug: slug.fullName.toValue(), fieldStage: stage.name.toValue(), - fieldCommitSha: commitSha.toValue(), + fieldHeadSha: headSha.toValue(), fieldCreationTime: creationTime.toValue(), fieldAuthor: author.toValue(), fieldCheckRun: json.encode(checkRun.toJson()).toValue(), - fieldRemainingBuilds: remainingBuilds.toValue(), - fieldFailedBuilds: failedBuilds.toValue(), - if (builds != null) - fieldBuilds: Value( + fieldRemainingJobs: remainingJobs.toValue(), + fieldFailedJobs: failedJobs.toValue(), + if (jobs != null) + fieldJobs: Value( mapValue: MapValue( - fields: builds.map((k, v) => MapEntry(k, v.value.toValue())), + fields: jobs.map((k, v) => MapEntry(k, v.value.toValue())), ), ), }, name: documentNameFor( slug: slug, - pullRequestId: pullRequestId, + prNum: prNum, checkRunId: checkRun.id!, stage: stage, ), @@ -178,14 +178,13 @@ final class PresubmitGuard extends AppDocument { this.name = name; } - String get commitSha => fields[fieldCommitSha]!.stringValue!; + String get commitSha => fields[fieldHeadSha]!.stringValue!; String get author => fields[fieldAuthor]!.stringValue!; int get creationTime => int.parse(fields[fieldCreationTime]!.integerValue!); - int get remainingBuilds => - int.parse(fields[fieldRemainingBuilds]!.integerValue!); - int get failedBuilds => int.parse(fields[fieldFailedBuilds]!.integerValue!); - Map get builds => - fields[fieldBuilds]?.mapValue?.fields?.map( + int get remainingJobs => int.parse(fields[fieldRemainingJobs]!.integerValue!); + int get failedJobs => int.parse(fields[fieldFailedJobs]!.integerValue!); + Map get jobs => + fields[fieldJobs]?.mapValue?.fields?.map( (k, v) => MapEntry(k, TaskStatus.from(v.stringValue!)), ) ?? {}; @@ -212,13 +211,13 @@ final class PresubmitGuard extends AppDocument { } /// The pull request for which this stage is recorded for. - int get pullRequestId { - if (fields[fieldPullRequestId] != null) { - return int.parse(fields[fieldPullRequestId]!.integerValue!); + int get prNum { + if (fields[fieldPrNum] != null) { + return int.parse(fields[fieldPrNum]!.integerValue!); } // Read it from the document name. - final [_, _, pullRequestId, _, _] = p.posix.basename(name!).split('_'); - return int.parse(pullRequestId); + final [_, _, prNum, _, _] = p.posix.basename(name!).split('_'); + return int.parse(prNum); } /// Which commit this stage is recorded for. @@ -243,23 +242,23 @@ final class PresubmitGuard extends AppDocument { return CiStage.values.firstWhere((e) => e.name == stageName); } - List get failedBuildNames => [ - for (final MapEntry(:key, :value) in builds.entries) + List get failedJobNames => [ + for (final MapEntry(:key, :value) in jobs.entries) if (value.isFailure) key, ]; - set remainingBuilds(int remainingBuilds) { - fields[fieldRemainingBuilds] = remainingBuilds.toValue(); + set remainingJobs(int remainingJobs) { + fields[fieldRemainingJobs] = remainingJobs.toValue(); } - set failedBuilds(int failedBuilds) { - fields[fieldFailedBuilds] = failedBuilds.toValue(); + set failedJobs(int failedJobs) { + fields[fieldFailedJobs] = failedJobs.toValue(); } - set builds(Map builds) { - fields[fieldBuilds] = Value( + set jobs(Map jobs) { + fields[fieldJobs] = Value( mapValue: MapValue( - fields: builds.map((k, v) => MapEntry(k, v.value.toValue())), + fields: jobs.map((k, v) => MapEntry(k, v.value.toValue())), ), ); } diff --git a/app_dart/lib/src/model/firestore/presubmit_check.dart b/app_dart/lib/src/model/firestore/presubmit_job.dart similarity index 71% rename from app_dart/lib/src/model/firestore/presubmit_check.dart rename to app_dart/lib/src/model/firestore/presubmit_job.dart index 93f3e6c70..5c285fafe 100644 --- a/app_dart/lib/src/model/firestore/presubmit_check.dart +++ b/app_dart/lib/src/model/firestore/presubmit_job.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -/// @docImport 'presubmit_check.dart'; +/// @docImport 'presubmit_job.dart'; library; import 'package:buildbucket/buildbucket_pb.dart' as bbv2; @@ -17,11 +17,11 @@ import '../bbv2_extension.dart'; import 'base.dart'; @immutable -final class PresubmitCheckId extends AppDocumentId { - PresubmitCheckId({ +final class PresubmitJobId extends AppDocumentId { + PresubmitJobId({ required this.slug, required this.checkRunId, - required this.buildName, + required this.jobName, required this.attemptNumber, }) { if (checkRunId < 1) { @@ -35,32 +35,32 @@ final class PresubmitCheckId extends AppDocumentId { } } - /// Parse the inverse of [PresubmitCheckId.documentName]. - factory PresubmitCheckId.parse(String documentName) { + /// Parse the inverse of [PresubmitJobId.documentName]. + factory PresubmitJobId.parse(String documentName) { final result = tryParse(documentName); if (result == null) { throw FormatException( - 'Unexpected firestore presubmit check document name: "$documentName"', + 'Unexpected firestore presubmit job document name: "$documentName"', ); } return result; } - /// Tries to parse the inverse of [PresubmitCheckId.documentName]. + /// Tries to parse the inverse of [PresubmitJobId.documentName]. /// /// If could not be parsed, returns `null`. - static PresubmitCheckId? tryParse(String documentName) { + static PresubmitJobId? tryParse(String documentName) { if (_parseDocumentName.matchAsPrefix(documentName) case final match?) { final owner = match.group(1)!; final repo = match.group(2)!; final checkRunId = int.tryParse(match.group(3)!); - final buildName = match.group(4)!; + final jobName = match.group(4)!; final attemptNumber = int.tryParse(match.group(5)!); if (checkRunId != null && attemptNumber != null) { - return PresubmitCheckId( + return PresubmitJobId( slug: RepositorySlug(owner, repo), checkRunId: checkRunId, - buildName: buildName, + jobName: jobName, attemptNumber: attemptNumber, ); } @@ -68,18 +68,18 @@ final class PresubmitCheckId extends AppDocumentId { return null; } - /// Parses `{owner}_{repo}_{checkRunId}_{buildName}_{attemptNumber}`. + /// Parses `{owner}_{repo}_{check_run_id}_{job_name}_{attempt_number}`. /// - /// [buildName] could also include underscores which led us to use regexp . - /// But we dont have build number at the moment of creating the document and - /// we need to query by checkRunId and buildName for updating the document. + /// [jobName] could also include underscores which led us to use regexp . + /// But we dont have job number at the moment of creating the document and + /// we need to query by check_run_id and job_name for updating the document. static final _parseDocumentName = RegExp( r'^([a-zA-Z0-9_-]+)_([a-zA-Z0-9_-]+)_([0-9]+)_(.*)_([0-9]+)$', ); final RepositorySlug slug; final int checkRunId; - final String buildName; + final String jobName; final int attemptNumber; @override @@ -88,39 +88,39 @@ final class PresubmitCheckId extends AppDocumentId { slug.owner, slug.name, checkRunId, - buildName, + jobName, attemptNumber, ].join('_'); } @override - AppDocumentMetadata get runtimeMetadata => - PresubmitCheck.metadata; + AppDocumentMetadata get runtimeMetadata => + PresubmitJob.metadata; } -final class PresubmitCheck extends AppDocument { - static const collectionId = 'presubmit_checks'; - static const fieldCheckRunId = 'checkRunId'; +final class PresubmitJob extends AppDocument { + static const collectionId = 'presubmit_jobs'; + static const fieldCheckRunId = 'check_run_id'; static const fieldSlug = 'slug'; - static const fieldBuildName = 'buildName'; - static const fieldBuildNumber = 'buildNumber'; + static const fieldJobName = 'job_name'; + static const fieldBuildNumber = 'build_number'; static const fieldStatus = 'status'; - static const fieldAttemptNumber = 'attemptNumber'; - static const fieldCreationTime = 'creationTime'; - static const fieldStartTime = 'startTime'; - static const fieldEndTime = 'endTime'; + static const fieldAttemptNumber = 'attempt_number'; + static const fieldCreationTime = 'creation_time'; + static const fieldStartTime = 'start_time'; + static const fieldEndTime = 'end_time'; static const fieldSummary = 'summary'; - static AppDocumentId documentIdFor({ + static AppDocumentId documentIdFor({ required RepositorySlug slug, required int checkRunId, - required String buildName, + required String jobName, required int attemptNumber, }) { - return PresubmitCheckId( + return PresubmitJobId( slug: slug, checkRunId: checkRunId, - buildName: buildName, + jobName: jobName, attemptNumber: attemptNumber, ); } @@ -129,41 +129,41 @@ final class PresubmitCheck extends AppDocument { static String documentNameFor({ required RepositorySlug slug, required int checkRunId, - required String buildName, + required String jobName, required int attemptNumber, }) { // Document names cannot cannot have '/' in the document id. final docId = documentIdFor( slug: slug, checkRunId: checkRunId, - buildName: buildName, + jobName: jobName, attemptNumber: attemptNumber, ); return '$kDocumentParent/$collectionId/${docId.documentId}'; } @override - AppDocumentMetadata get runtimeMetadata => metadata; + AppDocumentMetadata get runtimeMetadata => metadata; - static final metadata = AppDocumentMetadata( + static final metadata = AppDocumentMetadata( collectionId: collectionId, - fromDocument: PresubmitCheck.fromDocument, + fromDocument: PresubmitJob.fromDocument, ); - static Future fromFirestore( + static Future fromFirestore( FirestoreService firestoreService, - AppDocumentId id, + AppDocumentId id, ) async { final document = await firestoreService.getDocument( p.posix.join(kDatabase, 'documents', collectionId, id.documentId), ); - return PresubmitCheck.fromDocument(document); + return PresubmitJob.fromDocument(document); } - factory PresubmitCheck({ + factory PresubmitJob({ required RepositorySlug slug, required int checkRunId, - required String buildName, + required String jobName, required TaskStatus status, required int attemptNumber, required int creationTime, @@ -172,11 +172,11 @@ final class PresubmitCheck extends AppDocument { int? endTime, String? summary, }) { - return PresubmitCheck._( + return PresubmitJob._( { fieldSlug: slug.fullName.toValue(), fieldCheckRunId: checkRunId.toValue(), - fieldBuildName: buildName.toValue(), + fieldJobName: jobName.toValue(), fieldBuildNumber: ?buildNumber?.toValue(), fieldStatus: status.value.toValue(), fieldAttemptNumber: attemptNumber.toValue(), @@ -188,26 +188,26 @@ final class PresubmitCheck extends AppDocument { name: documentNameFor( slug: slug, checkRunId: checkRunId, - buildName: buildName, + jobName: jobName, attemptNumber: attemptNumber, ), ); } - factory PresubmitCheck.fromDocument(Document document) { - return PresubmitCheck._(document.fields!, name: document.name!); + factory PresubmitJob.fromDocument(Document document) { + return PresubmitJob._(document.fields!, name: document.name!); } - factory PresubmitCheck.init({ + factory PresubmitJob.init({ required RepositorySlug slug, - required String buildName, + required String jobName, required int checkRunId, required int creationTime, int? attemptNumber, }) { - return PresubmitCheck( + return PresubmitJob( slug: slug, - buildName: buildName, + jobName: jobName, attemptNumber: attemptNumber ?? 1, checkRunId: checkRunId, creationTime: creationTime, @@ -219,7 +219,7 @@ final class PresubmitCheck extends AppDocument { ); } - PresubmitCheck._(Map fields, {required String name}) { + PresubmitJob._(Map fields, {required String name}) { this ..fields = fields ..name = name; @@ -230,11 +230,11 @@ final class PresubmitCheck extends AppDocument { return RepositorySlug.full(fields[fieldSlug]!.stringValue!); } // Read it from the document name. - return PresubmitCheckId.parse(p.posix.basename(name!)).slug; + return PresubmitJobId.parse(p.posix.basename(name!)).slug; } int get checkRunId => int.parse(fields[fieldCheckRunId]!.integerValue!); - String get buildName => fields[fieldBuildName]!.stringValue!; + String get jobName => fields[fieldJobName]!.stringValue!; int get attemptNumber => int.parse(fields[fieldAttemptNumber]!.integerValue!); int get creationTime => int.parse(fields[fieldCreationTime]!.integerValue!); int? get buildNumber => fields[fieldBuildNumber] != null diff --git a/app_dart/lib/src/request_handlers/get_presubmit_guard.dart b/app_dart/lib/src/request_handlers/get_presubmit_guard.dart index d72037a7a..a7cf7bc49 100644 --- a/app_dart/lib/src/request_handlers/get_presubmit_guard.dart +++ b/app_dart/lib/src/request_handlers/get_presubmit_guard.dart @@ -65,12 +65,12 @@ final class GetPresubmitGuard extends PublicApiRequestHandler { // Consolidate metadata from the first record. final first = guards.first; - final totalFailed = guards.fold(0, (sum, g) => sum + g.failedBuilds); + final totalFailed = guards.fold(0, (sum, g) => sum + g.failedJobs); final totalRemaining = guards.fold( 0, - (sum, g) => sum + g.remainingBuilds, + (sum, g) => sum + g.remainingJobs, ); - final totalBuilds = guards.fold(0, (sum, g) => sum + g.builds.length); + final totalBuilds = guards.fold(0, (sum, g) => sum + g.jobs.length); final guardStatus = GuardStatus.calculate( failedBuilds: totalFailed, @@ -79,7 +79,7 @@ final class GetPresubmitGuard extends PublicApiRequestHandler { ); final response = rpc_model.PresubmitGuardResponse( - prNum: first.pullRequestId, + prNum: first.prNum, checkRunId: first.checkRunId, author: first.author, guardStatus: guardStatus, @@ -88,7 +88,7 @@ final class GetPresubmitGuard extends PublicApiRequestHandler { rpc_model.PresubmitGuardStage( name: g.stage.name, createdAt: g.creationTime, - builds: g.builds, + builds: g.jobs, ), ], ); diff --git a/app_dart/lib/src/request_handlers/get_presubmit_guard_summaries.dart b/app_dart/lib/src/request_handlers/get_presubmit_guard_summaries.dart index 897e53f51..16fc4a36a 100644 --- a/app_dart/lib/src/request_handlers/get_presubmit_guard_summaries.dart +++ b/app_dart/lib/src/request_handlers/get_presubmit_guard_summaries.dart @@ -46,19 +46,19 @@ final class GetPresubmitGuardSummaries extends PublicApiRequestHandler { checkRequiredQueryParameters(request, [kPRParam]); final repo = request.uri.queryParameters[kRepoParam] ?? 'flutter'; - final prNumber = int.parse(request.uri.queryParameters[kPRParam]!); + final pr = int.parse(request.uri.queryParameters[kPRParam]!); final owner = request.uri.queryParameters[kOwnerParam] ?? 'flutter'; final slug = RepositorySlug(owner, repo); final guards = await UnifiedCheckRun.getPresubmitGuardsForPullRequest( firestoreService: _firestore, slug: slug, - pullRequestId: prNumber, + prNum: pr, ); if (guards.isEmpty) { return Response.json({ - 'error': 'No guards found for PR $prNumber in $slug', + 'error': 'No guards found for PR $pr in $slug', }, statusCode: HttpStatus.notFound); } @@ -75,15 +75,15 @@ final class GetPresubmitGuardSummaries extends PublicApiRequestHandler { final totalFailed = shaGuards.fold( 0, - (int sum, PresubmitGuard g) => sum + g.failedBuilds, + (int sum, PresubmitGuard g) => sum + g.failedJobs, ); final totalRemaining = shaGuards.fold( 0, - (int sum, PresubmitGuard g) => sum + g.remainingBuilds, + (int sum, PresubmitGuard g) => sum + g.remainingJobs, ); final totalBuilds = shaGuards.fold( 0, - (int sum, PresubmitGuard g) => sum + g.builds.length, + (int sum, PresubmitGuard g) => sum + g.jobs.length, ); final earliestCreationTime = shaGuards.fold( // assuming creation time is always in the past :) @@ -93,7 +93,7 @@ final class GetPresubmitGuardSummaries extends PublicApiRequestHandler { responseGuards.add( rpc_model.PresubmitGuardSummary( - commitSha: sha, + headSha: sha, creationTime: earliestCreationTime, guardStatus: GuardStatus.calculate( failedBuilds: totalFailed, diff --git a/app_dart/lib/src/request_handlers/get_presubmit_checks.dart b/app_dart/lib/src/request_handlers/get_presubmit_jobs.dart similarity index 67% rename from app_dart/lib/src/request_handlers/get_presubmit_checks.dart rename to app_dart/lib/src/request_handlers/get_presubmit_jobs.dart index 3ea1a8893..5d7b6af56 100644 --- a/app_dart/lib/src/request_handlers/get_presubmit_checks.dart +++ b/app_dart/lib/src/request_handlers/get_presubmit_jobs.dart @@ -11,13 +11,13 @@ import '../../cocoon_service.dart'; import '../request_handling/public_api_request_handler.dart'; import '../service/firestore/unified_check_run.dart'; -/// Returns all checks for a specific presubmit check run. +/// Returns all jobs for a specific presubmit job. /// -/// GET: /api/public/get-presubmit-checks +/// GET: /api/public/get-presubmit-jobs /// /// Parameters: /// check_run_id: (int in query) mandatory. The GitHub Check Run ID. -/// build_name: (string in query) mandatory. The name of the check/build. +/// job_name: (string in query) mandatory. The name of the job. /// repo: (string in query) optional. The repository name. /// owner: (string in query) optional. The repository owner. /// @@ -25,7 +25,7 @@ import '../service/firestore/unified_check_run.dart'; /// [ /// { /// "attempt_number": 1, -/// "build_name": "Linux Device Doctor", +/// "job_name": "Linux Device Doctor", /// "creation_time": 1620134239000, /// "start_time": 1620134240000, /// "end_time": 1620134250000, @@ -33,8 +33,8 @@ import '../service/firestore/unified_check_run.dart'; /// "summary": "Check passed" /// } /// ] -final class GetPresubmitChecks extends PublicApiRequestHandler { - const GetPresubmitChecks({ +final class GetPresubmitJobs extends PublicApiRequestHandler { + const GetPresubmitJobs({ required super.config, required FirestoreService firestore, }) : _firestore = firestore; @@ -44,8 +44,8 @@ final class GetPresubmitChecks extends PublicApiRequestHandler { /// The query parameter for the GitHub Check Run ID. static const String kCheckRunIdParam = 'check_run_id'; - /// The query parameter for the build name. - static const String kBuildNameParam = 'build_name'; + /// The query parameter for the job name. + static const String kJobNameParam = 'job_name'; /// The name of the query parameter for the repository name (e.g. 'flutter'). static const String kRepoParam = 'repo'; @@ -56,14 +56,14 @@ final class GetPresubmitChecks extends PublicApiRequestHandler { @override Future get(Request request) async { final checkRunIdString = request.uri.queryParameters[kCheckRunIdParam]; - final buildName = request.uri.queryParameters[kBuildNameParam]; + final jobName = request.uri.queryParameters[kJobNameParam]; final repo = request.uri.queryParameters[kRepoParam] ?? 'flutter'; final owner = request.uri.queryParameters[kOwnerParam] ?? 'flutter'; - if (checkRunIdString == null || buildName == null) { + if (checkRunIdString == null || jobName == null) { return Response.json({ 'error': - 'Missing mandatory parameters: $kCheckRunIdParam, $kBuildNameParam', + 'Missing mandatory parameters: $kCheckRunIdParam, $kJobNameParam', }, statusCode: HttpStatus.badRequest); } @@ -75,31 +75,31 @@ final class GetPresubmitChecks extends PublicApiRequestHandler { } final slug = RepositorySlug(owner, repo); - final checks = await UnifiedCheckRun.getPresubmitCheckDetails( + final jobs = await UnifiedCheckRun.getPresubmitJobDetails( firestoreService: _firestore, checkRunId: checkRunId, - buildName: buildName, + jobName: jobName, slug: slug, ); - if (checks.isEmpty) { + if (jobs.isEmpty) { return Response.json({ 'error': - 'No checks found for check_run_id $checkRunId and build_name $buildName', + 'No checks found for check_run_id $checkRunId and job_name $jobName', }, statusCode: HttpStatus.notFound); } final rpcChecks = [ - for (final check in checks) - PresubmitCheckResponse( - attemptNumber: check.attemptNumber, - buildName: check.buildName, - creationTime: check.creationTime, - startTime: check.startTime, - endTime: check.endTime, - status: check.status.value, - summary: check.summary, - buildNumber: check.buildNumber, + for (final job in jobs) + PresubmitJobResponse( + attemptNumber: job.attemptNumber, + jobName: job.jobName, + creationTime: job.creationTime, + startTime: job.startTime, + endTime: job.endTime, + status: job.status.value, + summary: job.summary, + buildNumber: job.buildNumber, ), ]; diff --git a/app_dart/lib/src/request_handlers/presubmit_luci_subscription.dart b/app_dart/lib/src/request_handlers/presubmit_luci_subscription.dart index b13bd932e..f83c42e13 100644 --- a/app_dart/lib/src/request_handlers/presubmit_luci_subscription.dart +++ b/app_dart/lib/src/request_handlers/presubmit_luci_subscription.dart @@ -164,7 +164,7 @@ final class PresubmitLuciSubscription extends SubscriptionHandler { // Process to the check-run status in the merge queue document during // the LUCI callback. if (config.flags.closeMqGuardAfterPresubmit || isUnifiedCheckRun) { - final check = PresubmitCompletedCheck.fromBuild( + final check = PresubmitCompletedJob.fromBuild( build, userData, status: override == .neutral ? .neutral : null, diff --git a/app_dart/lib/src/request_handlers/rerun_all_failed_jobs.dart b/app_dart/lib/src/request_handlers/rerun_all_failed_jobs.dart index 90d4f7fa4..6d2c25b8d 100644 --- a/app_dart/lib/src/request_handlers/rerun_all_failed_jobs.dart +++ b/app_dart/lib/src/request_handlers/rerun_all_failed_jobs.dart @@ -50,10 +50,10 @@ final class RerunAllFailedJobs extends ApiRequestHandler { final slug = RepositorySlug(owner, repo); - final guard = await UnifiedCheckRun.getLatestPresubmitGuardByPullRequestNum( + final guard = await UnifiedCheckRun.getLatestPresubmitGuardForPrNum( firestoreService: _firestore, slug: slug, - pullRequestNum: prNumber, + prNum: prNumber, ); if (guard == null) { throw NotFoundException('No PresubmitGuard found for PR $slug/$prNumber'); @@ -72,10 +72,10 @@ final class RerunAllFailedJobs extends ApiRequestHandler { ); } - final failedChecks = await UnifiedCheckRun.reInitializeFailedChecks( + final failedChecks = await UnifiedCheckRun.reInitializeFailedJobs( firestoreService: _firestore, slug: slug, - pullRequestId: prNumber, + prNum: prNumber, guardCheckRunId: guard.checkRunId, ); @@ -90,12 +90,12 @@ final class RerunAllFailedJobs extends ApiRequestHandler { final checkRetries = {}; for (final target in targets) { - if (failedChecks.checkRetries.containsKey(target.name)) { - checkRetries[target] = failedChecks.checkRetries[target.name]!; + if (failedChecks.jobRetries.containsKey(target.name)) { + checkRetries[target] = failedChecks.jobRetries[target.name]!; } } - if (checkRetries.length != failedChecks.checkRetries.length) { + if (checkRetries.length != failedChecks.jobRetries.length) { throw const NotFoundException( 'Failed to find all failed targets in presubmit targets', ); diff --git a/app_dart/lib/src/request_handlers/rerun_failed_job.dart b/app_dart/lib/src/request_handlers/rerun_failed_job.dart index 8b47953f1..8749676ee 100644 --- a/app_dart/lib/src/request_handlers/rerun_failed_job.dart +++ b/app_dart/lib/src/request_handlers/rerun_failed_job.dart @@ -19,7 +19,7 @@ import '../service/firestore/unified_check_run.dart'; /// owner: (string in body) mandatory. The GitHub repository owner. /// repo: (string in body) mandatory. The GitHub repository name. /// pr: (int in body) mandatory. The Pull Request number. -/// build_name: (string in body) mandatory. The name of the build to re-run. +/// job_name: (string in body) mandatory. The name of the job to re-run. final class RerunFailedJob extends ApiRequestHandler { const RerunFailedJob({ required super.config, @@ -38,24 +38,24 @@ final class RerunFailedJob extends ApiRequestHandler { static const String kOwnerParam = 'owner'; static const String kRepoParam = 'repo'; static const String kPrParam = 'pr'; - static const String kBuildNameParam = 'build_name'; + static const String kJobNameParam = 'job_name'; @override Future post(Request request) async { final requestData = await request.readBodyAsJson(); - checkRequiredParameters(requestData, [kPrParam, kBuildNameParam]); + checkRequiredParameters(requestData, [kPrParam, kJobNameParam]); final owner = requestData[kOwnerParam] as String? ?? 'flutter'; final repo = requestData[kRepoParam] as String? ?? 'flutter'; final prNumber = requestData[kPrParam] as int; - final buildName = requestData[kBuildNameParam] as String; + final jobName = requestData[kJobNameParam] as String; final slug = RepositorySlug(owner, repo); - final guard = await UnifiedCheckRun.getLatestPresubmitGuardByPullRequestNum( + final guard = await UnifiedCheckRun.getLatestPresubmitGuardForPrNum( firestoreService: _firestore, slug: slug, - pullRequestNum: prNumber, + prNum: prNumber, ); if (guard == null) { throw NotFoundException('No PresubmitGuard found for PR $slug/$prNumber'); @@ -77,14 +77,14 @@ final class RerunFailedJob extends ApiRequestHandler { final rerunInfo = await UnifiedCheckRun.reInitializeFailedJob( firestoreService: _firestore, slug: slug, - pullRequestId: prNumber, + prNum: prNumber, guardCheckRunId: guard.checkRunId, - buildName: buildName, + jobName: jobName, ); if (rerunInfo == null) { throw BadRequestException( - 'Build $buildName is not a failed job in PR $slug/$prNumber', + 'Job $jobName is not a failed job in PR $slug/$prNumber', ); } @@ -94,12 +94,12 @@ final class RerunFailedJob extends ApiRequestHandler { ); final target = targets.firstWhere( - (t) => t.name == buildName, + (t) => t.name == jobName, orElse: () => - throw BadRequestException('Target $buildName not found in .ci.yaml'), + throw BadRequestException('Target $jobName not found in .ci.yaml'), ); - final retries = rerunInfo.checkRetries[buildName]!; + final retries = rerunInfo.jobRetries[jobName]!; await _luciBuildService.reScheduleTryBuilds( targets: {target: retries}, @@ -109,6 +109,6 @@ final class RerunFailedJob extends ApiRequestHandler { stage: rerunInfo.stage, ); - return Response.json({'builder': buildName, 'status': 'rescheduled'}); + return Response.json({'builder': jobName, 'status': 'rescheduled'}); } } diff --git a/app_dart/lib/src/service/firestore/unified_check_run.dart b/app_dart/lib/src/service/firestore/unified_check_run.dart index bfcba9dcf..53e982358 100644 --- a/app_dart/lib/src/service/firestore/unified_check_run.dart +++ b/app_dart/lib/src/service/firestore/unified_check_run.dart @@ -12,13 +12,13 @@ import 'package:github/github.dart'; import 'package:googleapis/firestore/v1.dart' hide Status; import 'package:meta/meta.dart'; -import '../../model/common/failed_presubmit_checks.dart'; -import '../../model/common/presubmit_check_state.dart'; +import '../../model/common/failed_presubmit_jobs.dart'; import '../../model/common/presubmit_guard_conclusion.dart'; +import '../../model/common/presubmit_job_state.dart'; import '../../model/firestore/base.dart'; import '../../model/firestore/ci_staging.dart'; -import '../../model/firestore/presubmit_check.dart'; import '../../model/firestore/presubmit_guard.dart'; +import '../../model/firestore/presubmit_job.dart'; import '../config.dart'; import '../firestore.dart'; @@ -39,7 +39,7 @@ final class UnifiedCheckRun { config.flags.isUnifiedCheckRunFlowEnabledForUser( pullRequest.user!.login!, )) { - // Create the UnifiedCheckRun and UnifiedCheckRunBuilds. + // Create the presubmit_guard and associated presubmit_job documents. log.info( 'Storing UnifiedCheckRun data for ${slug.fullName}#${pullRequest.number} as it enabled for user ${pullRequest.user!.login}.', ); @@ -49,27 +49,27 @@ final class UnifiedCheckRun { final creationTime = utcNow().microsecondsSinceEpoch; final guard = PresubmitGuard( checkRun: checkRun, - commitSha: sha, + headSha: sha, slug: slug, - pullRequestId: pullRequest.number!, + prNum: pullRequest.number!, stage: stage, creationTime: creationTime, author: pullRequest.user!.login!, - remainingBuilds: tasks.length, - failedBuilds: 0, - builds: {for (final task in tasks) task: TaskStatus.waitingForBackfill}, + remainingJobs: tasks.length, + failedJobs: 0, + jobs: {for (final task in tasks) task: TaskStatus.waitingForBackfill}, ); - final checks = [ + final jobs = [ for (final task in tasks) - PresubmitCheck.init( + PresubmitJob.init( slug: slug, - buildName: task, + jobName: task, checkRunId: checkRun.id!, creationTime: creationTime, ), ]; await firestoreService.writeViaTransaction( - documentsToWrites([...checks, guard], exists: false), + documentsToWrites([...jobs, guard], exists: false), ); } else { // Initialize the CiStaging document. @@ -84,18 +84,18 @@ final class UnifiedCheckRun { } } - /// Re-initializes all failed checks for the specified [guardCheckRunId]. - static Future reInitializeFailedChecks({ + /// Re-initializes all failed jobs for the specified [guardCheckRunId]. + static Future reInitializeFailedJobs({ required FirestoreService firestoreService, required RepositorySlug slug, - required int pullRequestId, + required int prNum, required int guardCheckRunId, @visibleForTesting DateTime Function() utcNow = DateTime.timestamp, }) async { final guard = await getLatestPresubmitGuardForCheckRun( firestoreService: firestoreService, slug: slug, - pullRequestId: pullRequestId, + prNum: prNum, checkRunId: guardCheckRunId, ); @@ -104,7 +104,7 @@ final class UnifiedCheckRun { } final logCrumb = - 'reInitializeFailedChecks(${slug.fullName}, $pullRequestId, $guardCheckRunId)'; + 'reInitializeFailedChecks(${slug.fullName}, $prNum, $guardCheckRunId)'; log.info('$logCrumb Re-Running failed checks.'); final transaction = await firestoreService.beginTransaction(); @@ -114,7 +114,7 @@ final class UnifiedCheckRun { final latestGuard = await getLatestPresubmitGuardForCheckRun( firestoreService: firestoreService, slug: slug, - pullRequestId: pullRequestId, + prNum: prNum, checkRunId: guardCheckRunId, transaction: transaction, ); @@ -125,29 +125,29 @@ final class UnifiedCheckRun { } final creationTime = utcNow().microsecondsSinceEpoch; - final failedBuildNames = latestGuard.failedBuildNames; - if (failedBuildNames.isNotEmpty) { - latestGuard.failedBuilds = 0; - latestGuard.remainingBuilds = failedBuildNames.length; - final builds = latestGuard.builds; - for (final buildName in failedBuildNames) { - builds[buildName] = TaskStatus.waitingForBackfill; + final failedJobNames = latestGuard.failedJobNames; + if (failedJobNames.isNotEmpty) { + latestGuard.failedJobs = 0; + latestGuard.remainingJobs = failedJobNames.length; + final jobs = latestGuard.jobs; + for (final jobName in failedJobNames) { + jobs[jobName] = TaskStatus.waitingForBackfill; } - latestGuard.builds = builds; - final checks = []; + latestGuard.jobs = jobs; + final checks = []; final checkRetries = {}; - for (final buildName in failedBuildNames) { - final latestCheck = await getLatestPresubmitCheck( + for (final jobName in failedJobNames) { + final latestCheck = await getLatestPresubmitJob( firestoreService: firestoreService, checkRunId: guardCheckRunId, - buildName: buildName, + jobName: jobName, transaction: transaction, ); - checkRetries[buildName] = (latestCheck?.attemptNumber ?? 0) + 1; + checkRetries[jobName] = (latestCheck?.attemptNumber ?? 0) + 1; checks.add( - PresubmitCheck.init( + PresubmitJob.init( slug: slug, - buildName: buildName, + jobName: jobName, checkRunId: guardCheckRunId, creationTime: creationTime, attemptNumber: (latestCheck?.attemptNumber ?? 0) + 1, @@ -162,13 +162,13 @@ final class UnifiedCheckRun { log.info( '$logCrumb: results = ${response.writeResults?.map((e) => e.toJson())}', ); - return FailedChecksForRerun( + return FailedJobsForRerun( checkRunGuard: latestGuard.checkRun, - checkRetries: checkRetries, + jobRetries: checkRetries, stage: latestGuard.stage, ); } catch (e) { - log.info('$logCrumb: failed to update presubmit check', e); + log.info('$logCrumb: failed to update presubmit job', e); rethrow; } } @@ -176,17 +176,17 @@ final class UnifiedCheckRun { return null; } - /// Re-initializes a specific failed check for the specified [guardCheckRunId] and [buildName]. - static Future reInitializeFailedJob({ + /// Re-initializes a specific failed check for the specified [guardCheckRunId] and [jobName]. + static Future reInitializeFailedJob({ required FirestoreService firestoreService, required RepositorySlug slug, - required int pullRequestId, + required int prNum, required int guardCheckRunId, - required String buildName, + required String jobName, @visibleForTesting DateTime Function() utcNow = DateTime.timestamp, }) async { final logCrumb = - 'reInitializeFailedJob(${slug.fullName}, $pullRequestId, $guardCheckRunId, $buildName)'; + 'reInitializeFailedJob(${slug.fullName}, $prNum, $guardCheckRunId, $jobName)'; log.info('$logCrumb Re-Running failed job.'); final transaction = await firestoreService.beginTransaction(); @@ -194,45 +194,45 @@ final class UnifiedCheckRun { final guard = await getLatestPresubmitGuardForCheckRun( firestoreService: firestoreService, slug: slug, - pullRequestId: pullRequestId, + prNum: prNum, checkRunId: guardCheckRunId, transaction: transaction, ); - if (guard == null || !guard.builds.containsKey(buildName)) { + if (guard == null || !guard.jobs.containsKey(jobName)) { await firestoreService.rollback(transaction); return null; } final creationTime = utcNow().microsecondsSinceEpoch; - final builds = guard.builds; - final currentStatus = builds[buildName]!; + final jobs = guard.jobs; + final currentStatus = jobs[jobName]!; - // If build is failed we increment remain builds and decrement failed. - // If build succeeded re-run is not possible but if some how they manage to - // request re-run we have to only increment remaining builds. - // If build is still in progress re-run is not possible but if some how they + // If job is failed we increment remain jobs and decrement failed. + // If job succeeded re-run is not possible but if some how they manage to + // request re-run we have to only increment remaining jobs. + // If job is still in progress re-run is not possible but if some how they // manage to request re-run we should not touch any counters. if (currentStatus.isComplete) { - guard.remainingBuilds += 1; - if (currentStatus.isFailure && guard.failedBuilds > 0) { - guard.failedBuilds -= 1; + guard.remainingJobs += 1; + if (currentStatus.isFailure && guard.failedJobs > 0) { + guard.failedJobs -= 1; } } - builds[buildName] = TaskStatus.waitingForBackfill; - guard.builds = builds; + jobs[jobName] = TaskStatus.waitingForBackfill; + guard.jobs = jobs; - final latestCheck = await getLatestPresubmitCheck( + final latestCheck = await getLatestPresubmitJob( firestoreService: firestoreService, checkRunId: guardCheckRunId, - buildName: buildName, + jobName: jobName, transaction: transaction, ); - final check = PresubmitCheck.init( + final check = PresubmitJob.init( slug: slug, - buildName: buildName, + jobName: jobName, checkRunId: guardCheckRunId, creationTime: creationTime, attemptNumber: (latestCheck?.attemptNumber ?? 0) + 1, @@ -246,65 +246,65 @@ final class UnifiedCheckRun { log.info( '$logCrumb: results = ${response.writeResults?.map((e) => e.toJson())}', ); - return FailedChecksForRerun( + return FailedJobsForRerun( checkRunGuard: guard.checkRun, - checkRetries: {buildName: (latestCheck?.attemptNumber ?? 0) + 1}, + jobRetries: {jobName: (latestCheck?.attemptNumber ?? 0) + 1}, stage: guard.stage, ); } catch (e) { - log.info('$logCrumb: failed to update presubmit check', e); + log.info('$logCrumb: failed to update presubmit job', e); rethrow; } } - /// Returns _all_ checks running against the specified github [checkRunId]. - static Future> queryAllPresubmitChecksForGuard({ + /// Returns _all_ jobs running against the specified github [checkRunId]. + static Future> queryAllPresubmitJobsForGuard({ required FirestoreService firestoreService, required int checkRunId, TaskStatus? status, - String? buildName, + String? jobName, Transaction? transaction, }) async { - return await _queryPresubmitChecks( + return await _queryPresubmitJobs( firestoreService: firestoreService, checkRunId: checkRunId, - buildName: buildName, + jobName: jobName, status: status, transaction: transaction, ); } /// Returns check for the specified github [checkRunId] and - /// [buildName] and [attemptNumber]. - static Future queryPresubmitCheck({ + /// [jobName] and [attemptNumber]. + static Future queryPresubmitJob({ required FirestoreService firestoreService, required int checkRunId, - required String buildName, + required String jobName, required int attemptNumber, Transaction? transaction, }) async { - return (await _queryPresubmitChecks( + return (await _queryPresubmitJobs( firestoreService: firestoreService, checkRunId: checkRunId, - buildName: buildName, + jobName: jobName, status: null, attemptNumber: attemptNumber, transaction: transaction, )).firstOrNull; } - /// Returns the latest [PresubmitCheck] for the specified github [checkRunId] and - /// [buildName]. - static Future getLatestPresubmitCheck({ + /// Returns the latest [PresubmitJob] for the specified github [checkRunId] and + /// [jobName]. + static Future getLatestPresubmitJob({ required FirestoreService firestoreService, required int checkRunId, - required String buildName, + required String jobName, Transaction? transaction, }) async { - return (await _queryPresubmitChecks( + return (await _queryPresubmitJobs( firestoreService: firestoreService, checkRunId: checkRunId, - buildName: buildName, + jobName: jobName, status: null, transaction: transaction, limit: 1, @@ -315,7 +315,7 @@ final class UnifiedCheckRun { static Future getLatestPresubmitGuardForCheckRun({ required FirestoreService firestoreService, required RepositorySlug slug, - required int pullRequestId, + required int prNum, required int checkRunId, Transaction? transaction, }) async { @@ -327,27 +327,27 @@ final class UnifiedCheckRun { )).firstOrNull; } - /// Returns the latest [PresubmitCheck] for each build in the specified github [checkRunId]. - static Future> getLatestFailedChecks({ + /// Returns the latest failed [PresubmitJob] for the specified github [checkRunId]. + static Future> getLatestFailedJobs({ required FirestoreService firestoreService, required int checkRunId, }) async { final filterMap = { - PresubmitCheck.fieldCheckRunId: checkRunId, + PresubmitJob.fieldCheckRunId: checkRunId, }; final docs = await firestoreService.query( - PresubmitCheck.collectionId, + PresubmitJob.collectionId, filterMap, ); - final allChecks = docs.map(PresubmitCheck.fromDocument).toList(); + final allChecks = docs.map(PresubmitJob.fromDocument).toList(); - // Group by buildName and find the latest attempt. - final latestChecks = {}; + // Group by jobName and find the latest attempt. + final latestChecks = {}; for (final check in allChecks) { - final currentLatest = latestChecks[check.buildName]; + final currentLatest = latestChecks[check.jobName]; if (currentLatest == null || check.attemptNumber > currentLatest.attemptNumber) { - latestChecks[check.buildName] = check; + latestChecks[check.jobName] = check; } } @@ -357,7 +357,7 @@ final class UnifiedCheckRun { } /// Returns the latest [PresubmitGuard] for the specified github [checkRunId]. - static Future getLatestPresubmitGuardByCheckRunId({ + static Future getLatestPresubmitGuardForCheckRunId({ required FirestoreService firestoreService, required int checkRunId, Transaction? transaction, @@ -370,17 +370,17 @@ final class UnifiedCheckRun { )).firstOrNull; } - /// Returns the latest [PresubmitGuard] for the specified [slug] and [pullRequestNum]. - static Future getLatestPresubmitGuardByPullRequestNum({ + /// Returns the latest [PresubmitGuard] for the specified [slug] and [prNum]. + static Future getLatestPresubmitGuardForPrNum({ required FirestoreService firestoreService, required RepositorySlug slug, - required int pullRequestNum, + required int prNum, Transaction? transaction, }) async { return (await _queryPresubmitGuards( firestoreService: firestoreService, slug: slug, - pullRequestId: pullRequestNum, + prNum: prNum, transaction: transaction, limit: 1, )).firstOrNull; @@ -399,16 +399,16 @@ final class UnifiedCheckRun { ); } - /// Queries for [PresubmitGuard] records by [slug] and [pullRequestId]. + /// Queries for [PresubmitGuard] records by [slug] and [prNum]. static Future> getPresubmitGuardsForPullRequest({ required FirestoreService firestoreService, required RepositorySlug slug, - required int pullRequestId, + required int prNum, }) async { return await _queryPresubmitGuards( firestoreService: firestoreService, slug: slug, - pullRequestId: pullRequestId, + prNum: prNum, ); } @@ -418,7 +418,7 @@ final class UnifiedCheckRun { int? checkRunId, String? commitSha, RepositorySlug? slug, - int? pullRequestId, + int? prNum, CiStage? stage, int? creationTime, String? author, @@ -429,12 +429,12 @@ final class UnifiedCheckRun { }) async { final filterMap = { '${PresubmitGuard.fieldSlug} =': ?slug?.fullName, - '${PresubmitGuard.fieldPullRequestId} =': ?pullRequestId, + '${PresubmitGuard.fieldPrNum} =': ?prNum, '${PresubmitGuard.fieldCheckRunId} =': ?checkRunId, '${PresubmitGuard.fieldStage} =': ?stage?.name, '${PresubmitGuard.fieldCreationTime} =': ?creationTime, '${PresubmitGuard.fieldAuthor} =': ?author, - '${PresubmitGuard.fieldCommitSha} =': ?commitSha, + '${PresubmitGuard.fieldHeadSha} =': ?commitSha, }; final documents = await firestoreService.query( PresubmitGuard.collectionId, @@ -446,56 +446,56 @@ final class UnifiedCheckRun { return [...documents.map(PresubmitGuard.fromDocument)]; } - /// Returns detailed information for a specific presubmit check identified by - /// [checkRunId] and [buildName]. + /// Returns detailed information for a specific presubmit job identified by + /// [checkRunId] and [jobName]. /// /// The results are ordered by attempt number descending. - static Future> getPresubmitCheckDetails({ + static Future> getPresubmitJobDetails({ required FirestoreService firestoreService, required int checkRunId, - required String buildName, + required String jobName, RepositorySlug? slug, }) async { - return await _queryPresubmitChecks( + return await _queryPresubmitJobs( firestoreService: firestoreService, checkRunId: checkRunId, - buildName: buildName, + jobName: jobName, slug: slug, ); } - static Future> _queryPresubmitChecks({ + static Future> _queryPresubmitJobs({ required FirestoreService firestoreService, required int checkRunId, RepositorySlug? slug, - String? buildName, + String? jobName, TaskStatus? status, Transaction? transaction, int? attemptNumber, // By default order by attempt number descending. Map? orderMap = const { - PresubmitCheck.fieldAttemptNumber: kQueryOrderDescending, + PresubmitJob.fieldAttemptNumber: kQueryOrderDescending, }, int? limit, }) async { final filterMap = { - '${PresubmitCheck.fieldSlug} =': ?slug?.fullName, - '${PresubmitCheck.fieldCheckRunId} =': checkRunId, - '${PresubmitCheck.fieldBuildName} =': ?buildName, - '${PresubmitCheck.fieldStatus} =': ?status?.value, - '${PresubmitCheck.fieldAttemptNumber} =': ?attemptNumber, + '${PresubmitJob.fieldSlug} =': ?slug?.fullName, + '${PresubmitJob.fieldCheckRunId} =': checkRunId, + '${PresubmitJob.fieldJobName} =': ?jobName, + '${PresubmitJob.fieldStatus} =': ?status?.value, + '${PresubmitJob.fieldAttemptNumber} =': ?attemptNumber, }; final documents = await firestoreService.query( - PresubmitCheck.collectionId, + PresubmitJob.collectionId, filterMap, limit: limit, orderMap: orderMap, transaction: transaction, ); - return [...documents.map(PresubmitCheck.fromDocument)]; + return [...documents.map(PresubmitJob.fromDocument)]; } - /// Mark a [buildName] for a given [stage] with [conclusion]. + /// Mark a [jobName] for a given [stage] with [conclusion]. /// /// Returns a [PresubmitGuardConclusion] record or throws. If the check_run was /// both valid and recorded successfully, the record's `remaining` value @@ -504,12 +504,12 @@ final class UnifiedCheckRun { static Future markConclusion({ required FirestoreService firestoreService, required PresubmitGuardId guardId, - required PresubmitCheckState state, + required PresubmitJobState state, }) async { final changeCrumb = - '${guardId.slug.owner}_${guardId.slug.name}_${guardId.pullRequestId}_${guardId.checkRunId}'; + '${guardId.slug.owner}_${guardId.slug.name}_${guardId.prNum}_${guardId.checkRunId}'; final logCrumb = - 'markConclusion(${changeCrumb}_${guardId.stage}, ${state.buildName}, ${state.status}, ${state.attemptNumber})'; + 'markConclusion(${changeCrumb}_${guardId.stage}, ${state.jobName}, ${state.status}, ${state.attemptNumber})'; // Marking needs to happen while in a transaction to ensure `remaining` is // updated correctly. For that to happen correctly; we need to perform a @@ -522,13 +522,13 @@ final class UnifiedCheckRun { var valid = false; late final PresubmitGuard presubmitGuard; - late final PresubmitCheck presubmitCheck; + late final PresubmitJob presubmitJob; // transaction block try { // First: read the fields we want to change. final presubmitGuardDocumentName = PresubmitGuard.documentNameFor( slug: guardId.slug, - pullRequestId: guardId.pullRequestId, + prNum: guardId.prNum, checkRunId: guardId.checkRunId, stage: guardId.stage, ); @@ -539,68 +539,68 @@ final class UnifiedCheckRun { presubmitGuard = PresubmitGuard.fromDocument(presubmitGuardDocument); // Check if the build is present in the guard before trying to load it. - if (presubmitGuard.builds[state.buildName] == null) { + if (presubmitGuard.jobs[state.jobName] == null) { log.info( - '$logCrumb: ${state.buildName} with attemptNumber ${state.attemptNumber} not present for $transaction / ${presubmitGuardDocument.fields}', + '$logCrumb: ${state.jobName} with attemptNumber ${state.attemptNumber} not present for $transaction / ${presubmitGuardDocument.fields}', ); await firestoreService.rollback(transaction); return PresubmitGuardConclusion( result: PresubmitGuardConclusionResult.missing, - remaining: presubmitGuard.remainingBuilds, + remaining: presubmitGuard.remainingJobs, checkRunGuard: presubmitGuard.checkRunJson, - failed: presubmitGuard.failedBuilds, + failed: presubmitGuard.failedJobs, summary: - 'Check run "${state.buildName}" not present in ${guardId.stage} CI stage', + 'Check run "${state.jobName}" not present in ${guardId.stage} CI stage', details: 'Change $changeCrumb', ); } - final checkDocName = PresubmitCheck.documentNameFor( + final checkDocName = PresubmitJob.documentNameFor( slug: guardId.slug, checkRunId: guardId.checkRunId, - buildName: state.buildName, + jobName: state.jobName, attemptNumber: state.attemptNumber, ); - final presubmitCheckDocument = await firestoreService.getDocument( + final presubmitJobDocument = await firestoreService.getDocument( checkDocName, transaction: transaction, ); - presubmitCheck = PresubmitCheck.fromDocument(presubmitCheckDocument); + presubmitJob = PresubmitJob.fromDocument(presubmitJobDocument); - remaining = presubmitGuard.remainingBuilds; - failed = presubmitGuard.failedBuilds; - final builds = presubmitGuard.builds; - var status = builds[state.buildName]!; + remaining = presubmitGuard.remainingJobs; + failed = presubmitGuard.failedJobs; + final jobs = presubmitGuard.jobs; + var status = jobs[state.jobName]!; - // If build is waiting for backfill, that means its initiated by github + // If job is waiting for backfill, that means its initiated by github // or re-run. So no processing needed, we should only update appropriate // checks with that [TaskStatus] if (state.status == TaskStatus.waitingForBackfill) { status = state.status; valid = true; - // If build is in progress, we should update apropriate checks with start - // time and their status to that [TaskStatus] only if the build is not + // If job is in progress, we should update apropriate checks with start + // time and their status to that [TaskStatus] only if the job is not // completed. } else if (state.status == TaskStatus.inProgress) { - presubmitCheck.startTime = state.startTime!; - // If the build is not completed, update the status. + presubmitJob.startTime = state.startTime!; + // If the job is not completed, update the status. if (!status.isComplete) { status = state.status; } valid = true; } else { - // If build already compleated remaining and failed should not updated. + // If job already compleated remaining and failed should not updated. if (!status.isComplete) { - // "remaining" should go down if build is succeeded or failed. + // "remaining" should go down if job is succeeded or failed. // "failed_count" can go up or down depending on: - // attemptNumber > 1 && buildSuccessed: down (-1) - // attemptNumber = 1 && buildFailed: up (+1) + // attemptNumber > 1 && jobSuccessed: down (-1) + // attemptNumber = 1 && jobFailed: up (+1) // So if the test existed and either remaining or failed_count is changed; // the response is valid. if (state.status.isComplete) { // Guard against going negative and log enough info so we can debug. if (remaining == 0) { - throw '$logCrumb: field "${PresubmitGuard.fieldRemainingBuilds}" is already zero for $transaction / ${presubmitGuardDocument.fields}'; + throw '$logCrumb: field "${PresubmitGuard.fieldRemainingJobs}" is already zero for $transaction / ${presubmitGuardDocument.fields}'; } remaining -= 1; valid = true; @@ -616,24 +616,24 @@ final class UnifiedCheckRun { log.info( '$logCrumb: setting remaining to $remaining, failed to $failed', ); - presubmitGuard.remainingBuilds = remaining; - presubmitGuard.failedBuilds = failed; - presubmitCheck.endTime = state.endTime!; - presubmitCheck.summary = state.summary; - presubmitCheck.buildNumber = state.buildNumber; + presubmitGuard.remainingJobs = remaining; + presubmitGuard.failedJobs = failed; + presubmitJob.endTime = state.endTime!; + presubmitJob.summary = state.summary; + presubmitJob.buildNumber = state.buildNumber; } else { status = state.status; valid = true; } } - builds[state.buildName] = status; - presubmitGuard.builds = builds; - presubmitCheck.status = status; + jobs[state.jobName] = status; + presubmitGuard.jobs = jobs; + presubmitJob.status = status; } on DetailedApiRequestError catch (e, stack) { if (e.status == 404) { // An attempt to read a document not in firestore should not be retried. log.info( - '$logCrumb: ${PresubmitCheck.collectionId} document not found for $transaction', + '$logCrumb: ${PresubmitJob.collectionId} document not found for $transaction', ); await firestoreService.rollback(transaction); return PresubmitGuardConclusion( @@ -644,7 +644,7 @@ final class UnifiedCheckRun { summary: 'Internal server error', details: ''' -${PresubmitCheck.collectionId} document not found for stage "${guardId.stage}" for $changeCrumb. Got 404 from Firestore. +${PresubmitJob.collectionId} document not found for stage "${guardId.stage}" for $changeCrumb. Got 404 from Firestore. Error: ${e.toString()} $stack ''', @@ -664,7 +664,7 @@ $stack try { final response = await firestoreService.commit( transaction, - documentsToWrites([presubmitGuard, presubmitCheck], exists: true), + documentsToWrites([presubmitGuard, presubmitJob], exists: true), ); log.info( '$logCrumb: results = ${response.writeResults?.map((e) => e.toJson())}', @@ -678,18 +678,18 @@ $stack failed: failed, summary: valid ? 'Successfully updated presubmit guard status' - : 'Not a valid state transition for ${state.buildName}', + : 'Not a valid state transition for ${state.jobName}', details: valid ? ''' For CI stage ${guardId.stage}: Pending: $remaining Failed: $failed ''' - : 'Attempted to set the state of check run ${state.buildName} ' + : 'Attempted to set the state of job ${state.jobName} ' 'to "${state.status.name}".', ); } catch (e) { - log.info('$logCrumb: failed to update presubmit check', e); + log.info('$logCrumb: failed to update presubmit job', e); rethrow; } } diff --git a/app_dart/lib/src/service/scheduler.dart b/app_dart/lib/src/service/scheduler.dart index 7facc59dd..afeb1f809 100644 --- a/app_dart/lib/src/service/scheduler.dart +++ b/app_dart/lib/src/service/scheduler.dart @@ -20,9 +20,9 @@ import '../model/ci_yaml/ci_yaml.dart'; import '../model/ci_yaml/target.dart'; import '../model/commit_ref.dart'; import '../model/common/checks_extension.dart'; -import '../model/common/presubmit_check_state.dart'; import '../model/common/presubmit_completed_check.dart'; import '../model/common/presubmit_guard_conclusion.dart'; +import '../model/common/presubmit_job_state.dart'; import '../model/firestore/base.dart'; import '../model/firestore/ci_staging.dart'; import '../model/firestore/commit.dart' as fs; @@ -1000,7 +1000,7 @@ detailsUrl: $detailsUrl /// /// Handles both fusion engine build and test stages, and both pull requests /// and merge groups. - Future processCheckRunCompleted(PresubmitCompletedCheck check) async { + Future processCheckRunCompleted(PresubmitCompletedJob check) async { if (kCheckRunsToIgnore.contains(check.name)) { return true; } @@ -1460,10 +1460,10 @@ $stacktrace Future _markUnifiedCheckRunConclusion({ required PresubmitGuardId guardId, - required PresubmitCheckState state, + required PresubmitJobState state, }) async { final logCrumb = - 'checkCompleted(${state.buildName}, ${state.buildNumber}, ${guardId.stage}, ${guardId.slug}, ${state.status})'; + 'checkCompleted(${state.jobName}, ${state.buildNumber}, ${guardId.stage}, ${guardId.slug}, ${state.status})'; log.info('$logCrumb: ${guardId.documentId}'); // We're doing a transactional update, which could fail if multiple tasks @@ -1505,7 +1505,7 @@ $stacktrace case 'completed': if (!_config.flags.closeMqGuardAfterPresubmit) { await processCheckRunCompleted( - PresubmitCompletedCheck.fromCheckRun( + PresubmitCompletedJob.fromCheckRun( checkRunEvent.checkRun!, checkRunEvent.repository!.slug(), ), @@ -1740,14 +1740,14 @@ $stacktrace checkRunEvent.checkRun!.checkSuite!.id!, ); - final failedChecks = await UnifiedCheckRun.reInitializeFailedChecks( + final failedChecks = await UnifiedCheckRun.reInitializeFailedJobs( firestoreService: _firestore, slug: slug, - pullRequestId: pullRequest!.number!, + prNum: pullRequest!.number!, guardCheckRunId: checkRunEvent.checkRun!.id!, ); - if (failedChecks == null || failedChecks.checkRetries.isEmpty) { + if (failedChecks == null || failedChecks.jobRetries.isEmpty) { log.error('$logCrumb: No failed targets found'); return const ProcessCheckRunResult.missingEntity( 'No failed targets found', @@ -1761,12 +1761,12 @@ $stacktrace final checkRetries = {}; for (final target in targets) { - if (failedChecks.checkRetries.containsKey(target.name)) { - checkRetries[target] = failedChecks.checkRetries[target.name]!; + if (failedChecks.jobRetries.containsKey(target.name)) { + checkRetries[target] = failedChecks.jobRetries[target.name]!; } } - if (checkRetries.length != failedChecks.checkRetries.length) { + if (checkRetries.length != failedChecks.jobRetries.length) { log.error( '$logCrumb: Failed to find all failed targets in presubmit targets', ); diff --git a/app_dart/test/model/common/presubmit_check_state_test.dart b/app_dart/test/model/common/presubmit_check_state_test.dart index 6d5a4f8ec..9285c0725 100644 --- a/app_dart/test/model/common/presubmit_check_state_test.dart +++ b/app_dart/test/model/common/presubmit_check_state_test.dart @@ -5,14 +5,14 @@ import 'package:buildbucket/buildbucket_pb.dart' as bbv2; import 'package:cocoon_common/task_status.dart'; import 'package:cocoon_server_test/test_logging.dart'; -import 'package:cocoon_service/src/model/common/presubmit_check_state.dart'; +import 'package:cocoon_service/src/model/common/presubmit_job_state.dart'; import 'package:fixnum/fixnum.dart'; import 'package:test/test.dart'; void main() { useTestLoggerPerTest(); - group('PresubmitCheckState', () { - test('BuildToPresubmitCheckState extension maps build number', () { + group('PresubmitJobState', () { + test('BuildToPresubmitJobState extension maps build number', () { final build = bbv2.Build( builder: bbv2.BuilderID(builder: 'linux_test'), status: bbv2.Status.SUCCESS, @@ -23,8 +23,8 @@ void main() { tags: [bbv2.StringPair(key: 'github_checkrun', value: '123')], ); - final state = build.toPresubmitCheckState(); - expect(state.buildName, 'linux_test'); + final state = build.toPresubmitJobState(); + expect(state.jobName, 'linux_test'); expect(state.status, TaskStatus.succeeded); expect(state.buildNumber, 12345); }); diff --git a/app_dart/test/model/common/presubmit_completed_check_test.dart b/app_dart/test/model/common/presubmit_completed_check_test.dart index 448c4fd3c..2f74c1d9d 100644 --- a/app_dart/test/model/common/presubmit_completed_check_test.dart +++ b/app_dart/test/model/common/presubmit_completed_check_test.dart @@ -29,7 +29,7 @@ void main() { conclusion: 'success', ); - final check = PresubmitCompletedCheck.fromCheckRun(checkRun, slug); + final check = PresubmitCompletedJob.fromCheckRun(checkRun, slug); expect(check.name, 'test_check'); expect(check.sha, sha); @@ -61,7 +61,7 @@ void main() { checkSuiteId: 456, ); - final check = PresubmitCompletedCheck.fromBuild(build, userData); + final check = PresubmitCompletedJob.fromBuild(build, userData); expect(check.name, 'test_builder'); expect(check.sha, sha); @@ -95,7 +95,7 @@ void main() { checkSuiteId: 456, ); - final check = PresubmitCompletedCheck.fromBuild(build, userData); + final check = PresubmitCompletedJob.fromBuild(build, userData); expect(check.name, 'test_builder'); expect(check.sha, sha); diff --git a/app_dart/test/model/firestore/presubmit_check_test.dart b/app_dart/test/model/firestore/presubmit_check_test.dart index 5c5b8ed76..94317643c 100644 --- a/app_dart/test/model/firestore/presubmit_check_test.dart +++ b/app_dart/test/model/firestore/presubmit_check_test.dart @@ -6,7 +6,7 @@ import 'package:buildbucket/buildbucket_pb.dart' as bbv2; import 'package:cocoon_common/task_status.dart'; import 'package:cocoon_integration_test/testing.dart'; import 'package:cocoon_server_test/test_logging.dart'; -import 'package:cocoon_service/src/model/firestore/presubmit_check.dart'; +import 'package:cocoon_service/src/model/firestore/presubmit_job.dart'; import 'package:fixnum/fixnum.dart'; import 'package:github/github.dart'; import 'package:googleapis/firestore/v1.dart'; @@ -15,15 +15,15 @@ import 'package:test/test.dart'; void main() { useTestLoggerPerTest(); - group('PresubmitCheckId', () { + group('PresubmitJobId', () { final slug = RepositorySlug('flutter', 'flutter'); test('validates checkRunId', () { expect( - () => PresubmitCheckId( + () => PresubmitJobId( slug: slug, checkRunId: 0, - buildName: 'linux', + jobName: 'linux', attemptNumber: 1, ), throwsA(isA()), @@ -32,10 +32,10 @@ void main() { test('validates attemptNumber', () { expect( - () => PresubmitCheckId( + () => PresubmitJobId( slug: slug, checkRunId: 1, - buildName: 'linux', + jobName: 'linux', attemptNumber: 0, ), throwsA(isA()), @@ -43,41 +43,41 @@ void main() { }); test('generates correct documentId', () { - final id = PresubmitCheckId( + final id = PresubmitJobId( slug: slug, checkRunId: 123, - buildName: 'linux_test', + jobName: 'linux_test', attemptNumber: 2, ); expect(id.documentId, 'flutter_flutter_123_linux_test_2'); }); test('parses valid documentName', () { - final id = PresubmitCheckId.parse('flutter_flutter_123_linux_test_2'); + final id = PresubmitJobId.parse('flutter_flutter_123_linux_test_2'); expect(id.slug, slug); expect(id.checkRunId, 123); - expect(id.buildName, 'linux_test'); + expect(id.jobName, 'linux_test'); expect(id.attemptNumber, 2); }); test('tryParse returns null for invalid format', () { - expect(PresubmitCheckId.tryParse('invalid'), isNull); - expect(PresubmitCheckId.tryParse('flutter_flutter_123_linux'), isNull); + expect(PresubmitJobId.tryParse('invalid'), isNull); + expect(PresubmitJobId.tryParse('flutter_flutter_123_linux'), isNull); }); test('generates correct documentId with different slug', () { final cocoonSlug = RepositorySlug('flutter', 'cocoon'); - final id = PresubmitCheckId( + final id = PresubmitJobId( slug: cocoonSlug, checkRunId: 123, - buildName: 'linux_test', + jobName: 'linux_test', attemptNumber: 2, ); expect(id.documentId, 'flutter_cocoon_123_linux_test_2'); }); }); - group('PresubmitCheck', () { + group('PresubmitJob', () { late FakeFirestoreService firestoreService; final slug = RepositorySlug('flutter', 'flutter'); @@ -86,15 +86,15 @@ void main() { }); test('init creates correct initial state', () { - final check = PresubmitCheck.init( + final check = PresubmitJob.init( slug: slug, - buildName: 'linux', + jobName: 'linux', checkRunId: 123, creationTime: 1000, ); expect(check.slug, slug); - expect(check.buildName, 'linux'); + expect(check.jobName, 'linux'); expect(check.checkRunId, 123); expect(check.creationTime, 1000); expect(check.attemptNumber, 1); @@ -106,10 +106,10 @@ void main() { }); test('constructor stores slug in fields', () { - final check = PresubmitCheck( + final check = PresubmitJob( slug: slug, checkRunId: 123, - buildName: 'linux', + jobName: 'linux', status: TaskStatus.succeeded, attemptNumber: 1, creationTime: 1000, @@ -117,16 +117,16 @@ void main() { expect(check.slug, slug); expect( - check.fields[PresubmitCheck.fieldSlug]!.stringValue, + check.fields[PresubmitJob.fieldSlug]!.stringValue, 'flutter/flutter', ); }); test('fromFirestore loads document correctly', () async { - final check = PresubmitCheck( + final check = PresubmitJob( slug: slug, checkRunId: 123, - buildName: 'linux', + jobName: 'linux', status: TaskStatus.succeeded, attemptNumber: 1, creationTime: 1000, @@ -137,33 +137,33 @@ void main() { ); // Use the helper to get the correct document name - final docName = PresubmitCheck.documentNameFor( + final docName = PresubmitJob.documentNameFor( slug: slug, checkRunId: 123, - buildName: 'linux', + jobName: 'linux', attemptNumber: 1, ); // Manually ensuring the name is set for the fake service, usually done by `putDocument` - // but we should verify the `PresubmitCheck` object has it right via the factory or init. - // Actually `PresubmitCheck` constructor sets name. + // but we should verify the `PresubmitJob` object has it right via the factory or init. + // Actually `PresubmitJob` constructor sets name. firestoreService.putDocument( Document(name: docName, fields: check.fields), ); - final loadedCheck = await PresubmitCheck.fromFirestore( + final loadedCheck = await PresubmitJob.fromFirestore( firestoreService, - PresubmitCheckId( + PresubmitJobId( slug: slug, checkRunId: 123, - buildName: 'linux', + jobName: 'linux', attemptNumber: 1, ), ); expect(loadedCheck.slug, slug); expect(loadedCheck.checkRunId, 123); - expect(loadedCheck.buildName, 'linux'); + expect(loadedCheck.jobName, 'linux'); expect(loadedCheck.status, TaskStatus.succeeded); expect(loadedCheck.attemptNumber, 1); expect(loadedCheck.creationTime, 1000); @@ -174,9 +174,9 @@ void main() { }); test('updateFromBuild updates fields', () { - final check = PresubmitCheck.init( + final check = PresubmitJob.init( slug: slug, - buildName: 'linux', + jobName: 'linux', checkRunId: 123, creationTime: 1000, ); @@ -199,9 +199,9 @@ void main() { }); test('updateFromBuild does not update status if already complete', () { - final check = PresubmitCheck.init( + final check = PresubmitJob.init( slug: slug, - buildName: 'linux', + jobName: 'linux', checkRunId: 123, creationTime: 1000, ); @@ -219,9 +219,9 @@ void main() { }); test('buildNumber setter updates fields', () { - final check = PresubmitCheck.init( + final check = PresubmitJob.init( slug: slug, - buildName: 'linux', + jobName: 'linux', checkRunId: 123, creationTime: 1000, ); diff --git a/app_dart/test/model/firestore/presubmit_guard_test.dart b/app_dart/test/model/firestore/presubmit_guard_test.dart index 4dc685fd2..d6ac0b52d 100644 --- a/app_dart/test/model/firestore/presubmit_guard_test.dart +++ b/app_dart/test/model/firestore/presubmit_guard_test.dart @@ -19,7 +19,7 @@ void main() { test('generates correct documentId', () { final id = PresubmitGuardId( slug: RepositorySlug('flutter', 'flutter'), - pullRequestId: 123, + prNum: 123, checkRunId: 456, stage: CiStage.fusionEngineBuild, ); @@ -40,30 +40,27 @@ void main() { test('init creates correct initial state', () { final guard = PresubmitGuard.init( slug: slug, - pullRequestId: 123, + prNum: 123, checkRun: checkRun, stage: CiStage.fusionEngineBuild, - commitSha: 'abc', + headSha: 'abc', creationTime: 1000, author: 'author', - buildCount: 2, + jobCount: 2, ); expect(guard.slug, slug); - expect(guard.pullRequestId, 123); + expect(guard.prNum, 123); expect(guard.checkRunId, 456); expect(guard.stage, CiStage.fusionEngineBuild); expect(guard.commitSha, 'abc'); expect(guard.creationTime, 1000); expect(guard.author, 'author'); - expect(guard.remainingBuilds, 2); - expect(guard.failedBuilds, 0); + expect(guard.remainingJobs, 2); + expect(guard.failedJobs, 0); expect(guard.checkRun.id, 456); expect(guard.fields[PresubmitGuard.fieldCheckRunId]!.integerValue, '456'); - expect( - guard.fields[PresubmitGuard.fieldPullRequestId]!.integerValue, - '123', - ); + expect(guard.fields[PresubmitGuard.fieldPrNum]!.integerValue, '123'); expect( guard.fields[PresubmitGuard.fieldSlug]!.stringValue, 'flutter/flutter', @@ -77,65 +74,65 @@ void main() { test('fromDocument loads correct state', () { final guard = PresubmitGuard.init( slug: slug, - pullRequestId: 123, + prNum: 123, checkRun: checkRun, stage: CiStage.fusionEngineBuild, - commitSha: 'abc', + headSha: 'abc', creationTime: 1000, author: 'author', - buildCount: 2, + jobCount: 2, ); - guard.builds = {'linux': TaskStatus.succeeded}; + guard.jobs = {'linux': TaskStatus.succeeded}; final doc = Document(name: guard.name, fields: guard.fields); final loadedGuard = PresubmitGuard.fromDocument(doc); expect(loadedGuard.slug, slug); - expect(loadedGuard.pullRequestId, 123); + expect(loadedGuard.prNum, 123); expect(loadedGuard.checkRunId, 456); expect(loadedGuard.stage, CiStage.fusionEngineBuild); - expect(loadedGuard.builds, {'linux': TaskStatus.succeeded}); - expect(loadedGuard.remainingBuilds, 2); + expect(loadedGuard.jobs, {'linux': TaskStatus.succeeded}); + expect(loadedGuard.remainingJobs, 2); }); test('updates fields correctly', () { final guard = PresubmitGuard.init( slug: slug, - pullRequestId: 123, + prNum: 123, checkRun: checkRun, stage: CiStage.fusionEngineBuild, - commitSha: 'abc', + headSha: 'abc', creationTime: 1000, author: 'author', - buildCount: 2, + jobCount: 2, ); - guard.remainingBuilds = 1; - guard.failedBuilds = 1; - guard.builds = {'linux': TaskStatus.failed}; + guard.remainingJobs = 1; + guard.failedJobs = 1; + guard.jobs = {'linux': TaskStatus.failed}; - expect(guard.remainingBuilds, 1); - expect(guard.failedBuilds, 1); - expect(guard.builds, {'linux': TaskStatus.failed}); + expect(guard.remainingJobs, 1); + expect(guard.failedJobs, 1); + expect(guard.jobs, {'linux': TaskStatus.failed}); }); test('parses properties from document name', () { // flutter_flutter_123_456_fusionEngineBuild final guard = PresubmitGuard( checkRun: checkRun, - commitSha: 'abc', + headSha: 'abc', slug: slug, - pullRequestId: 123, + prNum: 123, stage: CiStage.fusionEngineBuild, creationTime: 1000, author: 'author', - remainingBuilds: 0, - failedBuilds: 0, + remainingJobs: 0, + failedJobs: 0, ); expect(guard.slug, slug); - expect(guard.pullRequestId, 123); + expect(guard.prNum, 123); expect(guard.checkRunId, 456); expect(guard.stage, CiStage.fusionEngineBuild); }); diff --git a/app_dart/test/request_handlers/get_presubmit_checks_test.dart b/app_dart/test/request_handlers/get_presubmit_checks_test.dart index bdb525299..179c13087 100644 --- a/app_dart/test/request_handlers/get_presubmit_checks_test.dart +++ b/app_dart/test/request_handlers/get_presubmit_checks_test.dart @@ -9,29 +9,29 @@ import 'package:cocoon_common/task_status.dart'; import 'package:cocoon_integration_test/testing.dart'; import 'package:cocoon_server_test/test_logging.dart'; import 'package:cocoon_service/cocoon_service.dart'; -import 'package:cocoon_service/src/model/firestore/presubmit_check.dart' as fs; -import 'package:cocoon_service/src/request_handlers/get_presubmit_checks.dart'; +import 'package:cocoon_service/src/model/firestore/presubmit_job.dart' as fs; +import 'package:cocoon_service/src/request_handlers/get_presubmit_jobs.dart'; import 'package:github/github.dart'; import 'package:test/test.dart'; import '../src/request_handling/request_handler_tester.dart'; void main() { - group('GetPresubmitChecks', () { + group('GetPresubmitJobs', () { useTestLoggerPerTest(); late FakeConfig config; late RequestHandlerTester tester; - late GetPresubmitChecks handler; + late GetPresubmitJobs handler; late FakeFirestoreService firestoreService; setUp(() { config = FakeConfig(); tester = RequestHandlerTester(); firestoreService = FakeFirestoreService(); - handler = GetPresubmitChecks(config: config, firestore: firestoreService); + handler = GetPresubmitJobs(config: config, firestore: firestoreService); }); - Future?> getPresubmitCheckResponse( + Future?> getPresubmitJobResponse( Response response, ) async { if (response.statusCode != HttpStatus.ok) { @@ -45,7 +45,7 @@ void main() { } return [ for (final item in jsonBody) - PresubmitCheckResponse.fromJson(item as Map), + PresubmitJobResponse.fromJson(item as Map), ]; } @@ -57,25 +57,25 @@ void main() { test('returns 400 when check_run_id is not an integer', () async { tester.request = FakeHttpRequest( - queryParametersValue: {'check_run_id': 'abc', 'build_name': 'linux'}, + queryParametersValue: {'check_run_id': 'abc', 'job_name': 'linux'}, ); final response = await tester.get(handler); expect(response.statusCode, HttpStatus.badRequest); }); - test('returns 404 when no checks found', () async { + test('returns 404 when no jobs found', () async { tester.request = FakeHttpRequest( - queryParametersValue: {'check_run_id': '123', 'build_name': 'linux'}, + queryParametersValue: {'check_run_id': '123', 'job_name': 'linux'}, ); final response = await tester.get(handler); expect(response.statusCode, HttpStatus.notFound); }); - test('returns checks when found', () async { - final check = fs.PresubmitCheck( + test('returns jobs when found', () async { + final job = fs.PresubmitJob( slug: RepositorySlug('flutter', 'flutter'), checkRunId: 123, - buildName: 'linux', + jobName: 'linux', status: TaskStatus.succeeded, attemptNumber: 1, creationTime: 100, @@ -85,41 +85,41 @@ void main() { buildNumber: 456, ); await firestoreService.writeViaTransaction( - documentsToWrites([check], exists: false), + documentsToWrites([job], exists: false), ); tester.request = FakeHttpRequest( - queryParametersValue: {'check_run_id': '123', 'build_name': 'linux'}, + queryParametersValue: {'check_run_id': '123', 'job_name': 'linux'}, ); final response = await tester.get(handler); expect(response.statusCode, HttpStatus.ok); - final checks = (await getPresubmitCheckResponse(response))!; - expect(checks.length, 1); - expect(checks[0].attemptNumber, 1); - expect(checks[0].buildName, 'linux'); - expect(checks[0].status, 'Succeeded'); - expect(checks[0].buildNumber, 456); + final jobs = (await getPresubmitJobResponse(response))!; + expect(jobs.length, 1); + expect(jobs[0].attemptNumber, 1); + expect(jobs[0].jobName, 'linux'); + expect(jobs[0].status, 'Succeeded'); + expect(jobs[0].buildNumber, 456); }); test('returns checks when found with owner and repo', () async { final slug = RepositorySlug('flutter', 'cocoon'); - final check = fs.PresubmitCheck( + final job = fs.PresubmitJob( slug: slug, checkRunId: 123, - buildName: 'linux', + jobName: 'linux', status: TaskStatus.succeeded, attemptNumber: 1, creationTime: 100, ); await firestoreService.writeViaTransaction( - documentsToWrites([check], exists: false), + documentsToWrites([job], exists: false), ); tester.request = FakeHttpRequest( queryParametersValue: { 'check_run_id': '123', - 'build_name': 'linux', + 'job_name': 'linux', 'owner': 'flutter', 'repo': 'cocoon', }, @@ -127,10 +127,10 @@ void main() { final response = await tester.get(handler); expect(response.statusCode, HttpStatus.ok); - final checks = (await getPresubmitCheckResponse(response))!; - expect(checks.length, 1); - expect(checks[0].attemptNumber, 1); - expect(checks[0].buildName, 'linux'); + final jobs = (await getPresubmitJobResponse(response))!; + expect(jobs.length, 1); + expect(jobs[0].attemptNumber, 1); + expect(jobs[0].jobName, 'linux'); }); test( @@ -139,18 +139,18 @@ void main() { final slug1 = RepositorySlug('flutter', 'flutter'); final slug2 = RepositorySlug('flutter', 'cocoon'); - final check1 = fs.PresubmitCheck( + final check1 = fs.PresubmitJob( slug: slug1, checkRunId: 123, - buildName: 'linux', + jobName: 'linux', status: TaskStatus.succeeded, attemptNumber: 1, creationTime: 100, ); - final check2 = fs.PresubmitCheck( + final check2 = fs.PresubmitJob( slug: slug2, checkRunId: 123, - buildName: 'linux', + jobName: 'linux', status: TaskStatus.succeeded, attemptNumber: 1, creationTime: 100, @@ -162,7 +162,7 @@ void main() { tester.request = FakeHttpRequest( queryParametersValue: { 'check_run_id': '123', - 'build_name': 'linux', + 'job_name': 'linux', 'owner': 'flutter', 'repo': 'cocoon', }, @@ -170,64 +170,64 @@ void main() { final response = await tester.get(handler); expect(response.statusCode, HttpStatus.ok); - final checks = (await getPresubmitCheckResponse(response))!; - expect(checks.length, 1); - expect(checks[0].buildName, 'linux'); + final jobs = (await getPresubmitJobResponse(response))!; + expect(jobs.length, 1); + expect(jobs[0].jobName, 'linux'); // We need to verify it's the right one. - // Since we can't easily check fields of fs.PresubmitCheck from PresubmitCheckResponse + // Since we can't easily check fields of fs.PresubmitJob from PresubmitJobResponse // without more info, we'll rely on the handler logic using the slug. }, ); - test('returns multiple checks in descending order', () async { + test('returns multiple jobs in descending order', () async { final slug = RepositorySlug('flutter', 'flutter'); - final check1 = fs.PresubmitCheck( + final job1 = fs.PresubmitJob( slug: slug, checkRunId: 123, - buildName: 'linux', + jobName: 'linux', status: TaskStatus.succeeded, attemptNumber: 1, creationTime: 100, ); - final check2 = fs.PresubmitCheck( + final job2 = fs.PresubmitJob( slug: slug, checkRunId: 123, - buildName: 'linux', + jobName: 'linux', status: TaskStatus.failed, attemptNumber: 2, creationTime: 200, ); await firestoreService.writeViaTransaction( - documentsToWrites([check1, check2], exists: false), + documentsToWrites([job1, job2], exists: false), ); tester.request = FakeHttpRequest( - queryParametersValue: {'check_run_id': '123', 'build_name': 'linux'}, + queryParametersValue: {'check_run_id': '123', 'job_name': 'linux'}, ); final response = await tester.get(handler); expect(response.statusCode, HttpStatus.ok); - final checks = (await getPresubmitCheckResponse(response))!; - expect(checks.length, 2); - expect(checks[0].attemptNumber, 2); - expect(checks[1].attemptNumber, 1); + final jobs = (await getPresubmitJobResponse(response))!; + expect(jobs.length, 2); + expect(jobs[0].attemptNumber, 2); + expect(jobs[1].attemptNumber, 1); }); test('is accessible without authentication', () async { - final check = fs.PresubmitCheck( + final job = fs.PresubmitJob( slug: RepositorySlug('flutter', 'flutter'), checkRunId: 123, - buildName: 'linux', + jobName: 'linux', status: TaskStatus.succeeded, attemptNumber: 1, creationTime: 100, ); await firestoreService.writeViaTransaction( - documentsToWrites([check], exists: false), + documentsToWrites([job], exists: false), ); tester.request = FakeHttpRequest( - queryParametersValue: {'check_run_id': '123', 'build_name': 'linux'}, + queryParametersValue: {'check_run_id': '123', 'job_name': 'linux'}, ); // No auth context set on tester final response = await tester.get(handler); diff --git a/app_dart/test/request_handlers/get_presubmit_guard_summaries_test.dart b/app_dart/test/request_handlers/get_presubmit_guard_summaries_test.dart index 4c2485dc8..952ac1556 100644 --- a/app_dart/test/request_handlers/get_presubmit_guard_summaries_test.dart +++ b/app_dart/test/request_handlers/get_presubmit_guard_summaries_test.dart @@ -70,39 +70,39 @@ void main() { test('returns multiple guards grouped by commitSha', () async { final slug = RepositorySlug('flutter', 'flutter'); - const prNumber = 123; + const prNum = 123; // SHA1: Two stages, both succeeded. final guard1a = generatePresubmitGuard( slug: slug, - pullRequestId: prNumber, - commitSha: 'sha1', + prNum: prNum, + headSha: 'sha1', checkRun: generateCheckRun(1), creationTime: 100, - builds: {'test1': TaskStatus.succeeded}, - remainingBuilds: 0, + jobs: {'test1': TaskStatus.succeeded}, + remainingJobs: 0, ); final guard1b = generatePresubmitGuard( slug: slug, - pullRequestId: prNumber, - commitSha: 'sha1', + prNum: prNum, + headSha: 'sha1', checkRun: generateCheckRun(2), creationTime: 110, - builds: {'test2': TaskStatus.succeeded}, - remainingBuilds: 0, + jobs: {'test2': TaskStatus.succeeded}, + remainingJobs: 0, ); // SHA2: One stage, failed. final guard2 = generatePresubmitGuard( slug: slug, - pullRequestId: prNumber, - commitSha: 'sha2', + prNum: prNum, + headSha: 'sha2', checkRun: generateCheckRun(3), creationTime: 200, - builds: {'test3': TaskStatus.failed}, - failedBuilds: 1, - remainingBuilds: 0, + jobs: {'test3': TaskStatus.failed}, + failedJobs: 1, + remainingJobs: 0, ); firestore.putDocuments([guard1a, guard1b, guard2]); @@ -110,18 +110,18 @@ void main() { tester.request = FakeHttpRequest( queryParametersValue: { GetPresubmitGuardSummaries.kRepoParam: 'flutter', - GetPresubmitGuardSummaries.kPRParam: prNumber.toString(), + GetPresubmitGuardSummaries.kPRParam: prNum.toString(), }, ); final result = (await getResponse())!; expect(result.length, 2); - final item1 = result.firstWhere((g) => g.commitSha == 'sha1'); + final item1 = result.firstWhere((g) => g.headSha == 'sha1'); expect(item1.creationTime, 100); // earliest expect(item1.guardStatus, GuardStatus.succeeded); - final item2 = result.firstWhere((g) => g.commitSha == 'sha2'); + final item2 = result.firstWhere((g) => g.headSha == 'sha2'); expect(item2.creationTime, 200); expect(item2.guardStatus, GuardStatus.failed); }); @@ -132,8 +132,8 @@ void main() { final guard = generatePresubmitGuard( slug: slug, - pullRequestId: prNumber, - commitSha: 'sha1', + prNum: prNumber, + headSha: 'sha1', checkRun: generateCheckRun(1), creationTime: 100, ); diff --git a/app_dart/test/request_handlers/get_presubmit_guard_test.dart b/app_dart/test/request_handlers/get_presubmit_guard_test.dart index a37238290..f1cd640fa 100644 --- a/app_dart/test/request_handlers/get_presubmit_guard_test.dart +++ b/app_dart/test/request_handlers/get_presubmit_guard_test.dart @@ -72,17 +72,17 @@ void main() { final guard1 = generatePresubmitGuard( slug: slug, - commitSha: sha, + headSha: sha, stage: CiStage.fusionTests, - builds: {'test1': TaskStatus.succeeded}, - remainingBuilds: 0, + jobs: {'test1': TaskStatus.succeeded}, + remainingJobs: 0, ); final guard2 = generatePresubmitGuard( slug: slug, - commitSha: sha, + headSha: sha, stage: CiStage.fusionEngineBuild, - builds: {'engine1': TaskStatus.inProgress}, + jobs: {'engine1': TaskStatus.inProgress}, ); firestore.putDocuments([guard1, guard2]); @@ -117,10 +117,10 @@ void main() { final guard = generatePresubmitGuard( slug: slug, - commitSha: sha, - builds: {'test1': TaskStatus.failed}, - failedBuilds: 1, - remainingBuilds: 0, + headSha: sha, + jobs: {'test1': TaskStatus.failed}, + failedJobs: 1, + remainingJobs: 0, ); firestore.putDocuments([guard]); @@ -145,9 +145,9 @@ void main() { final guard = generatePresubmitGuard( slug: slug, - commitSha: sha, - builds: {'test1': TaskStatus.succeeded}, - remainingBuilds: 0, + headSha: sha, + jobs: {'test1': TaskStatus.succeeded}, + remainingJobs: 0, ); firestore.putDocuments([guard]); @@ -171,8 +171,8 @@ void main() { final guard = generatePresubmitGuard( slug: slug, - commitSha: sha, - builds: {'test1': TaskStatus.waitingForBackfill}, + headSha: sha, + jobs: {'test1': TaskStatus.waitingForBackfill}, ); firestore.putDocuments([guard]); @@ -195,9 +195,9 @@ void main() { final guard = generatePresubmitGuard( slug: slug, - commitSha: sha, - builds: {'test1': TaskStatus.succeeded}, - remainingBuilds: 0, + headSha: sha, + jobs: {'test1': TaskStatus.succeeded}, + remainingJobs: 0, ); firestore.putDocuments([guard]); diff --git a/app_dart/test/request_handlers/presubmit_luci_subscription_neutral_test.dart b/app_dart/test/request_handlers/presubmit_luci_subscription_neutral_test.dart index 6dddc0231..9b671f40a 100644 --- a/app_dart/test/request_handlers/presubmit_luci_subscription_neutral_test.dart +++ b/app_dart/test/request_handlers/presubmit_luci_subscription_neutral_test.dart @@ -146,7 +146,7 @@ void main() { expect(captured, hasLength(1)); expect( captured[0], - isA().having( + isA().having( (e) => e.status, 'status', TaskStatus.neutral, @@ -213,7 +213,7 @@ void main() { expect(captured, hasLength(1)); expect( captured[0], - isA().having( + isA().having( (e) => e.status, 'status', TaskStatus.failed, diff --git a/app_dart/test/request_handlers/presubmit_luci_subscription_test.dart b/app_dart/test/request_handlers/presubmit_luci_subscription_test.dart index 206a38bf1..7e7334ae5 100644 --- a/app_dart/test/request_handlers/presubmit_luci_subscription_test.dart +++ b/app_dart/test/request_handlers/presubmit_luci_subscription_test.dart @@ -572,7 +572,7 @@ void main() { expect(captured, hasLength(1)); expect( captured[0], - isA() + isA() .having((e) => e.name, 'name', 'Linux C') .having((e) => e.sha, 'sha', 'abc') .having((e) => e.checkRunId, 'checkRunId', 1) diff --git a/app_dart/test/request_handlers/rerun_all_failed_jobs_test.dart b/app_dart/test/request_handlers/rerun_all_failed_jobs_test.dart index 9611d9194..60f3b7488 100644 --- a/app_dart/test/request_handlers/rerun_all_failed_jobs_test.dart +++ b/app_dart/test/request_handlers/rerun_all_failed_jobs_test.dart @@ -57,8 +57,8 @@ void main() { final checkRun = generateCheckRun(1, name: 'Guard'); final guard = generatePresubmitGuard( checkRun: checkRun, - builds: {'Linux A': TaskStatus.failed, 'Linux B': TaskStatus.succeeded}, - remainingBuilds: 0, + jobs: {'Linux A': TaskStatus.failed, 'Linux B': TaskStatus.succeeded}, + remainingJobs: 0, ); firestore.putDocument(guard); @@ -72,10 +72,10 @@ void main() { ], ); - final failedCheck = PresubmitCheck( + final failedCheck = PresubmitJob( slug: Config.flutterSlug, checkRunId: 1, - buildName: 'Linux A', + jobName: 'Linux A', status: TaskStatus.failed, attemptNumber: 1, creationTime: 1, @@ -122,15 +122,15 @@ void main() { final updatedGuard = PresubmitGuard.fromDocument( await firestore.getDocument(guard.name!), ); - expect(updatedGuard.builds['Linux A'], TaskStatus.waitingForBackfill); + expect(updatedGuard.jobs['Linux A'], TaskStatus.waitingForBackfill); }); test('Re-run all failed jobs successful with default owner/repo', () async { final checkRun = generateCheckRun(1, name: 'Guard'); final guard = generatePresubmitGuard( checkRun: checkRun, - builds: {'Linux A': TaskStatus.failed}, - remainingBuilds: 0, + jobs: {'Linux A': TaskStatus.failed}, + remainingJobs: 0, ); firestore.putDocument(guard); @@ -144,10 +144,10 @@ void main() { ], ); - final failedCheck = PresubmitCheck( + final failedCheck = PresubmitJob( slug: Config.flutterSlug, checkRunId: 1, - buildName: 'Linux A', + jobName: 'Linux A', status: TaskStatus.failed, attemptNumber: 1, creationTime: 1, @@ -181,7 +181,7 @@ void main() { final checkRun = generateCheckRun(1, name: 'Guard'); final guard = generatePresubmitGuard( checkRun: checkRun, - builds: {'Linux A': TaskStatus.succeeded}, + jobs: {'Linux A': TaskStatus.succeeded}, ); firestore.putDocument(guard); @@ -198,7 +198,7 @@ void main() { tester.requestData = { 'owner': 'flutter', 'repo': 'flutter', - 'pr': guard.pullRequestId, + 'pr': guard.prNum, }; final response = await tester.post(handler); diff --git a/app_dart/test/request_handlers/rerun_failed_job_test.dart b/app_dart/test/request_handlers/rerun_failed_job_test.dart index f286dfc68..9cb0026af 100644 --- a/app_dart/test/request_handlers/rerun_failed_job_test.dart +++ b/app_dart/test/request_handlers/rerun_failed_job_test.dart @@ -56,8 +56,8 @@ void main() { final checkRun = generateCheckRun(1, name: 'Linux A'); final guard = generatePresubmitGuard( checkRun: checkRun, - builds: {'Linux A': TaskStatus.failed}, - remainingBuilds: 0, + jobs: {'Linux A': TaskStatus.failed}, + remainingJobs: 0, ); firestore.putDocument(guard); @@ -71,10 +71,10 @@ void main() { ], ); - final failedCheck = PresubmitCheck( + final failedCheck = PresubmitJob( slug: Config.flutterSlug, checkRunId: 1, - buildName: 'Linux A', + jobName: 'Linux A', status: TaskStatus.failed, attemptNumber: 1, creationTime: 1, @@ -102,7 +102,7 @@ void main() { 'owner': 'flutter', 'repo': 'flutter', 'pr': pullRequest.number!, - 'build_name': 'Linux A', + 'job_name': 'Linux A', }; final response = await tester.post(handler); @@ -121,16 +121,16 @@ void main() { final updatedGuard = PresubmitGuard.fromDocument( await firestore.getDocument(guard.name!), ); - expect(updatedGuard.builds['Linux A'], TaskStatus.waitingForBackfill); - expect(updatedGuard.remainingBuilds, 1); + expect(updatedGuard.jobs['Linux A'], TaskStatus.waitingForBackfill); + expect(updatedGuard.remainingJobs, 1); }); test('Re-run successful failed job with default owner/repo', () async { final checkRun = generateCheckRun(1, name: 'Linux A'); final guard = generatePresubmitGuard( checkRun: checkRun, - builds: {'Linux A': TaskStatus.failed}, - remainingBuilds: 0, + jobs: {'Linux A': TaskStatus.failed}, + remainingJobs: 0, ); firestore.putDocument(guard); @@ -144,10 +144,10 @@ void main() { ], ); - final failedCheck = PresubmitCheck( + final failedCheck = PresubmitJob( slug: Config.flutterSlug, checkRunId: 1, - buildName: 'Linux A', + jobName: 'Linux A', status: TaskStatus.failed, attemptNumber: 1, creationTime: 1, @@ -171,7 +171,7 @@ void main() { ), ).thenAnswer((_) async => []); - tester.requestData = {'pr': pullRequest.number!, 'build_name': 'Linux A'}; + tester.requestData = {'pr': pullRequest.number!, 'job_name': 'Linux A'}; final response = await tester.post(handler); expect(response.statusCode, HttpStatus.ok); @@ -182,7 +182,7 @@ void main() { 'owner': 'flutter', 'repo': 'flutter', 'pr': 123, - 'build_name': 'Linux A', + 'job_name': 'Linux A', }; await expectLater(tester.post(handler), throwsA(isA())); @@ -196,8 +196,8 @@ void main() { tester.requestData = { 'owner': 'flutter', 'repo': 'flutter', - 'pr': guard.pullRequestId + 1, - 'build_name': 'Linux A', + 'pr': guard.prNum + 1, + 'job_name': 'Linux A', }; await expectLater(tester.post(handler), throwsA(isA())); @@ -221,8 +221,8 @@ void main() { tester.requestData = { 'owner': 'flutter', 'repo': 'flutter', - 'pr': guard.pullRequestId, - 'build_name': 'Linux A', + 'pr': guard.prNum, + 'job_name': 'Linux A', }; await expectLater( diff --git a/app_dart/test/service/firestore/unified_check_run_test.dart b/app_dart/test/service/firestore/unified_check_run_test.dart index 079639ded..fcf4aae18 100644 --- a/app_dart/test/service/firestore/unified_check_run_test.dart +++ b/app_dart/test/service/firestore/unified_check_run_test.dart @@ -5,11 +5,11 @@ import 'package:cocoon_common/task_status.dart'; import 'package:cocoon_integration_test/testing.dart'; import 'package:cocoon_server_test/test_logging.dart'; -import 'package:cocoon_service/src/model/common/presubmit_check_state.dart'; import 'package:cocoon_service/src/model/common/presubmit_guard_conclusion.dart'; +import 'package:cocoon_service/src/model/common/presubmit_job_state.dart'; import 'package:cocoon_service/src/model/firestore/base.dart'; -import 'package:cocoon_service/src/model/firestore/presubmit_check.dart'; import 'package:cocoon_service/src/model/firestore/presubmit_guard.dart'; +import 'package:cocoon_service/src/model/firestore/presubmit_job.dart'; import 'package:cocoon_service/src/service/firestore.dart'; import 'package:cocoon_service/src/service/firestore/unified_check_run.dart'; import 'package:cocoon_service/src/service/flags/dynamic_config.dart'; @@ -65,7 +65,7 @@ void main() { final guardId = PresubmitGuard.documentIdFor( slug: slug, - pullRequestId: 1, + prNum: 1, checkRunId: 123, stage: CiStage.fusionEngineBuild, ); @@ -74,14 +74,14 @@ void main() { ); expect(guardDoc.name, endsWith(guardId.documentId)); - final checkId = PresubmitCheck.documentIdFor( + final checkId = PresubmitJob.documentIdFor( slug: slug, checkRunId: 123, - buildName: 'linux', + jobName: 'linux', attemptNumber: 1, ); final checkDoc = await firestoreService.getDocument( - 'projects/flutter-dashboard/databases/cocoon/documents/presubmit_checks/${checkId.documentId}', + 'projects/flutter-dashboard/databases/cocoon/documents/presubmit_jobs/${checkId.documentId}', ); expect(checkDoc.name, endsWith(checkId.documentId)); }); @@ -105,7 +105,7 @@ void main() { // Verify PresubmitGuard is NOT created final guardId = PresubmitGuard.documentIdFor( slug: slug, - pullRequestId: 1, + prNum: 1, checkRunId: 123, stage: CiStage.fusionEngineBuild, ); @@ -124,7 +124,7 @@ void main() { setUp(() async { guardId = PresubmitGuardId( slug: slug, - pullRequestId: 1, + prNum: 1, checkRunId: 123, stage: CiStage.fusionEngineBuild, ); @@ -132,29 +132,29 @@ void main() { // Initialize documents final guard = PresubmitGuard( checkRun: checkRun, - commitSha: sha, + headSha: sha, slug: slug, - pullRequestId: 1, + prNum: 1, stage: CiStage.fusionEngineBuild, creationTime: 1000, author: 'dash', - builds: { + jobs: { for (final task in ['linux', 'mac']) task: TaskStatus.waitingForBackfill, }, - remainingBuilds: 2, - failedBuilds: 0, + remainingJobs: 2, + failedJobs: 0, ); - final check1 = PresubmitCheck.init( + final check1 = PresubmitJob.init( slug: slug, - buildName: 'linux', + jobName: 'linux', checkRunId: guardId.checkRunId, creationTime: 1000, ); - final check2 = PresubmitCheck.init( + final check2 = PresubmitJob.init( slug: slug, - buildName: 'mac', + jobName: 'mac', checkRunId: guardId.checkRunId, creationTime: 1000, ); @@ -169,8 +169,8 @@ void main() { }); test('updates check status and remaining count on success', () async { - final state = const PresubmitCheckState( - buildName: 'linux', + final state = const PresubmitJobState( + jobName: 'linux', status: TaskStatus.succeeded, attemptNumber: 1, startTime: 2000, @@ -188,12 +188,12 @@ void main() { expect(result.remaining, 1); expect(result.failed, 0); - final checkDoc = await PresubmitCheck.fromFirestore( + final checkDoc = await PresubmitJob.fromFirestore( firestoreService, - PresubmitCheckId( + PresubmitJobId( slug: slug, checkRunId: 123, - buildName: 'linux', + jobName: 'linux', attemptNumber: 1, ), ); @@ -208,8 +208,8 @@ void main() { final result1 = await UnifiedCheckRun.markConclusion( firestoreService: firestoreService, guardId: guardId, - state: const PresubmitCheckState( - buildName: 'linux', + state: const PresubmitJobState( + jobName: 'linux', status: TaskStatus.succeeded, attemptNumber: 1, startTime: 2000, @@ -226,8 +226,8 @@ void main() { final result2 = await UnifiedCheckRun.markConclusion( firestoreService: firestoreService, guardId: guardId, - state: const PresubmitCheckState( - buildName: 'mac', + state: const PresubmitJobState( + jobName: 'mac', status: TaskStatus.succeeded, attemptNumber: 1, startTime: 2000, @@ -241,12 +241,12 @@ void main() { expect(result2.isComplete, true); expect(result2.isPending, false); - final checkDoc = await PresubmitCheck.fromFirestore( + final checkDoc = await PresubmitJob.fromFirestore( firestoreService, - PresubmitCheckId( + PresubmitJobId( slug: slug, checkRunId: 123, - buildName: 'linux', + jobName: 'linux', attemptNumber: 1, ), ); @@ -256,8 +256,8 @@ void main() { ); test('updates check status and failed count on failure', () async { - final state = const PresubmitCheckState( - buildName: 'linux', + final state = const PresubmitJobState( + jobName: 'linux', status: TaskStatus.failed, attemptNumber: 1, startTime: 2000, @@ -276,8 +276,8 @@ void main() { }); test('handles missing check gracefully', () async { - final state = const PresubmitCheckState( - buildName: 'windows', // Missing + final state = const PresubmitJobState( + jobName: 'windows', // Missing status: TaskStatus.succeeded, attemptNumber: 1, ); @@ -297,7 +297,7 @@ void main() { setUp(() async { fusionGuardId = PresubmitGuardId( slug: slug, - pullRequestId: 1, + prNum: 1, checkRunId: 123, stage: CiStage.fusionTests, ); @@ -305,29 +305,29 @@ void main() { // Initialize documents final guard = PresubmitGuard( checkRun: checkRun, - commitSha: sha, + headSha: sha, slug: slug, - pullRequestId: 1, + prNum: 1, stage: CiStage.fusionTests, creationTime: 1000, author: 'dash', - builds: {'linux': TaskStatus.failed, 'mac': TaskStatus.succeeded}, - remainingBuilds: 0, - failedBuilds: 1, + jobs: {'linux': TaskStatus.failed, 'mac': TaskStatus.succeeded}, + remainingJobs: 0, + failedJobs: 1, ); - final check1 = PresubmitCheck( + final check1 = PresubmitJob( slug: slug, - buildName: 'linux', + jobName: 'linux', checkRunId: fusionGuardId.checkRunId, creationTime: 1000, status: TaskStatus.failed, attemptNumber: 1, ); - final check2 = PresubmitCheck( + final check2 = PresubmitJob( slug: slug, - buildName: 'mac', + jobName: 'mac', checkRunId: fusionGuardId.checkRunId, creationTime: 1000, status: TaskStatus.succeeded, @@ -344,15 +344,15 @@ void main() { }); test('updates fusion failed checks and remaining count', () async { - final result = await UnifiedCheckRun.reInitializeFailedChecks( + final result = await UnifiedCheckRun.reInitializeFailedJobs( firestoreService: firestoreService, slug: slug, - pullRequestId: pullRequest.number!, + prNum: pullRequest.number!, guardCheckRunId: 123, ); expect(result, isNotNull); - expect(result!.checkRetries, containsPair('linux', 2)); - expect(result.checkRetries.keys, isNot(contains('mac'))); + expect(result!.jobRetries, containsPair('linux', 2)); + expect(result.jobRetries.keys, isNot(contains('mac'))); expect(result.stage, CiStage.fusionTests); final guardDoc = await firestoreService.getDocument( @@ -360,18 +360,18 @@ void main() { ); final guard = PresubmitGuard.fromDocument(guardDoc); - expect(guard.failedBuilds, 0); - expect(guard.remainingBuilds, 1); - expect(guard.builds['linux'], TaskStatus.waitingForBackfill); - expect(guard.builds['mac'], TaskStatus.succeeded); + expect(guard.failedJobs, 0); + expect(guard.remainingJobs, 1); + expect(guard.jobs['linux'], TaskStatus.waitingForBackfill); + expect(guard.jobs['mac'], TaskStatus.succeeded); // Verify new check document created with incremented attempt number - final checkDoc = await PresubmitCheck.fromFirestore( + final checkDoc = await PresubmitJob.fromFirestore( firestoreService, - PresubmitCheckId( + PresubmitJobId( slug: slug, checkRunId: 123, - buildName: 'linux', + jobName: 'linux', attemptNumber: 2, ), ); @@ -382,7 +382,7 @@ void main() { test('properly handle if engine and fusion guards are present', () async { final engineGuardId = PresubmitGuardId( slug: slug, - pullRequestId: 1, + prNum: 1, checkRunId: 123, stage: CiStage.fusionEngineBuild, ); @@ -390,29 +390,29 @@ void main() { // Initialize documents final guard = PresubmitGuard( checkRun: checkRun, - commitSha: sha, + headSha: sha, slug: slug, - pullRequestId: 1, + prNum: 1, stage: CiStage.fusionEngineBuild, creationTime: 1000, author: 'dash', - builds: {'win': TaskStatus.succeeded, 'ios': TaskStatus.succeeded}, - remainingBuilds: 0, - failedBuilds: 0, + jobs: {'win': TaskStatus.succeeded, 'ios': TaskStatus.succeeded}, + remainingJobs: 0, + failedJobs: 0, ); - final check1 = PresubmitCheck( + final check1 = PresubmitJob( slug: slug, - buildName: 'win', + jobName: 'win', checkRunId: engineGuardId.checkRunId, creationTime: 1000, status: TaskStatus.succeeded, attemptNumber: 1, ); - final check2 = PresubmitCheck( + final check2 = PresubmitJob( slug: slug, - buildName: 'ios', + jobName: 'ios', checkRunId: engineGuardId.checkRunId, creationTime: 1000, status: TaskStatus.succeeded, @@ -427,15 +427,15 @@ void main() { ], exists: false), ); - final result = await UnifiedCheckRun.reInitializeFailedChecks( + final result = await UnifiedCheckRun.reInitializeFailedJobs( firestoreService: firestoreService, slug: slug, - pullRequestId: pullRequest.number!, + prNum: pullRequest.number!, guardCheckRunId: 123, ); expect(result, isNotNull); - expect(result!.checkRetries, containsPair('linux', 2)); - expect(result.checkRetries.keys, isNot(contains('mac'))); + expect(result!.jobRetries, containsPair('linux', 2)); + expect(result.jobRetries.keys, isNot(contains('mac'))); expect(result.stage, CiStage.fusionTests); final guardDoc = await firestoreService.getDocument( @@ -443,18 +443,18 @@ void main() { ); final restartedGuard = PresubmitGuard.fromDocument(guardDoc); - expect(restartedGuard.failedBuilds, 0); - expect(restartedGuard.remainingBuilds, 1); - expect(restartedGuard.builds['linux'], TaskStatus.waitingForBackfill); - expect(restartedGuard.builds['mac'], TaskStatus.succeeded); + expect(restartedGuard.failedJobs, 0); + expect(restartedGuard.remainingJobs, 1); + expect(restartedGuard.jobs['linux'], TaskStatus.waitingForBackfill); + expect(restartedGuard.jobs['mac'], TaskStatus.succeeded); // Verify new check document created with incremented attempt number - final checkDoc = await PresubmitCheck.fromFirestore( + final checkDoc = await PresubmitJob.fromFirestore( firestoreService, - PresubmitCheckId( + PresubmitJobId( slug: slug, checkRunId: 123, - buildName: 'linux', + jobName: 'linux', attemptNumber: 2, ), ); @@ -468,18 +468,18 @@ void main() { 'projects/flutter-dashboard/databases/cocoon/documents/presubmit_guards/${fusionGuardId.documentId}', ); final guard = PresubmitGuard.fromDocument(guardDoc); - final builds = guard.builds; + final builds = guard.jobs; builds['linux'] = TaskStatus.succeeded; - guard.builds = builds; - guard.failedBuilds = 0; + guard.jobs = builds; + guard.failedJobs = 0; await firestoreService.writeViaTransaction( documentsToWrites([guard], exists: true), ); - final result = await UnifiedCheckRun.reInitializeFailedChecks( + final result = await UnifiedCheckRun.reInitializeFailedJobs( firestoreService: firestoreService, slug: slug, - pullRequestId: pullRequest.number!, + prNum: pullRequest.number!, guardCheckRunId: 123, ); expect(result, isNull); @@ -489,8 +489,8 @@ void main() { ); final updatedGuard = PresubmitGuard.fromDocument(guardDoc); // Should remain unchanged - expect(updatedGuard.failedBuilds, 0); - expect(updatedGuard.remainingBuilds, 0); + expect(updatedGuard.failedJobs, 0); + expect(updatedGuard.remainingJobs, 0); }); }); @@ -506,28 +506,28 @@ void main() { final guard1 = PresubmitGuard( checkRun: checkRun, - commitSha: sha, + headSha: sha, slug: slug, - pullRequestId: 1, + prNum: 1, stage: CiStage.fusionEngineBuild, creationTime: 1000, author: 'dash', - remainingBuilds: 1, - failedBuilds: 0, - builds: {'linux': TaskStatus.succeeded}, + remainingJobs: 1, + failedJobs: 0, + jobs: {'linux': TaskStatus.succeeded}, ); final guard2 = PresubmitGuard( checkRun: checkRun, - commitSha: sha, + headSha: sha, slug: slug, - pullRequestId: 1, + prNum: 1, stage: CiStage.fusionTests, creationTime: 2000, author: 'dash', - remainingBuilds: 1, - failedBuilds: 0, - builds: {'mac': TaskStatus.succeeded}, + remainingJobs: 1, + failedJobs: 0, + jobs: {'mac': TaskStatus.succeeded}, ); await firestoreService.writeViaTransaction( @@ -540,7 +540,7 @@ void main() { final guard = await UnifiedCheckRun.getLatestPresubmitGuardForCheckRun( firestoreService: firestoreService, slug: slug, - pullRequestId: 1, + prNum: 1, checkRunId: 123, ); @@ -554,35 +554,34 @@ void main() { () async { final guard1 = generatePresubmitGuard( checkRun: generateCheckRun(1), - commitSha: 'abc', - pullRequestId: 5678, + headSha: 'abc', + prNum: 5678, creationTime: 1000, ); final guard2 = generatePresubmitGuard( checkRun: generateCheckRun(2), - commitSha: 'abc', - pullRequestId: 5678, + headSha: 'abc', + prNum: 5678, creationTime: 2000, ); firestoreService.putDocument(guard1); firestoreService.putDocument(guard2); - final result = - await UnifiedCheckRun.getLatestPresubmitGuardByPullRequestNum( - firestoreService: firestoreService, - slug: slug, - pullRequestNum: 5678, - ); + final result = await UnifiedCheckRun.getLatestPresubmitGuardForPrNum( + firestoreService: firestoreService, + slug: slug, + prNum: 5678, + ); expect(result!.checkRunId, 2); }, ); - test('getPresubmitCheckDetails returns all attempts sorted', () async { - final check1 = PresubmitCheck( + test('getPresubmitJobDetails returns all attempts sorted', () async { + final check1 = PresubmitJob( slug: slug, checkRunId: 1234, - buildName: 'linux_test', + jobName: 'linux_test', status: TaskStatus.succeeded, attemptNumber: 1, creationTime: 100, @@ -590,10 +589,10 @@ void main() { endTime: 120, summary: 'attempt 1', ); - final check2 = PresubmitCheck( + final check2 = PresubmitJob( slug: slug, checkRunId: 1234, - buildName: 'linux_test', + jobName: 'linux_test', status: TaskStatus.failed, attemptNumber: 2, creationTime: 200, @@ -605,10 +604,10 @@ void main() { documentsToWrites([check1, check2], exists: false), ); - final attempts = await UnifiedCheckRun.getPresubmitCheckDetails( + final attempts = await UnifiedCheckRun.getPresubmitJobDetails( firestoreService: firestoreService, checkRunId: 1234, - buildName: 'linux_test', + jobName: 'linux_test', ); expect(attempts.length, 2); diff --git a/app_dart/test/service/presubmit_guard_query_test.dart b/app_dart/test/service/presubmit_guard_query_test.dart index 33900d3b7..ca20a8883 100644 --- a/app_dart/test/service/presubmit_guard_query_test.dart +++ b/app_dart/test/service/presubmit_guard_query_test.dart @@ -24,18 +24,18 @@ void main() { final guard1 = generatePresubmitGuard( slug: slug, - commitSha: commitSha, + headSha: commitSha, stage: CiStage.fusionTests, ); final guard2 = generatePresubmitGuard( slug: slug, - commitSha: commitSha, + headSha: commitSha, stage: CiStage.fusionEngineBuild, ); final otherGuard = generatePresubmitGuard( slug: slug, - pullRequestId: 456, - commitSha: 'def', + prNum: 456, + headSha: 'def', stage: CiStage.fusionTests, ); diff --git a/app_dart/test/service/scheduler_test.dart b/app_dart/test/service/scheduler_test.dart index 9626fb541..e2aaff219 100644 --- a/app_dart/test/service/scheduler_test.dart +++ b/app_dart/test/service/scheduler_test.dart @@ -938,7 +938,7 @@ void main() { verifyNever(mockGithubChecksUtil.createCheckRun(any, any, any, any)); }); - test('rerequested presubmit check triggers presubmit build', () async { + test('rerequested presubmit job triggers presubmit build', () async { // Note that we're not inserting any commits into the db, because // only postsubmit commits are stored in the Firestore. final pullRequest = generatePullRequest( @@ -1171,20 +1171,20 @@ targets: final guard = PresubmitGuard( checkRun: createGithubCheckRun(id: 1), - commitSha: 'sha', + headSha: 'sha', slug: slug, - pullRequestId: 1, + prNum: 1, stage: CiStage.fusionEngineBuild, creationTime: 1000, author: 'dash', - builds: {'Linux A': TaskStatus.failed}, - failedBuilds: 1, - remainingBuilds: 0, + jobs: {'Linux A': TaskStatus.failed}, + failedJobs: 1, + remainingJobs: 0, ); - final check = PresubmitCheck( + final check = PresubmitJob( slug: slug, - buildName: 'Linux A', + jobName: 'Linux A', checkRunId: 1, creationTime: 1000, status: TaskStatus.failed, @@ -1284,8 +1284,8 @@ targets: final updatedGuardDoc = await firestore.getDocument(guard.name!); final updatedGuard = PresubmitGuard.fromDocument(updatedGuardDoc); - expect(updatedGuard.failedBuilds, 0); - expect(updatedGuard.builds['Linux A'], TaskStatus.waitingForBackfill); + expect(updatedGuard.failedJobs, 0); + expect(updatedGuard.jobs['Linux A'], TaskStatus.waitingForBackfill); }); test('rerequested action reschedules failed checks for fusion', () async { @@ -1303,32 +1303,32 @@ targets: final engineGuard = PresubmitGuard( checkRun: createGithubCheckRun(id: 1), - commitSha: 'sha', + headSha: 'sha', slug: slug, - pullRequestId: 1, + prNum: 1, stage: CiStage.fusionEngineBuild, creationTime: 1000, author: 'dash', - failedBuilds: 0, - remainingBuilds: 0, + failedJobs: 0, + remainingJobs: 0, ); final fusionGuard = PresubmitGuard( checkRun: createGithubCheckRun(id: 1), - commitSha: 'sha', + headSha: 'sha', slug: slug, - pullRequestId: 1, + prNum: 1, stage: CiStage.fusionTests, creationTime: 2000, author: 'dash', - builds: {'Linux A': TaskStatus.failed}, - failedBuilds: 1, - remainingBuilds: 0, + jobs: {'Linux A': TaskStatus.failed}, + failedJobs: 1, + remainingJobs: 0, ); - final check = PresubmitCheck( + final check = PresubmitJob( slug: slug, - buildName: 'Linux A', + jobName: 'Linux A', checkRunId: 1, creationTime: 2000, status: TaskStatus.failed, @@ -1429,8 +1429,8 @@ targets: final updatedGuardDoc = await firestore.getDocument(fusionGuard.name!); final updatedGuard = PresubmitGuard.fromDocument(updatedGuardDoc); - expect(updatedGuard.failedBuilds, 0); - expect(updatedGuard.builds['Linux A'], TaskStatus.waitingForBackfill); + expect(updatedGuard.failedJobs, 0); + expect(updatedGuard.jobs['Linux A'], TaskStatus.waitingForBackfill); }); group('completed action', () { @@ -1462,7 +1462,7 @@ targets: for (final ignored in Scheduler.kCheckRunsToIgnore) { expect( await scheduler.processCheckRunCompleted( - PresubmitCompletedCheck.fromCheckRun( + PresubmitCompletedJob.fromCheckRun( createCocoonCheckRun(name: ignored, sha: 'abc123'), createGithubRepository().slug(), ), @@ -1497,7 +1497,7 @@ targets: expect( await scheduler.processCheckRunCompleted( - PresubmitCompletedCheck.fromCheckRun( + PresubmitCompletedJob.fromCheckRun( createCocoonCheckRun(name: 'Bar bar', sha: 'abc123'), createGithubRepository().slug(), ), @@ -1536,7 +1536,7 @@ targets: expect( await scheduler.processCheckRunCompleted( - PresubmitCompletedCheck.fromCheckRun( + PresubmitCompletedJob.fromCheckRun( createCocoonCheckRun(name: 'Bar bar', sha: 'abc123'), createGithubRepository().slug(), ), @@ -1590,7 +1590,7 @@ targets: expect( await scheduler.processCheckRunCompleted( - PresubmitCompletedCheck.fromCheckRun( + PresubmitCompletedJob.fromCheckRun( createCocoonCheckRun(name: 'Bar bar', sha: 'abc123'), createGithubRepository().slug(), ), @@ -1700,7 +1700,7 @@ targets: expect( await scheduler.processCheckRunCompleted( - PresubmitCompletedCheck.fromCheckRun( + PresubmitCompletedJob.fromCheckRun( createCocoonCheckRun(name: 'Bar bar', sha: 'testSha'), createGithubRepository().slug(), ), @@ -1844,7 +1844,7 @@ targets: expect( await scheduler.processCheckRunCompleted( - PresubmitCompletedCheck.fromCheckRun( + PresubmitCompletedJob.fromCheckRun( createCocoonCheckRun( name: 'Bar bar', sha: 'testSha', @@ -1953,7 +1953,7 @@ targets: expect( await scheduler.processCheckRunCompleted( - PresubmitCompletedCheck.fromCheckRun( + PresubmitCompletedJob.fromCheckRun( createCocoonCheckRun(name: 'Bar bar', sha: 'testSha'), createGithubRepository().slug(), ), @@ -2217,7 +2217,7 @@ targets: expect( await scheduler.processCheckRunCompleted( - PresubmitCompletedCheck.fromCheckRun( + PresubmitCompletedJob.fromCheckRun( createCocoonCheckRun( name: 'Bar bar', sha: 'testSha', @@ -2300,7 +2300,7 @@ targets: expect( await scheduler.processCheckRunCompleted( - PresubmitCompletedCheck.fromCheckRun( + PresubmitCompletedJob.fromCheckRun( createCocoonCheckRun( name: 'Bar bar', sha: 'testSha', @@ -2383,7 +2383,7 @@ targets: expect( await scheduler.processCheckRunCompleted( - PresubmitCompletedCheck.fromCheckRun( + PresubmitCompletedJob.fromCheckRun( createCocoonCheckRun( name: 'Bar bar', sha: 'testSha', @@ -2506,7 +2506,7 @@ targets: expect( await scheduler.processCheckRunCompleted( - PresubmitCompletedCheck.fromCheckRun( + PresubmitCompletedJob.fromCheckRun( createCocoonCheckRun(name: 'Bar bar', sha: 'testSha'), createGithubRepository().slug(), ), @@ -3894,23 +3894,23 @@ targets: firestore.putDocument( PresubmitGuard( checkRun: checkRunGuard, - commitSha: pullRequest.head!.sha!, + headSha: pullRequest.head!.sha!, slug: pullRequest.base!.repo!.slug(), - pullRequestId: pullRequest.number!, + prNum: pullRequest.number!, stage: CiStage.fusionEngineBuild, author: pullRequest.user!.login!, creationTime: DateTime.now().millisecondsSinceEpoch, - builds: {'Linux engine_build': TaskStatus.waitingForBackfill}, - remainingBuilds: 1, - failedBuilds: 0, + jobs: {'Linux engine_build': TaskStatus.waitingForBackfill}, + remainingJobs: 1, + failedJobs: 0, ), ); // Initialize check run for the task firestore.putDocument( - PresubmitCheck.init( + PresubmitJob.init( slug: pullRequest.base!.repo!.slug(), - buildName: 'Linux engine_build', + jobName: 'Linux engine_build', checkRunId: checkRunGuard.id!, creationTime: DateTime.now().millisecondsSinceEpoch, ), @@ -3946,7 +3946,7 @@ targets: ], ); - final check = PresubmitCompletedCheck.fromBuild(build, userData); + final check = PresubmitCompletedJob.fromBuild(build, userData); expect(await scheduler.processCheckRunCompleted(check), isTrue); @@ -3958,8 +3958,8 @@ targets: final guard = guards .map(PresubmitGuard.fromDocument) .firstWhere((g) => g.stage == CiStage.fusionEngineBuild); - expect(guard.builds['Linux engine_build'], TaskStatus.succeeded); - expect(guard.remainingBuilds, 0); + expect(guard.jobs['Linux engine_build'], TaskStatus.succeeded); + expect(guard.remainingJobs, 0); }); test( @@ -3985,23 +3985,23 @@ targets: firestore.putDocument( PresubmitGuard( checkRun: checkRunGuard, - commitSha: pullRequest.head!.sha!, + headSha: pullRequest.head!.sha!, slug: pullRequest.base!.repo!.slug(), - pullRequestId: pullRequest.number!, + prNum: pullRequest.number!, stage: CiStage.fusionTests, author: pullRequest.user!.login!, creationTime: DateTime.now().millisecondsSinceEpoch, - builds: {'Linux test': TaskStatus.waitingForBackfill}, - remainingBuilds: 1, - failedBuilds: 0, + jobs: {'Linux test': TaskStatus.waitingForBackfill}, + remainingJobs: 1, + failedJobs: 0, ), ); // Initialize check run for the task firestore.putDocument( - PresubmitCheck.init( + PresubmitJob.init( slug: pullRequest.base!.repo!.slug(), - buildName: 'Linux test', + jobName: 'Linux test', checkRunId: checkRunGuard.id!, creationTime: DateTime.now().millisecondsSinceEpoch, ), @@ -4026,7 +4026,7 @@ targets: tags: [bbv2.StringPair(key: 'current_attempt', value: '1')], ); - final check = PresubmitCompletedCheck.fromBuild(build, userData); + final check = PresubmitCompletedJob.fromBuild(build, userData); expect(await scheduler.processCheckRunCompleted(check), isTrue); @@ -4044,7 +4044,7 @@ targets: final guards = await firestore.query(PresubmitGuard.collectionId, {}); final guard = PresubmitGuard.fromDocument(guards.single); - expect(guard.failedBuilds, 1); + expect(guard.failedJobs, 1); }, ); @@ -4069,23 +4069,23 @@ targets: firestore.putDocument( PresubmitGuard( checkRun: checkRunGuard, - commitSha: pullRequest.head!.sha!, + headSha: pullRequest.head!.sha!, slug: pullRequest.base!.repo!.slug(), - pullRequestId: pullRequest.number!, + prNum: pullRequest.number!, stage: CiStage.fusionTests, author: pullRequest.user!.login!, creationTime: DateTime.now().millisecondsSinceEpoch, - builds: {'Linux test': TaskStatus.waitingForBackfill}, - remainingBuilds: 1, - failedBuilds: 0, + jobs: {'Linux test': TaskStatus.waitingForBackfill}, + remainingJobs: 1, + failedJobs: 0, ), ); // Initialize check run for the task firestore.putDocument( - PresubmitCheck.init( + PresubmitJob.init( slug: pullRequest.base!.repo!.slug(), - buildName: 'Linux test', + jobName: 'Linux test', checkRunId: checkRunGuard.id!, creationTime: DateTime.now().millisecondsSinceEpoch, ), @@ -4116,7 +4116,7 @@ targets: ], ); - final check = PresubmitCompletedCheck.fromBuild(build, userData); + final check = PresubmitCompletedJob.fromBuild(build, userData); expect(await scheduler.processCheckRunCompleted(check), isTrue); @@ -4133,7 +4133,7 @@ targets: final guards = await firestore.query(PresubmitGuard.collectionId, {}); final guard = PresubmitGuard.fromDocument(guards.single); - expect(guard.remainingBuilds, 0); + expect(guard.remainingJobs, 0); }); }); }); diff --git a/conductor/archive/add_build_number_20260212/metadata.json b/conductor/archive/add_build_number_20260212/metadata.json index 08ff09314..da4c168b9 100644 --- a/conductor/archive/add_build_number_20260212/metadata.json +++ b/conductor/archive/add_build_number_20260212/metadata.json @@ -4,5 +4,5 @@ "status": "new", "created_at": "2026-02-12T12:00:00Z", "updated_at": "2026-02-12T12:00:00Z", - "description": "Add optional buildNumber to presubmitCheck and fill it on processing checkrun completed" + "description": "Add optional buildNumber to presubmitJob and fill it on processing checkrun completed" } diff --git a/conductor/archive/add_build_number_20260212/plan.md b/conductor/archive/add_build_number_20260212/plan.md index b376f3088..ae5256bbe 100644 --- a/conductor/archive/add_build_number_20260212/plan.md +++ b/conductor/archive/add_build_number_20260212/plan.md @@ -1,4 +1,4 @@ -# Implementation Plan: Add `buildNumber` to `PresubmitCheck` +# Implementation Plan: Add `buildNumber` to `PresubmitJob` This plan outlines the steps to add an optional `buildNumber` field across the Cocoon backend models and ensure it is populated during the check run completion process. @@ -6,16 +6,16 @@ This plan outlines the steps to add an optional `buildNumber` field across the C This phase focuses on updating the internal and external data models to support the new `buildNumber` field. -- [x] Task: Update `PresubmitCheckState` Model - - [x] Add `int? buildNumber` to `PresubmitCheckState` class in `app_dart/lib/src/model/common/presubmit_check_state.dart`. - - [x] Update `BuildToPresubmitCheckState` extension to map `number` from `bbv2.Build` to `buildNumber`. +- [x] Task: Update `PresubmitJobState` Model + - [x] Add `int? buildNumber` to `PresubmitJobState` class in `app_dart/lib/src/model/common/presubmit_job_state.dart`. + - [x] Update `BuildToPresubmitJobState` extension to map `number` from `bbv2.Build` to `buildNumber`. - [x] Update existing tests to reflect constructor changes. -- [x] Task: Update `PresubmitCheck` Firestore Model - - [x] Add `fieldBuildNumber` constant and `buildNumber` getter/setter to `PresubmitCheck` in `app_dart/lib/src/model/firestore/presubmit_check.dart`. +- [x] Task: Update `PresubmitJob` Firestore Model + - [x] Add `fieldBuildNumber` constant and `buildNumber` getter/setter to `PresubmitJob` in `app_dart/lib/src/model/firestore/presubmit_job.dart`. - [x] Update `fromDocument`, `init`, and `toJson` (or equivalent) to handle the new field. - [x] Add unit tests for serialization/deserialization of `buildNumber`. -- [x] Task: Update `PresubmitCheckResponse` RPC Model - - [x] Add `int? buildNumber` to `PresubmitCheckResponse` in `packages/cocoon_common/lib/src/rpc_model/presubmit_check_response.dart`. +- [x] Task: Update `PresubmitJobResponse` RPC Model + - [x] Add `int? buildNumber` to `PresubmitJobResponse` in `packages/cocoon_common/lib/src/rpc_model/presubmit_job_response.dart`. - [x] Run `dart run build_runner build --delete-conflicting-outputs` in `packages/cocoon_common/` to regenerate JSON serialization code. - [x] Add unit tests for the RPC model. - [x] Task: Conductor - User Manual Verification 'Model Updates' (Protocol in workflow.md) @@ -25,9 +25,9 @@ This phase focuses on updating the internal and external data models to support This phase integrates the new field into the core logic and ensures it is returned by the API. - [x] Task: Update `UnifiedCheckRun.markConclusion` Logic - - [x] Update `markConclusion` in `app_dart/lib/src/service/firestore/unified_check_run.dart` to assign `state.buildNumber` to `presubmitCheck.buildNumber`. + - [x] Update `markConclusion` in `app_dart/lib/src/service/firestore/unified_check_run.dart` to assign `state.buildNumber` to `presubmitJob.buildNumber`. - [x] Add/update tests in `app_dart/test/service/firestore/unified_check_run_test.dart` to verify the build number is correctly saved to Firestore. -- [x] Task: Update `GetPresubmitChecks` API Handler - - [x] Update `GetPresubmitChecks` in `app_dart/lib/src/request_handlers/get_presubmit_checks.dart` to map `PresubmitCheck.buildNumber` to `PresubmitCheckResponse.buildNumber`. +- [x] Task: Update `GetPresubmitJobs` API Handler + - [x] Update `GetPresubmitJobs` in `app_dart/lib/src/request_handlers/get_presubmit_jobs.dart` to map `PresubmitJob.buildNumber` to `PresubmitJobResponse.buildNumber`. - [x] Update handler tests to verify the API response contains the build number. - [x] Task: Conductor - User Manual Verification 'Backend Logic and API Updates' (Protocol in workflow.md) diff --git a/conductor/archive/add_build_number_20260212/spec.md b/conductor/archive/add_build_number_20260212/spec.md index e6f483eec..95b92d36d 100644 --- a/conductor/archive/add_build_number_20260212/spec.md +++ b/conductor/archive/add_build_number_20260212/spec.md @@ -1,7 +1,7 @@ -# Specification: Add `buildNumber` to `PresubmitCheck` +# Specification: Add `buildNumber` to `PresubmitJob` ## Overview -Currently, the `PresubmitCheck` model in Cocoon's Firestore and the corresponding RPC response (`PresubmitCheckResponse`) do not include the canonical LUCI build number. This makes it difficult for backend processes to uniquely identify and link to specific build attempts. This feature adds an optional `buildNumber` field to these models, as well as the intermediate `PresubmitCheckState`, ensuring it is populated when a GitHub `check_run` completion event is processed. +Currently, the `PresubmitJob` model in Cocoon's Firestore and the corresponding RPC response (`PresubmitJobResponse`) do not include the canonical LUCI build number. This makes it difficult for backend processes to uniquely identify and link to specific build attempts. This feature adds an optional `buildNumber` field to these models, as well as the intermediate `PresubmitJobState`, ensuring it is populated when a GitHub `check_run` completion event is processed. ## Goals - **Improve Traceability:** Provide a direct reference to the LUCI build number in the backend data. @@ -9,12 +9,12 @@ Currently, the `PresubmitCheck` model in Cocoon's Firestore and the correspondin - **Future Support:** Lay the groundwork for re-running specific builds using their build number and for future UI integrations. ## Functional Requirements -1. **Intermediate State Update:** Add a `buildNumber` field (integer, optional) to `PresubmitCheckState` in `app_dart/lib/src/model/common/presubmit_check_state.dart`. -2. **Firestore Model Update:** Add a `buildNumber` field (integer, optional) to the `PresubmitCheck` document in Firestore. -3. **RPC Model Update:** Add a `buildNumber` field (integer, optional) to the `PresubmitCheckResponse` RPC model. +1. **Intermediate State Update:** Add a `buildNumber` field (integer, optional) to `PresubmitJobState` in `app_dart/lib/src/model/common/presubmit_job_state.dart`. +2. **Firestore Model Update:** Add a `buildNumber` field (integer, optional) to the `PresubmitJob` document in Firestore. +3. **RPC Model Update:** Add a `buildNumber` field (integer, optional) to the `PresubmitJobResponse` RPC model. 4. **Data Population:** Update `UnifiedCheckRun.markConclusion` (or the relevant handler for `check_run` completion) to: - Fetch the canonical build number from the LUCI BuildBucket API if it's not already available in the incoming `check_run` state. - - Store this `buildNumber` in the `PresubmitCheck` document. + - Store this `buildNumber` in the `PresubmitJob` document. 5. **Handling Missing Data:** Older check runs or runs where the build number cannot be retrieved should have the `buildNumber` field set to `null` or omitted. ## Non-Functional Requirements @@ -22,9 +22,9 @@ Currently, the `PresubmitCheck` model in Cocoon's Firestore and the correspondin - **Reliability:** If fetching the build number fails, the system should still record the completion status without the build number rather than failing the entire transaction. ## Acceptance Criteria -- [ ] `PresubmitCheckState` includes a `buildNumber` field. -- [ ] `PresubmitCheck` documents in Firestore can store a `buildNumber`. -- [ ] `PresubmitCheckResponse` JSON includes a `buildNumber` field when available. +- [ ] `PresubmitJobState` includes a `buildNumber` field. +- [ ] `PresubmitJob` documents in Firestore can store a `buildNumber`. +- [ ] `PresubmitJobResponse` JSON includes a `buildNumber` field when available. - [ ] When a `check_run` completes, the `buildNumber` is correctly retrieved and stored. - [ ] Existing check runs without a build number continue to work (field is null). diff --git a/conductor/archive/get_presubmit_check_20260205/metadata.json b/conductor/archive/get_presubmit_check_20260205/metadata.json deleted file mode 100644 index e813305c3..000000000 --- a/conductor/archive/get_presubmit_check_20260205/metadata.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "track_id": "get_presubmit_checks_20260205", - "type": "feature", - "status": "new", - "created_at": "2026-02-05T10:00:00Z", - "updated_at": "2026-02-05T10:00:00Z", - "description": "Implement get presubmit check api to show check details on dashboard" -} diff --git a/conductor/archive/get_presubmit_guard_20260204/spec.md b/conductor/archive/get_presubmit_guard_20260204/spec.md index b87273838..ce639eb5a 100644 --- a/conductor/archive/get_presubmit_guard_20260204/spec.md +++ b/conductor/archive/get_presubmit_guard_20260204/spec.md @@ -1,10 +1,10 @@ # Specification: Implement get presubmit guard api ## Overview -This track involves implementing a new backend API endpoint in the `app_dart` service to serve real-time presubmit check statuses (based on the `PresubmitGuard` entity) to the Cocoon dashboard. The dashboard needs to display the progress and results of various validation stages for active pull requests to provide developers with actionable visibility into their PR health. +This track involves implementing a new backend API endpoint in the `app_dart` service to serve real-time presubmit job statuses (based on the `PresubmitGuard` entity) to the Cocoon dashboard. The dashboard needs to display the progress and results of various validation stages for active pull requests to provide developers with actionable visibility into their PR health. ## User Stories -As a Flutter developer, I want to see the real-time status of my PR's presubmit checks on the Cocoon dashboard so that I can quickly identify and address failures without navigating through multiple GitHub or LUCI pages. +As a Flutter developer, I want to see the real-time status of my PR's presubmit jobs on the Cocoon dashboard so that I can quickly identify and address failures without navigating through multiple GitHub or LUCI pages. ## Functional Requirements 1. **New API Endpoint:** Create an authenticated GET endpoint in `app_dart` (e.g., `/api/public/get-presubmit-guard`). diff --git a/conductor/archive/get_presubmit_check_20260205/index.md b/conductor/archive/get_presubmit_job_20260205/index.md similarity index 67% rename from conductor/archive/get_presubmit_check_20260205/index.md rename to conductor/archive/get_presubmit_job_20260205/index.md index d40d210ff..d15f20d1f 100644 --- a/conductor/archive/get_presubmit_check_20260205/index.md +++ b/conductor/archive/get_presubmit_job_20260205/index.md @@ -1,4 +1,4 @@ -# Track get_presubmit_checks_20260205 Context +# Track get_presubmit_jobs_20260205 Context - [Specification](./spec.md) - [Implementation Plan](./plan.md) diff --git a/conductor/archive/get_presubmit_job_20260205/metadata.json b/conductor/archive/get_presubmit_job_20260205/metadata.json new file mode 100644 index 000000000..9ce365f35 --- /dev/null +++ b/conductor/archive/get_presubmit_job_20260205/metadata.json @@ -0,0 +1,8 @@ +{ + "track_id": "get_presubmit_jobs_20260205", + "type": "feature", + "status": "new", + "created_at": "2026-02-05T10:00:00Z", + "updated_at": "2026-02-05T10:00:00Z", + "description": "Implement get presubmit job api to show job details on dashboard" +} \ No newline at end of file diff --git a/conductor/archive/get_presubmit_check_20260205/plan.md b/conductor/archive/get_presubmit_job_20260205/plan.md similarity index 63% rename from conductor/archive/get_presubmit_check_20260205/plan.md rename to conductor/archive/get_presubmit_job_20260205/plan.md index 6d003f2cc..d8dc0166b 100644 --- a/conductor/archive/get_presubmit_check_20260205/plan.md +++ b/conductor/archive/get_presubmit_job_20260205/plan.md @@ -1,9 +1,9 @@ -# Implementation Plan: Presubmit Check Details API +# Implementation Plan: Presubmit Job Details API ## Phase 1: RPC Models -- [x] Task: Create `PresubmitCheck` RPC model - - [x] Create `packages/cocoon_common/lib/src/rpc_model/presubmit_check.dart` - - [x] Define `PresubmitCheck` with `JsonSerializable` and fields: `attemptNumber`, `taskName`, `creationTime`, `startTime`, `endTime`, `status`, `summary` +- [x] Task: Create `PresubmitJob` RPC model + - [x] Create `packages/cocoon_common/lib/src/rpc_model/presubmit_job.dart` + - [x] Define `PresubmitJob` with `JsonSerializable` and fields: `attemptNumber`, `taskName`, `creationTime`, `startTime`, `endTime`, `status`, `summary` - [x] Export in `packages/cocoon_common/lib/rpc_model.dart` - [x] Task: Generate JSON serialization code - [x] `dart run build_runner build` in `packages/cocoon_common` @@ -11,12 +11,12 @@ ## Phase 2: Backend Logic & API Handler - [x] Task: Update `UnifiedCheckRun` with retrieval method - - [x] Add `static Future> getPresubmitCheckDetails(...)` to `app_dart/lib/src/service/firestore/unified_check_run.dart` - - [x] Ensure it uses the existing `_queryPresubmitChecks` method -- [x] Task: Create `GetPresubmitChecks` RequestHandler - - [x] Create `app_dart/lib/src/request_handlers/get_presubmit_checks.dart` - - [x] Implement parameter validation (mandatory `check_run_id`, `build_name`) - - [x] Use `UnifiedCheckRun.getPresubmitCheckDetails` to fetch data + - [x] Add `static Future> getPresubmitJobDetails(...)` to `app_dart/lib/src/service/firestore/unified_check_run.dart` + - [x] Ensure it uses the existing `_queryPresubmitJobs` method +- [x] Task: Create `GetPresubmitJobs` RequestHandler + - [x] Create `app_dart/lib/src/request_handlers/get_presubmit_jobs.dart` + - [x] Implement parameter validation (mandatory `check_run_id`, `job_name`) + - [x] Use `UnifiedCheckRun.getPresubmitJobDetails` to fetch data - [x] Map Firestore models to RPC models and sort by `attemptNumber` ascending - [x] Return top-level JSON array - [x] Task: Conductor - User Manual Verification 'Phase 2: Backend Logic & API Handler' (Protocol in workflow.md) @@ -27,6 +27,6 @@ ## Phase 4: Quality Assurance - [x] Task: Write unit tests - - [x] Create `app_dart/test/request_handlers/get_presubmit_checks_test.dart` + - [x] Create `app_dart/test/request_handlers/get_presubmit_jobs_test.dart` - [x] Test success and error cases (400, 404) - [x] Task: Conductor - User Manual Verification 'Phase 4: Quality Assurance' (Protocol in workflow.md) diff --git a/conductor/archive/get_presubmit_check_20260205/spec.md b/conductor/archive/get_presubmit_job_20260205/spec.md similarity index 57% rename from conductor/archive/get_presubmit_check_20260205/spec.md rename to conductor/archive/get_presubmit_job_20260205/spec.md index 6c422a409..476f33947 100644 --- a/conductor/archive/get_presubmit_check_20260205/spec.md +++ b/conductor/archive/get_presubmit_job_20260205/spec.md @@ -1,22 +1,22 @@ -# Specification: Presubmit Check Details API +# Specification: Presubmit Job Details API ## Overview -This track involves implementing a new API endpoint in the `app_dart` backend service to provide detailed information about a specific presubmit check. The dashboard will use this API to display the history and status of all checks for a given check run. +This track involves implementing a new API endpoint in the `app_dart` backend service to provide detailed information about a specific presubmit job. The dashboard will use this API to display the history and status of all jobs for a given check run. ## Functional Requirements -- **Endpoint:** `/api/public/get-presubmit-checks` +- **Endpoint:** `/api/public/get-presubmit-jobs` - **Method:** GET - **Parameters (Mandatory):** - `check_run_id`: The unique identifier for the GitHub Check Run. - - `check_name`: The name of the check (e.g., "Linux Device Doctor"). + - `job_name`: The name of the job (e.g., "Linux Device Doctor"). - **Backend Service:** `app_dart`. - **Data Source:** Firestore. - **Response Format:** JSON (Top-level array). - **Response Data:** - - An array of `PresubmitCheckResponse` objects, sorted in descending order by `attempt_number`. - - Each `PresubmitCheckResponse` object MUST contain: + - An array of `PresubmitJobResponse` objects, sorted in descending order by `attempt_number`. + - Each `PresubmitJobResponse` object MUST contain: - `attempt_number`: Integer - - `build_name`: String + - `job_name`: String - `creation_time`: Timestamp (ISO 8601 or ms since epoch) - `start_time`: Timestamp - `end_time`: Timestamp @@ -25,4 +25,4 @@ This track involves implementing a new API endpoint in the `app_dart` backend se ## Error Handling - **400 Bad Request:** Returned if mandatory parameters are missing. -- **404 Not Found:** Returned if the check or its check history is not found. +- **404 Not Found:** Returned if the job or its job history is not found. diff --git a/conductor/archive/presubmit_view_20260209/plan.md b/conductor/archive/presubmit_view_20260209/plan.md index 1470681fc..b91cdf316 100644 --- a/conductor/archive/presubmit_view_20260209/plan.md +++ b/conductor/archive/presubmit_view_20260209/plan.md @@ -1,12 +1,12 @@ # Implementation Plan - Pull Request Detailed View ## Phase 1: Infrastructure & Data Model [checkpoint: 085b744] -- [x] Task: Define the `PresubmitGuardResponse` and `PresubmitCheckResponse` models. (3c968d9) +- [x] Task: Define the `PresubmitGuardResponse` and `PresubmitJobResponse` models. (3c968d9) - [x] Write Tests: Create unit tests for the new models, ensuring correct JSON deserialization based on the Cocoon API structure. (3c968d9) - [x] Implement: Reuse model classes from `cocoon_common`. (3c968d9) - [x] Task: Integrate the new endpoints into `CocoonService`. (3c968d9) - - [x] Write Tests: Mock the `/dashboard/api/public/get-presubmit-guard` and `/dashboard/api/public/get-presubmit-checks` endpoints and verify the service correctly fetches and parses the data. (3c968d9) - - [x] Implement: Add `fetchPresubmitGuard` and `fetchPresubmitCheckDetails` methods to `CocoonService` and its implementations. (3c968d9) + - [x] Write Tests: Mock the `/dashboard/api/public/get-presubmit-guard` and `/dashboard/api/public/get-presubmit-jobs` endpoints and verify the service correctly fetches and parses the data. (3c968d9) + - [x] Implement: Add `fetchPresubmitGuard` and `fetchPresubmitJobDetails` methods to `CocoonService` and its implementations. (3c968d9) - [x] Task: Conductor - User Manual Verification 'Phase 1: Infrastructure & Data Model' (Protocol in workflow.md) (085b744) ## Phase 2: UI Implementation - Sidebar & Header [checkpoint: a498231] diff --git a/conductor/archive/presubmit_view_20260209/spec.md b/conductor/archive/presubmit_view_20260209/spec.md index 0a9cb6181..2e2cc80d6 100644 --- a/conductor/archive/presubmit_view_20260209/spec.md +++ b/conductor/archive/presubmit_view_20260209/spec.md @@ -23,9 +23,9 @@ Implement a detailed monitoring view for a specific Pull Request (PR) in the Flu - **Log Viewer Pane:** - Display the "Execution Log" for the selected check in the sidebar. - For the functional `sha` route, fetch the check details using the Cocoon API: - `GET /api/public/get-presubmit-checks?check_run_id=&build_name=` + `GET /api/public/get-presubmit-jobs?check_run_id=&job_name=` - **Handling Multiple Attempts (Tabs):** - - If the API returns multiple `PresubmitCheckResponse` objects for a build, display them as tabs in the log viewer (as shown in the layout). + - If the API returns multiple `PresubmitJobResponse` objects for a build, display them as tabs in the log viewer (as shown in the layout). - **Tab Naming:** Use the `attemptNumber` prefixed with a hash as the tab label (e.g., `#1`, `#2`). - Selecting a tab displays the `summary` or log content from that specific attempt. - Include a link to view details on the external LUCI UI. @@ -40,7 +40,7 @@ Implement a detailed monitoring view for a specific Pull Request (PR) in the Flu ## Acceptance Criteria - [ ] Navigating to `?repo=flutter&sha=` correctly calls the `/api/public/get-presubmit-guard` endpoint and renders the sidebar. - [ ] Navigating to `?repo=flutter&pr=` displays the mocked dashboard layout. -- [ ] Selecting a check in the sidebar correctly calls the `/api/public/get-presubmit-checks` endpoint (for functional SHA routes). +- [ ] Selecting a check in the sidebar correctly calls the `/api/public/get-presubmit-jobs` endpoint (for functional SHA routes). - [ ] Multiple attempts for a check are displayed as clickable tabs labeled by their attempt number. - [ ] The UI supports both Light and Dark modes. diff --git a/conductor/archive/public_presubmit_apis_20260226/metadata.json b/conductor/archive/public_presubmit_apis_20260226/metadata.json index 4bb7fbd29..43a43b5ac 100644 --- a/conductor/archive/public_presubmit_apis_20260226/metadata.json +++ b/conductor/archive/public_presubmit_apis_20260226/metadata.json @@ -4,5 +4,5 @@ "status": "new", "created_at": "2026-02-26T14:30:00Z", "updated_at": "2026-02-26T14:30:00Z", - "description": "Make presubmit get api public. Refactor ApiRequestHandler to extend a new PublicApiRequestHandler and update GetPresubmitChecks, GetPresubmitGuardSummaries and GetPresubmitGuard to inherit from it." + "description": "Make presubmit get api public. Refactor ApiRequestHandler to extend a new PublicApiRequestHandler and update GetPresubmitJobs, GetPresubmitGuardSummaries and GetPresubmitGuard to inherit from it." } diff --git a/conductor/archive/public_presubmit_apis_20260226/plan.md b/conductor/archive/public_presubmit_apis_20260226/plan.md index 5d4124ff8..48f99393d 100644 --- a/conductor/archive/public_presubmit_apis_20260226/plan.md +++ b/conductor/archive/public_presubmit_apis_20260226/plan.md @@ -20,10 +20,10 @@ This phase focuses on introducing the `PublicApiRequestHandler` and refactoring ## Phase 2: Expose Target APIs Publicly [checkpoint: 4c366bf] This phase transitions the specified handlers to `PublicApiRequestHandler`. -- [x] Task: Refactor `GetPresubmitChecks` - - [x] Update `app_dart/lib/src/request_handlers/get_presubmit_checks.dart` to extend `PublicApiRequestHandler`. +- [x] Task: Refactor `GetPresubmitJobs` + - [x] Update `app_dart/lib/src/request_handlers/get_presubmit_jobs.dart` to extend `PublicApiRequestHandler`. - [x] Remove `authenticationProvider` from the constructor and `super` call. - - [x] Update tests in `app_dart/test/request_handlers/get_presubmit_checks_test.dart` to reflect constructor changes. + - [x] Update tests in `app_dart/test/request_handlers/get_presubmit_jobs_test.dart` to reflect constructor changes. - [x] Task: Refactor `GetPresubmitGuardSummaries` - [x] Update `app_dart/lib/src/request_handlers/get_presubmit_guard_summaries.dart` to extend `PublicApiRequestHandler`. - [x] Remove `authenticationProvider` from the constructor and `super` call. diff --git a/conductor/archive/public_presubmit_apis_20260226/spec.md b/conductor/archive/public_presubmit_apis_20260226/spec.md index e2b879d17..664754364 100644 --- a/conductor/archive/public_presubmit_apis_20260226/spec.md +++ b/conductor/archive/public_presubmit_apis_20260226/spec.md @@ -12,7 +12,7 @@ This track aims to make certain presubmit-related APIs public by refactoring the * Retain authentication logic and `authContext` access within `ApiRequestHandler`. 3. **Expose APIs Publicly**: * Update the following handlers to extend `PublicApiRequestHandler` instead of `ApiRequestHandler`: - * `GetPresubmitChecks` + * `GetPresubmitJobs` * `GetPresubmitGuardSummaries` * `GetPresubmitGuard` * Remove the `authenticationProvider` requirement from their constructors. @@ -23,7 +23,7 @@ This track aims to make certain presubmit-related APIs public by refactoring the ## Acceptance Criteria 1. `PublicApiRequestHandler` is correctly implemented and used as a base for `ApiRequestHandler`. -2. `GetPresubmitChecks`, `GetPresubmitGuardSummaries`, and `GetPresubmitGuard` no longer require authentication to be called. +2. `GetPresubmitJobs`, `GetPresubmitGuardSummaries`, and `GetPresubmitGuard` no longer require authentication to be called. 3. Existing unit tests for these handlers pass (with adjustments to the constructor/setup where necessary). 4. New tests verify that these APIs are accessible without an authentication token. 5. **Code Quality**: Running `dart format --set-exit-if-changed .` and `dart analyze --fatal-infos .` in `app_dart` results in no warnings or formatting issues. diff --git a/conductor/archive/rerun_failed_jobs_api_20260227/plan.md b/conductor/archive/rerun_failed_jobs_api_20260227/plan.md index 705ce2024..36f884d23 100644 --- a/conductor/archive/rerun_failed_jobs_api_20260227/plan.md +++ b/conductor/archive/rerun_failed_jobs_api_20260227/plan.md @@ -2,7 +2,7 @@ ## Phase 1: Research & Discovery [checkpoint: 41c1531] - [x] Task: Analyze `LuciBuildService` and `BuildBucketClient` in `app_dart/lib/src/service` to identify re-run capabilities. -- [x] Task: Research `unified_check_run.dart` and `GetPresubmitChecks` handler to understand how jobs are linked to `check_run_id`. +- [x] Task: Research `unified_check_run.dart` and `GetPresubmitJobs` handler to understand how jobs are linked to `check_run_id`. - [x] Task: Identify the appropriate method for GitHub write access verification (check existing `app_dart` patterns). - [x] Task: Conductor - User Manual Verification 'Research & Discovery' (Protocol in workflow.md) diff --git a/conductor/archive/unified_checkrun_20260303/plan.md b/conductor/archive/unified_checkrun_20260303/plan.md index b62212047..7a74fa599 100644 --- a/conductor/archive/unified_checkrun_20260303/plan.md +++ b/conductor/archive/unified_checkrun_20260303/plan.md @@ -1,39 +1,39 @@ -# Implementation Plan: Unified Checkrun API and PresubmitCheck Model Update +# Implementation Plan: Unified Checkrun API and PresubmitJob Model Update -This plan outlines the steps to add a `slug` field to the `PresubmitCheck` model, update the `GetPresubmitChecks` and `GetPresubmitGuard` APIs to use standardized `owner` and `repo` parameters, and update the Flutter dashboard to use these new APIs. +This plan outlines the steps to add a `slug` field to the `PresubmitJob` model, update the `GetPresubmitJobs` and `GetPresubmitGuard` APIs to use standardized `owner` and `repo` parameters, and update the Flutter dashboard to use these new APIs. ## Phase 1: Model Update (app_dart) [checkpoint: 3c65563] -In this phase, we update the `PresubmitCheck` model and the `UnifiedCheckRun` service to include the `slug` field. +In this phase, we update the `PresubmitJob` model and the `UnifiedCheckRun` service to include the `slug` field. -- [x] Task: Update `PresubmitCheckId` in `app_dart/lib/src/model/firestore/presubmit_check.dart` +- [x] Task: Update `PresubmitJobId` in `app_dart/lib/src/model/firestore/presubmit_job.dart` - [x] Add `RepositorySlug slug` field. - [x] Update `documentId` to format: `owner_repo_checkRunId_buildName_attemptNumber`. - [x] Update `tryParse` to handle the new format. -- [x] Task: Update `PresubmitCheck` in `app_dart/lib/src/model/firestore/presubmit_check.dart` +- [x] Task: Update `PresubmitJob` in `app_dart/lib/src/model/firestore/presubmit_job.dart` - [x] Add `fieldSlug` constant. - - [x] Update factory constructors (`PresubmitCheck`, `PresubmitCheck.init`) to accept and store `slug`. + - [x] Update factory constructors (`PresubmitJob`, `PresubmitJob.init`) to accept and store `slug`. - [x] Add `slug` getter. - [x] Task: Update `UnifiedCheckRun` in `app_dart/lib/src/service/firestore/unified_check_run.dart` - - [x] Update `initializeCiStagingDocument` to pass `slug` to `PresubmitCheck.init`. - - [x] Update `reInitializeFailedChecks` to pass `slug` to `PresubmitCheck.init`. - - [x] Update `_queryPresubmitChecks` to optionally filter by `slug`. - - [x] Update `markConclusion` to handle the new `PresubmitCheckId` format (needs `slug` from `guardId`). -- [x] Task: Update `PresubmitCheck` tests - - [x] Update `app_dart/test/model/firestore/presubmit_check_test.dart` to cover the new `slug` field and `documentId` format. + - [x] Update `initializeCiStagingDocument` to pass `slug` to `PresubmitJob.init`. + - [x] Update `reInitializeFailedChecks` to pass `slug` to `PresubmitJob.init`. + - [x] Update `_queryPresubmitJobs` to optionally filter by `slug`. + - [x] Update `markConclusion` to handle the new `PresubmitJobId` format (needs `slug` from `guardId`). +- [x] Task: Update `PresubmitJob` tests + - [x] Update `app_dart/test/model/firestore/presubmit_job_test.dart` to cover the new `slug` field and `documentId` format. - [ ] Task: Conductor - User Manual Verification 'Phase 1: Model Update' (Protocol in workflow.md) ## Phase 2: Backend API Update (app_dart) In this phase, we update the request handlers to use the standardized `owner` and `repo` parameters. -- [x] Task: Update `GetPresubmitChecks` in `app_dart/lib/src/request_handlers/get_presubmit_checks.dart` +- [x] Task: Update `GetPresubmitJobs` in `app_dart/lib/src/request_handlers/get_presubmit_jobs.dart` - [x] Add `kOwnerParam` and `kRepoParam`. - [x] Update `get` method to parse these parameters (default `owner` to 'flutter'). - - [x] Update call to `UnifiedCheckRun.getPresubmitCheckDetails` to include `slug` if possible (may need to update `getPresubmitCheckDetails` signature). + - [x] Update call to `UnifiedCheckRun.getPresubmitJobDetails` to include `slug` if possible (may need to update `getPresubmitJobDetails` signature). - [x] Task: Update `GetPresubmitGuard` in `app_dart/lib/src/request_handlers/get_presubmit_guard.dart` - [x] Replace `kSlugParam` with `kOwnerParam` and `kRepoParam`. - [x] Update `get` method to parse `owner` and `repo` and construct a `RepositorySlug`. - [x] Task: Update Backend API tests - - [x] Update `app_dart/test/request_handlers/get_presubmit_checks_test.dart`. + - [x] Update `app_dart/test/request_handlers/get_presubmit_jobs_test.dart`. - [x] Update `app_dart/test/request_handlers/get_presubmit_guard_test.dart`. - [ ] Task: Conductor - User Manual Verification 'Phase 2: Backend API Update' (Protocol in workflow.md) @@ -43,7 +43,7 @@ In this phase, we update the dashboard service and state to use the new API sign - [x] Task: Update `AppEngineCocoonService` in `dashboard/lib/service/appengine_cocoon.dart` - [x] Update `fetchPresubmitGuard` to pass `owner` and `repo` instead of `slug`. - - [x] Update `fetchPresubmitCheckDetails` to pass `owner` and `repo`. + - [x] Update `fetchPresubmitJobDetails` to pass `owner` and `repo`. - [x] Task: Update `PresubmitState` in `dashboard/lib/state/presubmit.dart` - [x] Ensure `fetchCheckDetails` and `fetchGuardStatus` pass the required parameters. - [x] Task: Update Frontend tests diff --git a/conductor/archive/unified_checkrun_20260303/spec.md b/conductor/archive/unified_checkrun_20260303/spec.md index eb2134edd..2977b4035 100644 --- a/conductor/archive/unified_checkrun_20260303/spec.md +++ b/conductor/archive/unified_checkrun_20260303/spec.md @@ -1,19 +1,19 @@ -# Specification: Unified Checkrun API and PresubmitCheck Model Update +# Specification: Unified Checkrun API and PresubmitJob Model Update ## Overview This track involves two main objectives: -1. **Model Enhancement:** Add a `slug` field to the `PresubmitCheck` model in `app_dart`, aligning it with the `PresubmitGuard` model. -2. **API Unification:** Standardize the query parameters for `GetPresubmitChecks` and `GetPresubmitGuard` request handlers to use `owner` and `repo`, and update the `dashboard` frontend accordingly. +1. **Model Enhancement:** Add a `slug` field to the `PresubmitJob` model in `app_dart`, aligning it with the `PresubmitGuard` model. +2. **API Unification:** Standardize the query parameters for `GetPresubmitJobs` and `GetPresubmitGuard` request handlers to use `owner` and `repo`, and update the `dashboard` frontend accordingly. ## Functional Requirements ### Backend (app_dart) -1. **`PresubmitCheck` Model Update:** - - Update `PresubmitCheckId` to include `RepositorySlug slug`. - - Update `PresubmitCheckId.documentId` to include the slug (format: `owner_repo_checkRunId_buildName_attemptNumber`). - - Add `fieldSlug` to `PresubmitCheck` and update the factory/constructor to handle it. -2. **`GetPresubmitChecks` API Update:** +1. **`PresubmitJob` Model Update:** + - Update `PresubmitJobId` to include `RepositorySlug slug`. + - Update `PresubmitJobId.documentId` to include the slug (format: `owner_repo_checkRunId_buildName_attemptNumber`). + - Add `fieldSlug` to `PresubmitJob` and update the factory/constructor to handle it. +2. **`GetPresubmitJobs` API Update:** - Add `owner` and `repo` as query parameters. - - Update the handler to use these parameters (e.g., to reconstruct the slug for the updated `PresubmitCheck` model). + - Update the handler to use these parameters (e.g., to reconstruct the slug for the updated `PresubmitJob` model). 3. **`GetPresubmitGuard` API Update:** - Replace the `slug` query parameter with `owner` and `repo`. - Standardize on `owner` and `repo` for identifying the repository. @@ -23,15 +23,15 @@ This track involves two main objectives: 2. **State Update:** Ensure `PresubmitState` (`dashboard/lib/state/presubmit.dart`) correctly provides these parameters. ## Non-Functional Requirements -- **Data Migration:** Be aware that changing `PresubmitCheckId.documentId` will change the Firestore document paths. Ensure this is acceptable or handle backward compatibility if existing data must be preserved. +- **Data Migration:** Be aware that changing `PresubmitJobId.documentId` will change the Firestore document paths. Ensure this is acceptable or handle backward compatibility if existing data must be preserved. - **TDD:** Write unit tests for the model changes and the updated request handlers. - **Coverage:** Maintain >95% code coverage for all modified files. ## Acceptance Criteria -- `PresubmitCheck` documents in Firestore now include a `slug` field. -- `GetPresubmitChecks` successfully retrieves data using `owner`, `repo`, `check_run_id`, and `build_name`. +- `PresubmitJob` documents in Firestore now include a `slug` field. +- `GetPresubmitJobs` successfully retrieves data using `owner`, `repo`, `check_run_id`, and `job_name`. - `GetPresubmitGuard` successfully retrieves data using `owner`, `repo`, and `sha`. - Dashboard correctly displays presubmit information using the new API signatures. ## Out of Scope -- Migrating existing `PresubmitCheck` documents in Firestore (this track focuses on the code changes and new entries). +- Migrating existing `PresubmitJob` documents in Firestore (this track focuses on the code changes and new entries). diff --git a/conductor/product.md b/conductor/product.md index a0f63c08f..b320eb6c6 100644 --- a/conductor/product.md +++ b/conductor/product.md @@ -17,10 +17,10 @@ Cocoon is the CI coordination and orchestration system for the Flutter project. ## Key Features * **Offline Integration Testing:** A dedicated testing environment that simulates all backend services (GitHub, Firestore, BigQuery, LUCI) with functional fakes, enabling deterministic, offline verification of frontend and backend logic. * **Tree Status Dashboard:** A Flutter-based web application that provides a visual overview of build health across various commits and branches. -* **Presubmit Check Details:** Backend APIs to retrieve detailed attempt history and status for specific presubmit checks, aiding in debugging and visibility. -* **Presubmit Guard Summaries:** Backend APIs to retrieve summaries of all presubmit checks (Presubmit Guards) of the provided pull request to the dashboard. +* **Presubmit Job Details:** Backend APIs to retrieve detailed attempt history and status for specific presubmit jobs, aiding in debugging and visibility. +* **Presubmit Guard Summaries:** Backend APIs to retrieve summaries of all presubmit jobs (Presubmit Guards) of the provided pull request to the dashboard. * **Presubmit Dashboard Filtering:** Interactive filtering for the Presubmit Dashboard, allowing users to narrow down visible jobs by status, platform, and regex. Filters persist within a session and automatically manage valid job selection for the details pane. -* **Presubmit Guard Details:** Displays detailed information and CI check statuses for a specific presubmit check (Presubmit Guard), sorted by status (prioritizing failures) and name for better visibility. Authenticated users can trigger re-runs for individual jobs or all failed jobs directly from the dashboard. +* **Presubmit Guard Details:** Displays detailed information and CI job statuses for a specific presubmit job (Presubmit Guard), sorted by status (prioritizing failures) and name for better visibility. Authenticated users can trigger re-runs for individual jobs or all failed jobs directly from the dashboard. * **Merge Queue Visibility:** APIs for querying and inspecting recent GitHub Merge Queue webhook events to diagnose integration issues. * **Auto-submit Bot:** Handles automated pull request management, including label-based merges, reverts, and validation checks. * **GitHub Integration:** Robust handling of GitHub webhooks to sync commits, manage check runs, and report build statuses back to PRs. diff --git a/dashboard/lib/service/appengine_cocoon.dart b/dashboard/lib/service/appengine_cocoon.dart index d1a9c7c8e..38a63059c 100644 --- a/dashboard/lib/service/appengine_cocoon.dart +++ b/dashboard/lib/service/appengine_cocoon.dart @@ -343,21 +343,20 @@ class AppEngineCocoonService implements CocoonService { } @override - Future>> - fetchPresubmitCheckDetails({ + Future>> fetchPresubmitJobDetails({ required int checkRunId, - required String buildName, + required String jobName, String repo = 'flutter', String owner = 'flutter', }) async { final queryParameters = { 'check_run_id': checkRunId.toString(), - 'build_name': buildName, + 'job_name': jobName, 'repo': repo, 'owner': owner, }; final getChecksUrl = apiEndpoint( - '/api/public/get-presubmit-checks', + '/api/public/get-presubmit-jobs', queryParameters: queryParameters, ); @@ -365,7 +364,7 @@ class AppEngineCocoonService implements CocoonService { if (response.statusCode != HttpStatus.ok) { return CocoonResponse.error( - '/api/public/get-presubmit-checks returned ${response.statusCode}', + '/api/public/get-presubmit-jobs returned ${response.statusCode}', statusCode: response.statusCode, ); } @@ -375,7 +374,7 @@ class AppEngineCocoonService implements CocoonService { return CocoonResponse.data( jsonResponse .cast>() - .map(PresubmitCheckResponse.fromJson) + .map(PresubmitJobResponse.fromJson) .toList(), ); } catch (error) { @@ -522,7 +521,7 @@ class AppEngineCocoonService implements CocoonService { required String? idToken, required String repo, required int pr, - required String buildName, + required String jobName, String owner = 'flutter', }) async { if (idToken == null || idToken.isEmpty) { @@ -540,7 +539,7 @@ class AppEngineCocoonService implements CocoonService { 'owner': owner, 'repo': repo, 'pr': pr, - 'build_name': buildName, + 'job_name': jobName, }), ); diff --git a/dashboard/lib/service/cocoon.dart b/dashboard/lib/service/cocoon.dart index d4cbbc702..11e1c5db6 100644 --- a/dashboard/lib/service/cocoon.dart +++ b/dashboard/lib/service/cocoon.dart @@ -73,12 +73,12 @@ abstract class CocoonService { required String branch, }); - /// Schedule the provided failed [buildName] to be re-run for the given [pr]. + /// Schedule the provided failed [jobName] to be re-run for the given [pr]. Future> rerunFailedJob({ required String? idToken, required String repo, required int pr, - required String buildName, + required String jobName, String owner = 'flutter', }); @@ -142,10 +142,9 @@ abstract class CocoonService { }); /// Gets the details for a specific presubmit check. - Future>> - fetchPresubmitCheckDetails({ + Future>> fetchPresubmitJobDetails({ required int checkRunId, - required String buildName, + required String jobName, String repo = 'flutter', String owner = 'flutter', }); diff --git a/dashboard/lib/service/data_seeder.dart b/dashboard/lib/service/data_seeder.dart index e81c885fe..0b0352c2a 100644 --- a/dashboard/lib/service/data_seeder.dart +++ b/dashboard/lib/service/data_seeder.dart @@ -50,18 +50,18 @@ class DataSeeder { void _seedPresubmitData(DateTime now) { final guards = []; - final checks = []; + final checks = []; // cafe5_1_mock_sha final prNum = 1234; var checkRunId = 123456; var creationTime = 1770000000000; - final engineBuilds = [ + final enginejobs = [ 'Mac mac_host_engine', 'Mac mac_ios_engine', 'Linux linux_android_aot_engine', ]; - final fusionBuilds = [ + final fusionjobs = [ 'Linux framework_tests', 'Mac framework_tests', 'Linux android framework_tests', @@ -73,23 +73,23 @@ class DataSeeder { 'Linux_android_emu android views', ]; var engineChecks = [ - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: engineBuilds[0], + jobName: enginejobs[0], status: TaskStatus.failed, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: engineBuilds[1], + jobName: enginejobs[1], status: TaskStatus.cancelled, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: engineBuilds[2], + jobName: enginejobs[2], status: TaskStatus.infraFailure, attemptNumber: 1, creationTime: creationTime, @@ -98,13 +98,13 @@ class DataSeeder { guards.add( _createPresubmitGuard( - commitSha: 'cafe5_1_mock_sha', + headSha: 'cafe5_1_mock_sha', checkRunId: checkRunId, - pullRequestId: prNum, + prNum: prNum, author: _authors[0], stage: CiStage.fusionEngineBuild, creationTime: creationTime, - builds: {for (var check in engineChecks) check.buildName: check.status}, + jobs: {for (var check in engineChecks) check.jobName: check.status}, ), ); checks.addAll(engineChecks); @@ -113,23 +113,23 @@ class DataSeeder { checkRunId = 234567; creationTime = creationTime + 100000; engineChecks = [ - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: engineBuilds[0], + jobName: enginejobs[0], status: TaskStatus.succeeded, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: engineBuilds[1], + jobName: enginejobs[1], status: TaskStatus.skipped, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: engineBuilds[2], + jobName: enginejobs[2], status: TaskStatus.succeeded, attemptNumber: 1, creationTime: creationTime, @@ -137,42 +137,42 @@ class DataSeeder { ]; guards.add( _createPresubmitGuard( - commitSha: 'face5_2_mock_sha', + headSha: 'face5_2_mock_sha', checkRunId: checkRunId, - pullRequestId: prNum, + prNum: prNum, author: _authors[1], stage: CiStage.fusionEngineBuild, creationTime: creationTime, - builds: _getLatestBuildStatuses(engineChecks), + jobs: _getLatestjobstatuses(engineChecks), ), ); checks.addAll(engineChecks); creationTime = creationTime + 100000; var fusionChecks = [ - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: fusionBuilds[0], + jobName: fusionjobs[0], status: TaskStatus.inProgress, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: fusionBuilds[1], + jobName: fusionjobs[1], status: TaskStatus.skipped, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: fusionBuilds[2], + jobName: fusionjobs[2], status: TaskStatus.succeeded, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: fusionBuilds[3], + jobName: fusionjobs[3], status: TaskStatus.succeeded, attemptNumber: 1, creationTime: creationTime, @@ -180,13 +180,13 @@ class DataSeeder { ]; guards.add( _createPresubmitGuard( - commitSha: 'face5_2_mock_sha', + headSha: 'face5_2_mock_sha', checkRunId: checkRunId, - pullRequestId: prNum, + prNum: prNum, author: _authors[1], stage: CiStage.fusionTests, creationTime: creationTime, - builds: _getLatestBuildStatuses(fusionChecks), + jobs: _getLatestjobstatuses(fusionChecks), ), ); checks.addAll(fusionChecks); @@ -195,23 +195,23 @@ class DataSeeder { checkRunId = 345678; creationTime = creationTime + 100000; engineChecks = [ - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: engineBuilds[0], + jobName: enginejobs[0], status: TaskStatus.succeeded, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: engineBuilds[1], + jobName: enginejobs[1], status: TaskStatus.skipped, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: engineBuilds[2], + jobName: enginejobs[2], status: TaskStatus.succeeded, attemptNumber: 1, creationTime: creationTime, @@ -219,50 +219,50 @@ class DataSeeder { ]; guards.add( _createPresubmitGuard( - commitSha: 'decaf_3_mock_sha', + headSha: 'decaf_3_mock_sha', checkRunId: checkRunId, - pullRequestId: prNum, + prNum: prNum, author: _authors[3], stage: CiStage.fusionEngineBuild, creationTime: creationTime, - builds: _getLatestBuildStatuses(engineChecks), + jobs: _getLatestjobstatuses(engineChecks), ), ); checks.addAll(engineChecks); creationTime = creationTime + 100000; var creationTime2 = creationTime + 100000; fusionChecks = [ - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: fusionBuilds[0], + jobName: fusionjobs[0], status: TaskStatus.failed, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: fusionBuilds[0], + jobName: fusionjobs[0], status: TaskStatus.succeeded, attemptNumber: 2, creationTime: creationTime2, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: fusionBuilds[1], + jobName: fusionjobs[1], status: TaskStatus.skipped, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: fusionBuilds[2], + jobName: fusionjobs[2], status: TaskStatus.succeeded, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: fusionBuilds[3], + jobName: fusionjobs[3], status: TaskStatus.succeeded, attemptNumber: 1, creationTime: creationTime, @@ -270,13 +270,13 @@ class DataSeeder { ]; guards.add( _createPresubmitGuard( - commitSha: 'decaf_3_mock_sha', + headSha: 'decaf_3_mock_sha', checkRunId: checkRunId, - pullRequestId: prNum, + prNum: prNum, author: _authors[3], stage: CiStage.fusionTests, creationTime: creationTime, - builds: _getLatestBuildStatuses(fusionChecks), + jobs: _getLatestjobstatuses(fusionChecks), ), ); checks.addAll(fusionChecks); @@ -285,23 +285,23 @@ class DataSeeder { checkRunId = 456789; creationTime = creationTime + 100000; engineChecks = [ - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: engineBuilds[0], + jobName: enginejobs[0], status: TaskStatus.succeeded, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: engineBuilds[1], + jobName: enginejobs[1], status: TaskStatus.skipped, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: engineBuilds[2], + jobName: enginejobs[2], status: TaskStatus.succeeded, attemptNumber: 1, creationTime: creationTime, @@ -309,92 +309,92 @@ class DataSeeder { ]; guards.add( _createPresubmitGuard( - commitSha: 'deafcab_mock_sha', + headSha: 'deafcab_mock_sha', checkRunId: checkRunId, - pullRequestId: prNum, + prNum: prNum, author: _authors[4], stage: CiStage.fusionEngineBuild, creationTime: creationTime, - builds: _getLatestBuildStatuses(engineChecks), + jobs: _getLatestjobstatuses(engineChecks), ), ); checks.addAll(engineChecks); creationTime = creationTime + 100000; creationTime2 = creationTime + 100000; fusionChecks = [ - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: fusionBuilds[0], + jobName: fusionjobs[0], status: TaskStatus.failed, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: fusionBuilds[0], + jobName: fusionjobs[0], status: TaskStatus.succeeded, attemptNumber: 2, creationTime: creationTime2, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: fusionBuilds[1], + jobName: fusionjobs[1], status: TaskStatus.cancelled, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: fusionBuilds[2], + jobName: fusionjobs[2], status: TaskStatus.infraFailure, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: fusionBuilds[3], + jobName: fusionjobs[3], status: TaskStatus.failed, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: fusionBuilds[3], + jobName: fusionjobs[3], status: TaskStatus.failed, attemptNumber: 2, creationTime: creationTime2, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: fusionBuilds[4], + jobName: fusionjobs[4], status: TaskStatus.neutral, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: fusionBuilds[5], + jobName: fusionjobs[5], status: TaskStatus.neutral, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: fusionBuilds[6], + jobName: fusionjobs[6], status: TaskStatus.neutral, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: fusionBuilds[7], + jobName: fusionjobs[7], status: TaskStatus.neutral, attemptNumber: 1, creationTime: creationTime, ), - _createPresubmitCheck( + _createPresubmitJob( checkRunId: checkRunId, - buildName: fusionBuilds[8], + jobName: fusionjobs[8], status: TaskStatus.neutral, attemptNumber: 1, creationTime: creationTime, @@ -402,13 +402,13 @@ class DataSeeder { ]; guards.add( _createPresubmitGuard( - commitSha: 'deafcab_mock_sha', + headSha: 'deafcab_mock_sha', checkRunId: checkRunId, - pullRequestId: prNum, + prNum: prNum, author: _authors[4], stage: CiStage.fusionTests, creationTime: creationTime, - builds: _getLatestBuildStatuses(fusionChecks), + jobs: _getLatestjobstatuses(fusionChecks), ), ); checks.addAll(fusionChecks); @@ -418,39 +418,35 @@ class DataSeeder { prCheckRuns.add(_createPrCheckRuns(guard)); } - // Add some checks with multiple attempts for testing fetchPresubmitCheckDetails + // Add some checks with multiple attempts for testing fetchPresubmitJobDetails _server.firestore.putDocuments(guards); _server.firestore.putDocuments(checks); _server.firestore.putDocuments(prCheckRuns); } - Map _getLatestBuildStatuses(List checks) { - final latestChecks = {}; + Map _getLatestjobstatuses(List checks) { + final latestChecks = {}; for (final check in checks) { - if (!latestChecks.containsKey(check.buildName) || - check.attemptNumber > latestChecks[check.buildName]!.attemptNumber) { - latestChecks[check.buildName] = check; + if (!latestChecks.containsKey(check.jobName) || + check.attemptNumber > latestChecks[check.jobName]!.attemptNumber) { + latestChecks[check.jobName] = check; } } - return { - for (var check in latestChecks.values) check.buildName: check.status, - }; + return {for (var check in latestChecks.values) check.jobName: check.status}; } PresubmitGuard _createPresubmitGuard({ - required String commitSha, + required String headSha, required int checkRunId, - required int pullRequestId, + required int prNum, required String author, required CiStage stage, required int creationTime, - required Map builds, + required Map jobs, }) { final slug = RepositorySlug('flutter', 'flutter'); - final failedBuilds = builds.values - .where((status) => status.isFailure) - .length; - final remainingBuilds = builds.values + final failedJobs = jobs.values.where((status) => status.isFailure).length; + final remainingJobs = jobs.values .where((status) => !status.isComplete) .length; @@ -460,48 +456,48 @@ class DataSeeder { name: 'Merge Queue Guard', startedAt: DateTime.fromMillisecondsSinceEpoch(creationTime), ), - commitSha: commitSha, + headSha: headSha, slug: slug, - pullRequestId: pullRequestId, + prNum: prNum, stage: stage, creationTime: creationTime, author: author, - remainingBuilds: remainingBuilds, - failedBuilds: failedBuilds, - builds: builds, + remainingJobs: remainingJobs, + failedJobs: failedJobs, + jobs: jobs, ); } - PresubmitCheck _createPresubmitCheck({ + PresubmitJob _createPresubmitJob({ required int checkRunId, - required String buildName, + required String jobName, required TaskStatus status, required int creationTime, int attemptNumber = 1, }) { - return PresubmitCheck( + return PresubmitJob( slug: RepositorySlug('flutter', 'flutter'), checkRunId: checkRunId, - buildName: buildName, + jobName: jobName, status: status, attemptNumber: attemptNumber, creationTime: creationTime, buildNumber: 1337 + attemptNumber, summary: switch (status) { .succeeded => - '[INFO] Starting task $buildName...\n[SUCCESS] All tests passed (452/452)', + '[INFO] Starting task $jobName...\n[SUCCESS] All tests passed (452/452)', .failed => - '[INFO] Starting task $buildName...\n[ERROR] Test failed: Dummy Tests', + '[INFO] Starting task $jobName...\n[ERROR] Test failed: Dummy Tests', .infraFailure => - '[INFO] Starting task $buildName...\n[ERROR] Infrastructure failure: Dummy Tests', + '[INFO] Starting task $jobName...\n[ERROR] Infrastructure failure: Dummy Tests', .cancelled => - '[INFO] Starting task $buildName...\n[ERROR] Test cancelled: Dummy Tests', - .inProgress => '[INFO] Starting task $buildName...', + '[INFO] Starting task $jobName...\n[ERROR] Test cancelled: Dummy Tests', + .inProgress => '[INFO] Starting task $jobName...', .waitingForBackfill => null, .skipped => - '[INFO] Starting task $buildName...\n[INFO] Test skipped: Dummy Tests', + '[INFO] Starting task $jobName...\n[INFO] Test skipped: Dummy Tests', .neutral => - '[INFO] Starting task $buildName...\n[INFO] Test neutral: Dummy Tests', + '[INFO] Starting task $jobName...\n[INFO] Test neutral: Dummy Tests', }, startTime: creationTime + 30000, endTime: creationTime + 60000, @@ -510,7 +506,7 @@ class DataSeeder { PrCheckRuns _createPrCheckRuns(PresubmitGuard guard) { final pr = PullRequest( - number: guard.pullRequestId, + number: guard.prNum, head: PullRequestHead( sha: guard.commitSha, repo: Repository( @@ -539,8 +535,8 @@ class DataSeeder { ..fields['Merge Queue Guard'] = guard.checkRun.id!.toString().toValue() ..name = docName; - for (final buildName in guard.builds.keys) { - prCheckRuns.fields[buildName] = '234567'.toString().toValue(); + for (final jobName in guard.jobs.keys) { + prCheckRuns.fields[jobName] = '234567'.toString().toValue(); } return prCheckRuns; @@ -637,7 +633,7 @@ class DataSeeder { final commitRandom = math.Random(commitTimestamp); // Generate a stable and unique SHA for each commit - final commitSha = _commitsSha[repo]![index]; + final headSha = _commitsSha[repo]![index]; final authorIndex = commitRandom.nextInt(_authors.length); final messageSeed = commitTimestamp % 37 + authorIndex; @@ -649,7 +645,7 @@ class DataSeeder { final commit = generateFirestoreCommit( index, - sha: commitSha, + sha: headSha, repo: repo, branch: branch, createTimestamp: commitTimestamp, @@ -673,7 +669,7 @@ class DataSeeder { index, i, commitRandom, - commitSha, + headSha, repo, ), ); diff --git a/dashboard/lib/state/presubmit.dart b/dashboard/lib/state/presubmit.dart index f9a9ee890..329f9893e 100644 --- a/dashboard/lib/state/presubmit.dart +++ b/dashboard/lib/state/presubmit.dart @@ -15,7 +15,7 @@ import '../service/firebase_auth.dart'; /// State for the Presubmit Dashboard. /// /// This state manages the data for a specific Pull Request (PR) or commit SHA, -/// including available SHAs, guard status, and individual check results. +/// including available SHAs, guard status, and individual job results. class PresubmitState extends ChangeNotifier { PresubmitState({ required this.cocoonService, @@ -43,11 +43,11 @@ class PresubmitState extends ChangeNotifier { /// Whether data is currently being fetched. bool get isLoading => - _isSummariesLoading || _isGuardLoading || _isChecksLoading; + _isSummariesLoading || _isGuardLoading || _isJobsLoading; bool _isSummariesLoading = false; bool _isGuardLoading = false; - bool _isChecksLoading = false; + bool _isJobsLoading = false; /// The full guard status response for the current [sha]. PresubmitGuardResponse? get guardResponse => _guardResponse; @@ -115,16 +115,16 @@ class PresubmitState extends ChangeNotifier { if (filtered == null || filtered.stages.isEmpty || filtered.stages.every((s) => s.builds.isEmpty)) { - _selectedCheck = null; - _checks = null; + _selectedJob = null; + _jobs = null; return; } // Check if current selection is still visible var isVisible = false; - if (_selectedCheck != null) { + if (_selectedJob != null) { for (final stage in filtered.stages) { - if (stage.builds.containsKey(_selectedCheck)) { + if (stage.builds.containsKey(_selectedJob)) { isVisible = true; break; } @@ -132,7 +132,7 @@ class PresubmitState extends ChangeNotifier { } if (!isVisible) { - // Select first available check based on UI sorting + // Select first available job based on UI sorting String? topMost; for (final stage in filtered.stages) { if (stage.builds.isNotEmpty) { @@ -143,10 +143,10 @@ class PresubmitState extends ChangeNotifier { } } - _selectedCheck = topMost; - _checks = null; - if (_selectedCheck != null) { - unawaited(fetchCheckDetails()); + _selectedJob = topMost; + _jobs = null; + if (_selectedJob != null) { + unawaited(fetchJobDetails()); } } } @@ -263,13 +263,13 @@ class PresubmitState extends ChangeNotifier { List get availableSummaries => _availableSummaries; List _availableSummaries = []; - /// The currently selected check name. - String? get selectedCheck => _selectedCheck; - String? _selectedCheck; + /// The currently selected job name. + String? get selectedJob => _selectedJob; + String? _selectedJob; - /// The checks/logs for the current [selectedCheck]. - List? get checks => _checks; - List? _checks; + /// The jobs/logs for the current [selectedJob]. + List? get jobs => _jobs; + List? _jobs; /// Track if we have already attempted to fetch summaries for the current [pr]. String? _lastFetchedPr; @@ -334,8 +334,8 @@ class PresubmitState extends ChangeNotifier { changed = true; _guardResponse = null; _lastFetchedSha = null; - _checks = null; - _selectedCheck = null; + _jobs = null; + _selectedJob = null; } if (changed) { @@ -359,13 +359,13 @@ class PresubmitState extends ChangeNotifier { } } - /// Selects a specific check and fetches its details. - void selectCheck(String buildName) { - if (_selectedCheck == buildName) return; - _selectedCheck = buildName; - _checks = null; + /// Selects a specific job and fetches its details. + void selectJob(String jobName) { + if (_selectedJob == jobName) return; + _selectedJob = jobName; + _jobs = null; notifyListeners(); - unawaited(fetchCheckDetails()); + unawaited(fetchJobDetails()); } /// Fetches available SHAs for the current [pr]. @@ -386,7 +386,7 @@ class PresubmitState extends ChangeNotifier { _availableSummaries = response.data ?? []; // Default to the latest SHA if none selected if (sha == null && _availableSummaries.isNotEmpty) { - sha = _availableSummaries.first.commitSha; + sha = _availableSummaries.first.headSha; unawaited(fetchGuardStatus()); } } @@ -420,41 +420,41 @@ class PresubmitState extends ChangeNotifier { notifyListeners(); } - /// Fetches details/logs for the current [selectedCheck]. - Future fetchCheckDetails() async { - if (_selectedCheck == null || _guardResponse == null) return; - _isChecksLoading = true; + /// Fetches details/logs for the current [selectedJob]. + Future fetchJobDetails() async { + if (_selectedJob == null || _guardResponse == null) return; + _isJobsLoading = true; notifyListeners(); - final response = await cocoonService.fetchPresubmitCheckDetails( + final response = await cocoonService.fetchPresubmitJobDetails( checkRunId: _guardResponse!.checkRunId, - buildName: _selectedCheck!, + jobName: _selectedJob!, repo: repo, ); if (response.error != null) { // TODO: Handle error } else { - _checks = response.data ?? []; + _jobs = response.data ?? []; } - _isChecksLoading = false; + _isJobsLoading = false; notifyListeners(); } /// Schedules a re-run for a failed job. - Future rerunFailedJob(String buildName) async { + Future rerunFailedJob(String jobName) async { if (pr == null) return 'No PR selected'; - _isChecksLoading = true; + _isJobsLoading = true; notifyListeners(); final response = await cocoonService.rerunFailedJob( idToken: await authService.idToken, repo: repo, pr: int.parse(pr!), - buildName: buildName, + jobName: jobName, ); - _isChecksLoading = false; + _isJobsLoading = false; if (response.error == null) { // Trigger a refresh after a small delay to allow the backend to update Timer(const Duration(seconds: 2), () => unawaited(fetchGuardStatus())); @@ -485,17 +485,17 @@ class PresubmitState extends ChangeNotifier { } /// Whether the user can trigger a re-run for a specific job. - bool canRerunFailedJob(String buildName) { + bool canRerunFailedJob(String jobName) { if (!authService.isAuthenticated || isLoading || _isRerunningAll) { return false; } // Only allow re-run if the job failed final stage = _guardResponse?.stages.firstWhere( - (s) => s.builds.containsKey(buildName), + (s) => s.builds.containsKey(jobName), orElse: () => const PresubmitGuardStage(name: '', createdAt: 0, builds: {}), ); - final status = stage?.builds[buildName]; + final status = stage?.builds[jobName]; return status == TaskStatus.failed || status == TaskStatus.infraFailure; } @@ -518,8 +518,8 @@ class PresubmitState extends ChangeNotifier { void _fetchRefreshUpdate() { if (!_active) return; fetchIfNeeded(); - if (_selectedCheck != null) { - unawaited(fetchCheckDetails()); + if (_selectedJob != null) { + unawaited(fetchJobDetails()); } } diff --git a/dashboard/lib/views/presubmit_view.dart b/dashboard/lib/views/presubmit_view.dart index 3bba7ebca..ccf50ddb4 100644 --- a/dashboard/lib/views/presubmit_view.dart +++ b/dashboard/lib/views/presubmit_view.dart @@ -24,7 +24,7 @@ import '../widgets/task_box.dart'; /// A detailed monitoring view for a specific Pull Request (PR) or commit SHA. /// -/// This view displays CI check statuses and execution logs. +/// This view displays CI job statuses and execution logs. final class PreSubmitView extends StatefulWidget { const PreSubmitView({ super.key, @@ -147,14 +147,14 @@ class _PreSubmitViewState extends State { final guardResponse = presubmitState.guardResponse; final isLoading = presubmitState.isLoading; - final selectedCheck = presubmitState.selectedCheck; + final selectedJob = presubmitState.selectedJob; var availableSummaries = presubmitState.availableSummaries; - if (sha != null && !availableSummaries.any((s) => s.commitSha == sha)) { + if (sha != null && !availableSummaries.any((s) => s.headSha == sha)) { availableSummaries = [ PresubmitGuardSummary( - commitSha: sha, + headSha: sha, creationTime: 0, guardStatus: GuardStatus.waitingForBackfill, ), @@ -174,14 +174,14 @@ class _PreSubmitViewState extends State { statusText = guardResponse.guardStatus.value; } else if (sha != null) { final summary = presubmitState.availableSummaries.firstWhere( - (s) => s.commitSha == sha, + (s) => s.headSha == sha, orElse: () => const PresubmitGuardSummary( - commitSha: '', + headSha: '', creationTime: 0, guardStatus: GuardStatus.waitingForBackfill, ), ); - if (summary.commitSha.isNotEmpty) { + if (summary.headSha.isNotEmpty) { statusText = summary.guardStatus.value; } } @@ -189,7 +189,7 @@ class _PreSubmitViewState extends State { final isLatestSha = pr != null && presubmitState.availableSummaries.isNotEmpty && - sha == presubmitState.availableSummaries.first.commitSha; + sha == presubmitState.availableSummaries.first.headSha; return Scaffold( appBar: CocoonAppBar( @@ -270,24 +270,21 @@ class _PreSubmitViewState extends State { child: Row( children: [ if (guardResponse != null) - _ChecksSidebar( + _JobsSidebar( guardResponse: presubmitState.filteredGuardResponse ?? guardResponse, - selectedCheck: selectedCheck, + selectedJob: selectedJob, isLatestSha: isLatestSha, - onCheckSelected: presubmitState.selectCheck, + onJobSelected: presubmitState.selectJob, onError: _showErrorDialog, ), const VerticalDivider(width: 1, thickness: 1), Expanded( child: - (selectedCheck == null || - guardResponse == null) + (selectedJob == null || guardResponse == null) ? const Center( - child: Text( - 'Select a check to view logs', - ), + child: Text('Select a job to view logs'), ) : const _LogViewerPane(), ), @@ -323,27 +320,27 @@ class _LogViewerPaneState extends State<_LogViewerPane> { animation: presubmitState, builder: (context, _) { final repo = presubmitState.repo; - final buildName = presubmitState.selectedCheck; - final checks = presubmitState.checks; + final jobName = presubmitState.selectedJob; + final jobs = presubmitState.jobs; final isLoading = presubmitState.isLoading; final borderColor = isDark ? const Color(0xFF333333) : const Color(0xFFD1D5DB); - if (isLoading && (checks == null || checks.isEmpty)) { + if (isLoading && (jobs == null || jobs.isEmpty)) { return const Center(child: CircularProgressIndicator()); } - if (checks == null || checks.isEmpty) { - return const Center(child: Text('No details found for this check')); + if (jobs == null || jobs.isEmpty) { + return const Center(child: Text('No details found for this job')); } - if (_selectedAttemptIndex >= checks.length) { + if (_selectedAttemptIndex >= jobs.length) { _selectedAttemptIndex = 0; } - final selectedCheck = checks[_selectedAttemptIndex]; + final selectedJob = jobs[_selectedAttemptIndex]; return Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -354,7 +351,7 @@ class _LogViewerPaneState extends State<_LogViewerPane> { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '$repo / $buildName', + '$repo / $jobName', style: const TextStyle( fontSize: 20, fontWeight: FontWeight.w600, @@ -362,7 +359,7 @@ class _LogViewerPaneState extends State<_LogViewerPane> { ), const SizedBox(height: 4), Text( - 'Status: ${selectedCheck.status}', + 'Status: ${selectedJob.status}', style: TextStyle( fontSize: 14, color: isDark @@ -382,9 +379,9 @@ class _LogViewerPaneState extends State<_LogViewerPane> { ), child: Row( children: [ - ...checks.asMap().entries.map((entry) { + ...jobs.asMap().entries.map((entry) { final index = entry.key; - final check = entry.value; + final job = entry.value; final isSelected = _selectedAttemptIndex == index; return InkWell( onTap: () => @@ -403,7 +400,7 @@ class _LogViewerPaneState extends State<_LogViewerPane> { ), ), child: Text( - '#${check.attemptNumber}', + '#${job.attemptNumber}', style: TextStyle( fontSize: 13, fontWeight: isSelected @@ -460,7 +457,7 @@ class _LogViewerPaneState extends State<_LogViewerPane> { width: double.infinity, child: SingleChildScrollView( child: Text( - selectedCheck.summary ?? 'No log summary available', + selectedJob.summary ?? 'No log summary available', style: const TextStyle( fontFamily: 'monospace', fontSize: 13, @@ -472,13 +469,13 @@ class _LogViewerPaneState extends State<_LogViewerPane> { Padding( padding: const EdgeInsets.all(24.0), child: ElevatedButton( - onPressed: selectedCheck.buildNumber == null + onPressed: selectedJob.buildNumber == null ? null : () async => await launchUrl( Uri.parse( generatePreSubmitBuildLogUrl( - buildName: selectedCheck.buildName, - buildNumber: selectedCheck.buildNumber!, + buildName: selectedJob.jobName, + buildNumber: selectedJob.buildNumber!, ), ), ), @@ -488,7 +485,7 @@ class _LogViewerPaneState extends State<_LogViewerPane> { Icon( Icons.open_in_new, size: 18, - color: selectedCheck.buildNumber == null + color: selectedJob.buildNumber == null ? Colors.grey : (isDark ? const Color(0xFF58A6FF) @@ -498,7 +495,7 @@ class _LogViewerPaneState extends State<_LogViewerPane> { Text( 'View more details on LUCI UI', style: TextStyle( - color: selectedCheck.buildNumber == null + color: selectedJob.buildNumber == null ? Colors.grey : (isDark ? const Color(0xFF58A6FF) @@ -517,26 +514,26 @@ class _LogViewerPaneState extends State<_LogViewerPane> { } } -class _ChecksSidebar extends StatefulWidget { - const _ChecksSidebar({ +class _JobsSidebar extends StatefulWidget { + const _JobsSidebar({ required this.guardResponse, - this.selectedCheck, + this.selectedJob, this.isLatestSha = false, - required this.onCheckSelected, + required this.onJobSelected, required this.onError, }); final PresubmitGuardResponse guardResponse; - final String? selectedCheck; + final String? selectedJob; final bool isLatestSha; - final ValueChanged onCheckSelected; + final ValueChanged onJobSelected; final ValueChanged onError; @override - State<_ChecksSidebar> createState() => _ChecksSidebarState(); + State<_JobsSidebar> createState() => _JobsSidebarState(); } -class _ChecksSidebarState extends State<_ChecksSidebar> { +class _JobsSidebarState extends State<_JobsSidebar> { final ScrollController _scrollController = ScrollController(); late List>> _sortedBuildsPerStage; @@ -544,28 +541,28 @@ class _ChecksSidebarState extends State<_ChecksSidebar> { void initState() { super.initState(); _updateSortedBuilds(); - _selectFirstCheck(); + _selectFirstJob(); } @override - void didUpdateWidget(_ChecksSidebar oldWidget) { + void didUpdateWidget(_JobsSidebar oldWidget) { super.didUpdateWidget(oldWidget); if (widget.guardResponse != oldWidget.guardResponse) { _updateSortedBuilds(); } - if (widget.selectedCheck == null) { - _selectFirstCheck(); + if (widget.selectedJob == null) { + _selectFirstJob(); } } - void _selectFirstCheck() { - if (widget.selectedCheck != null) return; + void _selectFirstJob() { + if (widget.selectedJob != null) return; for (final stage in _sortedBuildsPerStage) { if (stage.isNotEmpty) { - final firstCheck = stage.first.key; + final firstJob = stage.first.key; WidgetsBinding.instance.addPostFrameCallback((_) { - if (mounted && widget.selectedCheck == null) { - widget.onCheckSelected(firstCheck); + if (mounted && widget.selectedJob == null) { + widget.onJobSelected(firstJob); } }); break; @@ -628,13 +625,13 @@ class _ChecksSidebarState extends State<_ChecksSidebar> { ), ), ...sortedBuilds.map((entry) { - final isSelected = widget.selectedCheck == entry.key; - return _CheckItem( + final isSelected = widget.selectedJob == entry.key; + return _JobItem( name: entry.key, status: entry.value, isSelected: isSelected, isLatestSha: widget.isLatestSha, - onTap: () => widget.onCheckSelected(entry.key), + onTap: () => widget.onJobSelected(entry.key), onError: widget.onError, ); }), @@ -650,8 +647,8 @@ class _ChecksSidebarState extends State<_ChecksSidebar> { } } -class _CheckItem extends StatelessWidget { - const _CheckItem({ +class _JobItem extends StatelessWidget { + const _JobItem({ required this.name, required this.status, required this.isSelected, diff --git a/dashboard/lib/widgets/sha_selector.dart b/dashboard/lib/widgets/sha_selector.dart index 79d542d9b..ce86cec95 100644 --- a/dashboard/lib/widgets/sha_selector.dart +++ b/dashboard/lib/widgets/sha_selector.dart @@ -54,7 +54,7 @@ class ShaSelector extends StatelessWidget { } }, items: availableShas.map((summary) { - final sha = summary.commitSha; + final sha = summary.headSha; final status = summary.guardStatus; final creationTime = DateTime.fromMillisecondsSinceEpoch( summary.creationTime, diff --git a/dashboard/test/integration/get_presubmit_checks_test.dart b/dashboard/test/integration/get_presubmit_checks_test.dart index a82e63756..cb48bcc36 100644 --- a/dashboard/test/integration/get_presubmit_checks_test.dart +++ b/dashboard/test/integration/get_presubmit_checks_test.dart @@ -4,7 +4,7 @@ import 'package:cocoon_common/task_status.dart'; import 'package:cocoon_integration_test/cocoon_integration_test.dart'; -import 'package:cocoon_service/src/model/firestore/presubmit_check.dart'; +import 'package:cocoon_service/src/model/firestore/presubmit_job.dart'; import 'package:flutter_dashboard/service/appengine_cocoon.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:github/github.dart'; @@ -24,9 +24,9 @@ void main() { }); test('returns empty list when no checks exist', () async { - final response = await service.fetchPresubmitCheckDetails( + final response = await service.fetchPresubmitJobDetails( checkRunId: 123, - buildName: 'linux_android', + jobName: 'linux_android', ); expect(response.error, isNotNull); expect(response.statusCode, 404); @@ -34,10 +34,10 @@ void main() { test('returns presubmit check details', () async { final now = DateTime.now(); - final check = PresubmitCheck( + final check = PresubmitJob( slug: RepositorySlug('flutter', 'flutter'), checkRunId: 456, - buildName: 'linux android_2', + jobName: 'linux android_2', status: TaskStatus.succeeded, attemptNumber: 1, creationTime: now.millisecondsSinceEpoch, @@ -49,16 +49,16 @@ void main() { server.firestore.putDocuments([check]); - final response = await service.fetchPresubmitCheckDetails( + final response = await service.fetchPresubmitJobDetails( checkRunId: 456, - buildName: 'linux android_2', + jobName: 'linux android_2', ); expect(response.error, isNull); expect(response.data, hasLength(1)); final result = response.data!.first; - expect(result.buildName, 'linux android_2'); + expect(result.jobName, 'linux android_2'); expect(result.status, 'Succeeded'); expect(result.attemptNumber, 1); expect(result.buildNumber, 1337); @@ -67,10 +67,10 @@ void main() { test('returns multiple attempts for same build', () async { final now = DateTime.now(); - final checkAttempt1 = PresubmitCheck( + final checkAttempt1 = PresubmitJob( slug: RepositorySlug('flutter', 'flutter'), checkRunId: 789, - buildName: 'mac_ios', + jobName: 'mac_ios', status: TaskStatus.failed, attemptNumber: 1, creationTime: now @@ -80,10 +80,10 @@ void main() { summary: 'Build failed', ); - final checkAttempt2 = PresubmitCheck( + final checkAttempt2 = PresubmitJob( slug: RepositorySlug('flutter', 'flutter'), checkRunId: 789, - buildName: 'mac_ios', + jobName: 'mac_ios', status: TaskStatus.succeeded, attemptNumber: 2, creationTime: now.millisecondsSinceEpoch, @@ -93,18 +93,18 @@ void main() { server.firestore.putDocuments([checkAttempt1, checkAttempt2]); - final response = await service.fetchPresubmitCheckDetails( + final response = await service.fetchPresubmitJobDetails( checkRunId: 789, - buildName: 'mac_ios', + jobName: 'mac_ios', ); expect(response.error, isNull); expect(response.data, hasLength(2)); - // Should be ordered by attempt number descending (default behavior of GetPresubmitChecksHandler) + // Should be ordered by attempt number descending (default behavior of GetPresubmitJobsHandler) // I need to verify the order. - // Based on `UnifiedCheckRun.getPresubmitCheckDetails`: - // `orderMap: const { PresubmitCheck.fieldAttemptNumber: kQueryOrderDescending }` + // Based on `UnifiedCheckRun.getPresubmitJobDetails`: + // `orderMap: const { PresubmitJob.fieldAttemptNumber: kQueryOrderDescending }` expect(response.data![0].attemptNumber, 2); expect(response.data![0].status, 'Succeeded'); diff --git a/dashboard/test/logic/presubmit_guard_test.dart b/dashboard/test/logic/presubmit_guard_test.dart index 4b4d810fb..825f1bb97 100644 --- a/dashboard/test/logic/presubmit_guard_test.dart +++ b/dashboard/test/logic/presubmit_guard_test.dart @@ -37,20 +37,20 @@ void main() { }); }); - group('PresubmitCheckResponse', () { + group('PresubmitJobResponse', () { test('fromJson creates a valid object', () { final json = { 'attempt_number': 1, - 'build_name': 'Linux Device Doctor', + 'job_name': 'Linux Device Doctor', 'creation_time': 1620134239000, 'status': 'Succeeded', 'summary': 'Check passed', }; - final response = PresubmitCheckResponse.fromJson(json); + final response = PresubmitJobResponse.fromJson(json); expect(response.attemptNumber, 1); - expect(response.buildName, 'Linux Device Doctor'); + expect(response.jobName, 'Linux Device Doctor'); expect(response.creationTime, 1620134239000); expect(response.status, 'Succeeded'); expect(response.summary, 'Check passed'); diff --git a/dashboard/test/service/appengine_cocoon_test.dart b/dashboard/test/service/appengine_cocoon_test.dart index ecd927511..1943cec71 100644 --- a/dashboard/test/service/appengine_cocoon_test.dart +++ b/dashboard/test/service/appengine_cocoon_test.dart @@ -257,14 +257,14 @@ void main() { idToken: 'token', repo: 'flutter', pr: 123, - buildName: 'linux_bot', + jobName: 'linux_bot', ); expect(response.error, isNull); expect(capturedUrl, contains('/api/rerun-failed-job')); expect( capturedBody, - '{"owner":"flutter","repo":"flutter","pr":123,"build_name":"linux_bot"}', + '{"owner":"flutter","repo":"flutter","pr":123,"job_name":"linux_bot"}', ); }); diff --git a/dashboard/test/service/data_seeder_test.dart b/dashboard/test/service/data_seeder_test.dart index ae18f7241..0127099c1 100644 --- a/dashboard/test/service/data_seeder_test.dart +++ b/dashboard/test/service/data_seeder_test.dart @@ -66,7 +66,7 @@ void main() { ); expect( - firestore.documents.where((d) => d.name!.contains('presubmit_checks')), + firestore.documents.where((d) => d.name!.contains('presubmit_jobs')), isNotEmpty, ); diff --git a/dashboard/test/service/presubmit_service_test.dart b/dashboard/test/service/presubmit_service_test.dart index c7e812f55..dc25607ef 100644 --- a/dashboard/test/service/presubmit_service_test.dart +++ b/dashboard/test/service/presubmit_service_test.dart @@ -59,14 +59,14 @@ void main() { }); }); - group('AppEngine CocoonService fetchPresubmitCheckDetails', () { + group('AppEngine CocoonService fetchPresubmitJobDetails', () { late AppEngineCocoonService service; - test('should return expected List', () async { + test('should return expected List', () async { final checkData = [ { 'attempt_number': 1, - 'build_name': 'test1', + 'job_name': 'test1', 'creation_time': 123456789, 'status': 'Succeeded', 'summary': 'Passed', @@ -75,19 +75,19 @@ void main() { service = AppEngineCocoonService( client: MockClient((Request request) async { - expect(request.url.path, '/api/public/get-presubmit-checks'); + expect(request.url.path, '/api/public/get-presubmit-jobs'); return Response(jsonEncode(checkData), 200); }), ); - final response = await service.fetchPresubmitCheckDetails( + final response = await service.fetchPresubmitJobDetails( checkRunId: 456, - buildName: 'test1', + jobName: 'test1', ); expect(response.error, isNull); expect(response.data!.length, 1); - expect(response.data!.first.buildName, 'test1'); + expect(response.data!.first.jobName, 'test1'); }); }); @@ -97,7 +97,7 @@ void main() { test('should return expected List', () async { final summaryData = [ { - 'commit_sha': 'sha1', + 'head_sha': 'sha1', 'creation_time': 123456789, 'guard_status': 'Succeeded', }, @@ -117,7 +117,7 @@ void main() { expect(response.error, isNull); expect(response.data!.length, 1); - expect(response.data!.first.commitSha, 'sha1'); + expect(response.data!.first.headSha, 'sha1'); }); }); group('AppEngine CocoonService presubmit methods', () { @@ -148,20 +148,20 @@ void main() { }); test( - 'fetchPresubmitCheckDetails uses correct parameters and defaults', + 'fetchPresubmitJobDetails uses correct parameters and defaults', () async { - await service.fetchPresubmitCheckDetails( + await service.fetchPresubmitJobDetails( checkRunId: 123, - buildName: 'linux', + jobName: 'linux', ); expect(capturedUri.queryParameters['owner'], 'flutter'); expect(capturedUri.queryParameters['repo'], 'flutter'); expect(capturedUri.queryParameters['check_run_id'], '123'); - expect(capturedUri.queryParameters['build_name'], 'linux'); + expect(capturedUri.queryParameters['job_name'], 'linux'); - await service.fetchPresubmitCheckDetails( + await service.fetchPresubmitJobDetails( checkRunId: 123, - buildName: 'linux', + jobName: 'linux', repo: 'cocoon', owner: 'custom', ); diff --git a/dashboard/test/state/presubmit_filter_test.dart b/dashboard/test/state/presubmit_filter_test.dart index 6ee842f89..7ff8c7fc7 100644 --- a/dashboard/test/state/presubmit_filter_test.dart +++ b/dashboard/test/state/presubmit_filter_test.dart @@ -42,14 +42,14 @@ void main() { (_) async => const CocoonResponse.data(null), ); when( - mockCocoonService.fetchPresubmitCheckDetails( + mockCocoonService.fetchPresubmitJobDetails( checkRunId: anyNamed('checkRunId'), - buildName: anyNamed('buildName'), + jobName: anyNamed('jobName'), repo: anyNamed('repo'), owner: anyNamed('owner'), ), ).thenAnswer( - (_) async => const CocoonResponse>.data([]), + (_) async => const CocoonResponse>.data([]), ); presubmitState = PresubmitState( @@ -194,14 +194,14 @@ void main() { presubmitState.setGuardResponseForTest(response); // Initial selection should be 'linux test2' (failed has higher priority than succeeded) - expect(presubmitState.selectedCheck, 'linux test2'); + expect(presubmitState.selectedJob, 'linux test2'); // Filter out 'linux test2' presubmitState.updateFilters(statuses: {TaskStatus.succeeded}); - expect(presubmitState.selectedCheck, 'linux test1'); + expect(presubmitState.selectedJob, 'linux test1'); // Filter out everything presubmitState.updateFilters(jobNameFilter: 'none'); - expect(presubmitState.selectedCheck, isNull); + expect(presubmitState.selectedJob, isNull); }); } diff --git a/dashboard/test/state/presubmit_test.dart b/dashboard/test/state/presubmit_test.dart index fe74d8ab8..de8c113f0 100644 --- a/dashboard/test/state/presubmit_test.dart +++ b/dashboard/test/state/presubmit_test.dart @@ -43,14 +43,14 @@ void main() { (_) async => const CocoonResponse.data(null), ); when( - mockCocoonService.fetchPresubmitCheckDetails( + mockCocoonService.fetchPresubmitJobDetails( checkRunId: anyNamed('checkRunId'), - buildName: anyNamed('buildName'), + jobName: anyNamed('jobName'), repo: anyNamed('repo'), owner: anyNamed('owner'), ), ).thenAnswer( - (_) async => const CocoonResponse>.data([]), + (_) async => const CocoonResponse>.data([]), ); when( mockCocoonService.fetchCommitStatuses( @@ -96,7 +96,7 @@ void main() { () async { const summaries = [ PresubmitGuardSummary( - commitSha: 'sha1', + headSha: 'sha1', creationTime: 123, guardStatus: GuardStatus.succeeded, ), @@ -155,9 +155,9 @@ void main() { 'PresubmitState fetchCheckDetails updates checks and notifies listeners', () async { final checks = [ - PresubmitCheckResponse( + PresubmitJobResponse( attemptNumber: 1, - buildName: 'check1', + jobName: 'check1', creationTime: 0, status: 'Succeeded', ), @@ -172,22 +172,22 @@ void main() { presubmitState.setGuardResponseForTest(guardResponse); when( - mockCocoonService.fetchPresubmitCheckDetails( + mockCocoonService.fetchPresubmitJobDetails( checkRunId: 456, - buildName: 'check1', + jobName: 'check1', repo: 'flutter', ), ).thenAnswer( - (_) async => CocoonResponse>.data(checks), + (_) async => CocoonResponse>.data(checks), ); - presubmitState.selectCheck('check1'); + presubmitState.selectJob('check1'); var notified = false; presubmitState.addListener(() => notified = true); - await presubmitState.fetchCheckDetails(); + await presubmitState.fetchJobDetails(); - expect(presubmitState.checks, checks); + expect(presubmitState.jobs, checks); expect(notified, isTrue); }, ); @@ -223,7 +223,7 @@ void main() { () async { const summaries = [ PresubmitGuardSummary( - commitSha: 'latest', + headSha: 'latest', creationTime: 123, guardStatus: GuardStatus.succeeded, ), @@ -328,7 +328,7 @@ void main() { idToken: anyNamed('idToken'), repo: anyNamed('repo'), pr: anyNamed('pr'), - buildName: anyNamed('buildName'), + jobName: anyNamed('jobName'), ), ).thenAnswer((_) async => const CocoonResponse.data(null)); @@ -341,7 +341,7 @@ void main() { idToken: anyNamed('idToken'), repo: 'flutter', pr: 123, - buildName: 'check1', + jobName: 'check1', ), ).called(1); }); diff --git a/dashboard/test/utils/mocks.mocks.dart b/dashboard/test/utils/mocks.mocks.dart index 5c6953be4..25cfec539 100644 --- a/dashboard/test/utils/mocks.mocks.dart +++ b/dashboard/test/utils/mocks.mocks.dart @@ -449,7 +449,7 @@ class MockCocoonService extends _i1.Mock implements _i3.CocoonService { required String? idToken, required String? repo, required int? pr, - required String? buildName, + required String? jobName, String? owner = 'flutter', }) => (super.noSuchMethod( @@ -457,7 +457,7 @@ class MockCocoonService extends _i1.Mock implements _i3.CocoonService { #idToken: idToken, #repo: repo, #pr: pr, - #buildName: buildName, + #jobName: jobName, #owner: owner, }), returnValue: _i8.Future<_i3.CocoonResponse>.value( @@ -467,7 +467,7 @@ class MockCocoonService extends _i1.Mock implements _i3.CocoonService { #idToken: idToken, #repo: repo, #pr: pr, - #buildName: buildName, + #jobName: jobName, #owner: owner, }), ), @@ -677,36 +677,36 @@ class MockCocoonService extends _i1.Mock implements _i3.CocoonService { as _i8.Future<_i3.CocoonResponse<_i12.PresubmitGuardResponse>>); @override - _i8.Future<_i3.CocoonResponse>> - fetchPresubmitCheckDetails({ + _i8.Future<_i3.CocoonResponse>> + fetchPresubmitJobDetails({ required int? checkRunId, - required String? buildName, + required String? jobName, String? repo = 'flutter', String? owner = 'flutter', }) => (super.noSuchMethod( - Invocation.method(#fetchPresubmitCheckDetails, [], { + Invocation.method(#fetchPresubmitJobDetails, [], { #checkRunId: checkRunId, - #buildName: buildName, + #jobName: jobName, #repo: repo, #owner: owner, }), returnValue: _i8.Future< - _i3.CocoonResponse> + _i3.CocoonResponse> >.value( - _FakeCocoonResponse_2>( + _FakeCocoonResponse_2>( this, - Invocation.method(#fetchPresubmitCheckDetails, [], { + Invocation.method(#fetchPresubmitJobDetails, [], { #checkRunId: checkRunId, - #buildName: buildName, + #jobName: jobName, #repo: repo, #owner: owner, }), ), ), ) - as _i8.Future<_i3.CocoonResponse>>); + as _i8.Future<_i3.CocoonResponse>>); @override _i8.Future<_i3.CocoonResponse>> diff --git a/dashboard/test/views/presubmit_filter_view_test.dart b/dashboard/test/views/presubmit_filter_view_test.dart index a8417a980..7337a8f2b 100644 --- a/dashboard/test/views/presubmit_filter_view_test.dart +++ b/dashboard/test/views/presubmit_filter_view_test.dart @@ -69,7 +69,7 @@ void main() { ).thenAnswer( (_) async => const CocoonResponse.data([ PresubmitGuardSummary( - commitSha: 'abc', + headSha: 'abc', creationTime: 123, guardStatus: GuardStatus.succeeded, ), @@ -77,9 +77,9 @@ void main() { ); when( - mockCocoonService.fetchPresubmitCheckDetails( + mockCocoonService.fetchPresubmitJobDetails( checkRunId: anyNamed('checkRunId'), - buildName: anyNamed('buildName'), + jobName: anyNamed('jobName'), repo: anyNamed('repo'), owner: anyNamed('owner'), ), diff --git a/dashboard/test/views/presubmit_view_test.dart b/dashboard/test/views/presubmit_view_test.dart index 4096fb855..49f493eb0 100644 --- a/dashboard/test/views/presubmit_view_test.dart +++ b/dashboard/test/views/presubmit_view_test.dart @@ -72,17 +72,17 @@ void main() { ).thenAnswer( (_) async => const CocoonResponse.data([ PresubmitGuardSummary( - commitSha: 'decaf_3_real_sha', + headSha: 'decaf_3_real_sha', creationTime: 123456789, guardStatus: GuardStatus.succeeded, ), PresubmitGuardSummary( - commitSha: 'face5_2_mock_sha', + headSha: 'face5_2_mock_sha', creationTime: 123456789, guardStatus: GuardStatus.failed, ), PresubmitGuardSummary( - commitSha: 'cafe5_1_mock_sha', + headSha: 'cafe5_1_mock_sha', creationTime: 123456789, guardStatus: GuardStatus.inProgress, ), @@ -103,7 +103,7 @@ void main() { idToken: anyNamed('idToken'), repo: anyNamed('repo'), pr: anyNamed('pr'), - buildName: anyNamed('buildName'), + jobName: anyNamed('jobName'), ), ).thenAnswer((_) async => const CocoonResponse.data(null)); @@ -116,9 +116,9 @@ void main() { ).thenAnswer((_) async => const CocoonResponse.data(null)); when( - mockCocoonService.fetchPresubmitCheckDetails( + mockCocoonService.fetchPresubmitJobDetails( checkRunId: anyNamed('checkRunId'), - buildName: anyNamed('buildName'), + jobName: anyNamed('jobName'), ), ).thenAnswer((_) async => const CocoonResponse.data([])); @@ -222,22 +222,22 @@ void main() { ).thenAnswer((_) async => const CocoonResponse.data(guardResponse)); when( - mockCocoonService.fetchPresubmitCheckDetails( + mockCocoonService.fetchPresubmitJobDetails( checkRunId: anyNamed('checkRunId'), - buildName: argThat(contains('mac_host_engine'), named: 'buildName'), + jobName: argThat(contains('mac_host_engine'), named: 'jobName'), ), ).thenAnswer( (_) async => CocoonResponse.data([ - PresubmitCheckResponse( + PresubmitJobResponse( attemptNumber: 1, - buildName: 'Mac mac_host_engine 1', + jobName: 'Mac mac_host_engine 1', creationTime: 0, status: 'Succeeded', summary: 'All tests passed (452/452)', ), - PresubmitCheckResponse( + PresubmitJobResponse( attemptNumber: 2, - buildName: 'Mac mac_host_engine 1', + jobName: 'Mac mac_host_engine 1', creationTime: 0, status: 'Failed', summary: 'Test failed: Unit Tests', @@ -405,15 +405,15 @@ void main() { ).thenAnswer((_) async => const CocoonResponse.data(guardResponse)); when( - mockCocoonService.fetchPresubmitCheckDetails( + mockCocoonService.fetchPresubmitJobDetails( checkRunId: 456, - buildName: 'Mac mac_host_engine', + jobName: 'Mac mac_host_engine', ), ).thenAnswer( (_) async => CocoonResponse.data([ - PresubmitCheckResponse( + PresubmitJobResponse( attemptNumber: 1, - buildName: 'Mac mac_host_engine', + jobName: 'Mac mac_host_engine', creationTime: 0, status: 'Succeeded', summary: 'Live log content', diff --git a/dashboard/test/widgets/filter_dialog_test.dart b/dashboard/test/widgets/filter_dialog_test.dart index 50e9923a7..9438bb767 100644 --- a/dashboard/test/widgets/filter_dialog_test.dart +++ b/dashboard/test/widgets/filter_dialog_test.dart @@ -31,14 +31,14 @@ void main() { ); when( - mockCocoonService.fetchPresubmitCheckDetails( + mockCocoonService.fetchPresubmitJobDetails( checkRunId: anyNamed('checkRunId'), - buildName: anyNamed('buildName'), + jobName: anyNamed('jobName'), repo: anyNamed('repo'), owner: anyNamed('owner'), ), ).thenAnswer( - (_) async => const CocoonResponse>.data([]), + (_) async => const CocoonResponse>.data([]), ); const response = PresubmitGuardResponse( diff --git a/packages/cocoon_common/lib/rpc_model.dart b/packages/cocoon_common/lib/rpc_model.dart index 99bcad1e9..f94dace21 100644 --- a/packages/cocoon_common/lib/rpc_model.dart +++ b/packages/cocoon_common/lib/rpc_model.dart @@ -34,11 +34,10 @@ export 'src/rpc_model/commit_status.dart' show CommitStatus; export 'src/rpc_model/content_hash_lookup.dart' show ContentHashLookup; export 'src/rpc_model/merge_group_hooks.dart' show MergeGroupHook, MergeGroupHooks; -export 'src/rpc_model/presubmit_check_response.dart' - show PresubmitCheckResponse; export 'src/rpc_model/presubmit_guard.dart' show PresubmitGuardResponse, PresubmitGuardStage; export 'src/rpc_model/presubmit_guard_summary.dart' show PresubmitGuardSummary; +export 'src/rpc_model/presubmit_job_response.dart' show PresubmitJobResponse; export 'src/rpc_model/suppressed_test.dart' show SuppressedTest, SuppressionUpdate; export 'src/rpc_model/task.dart' show Task; diff --git a/packages/cocoon_common/lib/src/rpc_model/presubmit_guard.dart b/packages/cocoon_common/lib/src/rpc_model/presubmit_guard.dart index 7c1c0b4d7..ab2d7e0a8 100644 --- a/packages/cocoon_common/lib/src/rpc_model/presubmit_guard.dart +++ b/packages/cocoon_common/lib/src/rpc_model/presubmit_guard.dart @@ -12,7 +12,7 @@ part 'presubmit_guard.g.dart'; /// Response model for a Presubmit Guard. /// -/// Contains the aggregated status and stages of presubmit checks for a specific commit. +/// Contains the aggregated status and stages of presubmit jobs for a specific commit. @immutable @JsonSerializable(fieldRename: FieldRename.snake) final class PresubmitGuardResponse { diff --git a/packages/cocoon_common/lib/src/rpc_model/presubmit_guard_summary.dart b/packages/cocoon_common/lib/src/rpc_model/presubmit_guard_summary.dart index 1b6a54fc5..20a6bbd02 100644 --- a/packages/cocoon_common/lib/src/rpc_model/presubmit_guard_summary.dart +++ b/packages/cocoon_common/lib/src/rpc_model/presubmit_guard_summary.dart @@ -14,13 +14,13 @@ part 'presubmit_guard_summary.g.dart'; @JsonSerializable(fieldRename: FieldRename.snake) final class PresubmitGuardSummary { const PresubmitGuardSummary({ - required this.commitSha, + required this.headSha, required this.creationTime, required this.guardStatus, }); - /// The commit SHA. - final String commitSha; + /// The commit head SHA. + final String headSha; /// The creation timestamp in microseconds since epoch. final int creationTime; diff --git a/packages/cocoon_common/lib/src/rpc_model/presubmit_guard_summary.g.dart b/packages/cocoon_common/lib/src/rpc_model/presubmit_guard_summary.g.dart index d4acbe96d..7019676f7 100644 --- a/packages/cocoon_common/lib/src/rpc_model/presubmit_guard_summary.g.dart +++ b/packages/cocoon_common/lib/src/rpc_model/presubmit_guard_summary.g.dart @@ -9,7 +9,7 @@ part of 'presubmit_guard_summary.dart'; PresubmitGuardSummary _$PresubmitGuardSummaryFromJson( Map json, ) => PresubmitGuardSummary( - commitSha: json['commit_sha'] as String, + headSha: json['head_sha'] as String, creationTime: (json['creation_time'] as num).toInt(), guardStatus: $enumDecode(_$GuardStatusEnumMap, json['guard_status']), ); @@ -17,7 +17,7 @@ PresubmitGuardSummary _$PresubmitGuardSummaryFromJson( Map _$PresubmitGuardSummaryToJson( PresubmitGuardSummary instance, ) => { - 'commit_sha': instance.commitSha, + 'head_sha': instance.headSha, 'creation_time': instance.creationTime, 'guard_status': instance.guardStatus, }; diff --git a/packages/cocoon_common/lib/src/rpc_model/presubmit_check_response.dart b/packages/cocoon_common/lib/src/rpc_model/presubmit_job_response.dart similarity index 50% rename from packages/cocoon_common/lib/src/rpc_model/presubmit_check_response.dart rename to packages/cocoon_common/lib/src/rpc_model/presubmit_job_response.dart index 4d6b9b444..9f9325d07 100644 --- a/packages/cocoon_common/lib/src/rpc_model/presubmit_check_response.dart +++ b/packages/cocoon_common/lib/src/rpc_model/presubmit_job_response.dart @@ -7,20 +7,20 @@ import 'package:meta/meta.dart'; import 'base.dart'; -part 'presubmit_check_response.g.dart'; +part 'presubmit_job_response.g.dart'; -/// RPC model for a presubmit check. +/// RPC model for a presubmit job. @JsonSerializable( checked: true, fieldRename: FieldRename.snake, includeIfNull: false, ) @immutable -final class PresubmitCheckResponse extends Model { - /// Creates a [PresubmitCheckResponse] with the given properties. - PresubmitCheckResponse({ +final class PresubmitJobResponse extends Model { + /// Creates a [PresubmitJobResponse] with the given properties. + PresubmitJobResponse({ required this.attemptNumber, - required this.buildName, + required this.jobName, required this.creationTime, this.startTime, this.endTime, @@ -29,12 +29,12 @@ final class PresubmitCheckResponse extends Model { this.buildNumber, }); - /// Creates a [PresubmitCheckResponse] from [json] representation. - factory PresubmitCheckResponse.fromJson(Map json) { + /// Creates a [PresubmitJobResponse] from [json] representation. + factory PresubmitJobResponse.fromJson(Map json) { try { - return _$PresubmitCheckResponseFromJson(json); + return _$PresubmitJobResponseFromJson(json); } on CheckedFromJsonException catch (e) { - throw FormatException('Invalid PresubmitCheckResponse: $e', json); + throw FormatException('Invalid PresubmitJobResponse: $e', json); } } @@ -42,26 +42,26 @@ final class PresubmitCheckResponse extends Model { final int attemptNumber; /// The name of the build. - final String buildName; + final String jobName; - /// The time the check was created in milliseconds since the epoch. + /// The time the job was created in milliseconds since the epoch. final int creationTime; - /// The time the check started in milliseconds since the epoch. + /// The time the job started in milliseconds since the epoch. final int? startTime; - /// The time the check ended in milliseconds since the epoch. + /// The time the job ended in milliseconds since the epoch. final int? endTime; - /// The status of the check. + /// The status of the job. final String status; - /// A brief summary of the check result or link to logs. + /// A brief summary of the job result or link to logs. final String? summary; /// The LUCI build number. final int? buildNumber; @override - Map toJson() => _$PresubmitCheckResponseToJson(this); + Map toJson() => _$PresubmitJobResponseToJson(this); } diff --git a/packages/cocoon_common/lib/src/rpc_model/presubmit_check_response.g.dart b/packages/cocoon_common/lib/src/rpc_model/presubmit_job_response.g.dart similarity index 77% rename from packages/cocoon_common/lib/src/rpc_model/presubmit_check_response.g.dart rename to packages/cocoon_common/lib/src/rpc_model/presubmit_job_response.g.dart index e4cbf60c6..14fd88288 100644 --- a/packages/cocoon_common/lib/src/rpc_model/presubmit_check_response.g.dart +++ b/packages/cocoon_common/lib/src/rpc_model/presubmit_job_response.g.dart @@ -1,23 +1,23 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'presubmit_check_response.dart'; +part of 'presubmit_job_response.dart'; // ************************************************************************** // JsonSerializableGenerator // ************************************************************************** -PresubmitCheckResponse _$PresubmitCheckResponseFromJson( +PresubmitJobResponse _$PresubmitJobResponseFromJson( Map json, ) => $checkedCreate( - 'PresubmitCheckResponse', + 'PresubmitJobResponse', json, ($checkedConvert) { - final val = PresubmitCheckResponse( + final val = PresubmitJobResponse( attemptNumber: $checkedConvert( 'attempt_number', (v) => (v as num).toInt(), ), - buildName: $checkedConvert('build_name', (v) => v as String), + jobName: $checkedConvert('job_name', (v) => v as String), creationTime: $checkedConvert('creation_time', (v) => (v as num).toInt()), startTime: $checkedConvert('start_time', (v) => (v as num?)?.toInt()), endTime: $checkedConvert('end_time', (v) => (v as num?)?.toInt()), @@ -29,7 +29,7 @@ PresubmitCheckResponse _$PresubmitCheckResponseFromJson( }, fieldKeyMap: const { 'attemptNumber': 'attempt_number', - 'buildName': 'build_name', + 'jobName': 'job_name', 'creationTime': 'creation_time', 'startTime': 'start_time', 'endTime': 'end_time', @@ -37,11 +37,11 @@ PresubmitCheckResponse _$PresubmitCheckResponseFromJson( }, ); -Map _$PresubmitCheckResponseToJson( - PresubmitCheckResponse instance, +Map _$PresubmitJobResponseToJson( + PresubmitJobResponse instance, ) => { 'attempt_number': instance.attemptNumber, - 'build_name': instance.buildName, + 'job_name': instance.jobName, 'creation_time': instance.creationTime, 'start_time': ?instance.startTime, 'end_time': ?instance.endTime, diff --git a/packages/cocoon_common/test/presubmit_check_response_test.dart b/packages/cocoon_common/test/presubmit_check_response_test.dart index d77f62bf8..566cd8816 100644 --- a/packages/cocoon_common/test/presubmit_check_response_test.dart +++ b/packages/cocoon_common/test/presubmit_check_response_test.dart @@ -6,17 +6,17 @@ import 'package:cocoon_common/rpc_model.dart'; import 'package:test/test.dart'; void main() { - group('PresubmitCheckResponse', () { + group('PresubmitJobResponse', () { test('toJson and fromJson handles buildNumber', () { final json = { 'attempt_number': 1, - 'build_name': 'linux', + 'job_name': 'linux', 'creation_time': 1000, 'status': 'succeeded', 'build_number': 456, }; - final response = PresubmitCheckResponse.fromJson(json); + final response = PresubmitJobResponse.fromJson(json); expect(response.buildNumber, 456); final backToJson = response.toJson(); @@ -26,12 +26,12 @@ void main() { test('toJson and fromJson handles null buildNumber', () { final json = { 'attempt_number': 1, - 'build_name': 'linux', + 'job_name': 'linux', 'creation_time': 1000, 'status': 'succeeded', }; - final response = PresubmitCheckResponse.fromJson(json); + final response = PresubmitJobResponse.fromJson(json); expect(response.buildNumber, isNull); final backToJson = response.toJson(); diff --git a/packages/cocoon_integration_test/lib/src/utilities/entity_generators.dart b/packages/cocoon_integration_test/lib/src/utilities/entity_generators.dart index c37a9595a..5856df24a 100644 --- a/packages/cocoon_integration_test/lib/src/utilities/entity_generators.dart +++ b/packages/cocoon_integration_test/lib/src/utilities/entity_generators.dart @@ -313,28 +313,26 @@ SuppressedTest generateSuppressedTest({ PresubmitGuard generatePresubmitGuard({ github.RepositorySlug? slug, - int pullRequestId = 123, + int prNum = 123, github.CheckRun? checkRun, CiStage stage = CiStage.fusionTests, - String commitSha = 'abc', + String headSha = 'abc', int creationTime = 1, String author = 'dash', - int remainingBuilds = -1, - int failedBuilds = 0, - Map? builds, + int remainingJobs = -1, + int failedJobs = 0, + Map? jobs, }) { return PresubmitGuard( slug: slug ?? github.RepositorySlug('flutter', 'flutter'), - pullRequestId: pullRequestId, + prNum: prNum, checkRun: checkRun ?? generateCheckRun(1), stage: stage, - commitSha: commitSha, + headSha: headSha, creationTime: creationTime, author: author, - remainingBuilds: remainingBuilds >= 0 - ? remainingBuilds - : (builds?.length ?? 0), - failedBuilds: failedBuilds, - builds: builds, + remainingJobs: remainingJobs >= 0 ? remainingJobs : (jobs?.length ?? 0), + failedJobs: failedJobs, + jobs: jobs, ); } diff --git a/packages/cocoon_integration_test/lib/src/utilities/mocks.mocks.dart b/packages/cocoon_integration_test/lib/src/utilities/mocks.mocks.dart index cbcbd80af..37efe1c58 100644 --- a/packages/cocoon_integration_test/lib/src/utilities/mocks.mocks.dart +++ b/packages/cocoon_integration_test/lib/src/utilities/mocks.mocks.dart @@ -5771,7 +5771,7 @@ class MockScheduler extends _i1.Mock implements _i17.Scheduler { @override _i13.Future processCheckRunCompleted( - _i38.PresubmitCompletedCheck? check, + _i38.PresubmitCompletedJob? check, ) => (super.noSuchMethod( Invocation.method(#processCheckRunCompleted, [check]),