@@ -76,66 +76,6 @@ final class UnifiedCheckRun {
7676 }
7777 }
7878
79- /// Initializes a new document for the given [tasks] in Firestore so that stage-tracking can succeed.
80- ///
81- /// The list of tasks will be written as fields of a document with additional fields for tracking the creationTime
82- /// number of tasks, remaining count. It is required to include [commitSha] as a json encoded [CheckRun] as this
83- /// will be used to unlock any check runs blocking progress.
84- ///
85- /// Returns the created document or throws an error.
86- static Future <Document > initializePresubmitGuardDocument ({
87- required FirestoreService firestoreService,
88-
89- required RepositorySlug slug,
90- required int pullRequestId,
91- required CheckRun checkRun,
92- required CiStage stage,
93- required String commitSha,
94- required int creationTime,
95- required String author,
96- required List <String > tasks,
97- }) async {
98- final buildCount = tasks.length;
99- final logCrumb =
100- 'initializeDocument(${slug .owner }_${slug .name }_${pullRequestId }_${checkRun .id }_$stage , $buildCount builds)' ;
101-
102- final presubmitGuard = PresubmitGuard (
103- checkRun: checkRun,
104- commitSha: commitSha,
105- slug: slug,
106- pullRequestId: pullRequestId,
107- stage: stage,
108- creationTime: creationTime,
109- author: author,
110- remainingBuilds: buildCount,
111- failedBuilds: 0 ,
112- builds: {for (final task in tasks) task: TaskStatus .waitingForBackfill},
113- );
114-
115- final presubmitGuardId = PresubmitGuard .documentIdFor (
116- slug: slug,
117- pullRequestId: pullRequestId,
118- checkRunId: checkRun.id! ,
119- stage: stage,
120- );
121-
122- try {
123- // Calling createDocument multiple times for the same documentId will return a 409 - ALREADY_EXISTS error;
124- // this is good because it means we don't have to do any transactions.
125- // curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer <TOKEN>" "https://firestore.googleapis.com/v1beta1/projects/flutter-dashboard/databases/cocoon/documents/presubmit_guard?documentId=foo_bar_baz" -d '{"fields": {"test": {"stringValue": "baz"}}}'
126- final newDoc = await firestoreService.createDocument (
127- presubmitGuard,
128- collectionId: presubmitGuard.runtimeMetadata.collectionId,
129- documentId: presubmitGuardId.documentId,
130- );
131- log.info ('$logCrumb : document created' );
132- return newDoc;
133- } catch (e) {
134- log.warn ('$logCrumb : failed to create document' , e);
135- rethrow ;
136- }
137- }
138-
13979 /// Returns _all_ checks running against the specified github [checkRunId] .
14080 static Future <List <PresubmitCheck >> queryAllPresubmitChecksForGuard ({
14181 required FirestoreService firestoreService,
@@ -248,9 +188,9 @@ final class UnifiedCheckRun {
248188 await firestoreService.rollback (transaction);
249189 return PresubmitGuardConclusion (
250190 result: PresubmitGuardConclusionResult .missing,
251- remaining: presubmitGuard.remainingBuilds ?? - 1 ,
191+ remaining: presubmitGuard.remainingBuilds! ,
252192 checkRunGuard: presubmitGuard.checkRunJson,
253- failed: presubmitGuard.failedBuilds ?? - 1 ,
193+ failed: presubmitGuard.failedBuilds! ,
254194 summary:
255195 'Check run "${state .buildName }" not present in ${guardId .stage } CI stage' ,
256196 details: 'Change $changeCrumb ' ,
@@ -271,11 +211,24 @@ final class UnifiedCheckRun {
271211 remaining = presubmitGuard.remainingBuilds! ;
272212 failed = presubmitGuard.failedBuilds! ;
273213 final builds = presubmitGuard.builds;
214+ var status = builds? [state.buildName]! ;
274215
275- // If build is in progress, we should only update appropriate checks with
276- // that [TaskStatus]
277- if (state.status.isBuildInProgress) {
216+ // If build is waiting for backfill, that means its initiated by github
217+ // or re-run. So no processing needed, we should only update appropriate
218+ // checks with that [TaskStatus]
219+ if (state.status == TaskStatus .waitingForBackfill) {
220+ status = state.status;
221+ valid = true ;
222+ // If build is in progress, we should update apropriate checks with start
223+ // time and their status to that [TaskStatus] only if the build is not
224+ // completed.
225+ } else if (state.status == TaskStatus .inProgress) {
278226 presubmitCheck.startTime = state.startTime! ;
227+ // If the build is not completed, update the status.
228+ if (! status! .isBuildCompleted) {
229+ status = state.status;
230+ }
231+ valid = true ;
279232 } else {
280233 // "remaining" should go down if buildSuccessed of any attempt
281234 // or buildFailed a first attempt.
@@ -284,35 +237,35 @@ final class UnifiedCheckRun {
284237 // attemptNumber = 1 && buildFailed: up (+1)
285238 // So if the test existed and either remaining or failed_count is changed;
286239 // the response is valid.
287-
288- if (state.status.isBuildSuccessed ||
289- state.attemptNumber == 1 && state.status.isBuildFailed) {
240+ status = state.status;
241+ if (status.isBuildSuccessed) {
290242 // Guard against going negative and log enough info so we can debug.
291243 if (remaining == 0 ) {
292244 throw '$logCrumb : field "${PresubmitGuard .fieldRemainingBuilds }" is already zero for $transaction / ${presubmitGuardDocument .fields }' ;
293245 }
294246 remaining = remaining - 1 ;
295- valid = true ;
296- }
297247
298- // Only rollback the "failed" counter if this is a successful test run,
299- // i.e. the test failed, the user requested a rerun, and now it passes.
300- if (state.attemptNumber > 1 && state.status.isBuildSuccessed) {
301- log.info (
302- '$logCrumb : conclusion flipped to positive - assuming test was re-run' ,
303- );
304- if (failed == 0 ) {
305- throw '$logCrumb : field "${PresubmitGuard .fieldFailedBuilds }" is already zero for $transaction / ${presubmitGuardDocument .fields }' ;
248+ // Only rollback the "failed" counter if this is a successful test run,
249+ // i.e. the test failed, the user requested a rerun, and now it passes.
250+ if (state.attemptNumber > 1 ) {
251+ log.info (
252+ '$logCrumb : conclusion flipped to positive - assuming test was re-run' ,
253+ );
254+ if (failed == 0 ) {
255+ throw '$logCrumb : field "${PresubmitGuard .fieldFailedBuilds }" is already zero for $transaction / ${presubmitGuardDocument .fields }' ;
256+ }
257+ failed = failed - 1 ;
306258 }
307259 valid = true ;
308- failed = failed - 1 ;
309260 }
310261
311262 // Only increment the "failed" counter if the conclusion failed for the first attempt.
312- if (state.attemptNumber == 1 && state.status.isBuildFailed) {
313- log.info ('$logCrumb : test failed' );
263+ if (status.isBuildFailed) {
264+ if (state.attemptNumber == 1 ) {
265+ log.info ('$logCrumb : test failed' );
266+ failed = failed + 1 ;
267+ }
314268 valid = true ;
315- failed = failed + 1 ;
316269 }
317270
318271 // All checks pass. "valid" is only set to true if there was a change in either the remaining or failed count.
@@ -323,9 +276,10 @@ final class UnifiedCheckRun {
323276 presubmitGuard.failedBuilds = failed;
324277 presubmitCheck.endTime = state.endTime! ;
325278 }
326- builds! [state.buildName] = state. status;
279+ builds! [state.buildName] = status;
327280 presubmitGuard.builds = builds;
328- presubmitCheck.status = state.status;
281+ presubmitCheck.status = status;
282+ presubmitCheck.summary = state.summary;
329283 } on DetailedApiRequestError catch (e, stack) {
330284 if (e.status == 404 ) {
331285 // An attempt to read a document not in firestore should not be retried.
0 commit comments