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,78 @@
|
|
|
1
|
+
import type { PullRequest } from './types.mjs';
|
|
2
|
+
import { isVersionPullRequest, releaseBlockedNote } from './version-pr.mjs';
|
|
3
|
+
|
|
4
|
+
const pullRequest = (
|
|
5
|
+
fields: Partial<PullRequest> & Readonly<{ number: number }>,
|
|
6
|
+
): PullRequest =>
|
|
7
|
+
({
|
|
8
|
+
id: `PR_${fields.number}`,
|
|
9
|
+
title: `pull request #${fields.number}`,
|
|
10
|
+
body: '',
|
|
11
|
+
state: 'OPEN',
|
|
12
|
+
headRefName: `feature/${fields.number}`,
|
|
13
|
+
headRefOid: 'a'.repeat(40),
|
|
14
|
+
baseRefName: 'main',
|
|
15
|
+
isCrossRepository: false,
|
|
16
|
+
isDraft: false,
|
|
17
|
+
mergeStateStatus: 'BLOCKED',
|
|
18
|
+
autoMergeRequest: {},
|
|
19
|
+
labels: [],
|
|
20
|
+
...fields,
|
|
21
|
+
}) as const;
|
|
22
|
+
|
|
23
|
+
const versionPr = (number: number): PullRequest =>
|
|
24
|
+
pullRequest({
|
|
25
|
+
number,
|
|
26
|
+
headRefName: 'changeset-release/main',
|
|
27
|
+
labels: [{ name: 'merge-queued' }, { name: 'skip-ci' }],
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe(isVersionPullRequest, () => {
|
|
31
|
+
test('identifies it by its branch', () => {
|
|
32
|
+
assert.isTrue(
|
|
33
|
+
isVersionPullRequest(
|
|
34
|
+
pullRequest({ number: 1, headRefName: 'changeset-release/main' }),
|
|
35
|
+
'main',
|
|
36
|
+
),
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Its title is `pr-title` from `release.yml`, which anyone may reuse, and
|
|
41
|
+
// its number changes with every release. The branch is the only handle.
|
|
42
|
+
test('does not take another branch for it by its title', () => {
|
|
43
|
+
assert.isFalse(
|
|
44
|
+
isVersionPullRequest(
|
|
45
|
+
pullRequest({
|
|
46
|
+
number: 1,
|
|
47
|
+
title: 'chore: version packages',
|
|
48
|
+
headRefName: 'chore/version-packages',
|
|
49
|
+
}),
|
|
50
|
+
'main',
|
|
51
|
+
),
|
|
52
|
+
);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test('is read against the default branch it was given', () => {
|
|
56
|
+
assert.isFalse(
|
|
57
|
+
isVersionPullRequest(
|
|
58
|
+
pullRequest({ number: 1, headRefName: 'changeset-release/main' }),
|
|
59
|
+
'develop',
|
|
60
|
+
),
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
describe(releaseBlockedNote, () => {
|
|
66
|
+
test('reports the blockers by number, marking the drafts', () => {
|
|
67
|
+
assert.deepStrictEqual(
|
|
68
|
+
releaseBlockedNote(versionPr(1950), [
|
|
69
|
+
{ number: 1901, isDraft: false },
|
|
70
|
+
{ number: 1903, isDraft: true },
|
|
71
|
+
]),
|
|
72
|
+
{
|
|
73
|
+
kind: 'note',
|
|
74
|
+
note: '#1950: blocks-release on #1901, #1903 (draft) — still open, so the release waits',
|
|
75
|
+
},
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/** Polling one pull request until it merges, or until it will not. */
|
|
2
|
+
|
|
3
|
+
import { isMergeableState } from 'pr-report-core';
|
|
4
|
+
import { isRecord, Result } from 'ts-data-forge';
|
|
5
|
+
import { log, type ApiContext } from '../lib/index.mjs';
|
|
6
|
+
import {
|
|
7
|
+
describeWaitingOn,
|
|
8
|
+
listRequiredChecks,
|
|
9
|
+
listRunningChecks,
|
|
10
|
+
summarizeChecks,
|
|
11
|
+
type ReportedCheck,
|
|
12
|
+
type RunningCheck,
|
|
13
|
+
} from './checks.mjs';
|
|
14
|
+
import {
|
|
15
|
+
BLOCKED_GREEN_POLLS_BEFORE_GIVING_UP,
|
|
16
|
+
GREEN_POLLS_BEFORE_GIVING_UP,
|
|
17
|
+
MAX_CONSECUTIVE_POLL_ERRORS,
|
|
18
|
+
} from './constants.mjs';
|
|
19
|
+
import { viewPullRequest, viewReviewDecision } from './github.mjs';
|
|
20
|
+
import { isSkipCiLabelled } from './labels.mjs';
|
|
21
|
+
import type { Options } from './options.mjs';
|
|
22
|
+
import {
|
|
23
|
+
describeFailedChecks,
|
|
24
|
+
describeHold,
|
|
25
|
+
describeTimeout,
|
|
26
|
+
} from './set-aside-detail.mjs';
|
|
27
|
+
import type { PullRequest, Watched } from './types.mjs';
|
|
28
|
+
import { pause, stopRequested } from './util.mjs';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Polls one pull request until it merges or until something says it will not.
|
|
32
|
+
* `expectedHead` is the commit the checks are expected on; a different head
|
|
33
|
+
* means someone else pushed, and the survey has to start over.
|
|
34
|
+
*
|
|
35
|
+
* `bypassReason` is set for a pull request only a ruleset bypass merges
|
|
36
|
+
* (`pr-report-core`'s `review-hold.mts`). It has no auto-merge to lose, and
|
|
37
|
+
* nothing will merge it on green, so the watch ends at the verdict: failed as
|
|
38
|
+
* for any other, or green and `awaiting-bypass`, with the reason for the
|
|
39
|
+
* comment to say.
|
|
40
|
+
*/
|
|
41
|
+
export const watch = async (
|
|
42
|
+
api: ApiContext,
|
|
43
|
+
pr: PullRequest,
|
|
44
|
+
expectedHead: string,
|
|
45
|
+
requiredContexts: readonly string[],
|
|
46
|
+
options: Options,
|
|
47
|
+
bypassReason: string | undefined,
|
|
48
|
+
): Promise<Watched> => {
|
|
49
|
+
const deadline = Date.now() + options.watchTimeoutMin * 60_000;
|
|
50
|
+
|
|
51
|
+
let mut_greenPolls = 0;
|
|
52
|
+
|
|
53
|
+
let mut_errors = 0;
|
|
54
|
+
|
|
55
|
+
while (!stopRequested()) {
|
|
56
|
+
await pause(options.pollIntervalSec * 1000);
|
|
57
|
+
|
|
58
|
+
if (stopRequested()) {
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const viewed = await viewPullRequest(api, pr.number);
|
|
63
|
+
|
|
64
|
+
if (Result.isErr(viewed)) {
|
|
65
|
+
mut_errors += 1;
|
|
66
|
+
|
|
67
|
+
log(`#${pr.number}: poll failed (${mut_errors}): ${viewed.value}`);
|
|
68
|
+
|
|
69
|
+
if (mut_errors >= MAX_CONSECUTIVE_POLL_ERRORS) {
|
|
70
|
+
return { outcome: 'error' };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const current = viewed.value;
|
|
77
|
+
|
|
78
|
+
if (current.state === 'MERGED') {
|
|
79
|
+
return { outcome: 'merged' };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (current.state !== 'OPEN') {
|
|
83
|
+
return { outcome: 'closed' };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (bypassReason === undefined && !isRecord(current.autoMergeRequest)) {
|
|
87
|
+
return { outcome: 'auto-merge-disabled' };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// The label skips every check workflow and leaves `no-skip-ci-label`
|
|
91
|
+
// `pending`, so from here the checks can only sit there until the watch
|
|
92
|
+
// times out. Stop now and let the survey set it aside.
|
|
93
|
+
if (isSkipCiLabelled(current)) {
|
|
94
|
+
return { outcome: 'skip-ci-labelled' };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (current.headRefOid !== expectedHead) {
|
|
98
|
+
return { outcome: 'head-moved' };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (
|
|
102
|
+
current.mergeStateStatus === 'BEHIND' ||
|
|
103
|
+
current.mergeStateStatus === 'DIRTY'
|
|
104
|
+
) {
|
|
105
|
+
return { outcome: 'behind-again' };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const checks = await readChecks(api, pr.number);
|
|
109
|
+
|
|
110
|
+
if (Result.isErr(checks)) {
|
|
111
|
+
mut_errors += 1;
|
|
112
|
+
|
|
113
|
+
log(`#${pr.number}: poll failed (${mut_errors}): ${checks.value}`);
|
|
114
|
+
|
|
115
|
+
if (mut_errors >= MAX_CONSECUTIVE_POLL_ERRORS) {
|
|
116
|
+
return { outcome: 'error' };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
mut_errors = 0;
|
|
123
|
+
|
|
124
|
+
const summary = summarizeChecks(
|
|
125
|
+
checks.value.required,
|
|
126
|
+
requiredContexts,
|
|
127
|
+
checks.value.running,
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
if (summary.verdict === 'failing') {
|
|
131
|
+
const failed = describeFailedChecks(summary);
|
|
132
|
+
|
|
133
|
+
log(`#${pr.number}: ${failed.detail}`);
|
|
134
|
+
|
|
135
|
+
return { outcome: 'checks-failed', ...failed };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (summary.verdict === 'pending') {
|
|
139
|
+
mut_greenPolls = 0;
|
|
140
|
+
|
|
141
|
+
log(
|
|
142
|
+
`#${pr.number}: ${current.mergeStateStatus}, waiting on ${describeWaitingOn(summary)}`,
|
|
143
|
+
);
|
|
144
|
+
} else if (bypassReason !== undefined) {
|
|
145
|
+
log(
|
|
146
|
+
`#${pr.number}: all ${summary.required} required checks green; it waits for a bypass merge.`,
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
outcome: 'awaiting-bypass',
|
|
151
|
+
detail: `every required check is green; ${bypassReason}`,
|
|
152
|
+
};
|
|
153
|
+
} else {
|
|
154
|
+
mut_greenPolls += 1;
|
|
155
|
+
|
|
156
|
+
// GitHub calling it BLOCKED while every required context reads green is
|
|
157
|
+
// the one combination that is usually transient, so it is given longer
|
|
158
|
+
// than a pull request GitHub already considers mergeable.
|
|
159
|
+
const budget = isMergeableState(current.mergeStateStatus)
|
|
160
|
+
? GREEN_POLLS_BEFORE_GIVING_UP
|
|
161
|
+
: BLOCKED_GREEN_POLLS_BEFORE_GIVING_UP;
|
|
162
|
+
|
|
163
|
+
log(
|
|
164
|
+
`#${pr.number}: ${current.mergeStateStatus}, all ${summary.required} required checks green (${mut_greenPolls}/${budget}), waiting for auto-merge`,
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
if (mut_greenPolls >= budget) {
|
|
168
|
+
const reviewDecision = await viewReviewDecision(api, pr.number);
|
|
169
|
+
|
|
170
|
+
return {
|
|
171
|
+
outcome: 'not-merging',
|
|
172
|
+
detail: describeHold(
|
|
173
|
+
current.mergeStateStatus,
|
|
174
|
+
Result.isOk(reviewDecision) ? reviewDecision.value : undefined,
|
|
175
|
+
),
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (Date.now() > deadline) {
|
|
181
|
+
log(
|
|
182
|
+
`#${pr.number}: still waiting on ${describeWaitingOn(summary)} after ${options.watchTimeoutMin} minutes.`,
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
outcome: 'timeout',
|
|
187
|
+
detail: describeTimeout(summary, options.watchTimeoutMin),
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return { outcome: 'stopped' };
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
/** The required checks and the names of every check still running. */
|
|
196
|
+
const readChecks = async (
|
|
197
|
+
api: ApiContext,
|
|
198
|
+
prNumber: number,
|
|
199
|
+
): Promise<
|
|
200
|
+
Result<
|
|
201
|
+
Readonly<{
|
|
202
|
+
required: readonly ReportedCheck[];
|
|
203
|
+
running: readonly RunningCheck[];
|
|
204
|
+
}>,
|
|
205
|
+
string
|
|
206
|
+
>
|
|
207
|
+
> => {
|
|
208
|
+
const required = await listRequiredChecks(api, prNumber);
|
|
209
|
+
|
|
210
|
+
if (Result.isErr(required)) {
|
|
211
|
+
return required;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const running = await listRunningChecks(api, prNumber);
|
|
215
|
+
|
|
216
|
+
return Result.isErr(running)
|
|
217
|
+
? running
|
|
218
|
+
: Result.ok({ required: required.value, running: running.value });
|
|
219
|
+
};
|