pr-merge-queue 0.0.0-stage → 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +125 -2
- package/dist/claim-pr/claim-pr.d.mts +45 -0
- package/dist/claim-pr/claim-pr.d.mts.map +1 -0
- package/dist/claim-pr/claim-pr.mjs +217 -0
- package/dist/claim-pr/claim-pr.mjs.map +1 -0
- package/dist/claim-pr/index.d.mts +2 -0
- package/dist/claim-pr/index.d.mts.map +1 -0
- package/dist/claim-pr/index.mjs +2 -0
- package/dist/claim-pr/index.mjs.map +1 -0
- package/dist/cmd/claim-pr.d.mts +3 -0
- package/dist/cmd/claim-pr.d.mts.map +1 -0
- package/dist/cmd/claim-pr.mjs +20 -0
- package/dist/cmd/claim-pr.mjs.map +1 -0
- package/dist/cmd/open-pr.d.mts +3 -0
- package/dist/cmd/open-pr.d.mts.map +1 -0
- package/dist/cmd/open-pr.mjs +20 -0
- package/dist/cmd/open-pr.mjs.map +1 -0
- package/dist/cmd/pr-report.d.mts +3 -0
- package/dist/cmd/pr-report.d.mts.map +1 -0
- package/dist/cmd/pr-report.mjs +20 -0
- package/dist/cmd/pr-report.mjs.map +1 -0
- package/dist/cmd/push-fixed-pr.d.mts +3 -0
- package/dist/cmd/push-fixed-pr.d.mts.map +1 -0
- package/dist/cmd/push-fixed-pr.mjs +20 -0
- package/dist/cmd/push-fixed-pr.mjs.map +1 -0
- package/dist/cmd/report-unowned-prs.d.mts +3 -0
- package/dist/cmd/report-unowned-prs.d.mts.map +1 -0
- package/dist/cmd/report-unowned-prs.mjs +20 -0
- package/dist/cmd/report-unowned-prs.mjs.map +1 -0
- package/dist/cmd/unblock-prs.d.mts +3 -0
- package/dist/cmd/unblock-prs.d.mts.map +1 -0
- package/dist/cmd/unblock-prs.mjs +19 -0
- package/dist/cmd/unblock-prs.mjs.map +1 -0
- package/dist/entry-point.d.mts +3 -0
- package/dist/entry-point.d.mts.map +1 -0
- package/dist/entry-point.mjs +3 -0
- package/dist/entry-point.mjs.map +1 -0
- package/dist/lib/cli-args.d.mts +27 -0
- package/dist/lib/cli-args.d.mts.map +1 -0
- package/dist/lib/cli-args.mjs +55 -0
- package/dist/lib/cli-args.mjs.map +1 -0
- package/dist/lib/github-api.d.mts +153 -0
- package/dist/lib/github-api.d.mts.map +1 -0
- package/dist/lib/github-api.mjs +291 -0
- package/dist/lib/github-api.mjs.map +1 -0
- package/dist/lib/index.d.mts +7 -0
- package/dist/lib/index.d.mts.map +1 -0
- package/dist/lib/index.mjs +7 -0
- package/dist/lib/index.mjs.map +1 -0
- package/dist/lib/json.d.mts +12 -0
- package/dist/lib/json.d.mts.map +1 -0
- package/dist/lib/json.mjs +28 -0
- package/dist/lib/json.mjs.map +1 -0
- package/dist/lib/log.d.mts +10 -0
- package/dist/lib/log.d.mts.map +1 -0
- package/dist/lib/log.mjs +13 -0
- package/dist/lib/log.mjs.map +1 -0
- package/dist/lib/shell.d.mts +18 -0
- package/dist/lib/shell.d.mts.map +1 -0
- package/dist/lib/shell.mjs +42 -0
- package/dist/lib/shell.mjs.map +1 -0
- package/dist/lib/time.d.mts +17 -0
- package/dist/lib/time.d.mts.map +1 -0
- package/dist/lib/time.mjs +35 -0
- package/dist/lib/time.mjs.map +1 -0
- package/dist/open-pr/github.d.mts +72 -0
- package/dist/open-pr/github.d.mts.map +1 -0
- package/dist/open-pr/github.mjs +249 -0
- package/dist/open-pr/github.mjs.map +1 -0
- package/dist/open-pr/index.d.mts +6 -0
- package/dist/open-pr/index.d.mts.map +1 -0
- package/dist/open-pr/index.mjs +6 -0
- package/dist/open-pr/index.mjs.map +1 -0
- package/dist/open-pr/main.d.mts +36 -0
- package/dist/open-pr/main.d.mts.map +1 -0
- package/dist/open-pr/main.mjs +204 -0
- package/dist/open-pr/main.mjs.map +1 -0
- package/dist/open-pr/options.d.mts +20 -0
- package/dist/open-pr/options.d.mts.map +1 -0
- package/dist/open-pr/options.mjs +66 -0
- package/dist/open-pr/options.mjs.map +1 -0
- package/dist/open-pr/steps.d.mts +23 -0
- package/dist/open-pr/steps.d.mts.map +1 -0
- package/dist/open-pr/steps.mjs +38 -0
- package/dist/open-pr/steps.mjs.map +1 -0
- package/dist/open-pr/types.d.mts +179 -0
- package/dist/open-pr/types.d.mts.map +1 -0
- package/dist/open-pr/types.mjs +20 -0
- package/dist/open-pr/types.mjs.map +1 -0
- package/dist/pr-report/github.d.mts +59 -0
- package/dist/pr-report/github.d.mts.map +1 -0
- package/dist/pr-report/github.mjs +561 -0
- package/dist/pr-report/github.mjs.map +1 -0
- package/dist/pr-report/index.d.mts +8 -0
- package/dist/pr-report/index.d.mts.map +1 -0
- package/dist/pr-report/index.mjs +8 -0
- package/dist/pr-report/index.mjs.map +1 -0
- package/dist/pr-report/linked-issues.d.mts +15 -0
- package/dist/pr-report/linked-issues.d.mts.map +1 -0
- package/dist/pr-report/linked-issues.mjs +39 -0
- package/dist/pr-report/linked-issues.mjs.map +1 -0
- package/dist/pr-report/main.d.mts +42 -0
- package/dist/pr-report/main.d.mts.map +1 -0
- package/dist/pr-report/main.mjs +163 -0
- package/dist/pr-report/main.mjs.map +1 -0
- package/dist/pr-report/options.d.mts +36 -0
- package/dist/pr-report/options.d.mts.map +1 -0
- package/dist/pr-report/options.mjs +90 -0
- package/dist/pr-report/options.mjs.map +1 -0
- package/dist/pr-report/queue.d.mts +28 -0
- package/dist/pr-report/queue.d.mts.map +1 -0
- package/dist/pr-report/queue.mjs +74 -0
- package/dist/pr-report/queue.mjs.map +1 -0
- package/dist/pr-report/render.d.mts +14 -0
- package/dist/pr-report/render.d.mts.map +1 -0
- package/dist/pr-report/render.mjs +318 -0
- package/dist/pr-report/render.mjs.map +1 -0
- package/dist/pr-report/repo-settings.d.mts +12 -0
- package/dist/pr-report/repo-settings.d.mts.map +1 -0
- package/dist/pr-report/repo-settings.mjs +22 -0
- package/dist/pr-report/repo-settings.mjs.map +1 -0
- package/dist/push-fixed-pr/index.d.mts +2 -0
- package/dist/push-fixed-pr/index.d.mts.map +1 -0
- package/dist/push-fixed-pr/index.mjs +2 -0
- package/dist/push-fixed-pr/index.mjs.map +1 -0
- package/dist/push-fixed-pr/push-fixed-pr.d.mts +54 -0
- package/dist/push-fixed-pr/push-fixed-pr.d.mts.map +1 -0
- package/dist/push-fixed-pr/push-fixed-pr.mjs +172 -0
- package/dist/push-fixed-pr/push-fixed-pr.mjs.map +1 -0
- package/dist/report-unowned-prs/index.d.mts +2 -0
- package/dist/report-unowned-prs/index.d.mts.map +1 -0
- package/dist/report-unowned-prs/index.mjs +2 -0
- package/dist/report-unowned-prs/index.mjs.map +1 -0
- package/dist/report-unowned-prs/report-unowned-prs.d.mts +49 -0
- package/dist/report-unowned-prs/report-unowned-prs.d.mts.map +1 -0
- package/dist/report-unowned-prs/report-unowned-prs.mjs +127 -0
- package/dist/report-unowned-prs/report-unowned-prs.mjs.map +1 -0
- package/dist/tsconfig.json +1 -0
- package/dist/unblock-prs/auto-fix.d.mts +45 -0
- package/dist/unblock-prs/auto-fix.d.mts.map +1 -0
- package/dist/unblock-prs/auto-fix.mjs +207 -0
- package/dist/unblock-prs/auto-fix.mjs.map +1 -0
- package/dist/unblock-prs/checks.d.mts +307 -0
- package/dist/unblock-prs/checks.d.mts.map +1 -0
- package/dist/unblock-prs/checks.mjs +372 -0
- package/dist/unblock-prs/checks.mjs.map +1 -0
- package/dist/unblock-prs/claims.d.mts +21 -0
- package/dist/unblock-prs/claims.d.mts.map +1 -0
- package/dist/unblock-prs/claims.mjs +23 -0
- package/dist/unblock-prs/claims.mjs.map +1 -0
- package/dist/unblock-prs/config.d.mts +487 -0
- package/dist/unblock-prs/config.d.mts.map +1 -0
- package/dist/unblock-prs/config.mjs +119 -0
- package/dist/unblock-prs/config.mjs.map +1 -0
- package/dist/unblock-prs/constants.d.mts +28 -0
- package/dist/unblock-prs/constants.d.mts.map +1 -0
- package/dist/unblock-prs/constants.mjs +28 -0
- package/dist/unblock-prs/constants.mjs.map +1 -0
- package/dist/unblock-prs/demotions.d.mts +42 -0
- package/dist/unblock-prs/demotions.d.mts.map +1 -0
- package/dist/unblock-prs/demotions.mjs +50 -0
- package/dist/unblock-prs/demotions.mjs.map +1 -0
- package/dist/unblock-prs/github.d.mts +739 -0
- package/dist/unblock-prs/github.d.mts.map +1 -0
- package/dist/unblock-prs/github.mjs +626 -0
- package/dist/unblock-prs/github.mjs.map +1 -0
- package/dist/unblock-prs/index.d.mts +25 -0
- package/dist/unblock-prs/index.d.mts.map +1 -0
- package/dist/unblock-prs/index.mjs +25 -0
- package/dist/unblock-prs/index.mjs.map +1 -0
- package/dist/unblock-prs/labels.d.mts +49 -0
- package/dist/unblock-prs/labels.d.mts.map +1 -0
- package/dist/unblock-prs/labels.mjs +49 -0
- package/dist/unblock-prs/labels.mjs.map +1 -0
- package/dist/unblock-prs/main.d.mts +179 -0
- package/dist/unblock-prs/main.d.mts.map +1 -0
- package/dist/unblock-prs/main.mjs +640 -0
- package/dist/unblock-prs/main.mjs.map +1 -0
- package/dist/unblock-prs/merge-after.d.mts +46 -0
- package/dist/unblock-prs/merge-after.d.mts.map +1 -0
- package/dist/unblock-prs/merge-after.mjs +65 -0
- package/dist/unblock-prs/merge-after.mjs.map +1 -0
- package/dist/unblock-prs/options.d.mts +35 -0
- package/dist/unblock-prs/options.d.mts.map +1 -0
- package/dist/unblock-prs/options.mjs +88 -0
- package/dist/unblock-prs/options.mjs.map +1 -0
- package/dist/unblock-prs/owner.d.mts +32 -0
- package/dist/unblock-prs/owner.d.mts.map +1 -0
- package/dist/unblock-prs/owner.mjs +63 -0
- package/dist/unblock-prs/owner.mjs.map +1 -0
- package/dist/unblock-prs/quiet.d.mts +21 -0
- package/dist/unblock-prs/quiet.d.mts.map +1 -0
- package/dist/unblock-prs/quiet.mjs +42 -0
- package/dist/unblock-prs/quiet.mjs.map +1 -0
- package/dist/unblock-prs/rebase.d.mts +120 -0
- package/dist/unblock-prs/rebase.d.mts.map +1 -0
- package/dist/unblock-prs/rebase.mjs +576 -0
- package/dist/unblock-prs/rebase.mjs.map +1 -0
- package/dist/unblock-prs/release.d.mts +62 -0
- package/dist/unblock-prs/release.d.mts.map +1 -0
- package/dist/unblock-prs/release.mjs +94 -0
- package/dist/unblock-prs/release.mjs.map +1 -0
- package/dist/unblock-prs/set-aside-comment.d.mts +20 -0
- package/dist/unblock-prs/set-aside-comment.d.mts.map +1 -0
- package/dist/unblock-prs/set-aside-comment.mjs +93 -0
- package/dist/unblock-prs/set-aside-comment.mjs.map +1 -0
- package/dist/unblock-prs/set-aside-detail.d.mts +41 -0
- package/dist/unblock-prs/set-aside-detail.d.mts.map +1 -0
- package/dist/unblock-prs/set-aside-detail.mjs +56 -0
- package/dist/unblock-prs/set-aside-detail.mjs.map +1 -0
- package/dist/unblock-prs/skips.d.mts +85 -0
- package/dist/unblock-prs/skips.d.mts.map +1 -0
- package/dist/unblock-prs/skips.mjs +141 -0
- package/dist/unblock-prs/skips.mjs.map +1 -0
- package/dist/unblock-prs/stack.d.mts +98 -0
- package/dist/unblock-prs/stack.d.mts.map +1 -0
- package/dist/unblock-prs/stack.mjs +141 -0
- package/dist/unblock-prs/stack.mjs.map +1 -0
- package/dist/unblock-prs/triage.d.mts +28 -0
- package/dist/unblock-prs/triage.d.mts.map +1 -0
- package/dist/unblock-prs/triage.mjs +396 -0
- package/dist/unblock-prs/triage.mjs.map +1 -0
- package/dist/unblock-prs/types.d.mts +793 -0
- package/dist/unblock-prs/types.d.mts.map +1 -0
- package/dist/unblock-prs/types.mjs +26 -0
- package/dist/unblock-prs/types.mjs.map +1 -0
- package/dist/unblock-prs/util.d.mts +23 -0
- package/dist/unblock-prs/util.d.mts.map +1 -0
- package/dist/unblock-prs/util.mjs +60 -0
- package/dist/unblock-prs/util.mjs.map +1 -0
- package/dist/unblock-prs/version-pr.d.mts +57 -0
- package/dist/unblock-prs/version-pr.d.mts.map +1 -0
- package/dist/unblock-prs/version-pr.mjs +79 -0
- package/dist/unblock-prs/version-pr.mjs.map +1 -0
- package/dist/unblock-prs/watch.d.mts +17 -0
- package/dist/unblock-prs/watch.d.mts.map +1 -0
- package/dist/unblock-prs/watch.mjs +128 -0
- package/dist/unblock-prs/watch.mjs.map +1 -0
- package/package.json +118 -3
- package/src/claim-pr/claim-pr.mts +380 -0
- package/src/claim-pr/claim-pr.test.mts +176 -0
- package/src/claim-pr/index.mts +1 -0
- package/src/cmd/claim-pr.mts +32 -0
- package/src/cmd/open-pr.mts +28 -0
- package/src/cmd/pr-report.mts +28 -0
- package/src/cmd/push-fixed-pr.mts +36 -0
- package/src/cmd/report-unowned-prs.mts +37 -0
- package/src/cmd/unblock-prs.mts +24 -0
- package/src/entry-point.mts +3 -0
- package/src/lib/cli-args.mts +86 -0
- package/src/lib/cli-args.test.mts +92 -0
- package/src/lib/github-api.mts +463 -0
- package/src/lib/github-api.test.mts +40 -0
- package/src/lib/index.mts +6 -0
- package/src/lib/json.mts +43 -0
- package/src/lib/json.test.mts +34 -0
- package/src/lib/log.mts +19 -0
- package/src/lib/log.test.mts +45 -0
- package/src/lib/shell.mts +52 -0
- package/src/lib/time.mts +49 -0
- package/src/open-pr/README.md +237 -0
- package/src/open-pr/github.mts +444 -0
- package/src/open-pr/index.mts +5 -0
- package/src/open-pr/main.mts +327 -0
- package/src/open-pr/options.mts +101 -0
- package/src/open-pr/options.test.mts +67 -0
- package/src/open-pr/steps.mts +57 -0
- package/src/open-pr/steps.test.mts +59 -0
- package/src/open-pr/types.mts +42 -0
- package/src/pr-report/README.md +244 -0
- package/src/pr-report/github.mts +911 -0
- package/src/pr-report/index.mts +7 -0
- package/src/pr-report/linked-issues.mts +51 -0
- package/src/pr-report/linked-issues.test.mts +65 -0
- package/src/pr-report/main.mts +257 -0
- package/src/pr-report/options.mts +140 -0
- package/src/pr-report/queue.mts +125 -0
- package/src/pr-report/render.mts +428 -0
- package/src/pr-report/render.test.mts +379 -0
- package/src/pr-report/repo-settings.mts +34 -0
- package/src/push-fixed-pr/index.mts +1 -0
- package/src/push-fixed-pr/push-fixed-pr.mts +276 -0
- package/src/push-fixed-pr/push-fixed-pr.test.mts +228 -0
- package/src/report-unowned-prs/index.mts +1 -0
- package/src/report-unowned-prs/report-unowned-prs.mts +190 -0
- package/src/report-unowned-prs/report-unowned-prs.test.mts +87 -0
- package/src/unblock-prs/README.md +1616 -0
- package/src/unblock-prs/auto-fix.mts +334 -0
- package/src/unblock-prs/auto-fix.test.mts +159 -0
- package/src/unblock-prs/checks.mts +538 -0
- package/src/unblock-prs/checks.test.mts +507 -0
- package/src/unblock-prs/claims.mts +33 -0
- package/src/unblock-prs/claims.test.mts +64 -0
- package/src/unblock-prs/config.mts +187 -0
- package/src/unblock-prs/config.schema.json +71 -0
- package/src/unblock-prs/config.test.mts +139 -0
- package/src/unblock-prs/constants.mts +33 -0
- package/src/unblock-prs/demotions.mts +73 -0
- package/src/unblock-prs/demotions.test.mts +100 -0
- package/src/unblock-prs/github.mts +1042 -0
- package/src/unblock-prs/github.test.mts +84 -0
- package/src/unblock-prs/index.mts +24 -0
- package/src/unblock-prs/labels.mts +70 -0
- package/src/unblock-prs/main.mts +1051 -0
- package/src/unblock-prs/merge-after.mts +117 -0
- package/src/unblock-prs/merge-after.test.mts +120 -0
- package/src/unblock-prs/options.mts +157 -0
- package/src/unblock-prs/owner.mts +91 -0
- package/src/unblock-prs/owner.test.mts +114 -0
- package/src/unblock-prs/quiet.mts +62 -0
- package/src/unblock-prs/quiet.test.mts +175 -0
- package/src/unblock-prs/rebase.mts +962 -0
- package/src/unblock-prs/release.mts +149 -0
- package/src/unblock-prs/release.test.mts +209 -0
- package/src/unblock-prs/set-aside-comment.mts +143 -0
- package/src/unblock-prs/set-aside-comment.test.mts +148 -0
- package/src/unblock-prs/set-aside-detail.mts +82 -0
- package/src/unblock-prs/set-aside-detail.test.mts +131 -0
- package/src/unblock-prs/skips.mts +215 -0
- package/src/unblock-prs/skips.test.mts +280 -0
- package/src/unblock-prs/stack.mts +220 -0
- package/src/unblock-prs/stack.test.mts +449 -0
- package/src/unblock-prs/triage.mts +669 -0
- package/src/unblock-prs/triage.test.mts +100 -0
- package/src/unblock-prs/types.mts +358 -0
- package/src/unblock-prs/util.mts +78 -0
- package/src/unblock-prs/util.test.mts +26 -0
- package/src/unblock-prs/version-pr.mts +112 -0
- package/src/unblock-prs/version-pr.test.mts +78 -0
- package/src/unblock-prs/watch.mts +219 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the merge is waiting for, read from the head commit's checks and
|
|
3
|
+
* judged against the contexts the ruleset requires.
|
|
4
|
+
*/
|
|
5
|
+
import { Result } from 'ts-data-forge';
|
|
6
|
+
import * as t from 'ts-fortress';
|
|
7
|
+
import { type ApiContext } from '../lib/index.mjs';
|
|
8
|
+
import type { ChecksSummary } from './types.mjs';
|
|
9
|
+
/**
|
|
10
|
+
* One check on the head, in the shape `gh pr checks --json` printed, which
|
|
11
|
+
* is what this script read until it called the API itself.
|
|
12
|
+
*/
|
|
13
|
+
export type ReportedCheck = Readonly<{
|
|
14
|
+
name: string;
|
|
15
|
+
/** `pass` | `fail` | `pending` | `skipping` | `cancel` */
|
|
16
|
+
bucket: string;
|
|
17
|
+
link: string;
|
|
18
|
+
/** ISO 8601; GitHub's zero time before the check has started. */
|
|
19
|
+
startedAt: string;
|
|
20
|
+
/** ISO 8601; GitHub's zero time before the check has finished. */
|
|
21
|
+
completedAt: string;
|
|
22
|
+
/** The workflow the job belongs to; empty for a commit status. */
|
|
23
|
+
workflow: string;
|
|
24
|
+
}>;
|
|
25
|
+
/**
|
|
26
|
+
* A check on the head that has not finished, when it started, and the
|
|
27
|
+
* workflow run it is a job of.
|
|
28
|
+
*/
|
|
29
|
+
export type RunningCheck = Readonly<{
|
|
30
|
+
name: string;
|
|
31
|
+
startedAt: string;
|
|
32
|
+
workflow: string;
|
|
33
|
+
link: string;
|
|
34
|
+
}>;
|
|
35
|
+
/**
|
|
36
|
+
* The checks that gate the merge, as GitHub reports them for the head commit.
|
|
37
|
+
* `isRequired` is GitHub's own answer for this pull request, so the list
|
|
38
|
+
* follows the ruleset without this script having to know it.
|
|
39
|
+
*/
|
|
40
|
+
export declare const listRequiredChecks: (api: ApiContext, prNumber: number) => Promise<Result<readonly ReportedCheck[], string>>;
|
|
41
|
+
/**
|
|
42
|
+
* The checks on the head commit that have not finished, required or not.
|
|
43
|
+
*
|
|
44
|
+
* A required aggregate has no run in a new round until the jobs it waits on
|
|
45
|
+
* are done, so until then the required ones answer with the round before.
|
|
46
|
+
* When that round was the one `skip-ci` skipped, every aggregate reads
|
|
47
|
+
* `skipped` and the commit looks green halfway through its matrix. Anything
|
|
48
|
+
* still running is what says the round is not over, and when it started is
|
|
49
|
+
* what tells a failure of the round before from one of this round.
|
|
50
|
+
*/
|
|
51
|
+
export declare const listRunningChecks: (api: ApiContext, prNumber: number) => Promise<Result<readonly RunningCheck[], string>>;
|
|
52
|
+
/**
|
|
53
|
+
* What the head commit's checks say, as `gh pr checks` said it: each check
|
|
54
|
+
* run and commit status in a bucket, and of the runs of one job in one
|
|
55
|
+
* workflow and event only the latest — a re-run, or the round `skip-ci`
|
|
56
|
+
* cancelled under the one now running — so that a superseded failure does
|
|
57
|
+
* not speak for its context. `which` is `'required'` for only what GitHub
|
|
58
|
+
* says this pull request requires.
|
|
59
|
+
*
|
|
60
|
+
* Unlike `gh`, the survivors keep the order GitHub listed them in. A commit
|
|
61
|
+
* status's start and finish are both when it was set, the one time it has.
|
|
62
|
+
*/
|
|
63
|
+
export declare const reportedChecksOf: (contexts: readonly CheckContextNode[], which: 'all' | 'required') => readonly ReportedCheck[];
|
|
64
|
+
/** A context of the head commit's status check rollup, as read. */
|
|
65
|
+
export type CheckContextNode = t.TypeOf<typeof CheckContextNodeSchema>;
|
|
66
|
+
declare const CheckContextNodeSchema: Readonly<{
|
|
67
|
+
typeName: string;
|
|
68
|
+
defaultValue: Readonly<{
|
|
69
|
+
__typename: "CheckRun";
|
|
70
|
+
checkSuite: Readonly<{
|
|
71
|
+
workflowRun: Readonly<{
|
|
72
|
+
event: string;
|
|
73
|
+
workflow: Readonly<{
|
|
74
|
+
name: string;
|
|
75
|
+
}>;
|
|
76
|
+
}> | null;
|
|
77
|
+
}> | null;
|
|
78
|
+
completedAt: string | null;
|
|
79
|
+
conclusion: string | null;
|
|
80
|
+
detailsUrl: string | null;
|
|
81
|
+
isRequired: boolean;
|
|
82
|
+
name: string;
|
|
83
|
+
startedAt: string | null;
|
|
84
|
+
status: string;
|
|
85
|
+
}> | Readonly<{
|
|
86
|
+
__typename: "StatusContext";
|
|
87
|
+
context: string;
|
|
88
|
+
createdAt: string;
|
|
89
|
+
isRequired: boolean;
|
|
90
|
+
state: string;
|
|
91
|
+
targetUrl: string | null;
|
|
92
|
+
}>;
|
|
93
|
+
is: (a: unknown) => a is Readonly<{
|
|
94
|
+
__typename: "CheckRun";
|
|
95
|
+
checkSuite: Readonly<{
|
|
96
|
+
workflowRun: Readonly<{
|
|
97
|
+
event: string;
|
|
98
|
+
workflow: Readonly<{
|
|
99
|
+
name: string;
|
|
100
|
+
}>;
|
|
101
|
+
}> | null;
|
|
102
|
+
}> | null;
|
|
103
|
+
completedAt: string | null;
|
|
104
|
+
conclusion: string | null;
|
|
105
|
+
detailsUrl: string | null;
|
|
106
|
+
isRequired: boolean;
|
|
107
|
+
name: string;
|
|
108
|
+
startedAt: string | null;
|
|
109
|
+
status: string;
|
|
110
|
+
}> | Readonly<{
|
|
111
|
+
__typename: "StatusContext";
|
|
112
|
+
context: string;
|
|
113
|
+
createdAt: string;
|
|
114
|
+
isRequired: boolean;
|
|
115
|
+
state: string;
|
|
116
|
+
targetUrl: string | null;
|
|
117
|
+
}>;
|
|
118
|
+
assertIs: (a: unknown) => asserts a is Readonly<{
|
|
119
|
+
__typename: "CheckRun";
|
|
120
|
+
checkSuite: Readonly<{
|
|
121
|
+
workflowRun: Readonly<{
|
|
122
|
+
event: string;
|
|
123
|
+
workflow: Readonly<{
|
|
124
|
+
name: string;
|
|
125
|
+
}>;
|
|
126
|
+
}> | null;
|
|
127
|
+
}> | null;
|
|
128
|
+
completedAt: string | null;
|
|
129
|
+
conclusion: string | null;
|
|
130
|
+
detailsUrl: string | null;
|
|
131
|
+
isRequired: boolean;
|
|
132
|
+
name: string;
|
|
133
|
+
startedAt: string | null;
|
|
134
|
+
status: string;
|
|
135
|
+
}> | Readonly<{
|
|
136
|
+
__typename: "StatusContext";
|
|
137
|
+
context: string;
|
|
138
|
+
createdAt: string;
|
|
139
|
+
isRequired: boolean;
|
|
140
|
+
state: string;
|
|
141
|
+
targetUrl: string | null;
|
|
142
|
+
}>;
|
|
143
|
+
cast: (a: unknown) => Readonly<{
|
|
144
|
+
__typename: "CheckRun";
|
|
145
|
+
checkSuite: Readonly<{
|
|
146
|
+
workflowRun: Readonly<{
|
|
147
|
+
event: string;
|
|
148
|
+
workflow: Readonly<{
|
|
149
|
+
name: string;
|
|
150
|
+
}>;
|
|
151
|
+
}> | null;
|
|
152
|
+
}> | null;
|
|
153
|
+
completedAt: string | null;
|
|
154
|
+
conclusion: string | null;
|
|
155
|
+
detailsUrl: string | null;
|
|
156
|
+
isRequired: boolean;
|
|
157
|
+
name: string;
|
|
158
|
+
startedAt: string | null;
|
|
159
|
+
status: string;
|
|
160
|
+
}> | Readonly<{
|
|
161
|
+
__typename: "StatusContext";
|
|
162
|
+
context: string;
|
|
163
|
+
createdAt: string;
|
|
164
|
+
isRequired: boolean;
|
|
165
|
+
state: string;
|
|
166
|
+
targetUrl: string | null;
|
|
167
|
+
}>;
|
|
168
|
+
fill: (a: unknown) => Readonly<{
|
|
169
|
+
__typename: "CheckRun";
|
|
170
|
+
checkSuite: Readonly<{
|
|
171
|
+
workflowRun: Readonly<{
|
|
172
|
+
event: string;
|
|
173
|
+
workflow: Readonly<{
|
|
174
|
+
name: string;
|
|
175
|
+
}>;
|
|
176
|
+
}> | null;
|
|
177
|
+
}> | null;
|
|
178
|
+
completedAt: string | null;
|
|
179
|
+
conclusion: string | null;
|
|
180
|
+
detailsUrl: string | null;
|
|
181
|
+
isRequired: boolean;
|
|
182
|
+
name: string;
|
|
183
|
+
startedAt: string | null;
|
|
184
|
+
status: string;
|
|
185
|
+
}> | Readonly<{
|
|
186
|
+
__typename: "StatusContext";
|
|
187
|
+
context: string;
|
|
188
|
+
createdAt: string;
|
|
189
|
+
isRequired: boolean;
|
|
190
|
+
state: string;
|
|
191
|
+
targetUrl: string | null;
|
|
192
|
+
}>;
|
|
193
|
+
prune: <B extends Readonly<{
|
|
194
|
+
__typename: "CheckRun";
|
|
195
|
+
checkSuite: Readonly<{
|
|
196
|
+
workflowRun: Readonly<{
|
|
197
|
+
event: string;
|
|
198
|
+
workflow: Readonly<{
|
|
199
|
+
name: string;
|
|
200
|
+
}>;
|
|
201
|
+
}> | null;
|
|
202
|
+
}> | null;
|
|
203
|
+
completedAt: string | null;
|
|
204
|
+
conclusion: string | null;
|
|
205
|
+
detailsUrl: string | null;
|
|
206
|
+
isRequired: boolean;
|
|
207
|
+
name: string;
|
|
208
|
+
startedAt: string | null;
|
|
209
|
+
status: string;
|
|
210
|
+
}> | Readonly<{
|
|
211
|
+
__typename: "StatusContext";
|
|
212
|
+
context: string;
|
|
213
|
+
createdAt: string;
|
|
214
|
+
isRequired: boolean;
|
|
215
|
+
state: string;
|
|
216
|
+
targetUrl: string | null;
|
|
217
|
+
}>>(a: B) => Readonly<{
|
|
218
|
+
__typename: "CheckRun";
|
|
219
|
+
checkSuite: Readonly<{
|
|
220
|
+
workflowRun: Readonly<{
|
|
221
|
+
event: string;
|
|
222
|
+
workflow: Readonly<{
|
|
223
|
+
name: string;
|
|
224
|
+
}>;
|
|
225
|
+
}> | null;
|
|
226
|
+
}> | null;
|
|
227
|
+
completedAt: string | null;
|
|
228
|
+
conclusion: string | null;
|
|
229
|
+
detailsUrl: string | null;
|
|
230
|
+
isRequired: boolean;
|
|
231
|
+
name: string;
|
|
232
|
+
startedAt: string | null;
|
|
233
|
+
status: string;
|
|
234
|
+
}> | Readonly<{
|
|
235
|
+
__typename: "StatusContext";
|
|
236
|
+
context: string;
|
|
237
|
+
createdAt: string;
|
|
238
|
+
isRequired: boolean;
|
|
239
|
+
state: string;
|
|
240
|
+
targetUrl: string | null;
|
|
241
|
+
}>;
|
|
242
|
+
validate: (a: unknown) => Result<Readonly<{
|
|
243
|
+
__typename: "CheckRun";
|
|
244
|
+
checkSuite: Readonly<{
|
|
245
|
+
workflowRun: Readonly<{
|
|
246
|
+
event: string;
|
|
247
|
+
workflow: Readonly<{
|
|
248
|
+
name: string;
|
|
249
|
+
}>;
|
|
250
|
+
}> | null;
|
|
251
|
+
}> | null;
|
|
252
|
+
completedAt: string | null;
|
|
253
|
+
conclusion: string | null;
|
|
254
|
+
detailsUrl: string | null;
|
|
255
|
+
isRequired: boolean;
|
|
256
|
+
name: string;
|
|
257
|
+
startedAt: string | null;
|
|
258
|
+
status: string;
|
|
259
|
+
}> | Readonly<{
|
|
260
|
+
__typename: "StatusContext";
|
|
261
|
+
context: string;
|
|
262
|
+
createdAt: string;
|
|
263
|
+
isRequired: boolean;
|
|
264
|
+
state: string;
|
|
265
|
+
targetUrl: string | null;
|
|
266
|
+
}>, readonly Readonly<{
|
|
267
|
+
path: readonly string[];
|
|
268
|
+
actualValue: unknown;
|
|
269
|
+
expectedType: string;
|
|
270
|
+
typeName: string;
|
|
271
|
+
details?: t.ValidationErrorDetails | undefined;
|
|
272
|
+
}>[]>;
|
|
273
|
+
structure?: t.TypeStructure;
|
|
274
|
+
annotations?: t.TypeAnnotations;
|
|
275
|
+
optional?: true;
|
|
276
|
+
}>;
|
|
277
|
+
/**
|
|
278
|
+
* `checks` is what {@link listRequiredChecks} reported for the head commit;
|
|
279
|
+
* `requiredContexts` is what the ruleset asks for. The difference between the
|
|
280
|
+
* two is the point: a context in the second and not the first has not
|
|
281
|
+
* reported yet, and GitHub will not merge until it does. `running` is every
|
|
282
|
+
* check on the head that has not finished ({@link listRunningChecks}); while
|
|
283
|
+
* it is not empty the required ones may be the round before speaking, so
|
|
284
|
+
* they cannot pass the pull request.
|
|
285
|
+
*
|
|
286
|
+
* Nor can they fail it when they finished before the round still running
|
|
287
|
+
* began: the round `skip-ci` cancelled, as `open-pr` opens every pull request
|
|
288
|
+
* under it, leaves its aggregates red, and reading that red as this round's
|
|
289
|
+
* set a pull request aside while its first real round was under way (#2246).
|
|
290
|
+
* Such a failure waits for the round to end, as a check not yet reported
|
|
291
|
+
* does. So does one that finished after the round began but whose workflow
|
|
292
|
+
* has a newer run still going: the round `skip-ci` was put on for can take
|
|
293
|
+
* long enough to be cancelled that its aggregate goes red after the round
|
|
294
|
+
* taking its place has started, and only the run that replaced it says it is
|
|
295
|
+
* the round before (#2463). A failure of this round still fails the pull
|
|
296
|
+
* request at once.
|
|
297
|
+
*
|
|
298
|
+
* The verdict itself is `pr-report-core`'s `summarizeChecks`, which
|
|
299
|
+
* `pr-report` and the page reach theirs through, so the worker and the report
|
|
300
|
+
* cannot disagree about one; what is here turns what GitHub reports into
|
|
301
|
+
* the states that reads.
|
|
302
|
+
*/
|
|
303
|
+
export declare const summarizeChecks: (checks: readonly ReportedCheck[], requiredContexts: readonly string[], running: readonly RunningCheck[]) => ChecksSummary;
|
|
304
|
+
/** Everything the merge is still waiting for, reported and unreported. */
|
|
305
|
+
export declare const describeWaitingOn: (summary: ChecksSummary) => string;
|
|
306
|
+
export {};
|
|
307
|
+
//# sourceMappingURL=checks.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checks.d.mts","sourceRoot":"","sources":["../../src/unblock-prs/checks.mts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAAY,MAAM,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,CAAC,MAAM,aAAa,CAAC;AACjC,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,QACxB,UAAU,YACL,MAAM,KACf,OAAO,CAAC,MAAM,CAAC,SAAS,aAAa,EAAE,EAAE,MAAM,CAAC,CAGhD,CAAC;AAEJ;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,QACvB,UAAU,YACL,MAAM,KACf,OAAO,CAAC,MAAM,CAAC,SAAS,YAAY,EAAE,EAAE,MAAM,CAAC,CAU/C,CAAC;AAEJ;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,aACjB,SAAS,gBAAgB,EAAE,SAC9B,KAAK,GAAG,UAAU,KACxB,SAAS,aAAa,EAqBxB,CAAC;AAEF,mEAAmE;AACnE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAsGvE,QAAA,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+B1B,CAAC;AAuGH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,eAAe,WAClB,SAAS,aAAa,EAAE,oBACd,SAAS,MAAM,EAAE,WAC1B,SAAS,YAAY,EAAE,KAC/B,aAmEF,CAAC;AAEF,0EAA0E;AAC1E,eAAO,MAAM,iBAAiB,YAAa,aAAa,KAAG,MAQ1D,CAAC"}
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
import { combineContextStates, epochMsOf, summarizeChecks as summarizeContexts, } from 'pr-report-core';
|
|
6
|
+
import { Arr, Num, Result } from 'ts-data-forge';
|
|
7
|
+
import * as t from 'ts-fortress';
|
|
8
|
+
import { graphqlQuery } from '../lib/index.mjs';
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
export const listRequiredChecks = async (api, prNumber) => Result.map(await readCheckContexts(api, prNumber), (contexts) => reportedChecksOf(contexts, 'required'));
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
export const listRunningChecks = async (api, prNumber) => Result.map(await readCheckContexts(api, prNumber), (contexts) => reportedChecksOf(contexts, 'all')
|
|
26
|
+
.filter((check) => check.bucket === 'pending')
|
|
27
|
+
.map(({ name, startedAt, workflow, link }) => ({
|
|
28
|
+
name,
|
|
29
|
+
startedAt,
|
|
30
|
+
workflow,
|
|
31
|
+
link,
|
|
32
|
+
})));
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
export const reportedChecksOf = (contexts, which) => {
|
|
45
|
+
const mut_latest = new Map();
|
|
46
|
+
for (const context of contexts) {
|
|
47
|
+
const key = keyOf(context);
|
|
48
|
+
const kept = mut_latest.get(key);
|
|
49
|
+
if (kept === undefined || startedAtOf(context) > startedAtOf(kept)) {
|
|
50
|
+
mut_latest.set(key, context);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const survivors = new Set(mut_latest.values());
|
|
54
|
+
return contexts
|
|
55
|
+
.filter((context) => survivors.has(context) && (which === 'all' || context.isRequired))
|
|
56
|
+
.map(reportedCheckOf);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
const readCheckContexts = async (api, prNumber) => {
|
|
63
|
+
const mut_contexts = [];
|
|
64
|
+
let mut_after = undefined;
|
|
65
|
+
for (const _page of Arr.seq(MAX_PAGES)) {
|
|
66
|
+
const rollup = await readRollupPage(api, prNumber, mut_after);
|
|
67
|
+
if (Result.isErr(rollup)) {
|
|
68
|
+
return rollup;
|
|
69
|
+
}
|
|
70
|
+
if (rollup.value === null) {
|
|
71
|
+
return Result.ok(mut_contexts);
|
|
72
|
+
}
|
|
73
|
+
mut_contexts.push(...rollup.value.nodes);
|
|
74
|
+
const { hasNextPage, endCursor } = rollup.value.pageInfo;
|
|
75
|
+
if (!hasNextPage || endCursor === null) {
|
|
76
|
+
return Result.ok(mut_contexts);
|
|
77
|
+
}
|
|
78
|
+
mut_after = endCursor;
|
|
79
|
+
}
|
|
80
|
+
return Result.err(`#${prNumber} has more than ${MAX_PAGES * PAGE_SIZE} checks on its head`);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
const readRollupPage = async (api, prNumber, after) => Result.map(await graphqlQuery(api, CHECKS_QUERY, {
|
|
87
|
+
owner: api.repo.owner,
|
|
88
|
+
name: api.repo.name,
|
|
89
|
+
number: prNumber,
|
|
90
|
+
...(after === undefined ? {} : { after }),
|
|
91
|
+
}, ChecksAnswerSchema), (answer) => answer.repository.pullRequest.commits.nodes[0]?.commit.statusCheckRollup
|
|
92
|
+
?.contexts ?? null);
|
|
93
|
+
const PAGE_SIZE = 100;
|
|
94
|
+
const MAX_PAGES = 10;
|
|
95
|
+
const CHECKS_QUERY = [
|
|
96
|
+
'query($owner: String!, $name: String!, $number: Int!, $after: String) {',
|
|
97
|
+
' repository(owner: $owner, name: $name) {',
|
|
98
|
+
' pullRequest(number: $number) {',
|
|
99
|
+
' commits(last: 1) { nodes { commit { statusCheckRollup {',
|
|
100
|
+
` contexts(first: ${PAGE_SIZE}, after: $after) {`,
|
|
101
|
+
' pageInfo { hasNextPage endCursor }',
|
|
102
|
+
' nodes {',
|
|
103
|
+
' __typename',
|
|
104
|
+
' ... on CheckRun {',
|
|
105
|
+
' name status conclusion startedAt completedAt detailsUrl',
|
|
106
|
+
' isRequired(pullRequestNumber: $number)',
|
|
107
|
+
' checkSuite { workflowRun { event workflow { name } } }',
|
|
108
|
+
' }',
|
|
109
|
+
' ... on StatusContext {',
|
|
110
|
+
' context state targetUrl createdAt',
|
|
111
|
+
' isRequired(pullRequestNumber: $number)',
|
|
112
|
+
' }',
|
|
113
|
+
' }',
|
|
114
|
+
' }',
|
|
115
|
+
' } } }',
|
|
116
|
+
' }',
|
|
117
|
+
' }',
|
|
118
|
+
'}',
|
|
119
|
+
].join('\n');
|
|
120
|
+
const CheckContextNodeSchema = t.union([
|
|
121
|
+
t.record({
|
|
122
|
+
__typename: t.literal('CheckRun'),
|
|
123
|
+
name: t.string(),
|
|
124
|
+
status: t.string(),
|
|
125
|
+
conclusion: t.union([t.string(), t.nullType]),
|
|
126
|
+
startedAt: t.union([t.string(), t.nullType]),
|
|
127
|
+
completedAt: t.union([t.string(), t.nullType]),
|
|
128
|
+
detailsUrl: t.union([t.string(), t.nullType]),
|
|
129
|
+
isRequired: t.boolean(),
|
|
130
|
+
checkSuite: t.union([
|
|
131
|
+
t.record({
|
|
132
|
+
workflowRun: t.union([
|
|
133
|
+
t.record({
|
|
134
|
+
event: t.string(),
|
|
135
|
+
workflow: t.record({ name: t.string() }),
|
|
136
|
+
}),
|
|
137
|
+
t.nullType,
|
|
138
|
+
]),
|
|
139
|
+
}),
|
|
140
|
+
t.nullType,
|
|
141
|
+
]),
|
|
142
|
+
}),
|
|
143
|
+
t.record({
|
|
144
|
+
__typename: t.literal('StatusContext'),
|
|
145
|
+
context: t.string(),
|
|
146
|
+
state: t.string(),
|
|
147
|
+
targetUrl: t.union([t.string(), t.nullType]),
|
|
148
|
+
createdAt: t.string(),
|
|
149
|
+
isRequired: t.boolean(),
|
|
150
|
+
}),
|
|
151
|
+
]);
|
|
152
|
+
const ChecksAnswerSchema = t.record({
|
|
153
|
+
repository: t.record({
|
|
154
|
+
pullRequest: t.record({
|
|
155
|
+
commits: t.record({
|
|
156
|
+
nodes: t.array(t.record({
|
|
157
|
+
commit: t.record({
|
|
158
|
+
statusCheckRollup: t.union([
|
|
159
|
+
t.record({
|
|
160
|
+
contexts: t.record({
|
|
161
|
+
pageInfo: t.record({
|
|
162
|
+
hasNextPage: t.boolean(),
|
|
163
|
+
endCursor: t.union([t.string(), t.nullType]),
|
|
164
|
+
}),
|
|
165
|
+
nodes: t.array(CheckContextNodeSchema),
|
|
166
|
+
}),
|
|
167
|
+
}),
|
|
168
|
+
t.nullType,
|
|
169
|
+
]),
|
|
170
|
+
}),
|
|
171
|
+
})),
|
|
172
|
+
}),
|
|
173
|
+
}),
|
|
174
|
+
}),
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
const ZERO_TIME = '0001-01-01T00:00:00Z';
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
const keyOf = (context) => context.__typename === 'StatusContext'
|
|
183
|
+
? `status:${context.context}`
|
|
184
|
+
: [
|
|
185
|
+
'run',
|
|
186
|
+
context.name,
|
|
187
|
+
context.checkSuite?.workflowRun?.workflow.name ?? '',
|
|
188
|
+
context.checkSuite?.workflowRun?.event ?? '',
|
|
189
|
+
].join(':');
|
|
190
|
+
const startedAtOf = (context) => (context.__typename === 'StatusContext'
|
|
191
|
+
? context.createdAt
|
|
192
|
+
: context.startedAt) ?? ZERO_TIME;
|
|
193
|
+
const reportedCheckOf = (context) => context.__typename === 'StatusContext'
|
|
194
|
+
? {
|
|
195
|
+
name: context.context,
|
|
196
|
+
bucket: bucketOf(context.state),
|
|
197
|
+
link: context.targetUrl ?? '',
|
|
198
|
+
startedAt: context.createdAt,
|
|
199
|
+
completedAt: context.createdAt,
|
|
200
|
+
workflow: '',
|
|
201
|
+
}
|
|
202
|
+
: {
|
|
203
|
+
name: context.name,
|
|
204
|
+
bucket: bucketOf(context.status === 'COMPLETED'
|
|
205
|
+
? (context.conclusion ?? '')
|
|
206
|
+
: context.status),
|
|
207
|
+
link: context.detailsUrl ?? '',
|
|
208
|
+
startedAt: context.startedAt ?? ZERO_TIME,
|
|
209
|
+
completedAt: context.completedAt ?? ZERO_TIME,
|
|
210
|
+
workflow: context.checkSuite?.workflowRun?.workflow.name ?? '',
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
const bucketOf = (state) => {
|
|
218
|
+
switch (state) {
|
|
219
|
+
case 'SUCCESS':
|
|
220
|
+
return 'pass';
|
|
221
|
+
case 'SKIPPED':
|
|
222
|
+
case 'NEUTRAL':
|
|
223
|
+
return 'skipping';
|
|
224
|
+
case 'ERROR':
|
|
225
|
+
case 'FAILURE':
|
|
226
|
+
case 'TIMED_OUT':
|
|
227
|
+
case 'ACTION_REQUIRED':
|
|
228
|
+
case 'STARTUP_FAILURE':
|
|
229
|
+
return 'fail';
|
|
230
|
+
case 'CANCELLED':
|
|
231
|
+
return 'cancel';
|
|
232
|
+
default:
|
|
233
|
+
return 'pending';
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
export const summarizeChecks = (checks, requiredContexts, running) => {
|
|
263
|
+
const roundStartedMs = earliestStart(running);
|
|
264
|
+
const isOfRoundBefore = (check) => {
|
|
265
|
+
const completedMs = epochMsOf(check.completedAt);
|
|
266
|
+
return ((roundStartedMs !== undefined &&
|
|
267
|
+
completedMs !== undefined &&
|
|
268
|
+
completedMs < roundStartedMs) ||
|
|
269
|
+
isSuperseded(check, running));
|
|
270
|
+
};
|
|
271
|
+
const isFailureOfThisRound = (check) => isFailure(check) && !isOfRoundBefore(check);
|
|
272
|
+
const mut_reported = new Map();
|
|
273
|
+
for (const check of checks) {
|
|
274
|
+
const state = stateOf(check, isOfRoundBefore(check));
|
|
275
|
+
const previous = mut_reported.get(check.name);
|
|
276
|
+
mut_reported.set(check.name, previous === undefined ? state : combineContextStates(previous, state));
|
|
277
|
+
}
|
|
278
|
+
const pendingNames = new Set(checks
|
|
279
|
+
.filter((check) => mut_reported.get(check.name) === 'pending')
|
|
280
|
+
.map((check) => check.name));
|
|
281
|
+
const stillRunning = running
|
|
282
|
+
.map(({ name }) => name)
|
|
283
|
+
.filter((name) => !pendingNames.has(name));
|
|
284
|
+
const summary = summarizeContexts({
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
required: Arr.uniq([
|
|
288
|
+
...requiredContexts,
|
|
289
|
+
...checks.map((check) => check.name),
|
|
290
|
+
]),
|
|
291
|
+
reported: mut_reported,
|
|
292
|
+
|
|
293
|
+
paused: false,
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
running: Arr.isNonEmpty(stillRunning) || !Arr.isNonEmpty(checks),
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
baseCovered: true,
|
|
302
|
+
});
|
|
303
|
+
return {
|
|
304
|
+
...summary,
|
|
305
|
+
failedRuns: checks
|
|
306
|
+
.filter(isFailureOfThisRound)
|
|
307
|
+
.map(({ name, link }) => ({ name, link })),
|
|
308
|
+
running: stillRunning,
|
|
309
|
+
};
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
export const describeWaitingOn = (summary) => {
|
|
313
|
+
const waiting = [
|
|
314
|
+
...summary.pending,
|
|
315
|
+
...summary.missing.map((context) => `${context} (not reported yet)`),
|
|
316
|
+
...summary.running.map((name) => `${name} (running)`),
|
|
317
|
+
];
|
|
318
|
+
return Arr.isNonEmpty(waiting) ? waiting.join(', ') : 'checks to be reported';
|
|
319
|
+
};
|
|
320
|
+
const isFailure = (check) => check.bucket === 'fail' || check.bucket === 'cancel';
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
const stateOf = (check, ofRoundBefore) => isFailure(check)
|
|
326
|
+
? ofRoundBefore
|
|
327
|
+
? 'pending'
|
|
328
|
+
: 'failed'
|
|
329
|
+
: check.bucket === 'pending'
|
|
330
|
+
? 'pending'
|
|
331
|
+
: check.bucket === 'skipping'
|
|
332
|
+
? 'skipped'
|
|
333
|
+
: 'passed';
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
const isSuperseded = (check, running) => {
|
|
340
|
+
const runId = workflowRunId(check.link);
|
|
341
|
+
return (check.workflow !== '' &&
|
|
342
|
+
runId !== undefined &&
|
|
343
|
+
running.some((other) => {
|
|
344
|
+
const otherRunId = workflowRunId(other.link);
|
|
345
|
+
return (other.workflow === check.workflow &&
|
|
346
|
+
otherRunId !== undefined &&
|
|
347
|
+
otherRunId > runId);
|
|
348
|
+
}));
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
const workflowRunId = (link) => {
|
|
352
|
+
const id = /\/actions\/runs\/(\d+)\//u.exec(link)?.[1];
|
|
353
|
+
return id === undefined
|
|
354
|
+
? undefined
|
|
355
|
+
: Result.unwrapOkOr(Num.safeParseInt(id), undefined);
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
const earliestStart = (running) => {
|
|
362
|
+
const starts = Arr.generate(function* () {
|
|
363
|
+
for (const { startedAt } of running) {
|
|
364
|
+
const ms = epochMsOf(startedAt);
|
|
365
|
+
if (ms !== undefined) {
|
|
366
|
+
yield ms;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
return Arr.isNonEmpty(starts) ? Math.min(...starts) : undefined;
|
|
371
|
+
};
|
|
372
|
+
//# sourceMappingURL=checks.mjs.map
|