diff --git a/app_dart/lib/src/service/luci_build_service.dart b/app_dart/lib/src/service/luci_build_service.dart index cfae590e5..859615350 100644 --- a/app_dart/lib/src/service/luci_build_service.dart +++ b/app_dart/lib/src/service/luci_build_service.dart @@ -445,8 +445,11 @@ class LuciBuildService { ); } - if (isUnifiedCheckRunFlow && dashboardChecks != null) { - // For unified check run flow, update dashboard checks to in progress. + // Only set the dashboard check status to `CheckRunStatus.inProgress` for + // the initial run. For Re-run Failed Checks, we need to call GitHub's + // "rerequest check run" API, once it is supported by the `github` package. + final isInitialRun = targets.values.first == 1; + if (isUnifiedCheckRunFlow && dashboardChecks != null && isInitialRun) { try { await _githubChecksUtil.updateCheckRun( _config, diff --git a/app_dart/test/service/luci_build_service/schedule_try_builds_test.dart b/app_dart/test/service/luci_build_service/schedule_try_builds_test.dart index ea459b2ee..b7d2b1403 100644 --- a/app_dart/test/service/luci_build_service/schedule_try_builds_test.dart +++ b/app_dart/test/service/luci_build_service/schedule_try_builds_test.dart @@ -630,6 +630,90 @@ void main() { ).called(1); }, ); + + test('does not update dashboard checks for re-run failed checks', () async { + final pullRequest = generatePullRequest( + id: 1, + repo: 'flutter', + headSha: 'headsha123', + ); + + final buildTarget = generateTarget( + 1, + properties: {'os': 'abc'}, + slug: RepositorySlug.full('flutter/flutter'), + name: 'Linux foo', + ); + + // Enable Unified Check Run Flow + luci = LuciBuildService( + config: FakeConfig( + dynamicConfig: DynamicConfig( + unifiedCheckRunFlow: UnifiedCheckRunFlow(useForAll: true), + ), + ), + cache: CacheService.inMemory(), + buildBucketClient: mockBuildBucketClient, + githubChecksUtil: mockGithubChecksUtil, + pubsub: pubSub, + gerritService: gerritService, + firestore: firestore, + ); + + final checkRunGuard = generateCheckRun(1234, name: 'Guard'); + + await expectLater( + luci.reScheduleTryBuilds( + pullRequest: pullRequest, + targets: {buildTarget: 2}, // Re-run failed (attempt 2) + engineArtifacts: EngineArtifacts.builtFromSource( + commitSha: pullRequest.head!.sha!, + ), + dashboardChecks: checkRunGuard, + stage: CiStage.fusionTests, + ), + completion([isTarget.hasName('Linux foo')]), + ); + + // Should NOT create individual check runs + verifyNever(mockGithubChecksUtil.createCheckRun(any, any, any, any)); + + // Should NOT update dashboard checks status + verifyNever( + mockGithubChecksUtil.updateCheckRun( + any, + any, + any, + status: anyNamed('status'), + ), + ); + + final bbv2.ScheduleBuildRequest scheduleBuild; + { + final batchRequest = bbv2.BatchRequest().createEmptyInstance(); + batchRequest.mergeFromProto3Json(pubSub.messages.single); + scheduleBuild = batchRequest.requests.single.scheduleBuild; + } + + final userData = PresubmitUserData.fromBytes( + scheduleBuild.notify.userData, + ); + expect(userData.guardCheckRunId, 1234); + expect(userData.stage, CiStage.fusionTests); + expect(userData.checkRunId, isNull); + + final tags = BuildTags.fromStringPairs(scheduleBuild.tags); + expect( + tags.buildTags.contains(GuardCheckRunIdBuildTag(guardCheckRunId: 1234)), + isTrue, + reason: 'Should have GuardCheckRunIdBuildTag', + ); + expect( + tags.buildTags.contains(CurrentAttemptBuildTag(attemptNumber: 2)), + isTrue, + reason: 'Should have CurrentAttemptBuildTag', + ); + }); }); group('Ordered Presubmit', () {