| ... | @@ -1576,6 +1576,9 @@ function toCheckStatus(raw: Schema.Schema.Type<typeof RawCheckSchema>): PullRequ | ... | @@ -1576,6 +1576,9 @@ function toCheckStatus(raw: Schema.Schema.Type<typeof RawCheckSchema>): PullRequ |
| 1576 | /** What GitHub writes where a run has not reached that moment yet, which is not a time. */ | 1576 | /** What GitHub writes where a run has not reached that moment yet, which is not a time. */ |
| 1577 | const UNSET_TIMESTAMP = "0001-01-01T00:00:00Z"; | 1577 | const UNSET_TIMESTAMP = "0001-01-01T00:00:00Z"; |
| 1578 | | 1578 | |
| | 1579 | /** Sorts after every real timestamp, so the deduper keeps a run that has not finished. */ |
| | 1580 | const STILL_RUNNING = "9999-12-31T23:59:59Z"; |
| | 1581 | |
| 1579 | function realTimestamp(value: string | null | undefined): string | null { | 1582 | function realTimestamp(value: string | null | undefined): string | null { |
| 1580 | const at = trimmed(value); | 1583 | const at = trimmed(value); |
| 1581 | return at === null || at === UNSET_TIMESTAMP ? null : at; | 1584 | return at === null || at === UNSET_TIMESTAMP ? null : at; |
| ... | @@ -1588,8 +1591,9 @@ function isNamelessCheck(raw: Schema.Schema.Type<typeof RawCheckSchema>): boolea | ... | @@ -1588,8 +1591,9 @@ function isNamelessCheck(raw: Schema.Schema.Type<typeof RawCheckSchema>): boolea |
| 1588 | | 1591 | |
| 1589 | /** | 1592 | /** |
| 1590 | * The rollup as the deduper reads it: a check, the workflow that owns it, and when the run last | 1593 | * The rollup as the deduper reads it: a check, the workflow that owns it, and when the run last |
| 1591 | * had something to say. A queued run reports a completion time it has not reached, so the start | 1594 | * had something to say. A run that has not finished outranks any finished run of the same check: |
| 1592 | * stands in for it rather than sorting the newest run to the bottom. | 1595 | * a workflow triggered by both `push` and `pull_request` runs the check twice on one commit, and |
| | 1596 | * the run that finished first must not hide the one still going. |
| 1593 | */ | 1597 | */ |
| 1594 | function toCheckEntries( | 1598 | function toCheckEntries( |
| 1595 | raw: ReadonlyArray<Schema.Schema.Type<typeof RawCheckSchema>> | null | undefined, | 1599 | raw: ReadonlyArray<Schema.Schema.Type<typeof RawCheckSchema>> | null | undefined, |
| ... | @@ -1601,17 +1605,21 @@ function toCheckEntries( | ... | @@ -1601,17 +1605,21 @@ function toCheckEntries( |
| 1601 | return (raw ?? []).flatMap((check) => { | 1605 | return (raw ?? []).flatMap((check) => { |
| 1602 | const name = trimmed(check.name) ?? trimmed(check.context); | 1606 | const name = trimmed(check.name) ?? trimmed(check.context); |
| 1603 | if (name === null) return []; | 1607 | if (name === null) return []; |
| | 1608 | const status = toCheckStatus(check); |
| 1604 | return [ | 1609 | return [ |
| 1605 | { | 1610 | { |
| 1606 | check: { | 1611 | check: { |
| 1607 | name, | 1612 | name, |
| 1608 | status: toCheckStatus(check), | 1613 | status, |
| 1609 | description: trimmed(check.description), | 1614 | description: trimmed(check.description), |
| 1610 | url: trimmed(check.detailsUrl) ?? trimmed(check.targetUrl), | 1615 | url: trimmed(check.detailsUrl) ?? trimmed(check.targetUrl), |
| 1611 | ...(typeof check.isRequired === "boolean" ? { required: check.isRequired } : {}), | 1616 | ...(typeof check.isRequired === "boolean" ? { required: check.isRequired } : {}), |
| 1612 | }, | 1617 | }, |
| 1613 | workflowName: trimmed(check.workflowName), | 1618 | workflowName: trimmed(check.workflowName), |
| 1614 | at: realTimestamp(check.completedAt) ?? realTimestamp(check.startedAt), | 1619 | at: |
| | 1620 | status === "pending" |
| | 1621 | ? STILL_RUNNING |
| | 1622 | : (realTimestamp(check.completedAt) ?? realTimestamp(check.startedAt)), |
| 1615 | }, | 1623 | }, |
| 1616 | ]; | 1624 | ]; |
| 1617 | }); | 1625 | }); |