Skip to content

Commit 5d30a1f

Browse files
authored
Unified check run data layer (#4905)
Unified check run data layer Fixes: flutter/flutter#176979
1 parent 3dc7899 commit 5d30a1f

20 files changed

+1683
-33
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright 2025 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
/// @docImport 'presubmit_check_state.dart';
6+
library;
7+
8+
import 'package:buildbucket/buildbucket_pb.dart' as bbv2;
9+
import 'package:cocoon_common/task_status.dart';
10+
11+
import '../../service/luci_build_service/build_tags.dart';
12+
import '../bbv2_extension.dart';
13+
14+
/// Represents the current state of a check run.
15+
class PresubmitCheckState {
16+
final String buildName;
17+
final TaskStatus status;
18+
final int attemptNumber; //static int _currentAttempt(BuildTags buildTags)
19+
final int? startTime;
20+
final int? endTime;
21+
final String? summary;
22+
23+
const PresubmitCheckState({
24+
required this.buildName,
25+
required this.status,
26+
required this.attemptNumber,
27+
this.startTime,
28+
this.endTime,
29+
this.summary,
30+
});
31+
32+
/// Returns true if the build is waiting for backfill or in progress.
33+
bool get isBuildInProgress =>
34+
status == TaskStatus.waitingForBackfill ||
35+
status == TaskStatus.inProgress;
36+
37+
/// Returns true if the build succeeded or was skipped.
38+
bool get isBuildSuccessed =>
39+
status == TaskStatus.succeeded || status == TaskStatus.skipped;
40+
41+
/// Returns true if the build failed, had an infra failure, or was cancelled.
42+
bool get isBuildFailed =>
43+
status == TaskStatus.failed ||
44+
status == TaskStatus.infraFailure ||
45+
status == TaskStatus.cancelled;
46+
}
47+
48+
extension BuildToPresubmitCheckState on bbv2.Build {
49+
PresubmitCheckState toPresubmitCheckState() => PresubmitCheckState(
50+
buildName: builder.builder,
51+
status: status.toTaskStatus(),
52+
attemptNumber: BuildTags.fromStringPairs(tags).currentAttempt,
53+
startTime: startTime.toDateTime().microsecondsSinceEpoch,
54+
endTime: endTime.toDateTime().microsecondsSinceEpoch,
55+
summary: summaryMarkdown,
56+
);
57+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright 2025 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
/// @docImport 'presubmit_guard_conclusion.dart';
6+
library;
7+
8+
/// Explains what happened when attempting to mark the conclusion of a check run
9+
/// using [PresubmitGuard.markConclusion].
10+
enum PresubmitGuardConclusionResult {
11+
/// Check run update recorded successfully in the respective CI stage.
12+
///
13+
/// It is OK to evaluate returned results for stage completeness.
14+
ok,
15+
16+
/// The check run is not in the specified CI stage.
17+
///
18+
/// Perhaps it's from a different CI stage.
19+
missing,
20+
21+
/// An unexpected error happened, and the results of the conclusion are
22+
/// undefined.
23+
///
24+
/// Examples of situations that can lead to this result:
25+
///
26+
/// * The Firestore document is missing.
27+
/// * The contents of the Firestore document are inconsistent.
28+
/// * An unexpected error happend while trying to read from/write to Firestore.
29+
///
30+
/// When this happens, it's best to stop the current transaction, report the
31+
/// error to the logs, and have someone investigate the issue.
32+
internalError,
33+
}
34+
35+
/// Results from attempting to mark a staging task as completed.
36+
///
37+
/// See: [PresubmitGuard.markConclusion]
38+
class PresubmitGuardConclusion {
39+
final PresubmitGuardConclusionResult result;
40+
final int remaining;
41+
final int? checkRunId;
42+
final int failed;
43+
final String summary;
44+
final String details;
45+
46+
const PresubmitGuardConclusion({
47+
required this.result,
48+
required this.remaining,
49+
required this.checkRunId,
50+
required this.failed,
51+
required this.summary,
52+
required this.details,
53+
});
54+
55+
bool get isOk => result == PresubmitGuardConclusionResult.ok;
56+
57+
bool get isPending => isOk && remaining > 0;
58+
59+
bool get isFailed => isOk && !isPending && failed > 0;
60+
61+
bool get isComplete => isOk && !isPending && !isFailed;
62+
63+
@override
64+
bool operator ==(Object other) =>
65+
identical(this, other) ||
66+
(other is PresubmitGuardConclusion &&
67+
other.result == result &&
68+
other.remaining == remaining &&
69+
other.checkRunId == checkRunId &&
70+
other.failed == failed &&
71+
other.summary == summary &&
72+
other.details == details);
73+
74+
@override
75+
int get hashCode =>
76+
Object.hashAll([result, remaining, checkRunId, failed, summary, details]);
77+
78+
@override
79+
String toString() =>
80+
'BuildConclusion("$result", "$remaining", "$checkRunId", "$failed", "$summary", "$details")';
81+
}

app_dart/lib/src/model/firestore/base.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,25 @@ import 'dart:convert';
77
import 'package:googleapis/firestore/v1.dart' as g;
88
import 'package:meta/meta.dart';
99

10+
/// Well-defined stages in the build infrastructure.
11+
enum CiStage implements Comparable<CiStage> {
12+
/// Build engine artifacts
13+
fusionEngineBuild('engine'),
14+
15+
/// All non-engine artifact tests (engine & framework)
16+
fusionTests('fusion');
17+
18+
const CiStage(this.name);
19+
20+
final String name;
21+
22+
@override
23+
int compareTo(CiStage other) => index - other.index;
24+
25+
@override
26+
String toString() => name;
27+
}
28+
1029
/// Defines the `documentId` for a given document [T].
1130
///
1231
/// The path to a document in Firestore follows the pattern:

app_dart/lib/src/model/firestore/ci_staging.dart

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -479,25 +479,6 @@ enum TaskConclusion {
479479
bool get isSuccess => this == success;
480480
}
481481

482-
/// Well-defined stages in the build infrastructure.
483-
enum CiStage implements Comparable<CiStage> {
484-
/// Build engine artifacts
485-
fusionEngineBuild('engine'),
486-
487-
/// All non-engine artifact tests (engine & framework)
488-
fusionTests('fusion');
489-
490-
const CiStage(this.name);
491-
492-
final String name;
493-
494-
@override
495-
int compareTo(CiStage other) => index - other.index;
496-
497-
@override
498-
String toString() => name;
499-
}
500-
501482
/// Explains what happened when attempting to mark the conclusion of a check run
502483
/// using [CiStaging.markConclusion].
503484
enum StagingConclusionResult {

0 commit comments

Comments
 (0)