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,380 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CLAIM_LIFETIME_MINUTES,
|
|
3
|
+
isClaimant,
|
|
4
|
+
readQueueComments,
|
|
5
|
+
writeClaimComment,
|
|
6
|
+
writeReleasedClaimComment,
|
|
7
|
+
type QueueComments,
|
|
8
|
+
type QueueOwner,
|
|
9
|
+
} from 'pr-report-core';
|
|
10
|
+
import { Arr, Result } from 'ts-data-forge';
|
|
11
|
+
import * as t from 'ts-fortress';
|
|
12
|
+
import {
|
|
13
|
+
currentEpochMs,
|
|
14
|
+
isoSeconds,
|
|
15
|
+
pullRequestNumber,
|
|
16
|
+
resolveRepo,
|
|
17
|
+
resolveToken,
|
|
18
|
+
rest,
|
|
19
|
+
viewerLogin,
|
|
20
|
+
type ApiContext,
|
|
21
|
+
} from '../lib/index.mjs';
|
|
22
|
+
import { readQueueState } from '../pr-report/index.mjs';
|
|
23
|
+
|
|
24
|
+
/** What `claim-pr --help` prints. */
|
|
25
|
+
export const CLAIM_PR_HELP = [
|
|
26
|
+
'Usage: claim-pr <number> --by <claimant> [--release]',
|
|
27
|
+
'',
|
|
28
|
+
'Claims a pull request unblock-prs set aside, before fixing it, so that',
|
|
29
|
+
'unblock-prs and every other session leave it alone meanwhile. A push to',
|
|
30
|
+
'the branch ends the claim; --release gives it up without one.',
|
|
31
|
+
'',
|
|
32
|
+
'Options:',
|
|
33
|
+
' --by <claimant> who claims it: a session URL, or any word unique to you',
|
|
34
|
+
' --release give the claim up',
|
|
35
|
+
' -h, --help show this help',
|
|
36
|
+
'',
|
|
37
|
+
'It writes as the token (GH_TOKEN or GITHUB_TOKEN) account, which has to',
|
|
38
|
+
'be the one unblock-prs runs as.',
|
|
39
|
+
].join('\n');
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Claims a pull request `unblock-prs` set aside, before fixing it, so that the
|
|
43
|
+
* script and every other session leave it alone meanwhile
|
|
44
|
+
* (`pr-report-core`'s `claim.mts` says what a claim is and how long it lasts).
|
|
45
|
+
*
|
|
46
|
+
* ```sh
|
|
47
|
+
* claim-pr 2154 --by <session URL> # claim, or renew
|
|
48
|
+
* claim-pr 2154 --by <session URL> --release # give it up
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* A claim is refused for a pull request whose owner (`pr-report-core`'s
|
|
52
|
+
* `queue-owner.mts`, read through `pr-report/queue.mts` as every other
|
|
53
|
+
* command reads it) is not a skill — the worker is about to act on it, or a
|
|
54
|
+
* person has to — and for one someone else holds. A push to the branch ends the claim by itself;
|
|
55
|
+
* `--release` is for giving up without one. It prints what it did, and exits
|
|
56
|
+
* 1 when it did not get the claim.
|
|
57
|
+
*
|
|
58
|
+
* It writes as the token's account, which has to be the one `unblock-prs`
|
|
59
|
+
* runs as: both trust only comments their own account wrote.
|
|
60
|
+
*/
|
|
61
|
+
export const claimPr = async (
|
|
62
|
+
args: ClaimArgs,
|
|
63
|
+
): Promise<Result<string, string>> => {
|
|
64
|
+
const token = await resolveToken();
|
|
65
|
+
|
|
66
|
+
if (Result.isErr(token)) {
|
|
67
|
+
return token;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const repo = await resolveRepo();
|
|
71
|
+
|
|
72
|
+
if (Result.isErr(repo)) {
|
|
73
|
+
return repo;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const viewer = await viewerLogin(token.value);
|
|
77
|
+
|
|
78
|
+
if (Result.isErr(viewer)) {
|
|
79
|
+
return Result.err(`cannot read who the token is: ${viewer.value}`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const context: ApiContext = { repo: repo.value, token: token.value } as const;
|
|
83
|
+
|
|
84
|
+
const before = await readPullRequest(context, args.number, viewer.value);
|
|
85
|
+
|
|
86
|
+
return Result.isErr(before)
|
|
87
|
+
? before
|
|
88
|
+
: args.release
|
|
89
|
+
? release(context, args, before.value)
|
|
90
|
+
: claim(context, args, viewer.value, before.value);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* What to do about a claim by `by`, given who owns the pull request and what
|
|
95
|
+
* its comments say now: write it (over `commentId` when there is one to edit
|
|
96
|
+
* in place), or refuse and why.
|
|
97
|
+
*/
|
|
98
|
+
export const decideClaim = (
|
|
99
|
+
owner: QueueOwner | undefined,
|
|
100
|
+
queue: QueueComments,
|
|
101
|
+
by: string,
|
|
102
|
+
): Readonly<
|
|
103
|
+
| { kind: 'write'; commentId: number | undefined }
|
|
104
|
+
| { kind: 'refuse'; reason: string }
|
|
105
|
+
> => {
|
|
106
|
+
if (owner?.owner !== 'skill') {
|
|
107
|
+
return {
|
|
108
|
+
kind: 'refuse',
|
|
109
|
+
reason:
|
|
110
|
+
owner === undefined
|
|
111
|
+
? 'who owns it could not be read'
|
|
112
|
+
: `it is the ${owner.owner}'s (${owner.reason}), not a skill's`,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const held = queue.claim;
|
|
117
|
+
|
|
118
|
+
if (
|
|
119
|
+
held?.applies === true &&
|
|
120
|
+
held.says.kind === 'standing' &&
|
|
121
|
+
held.says.claim.by !== by
|
|
122
|
+
) {
|
|
123
|
+
return {
|
|
124
|
+
kind: 'refuse',
|
|
125
|
+
reason: `${held.says.claim.by} claimed it at ${held.says.claim.at}`,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return { kind: 'write', commentId: held?.commentId };
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
/** The command line, or what is wrong with it. */
|
|
133
|
+
export const parseClaimArgs = (args: readonly string[]): ClaimArgs | string => {
|
|
134
|
+
const byAt = args.indexOf('--by');
|
|
135
|
+
|
|
136
|
+
const by = byAt === -1 ? undefined : args[byAt + 1];
|
|
137
|
+
|
|
138
|
+
const positional = args.filter(
|
|
139
|
+
(arg, index) =>
|
|
140
|
+
arg !== '--' &&
|
|
141
|
+
arg !== '--release' &&
|
|
142
|
+
(byAt === -1 || (index !== byAt && index !== byAt + 1)),
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
const [first] = positional;
|
|
146
|
+
|
|
147
|
+
const number = first === undefined ? undefined : pullRequestNumber(first);
|
|
148
|
+
|
|
149
|
+
return positional.length > 1
|
|
150
|
+
? `unexpected argument: ${Arr.tail(positional).join(' ')}`
|
|
151
|
+
: number === undefined
|
|
152
|
+
? 'name the pull request by its number'
|
|
153
|
+
: by === undefined || !isClaimant(by)
|
|
154
|
+
? '--by names the claimant: a session URL, or any other word unique to you'
|
|
155
|
+
: { number, by, release: args.includes('--release') };
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
export type ClaimArgs = Readonly<{
|
|
159
|
+
number: number;
|
|
160
|
+
by: string;
|
|
161
|
+
release: boolean;
|
|
162
|
+
}>;
|
|
163
|
+
|
|
164
|
+
const claim = async (
|
|
165
|
+
context: ApiContext,
|
|
166
|
+
args: ClaimArgs,
|
|
167
|
+
viewer: string,
|
|
168
|
+
before: PullRequestState,
|
|
169
|
+
): Promise<Result<string, string>> => {
|
|
170
|
+
const state = await readQueueState();
|
|
171
|
+
|
|
172
|
+
if (Result.isErr(state)) {
|
|
173
|
+
return Result.err(`cannot read the queue: ${state.value}`);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const decided = decideClaim(
|
|
177
|
+
state.value.owners.get(args.number),
|
|
178
|
+
before.queue,
|
|
179
|
+
args.by,
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
if (decided.kind === 'refuse') {
|
|
183
|
+
return Result.err(`#${args.number} not claimed: ${decided.reason}.`);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const atEpochMs = currentEpochMs();
|
|
187
|
+
|
|
188
|
+
const reason =
|
|
189
|
+
before.queue.setAside?.says.kind === 'standing'
|
|
190
|
+
? before.queue.setAside.says.setAside.reason
|
|
191
|
+
: 'set aside';
|
|
192
|
+
|
|
193
|
+
const written = await writeComment(
|
|
194
|
+
context,
|
|
195
|
+
args.number,
|
|
196
|
+
decided.commentId,
|
|
197
|
+
writeClaimComment(
|
|
198
|
+
{ headSha: before.headSha, by: args.by, at: isoSeconds(atEpochMs) },
|
|
199
|
+
[
|
|
200
|
+
`Being fixed by ${args.by}, after \`unblock-prs\` set it aside (\`${reason}\`).`,
|
|
201
|
+
`\`unblock-prs\` and other sessions leave it alone until the branch is pushed, or until ${isoSeconds(atEpochMs + CLAIM_LIFETIME_MINUTES * 60_000)}.`,
|
|
202
|
+
].join(' '),
|
|
203
|
+
),
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
if (Result.isErr(written)) {
|
|
207
|
+
return written;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Two claimants writing at once both see nothing to refuse. Whichever
|
|
211
|
+
// claim reads back afterwards is the one that holds — the oldest comment,
|
|
212
|
+
// last written — and the other learns it lost here.
|
|
213
|
+
await new Promise((resolve) => {
|
|
214
|
+
setTimeout(resolve, READ_BACK_DELAY_MS);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
const after = await readPullRequest(context, args.number, viewer);
|
|
218
|
+
|
|
219
|
+
if (Result.isErr(after)) {
|
|
220
|
+
return after;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const held = after.value.queue.claim;
|
|
224
|
+
|
|
225
|
+
return held?.applies === true &&
|
|
226
|
+
held.says.kind === 'standing' &&
|
|
227
|
+
held.says.claim.by === args.by
|
|
228
|
+
? Result.ok(
|
|
229
|
+
`#${args.number} claimed by ${args.by} at ${before.headSha}, until it is pushed or ${isoSeconds(atEpochMs + CLAIM_LIFETIME_MINUTES * 60_000)}.`,
|
|
230
|
+
)
|
|
231
|
+
: Result.err(
|
|
232
|
+
`#${args.number} not claimed: ${held?.says.kind === 'standing' ? `${held.says.claim.by} claimed it at the same time` : 'the claim did not read back'}.`,
|
|
233
|
+
);
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
const release = async (
|
|
237
|
+
context: ApiContext,
|
|
238
|
+
args: ClaimArgs,
|
|
239
|
+
before: PullRequestState,
|
|
240
|
+
): Promise<Result<string, string>> => {
|
|
241
|
+
const held = before.queue.claim;
|
|
242
|
+
|
|
243
|
+
if (held?.says.kind !== 'standing' || held.says.claim.by !== args.by) {
|
|
244
|
+
return Result.ok(`#${args.number}: ${args.by} holds no claim on it.`);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const written = await writeComment(
|
|
248
|
+
context,
|
|
249
|
+
args.number,
|
|
250
|
+
held.commentId,
|
|
251
|
+
writeReleasedClaimComment(
|
|
252
|
+
`${args.by} gave up the claim; \`unblock-prs\` and other sessions may take it up again.`,
|
|
253
|
+
),
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
return Result.isErr(written)
|
|
257
|
+
? written
|
|
258
|
+
: Result.ok(`#${args.number}: claim released.`);
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
type PullRequestState = Readonly<{ headSha: string; queue: QueueComments }>;
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* The head, and what this account's comments say about it against the tip
|
|
265
|
+
* of the default branch, which is what a set-aside is recorded against.
|
|
266
|
+
*/
|
|
267
|
+
const readPullRequest = async (
|
|
268
|
+
context: ApiContext,
|
|
269
|
+
number: number,
|
|
270
|
+
viewer: string,
|
|
271
|
+
): Promise<Result<PullRequestState, string>> => {
|
|
272
|
+
const pr = await rest(context, 'GET', `/pulls/${number}`, PullRequestSchema);
|
|
273
|
+
|
|
274
|
+
if (Result.isErr(pr)) {
|
|
275
|
+
return Result.err(`cannot read #${number}: ${pr.value}`);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (pr.value.state !== 'open') {
|
|
279
|
+
return Result.err(`#${number} is ${pr.value.state}.`);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const repo = await rest(context, 'GET', '', RepositorySchema);
|
|
283
|
+
|
|
284
|
+
if (Result.isErr(repo)) {
|
|
285
|
+
return repo;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const tip = await rest(
|
|
289
|
+
context,
|
|
290
|
+
'GET',
|
|
291
|
+
`/git/ref/heads/${repo.value.default_branch}`,
|
|
292
|
+
RefSchema,
|
|
293
|
+
);
|
|
294
|
+
|
|
295
|
+
if (Result.isErr(tip)) {
|
|
296
|
+
return tip;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// The first page, oldest first: both comments are edited in place, so
|
|
300
|
+
// they stay where they were first posted.
|
|
301
|
+
const comments = await rest(
|
|
302
|
+
context,
|
|
303
|
+
'GET',
|
|
304
|
+
`/issues/${number}/comments`,
|
|
305
|
+
CommentListSchema,
|
|
306
|
+
{ query: { per_page: '100' } },
|
|
307
|
+
);
|
|
308
|
+
|
|
309
|
+
if (Result.isErr(comments)) {
|
|
310
|
+
return comments;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return Result.ok({
|
|
314
|
+
headSha: pr.value.head.sha,
|
|
315
|
+
queue: readQueueComments(
|
|
316
|
+
Arr.generate(function* () {
|
|
317
|
+
for (const { id, body, user } of comments.value) {
|
|
318
|
+
if (user?.login === viewer) {
|
|
319
|
+
yield { id, body: body ?? '' };
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}),
|
|
323
|
+
{
|
|
324
|
+
headSha: pr.value.head.sha,
|
|
325
|
+
baseTip: tip.value.object.sha,
|
|
326
|
+
nowEpochMs: currentEpochMs(),
|
|
327
|
+
},
|
|
328
|
+
),
|
|
329
|
+
});
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
const writeComment = async (
|
|
333
|
+
context: ApiContext,
|
|
334
|
+
number: number,
|
|
335
|
+
commentId: number | undefined,
|
|
336
|
+
body: string,
|
|
337
|
+
): Promise<Result<undefined, string>> => {
|
|
338
|
+
const written =
|
|
339
|
+
commentId === undefined
|
|
340
|
+
? await rest(
|
|
341
|
+
context,
|
|
342
|
+
'POST',
|
|
343
|
+
`/issues/${number}/comments`,
|
|
344
|
+
CommentSchema,
|
|
345
|
+
{
|
|
346
|
+
body: { body },
|
|
347
|
+
},
|
|
348
|
+
)
|
|
349
|
+
: await rest(
|
|
350
|
+
context,
|
|
351
|
+
'PATCH',
|
|
352
|
+
`/issues/comments/${commentId}`,
|
|
353
|
+
CommentSchema,
|
|
354
|
+
{ body: { body } },
|
|
355
|
+
);
|
|
356
|
+
|
|
357
|
+
return Result.isErr(written)
|
|
358
|
+
? Result.err(`cannot write the claim on #${number}: ${written.value}`)
|
|
359
|
+
: Result.ok(undefined);
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
/** Long enough for a write made in the same moment to be read back too. */
|
|
363
|
+
const READ_BACK_DELAY_MS = 3000;
|
|
364
|
+
|
|
365
|
+
const PullRequestSchema = t.record({
|
|
366
|
+
state: t.string(),
|
|
367
|
+
head: t.record({ sha: t.string() }),
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
const RepositorySchema = t.record({ default_branch: t.string() });
|
|
371
|
+
|
|
372
|
+
const RefSchema = t.record({ object: t.record({ sha: t.string() }) });
|
|
373
|
+
|
|
374
|
+
const CommentSchema = t.record({
|
|
375
|
+
id: t.number(),
|
|
376
|
+
body: t.union([t.string(), t.nullType]),
|
|
377
|
+
user: t.union([t.record({ login: t.string() }), t.nullType]),
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
const CommentListSchema = t.array(CommentSchema);
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import {
|
|
2
|
+
queueOwner,
|
|
3
|
+
readQueueComments,
|
|
4
|
+
writeClaimComment,
|
|
5
|
+
writeReleasedClaimComment,
|
|
6
|
+
writeSetAsideComment,
|
|
7
|
+
type QueueComments,
|
|
8
|
+
type QueueOwner,
|
|
9
|
+
} from 'pr-report-core';
|
|
10
|
+
import { decideClaim, parseClaimArgs } from './claim-pr.mjs';
|
|
11
|
+
|
|
12
|
+
const HEAD = 'c'.repeat(40);
|
|
13
|
+
|
|
14
|
+
const BASE = 'a'.repeat(40);
|
|
15
|
+
|
|
16
|
+
const NOW = Date.parse('2026-10-12T01:30:00Z');
|
|
17
|
+
|
|
18
|
+
const SET_ASIDE = writeSetAsideComment(
|
|
19
|
+
{ reason: 'rebase-failed', headSha: HEAD, baseSha: BASE },
|
|
20
|
+
'prose',
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
const claimedBy = (by: string): string =>
|
|
24
|
+
writeClaimComment({ headSha: HEAD, by, at: '2026-10-12T01:00:00Z' }, 'prose');
|
|
25
|
+
|
|
26
|
+
const read = (
|
|
27
|
+
...bodies: readonly string[]
|
|
28
|
+
): ReturnType<typeof readQueueComments> =>
|
|
29
|
+
readQueueComments(
|
|
30
|
+
bodies.map((body, index) => ({ id: index + 1, body })),
|
|
31
|
+
{ headSha: HEAD, baseTip: BASE, nowEpochMs: NOW },
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
/** The owner `claim-pr` reads, from the same comments, for a queued pull request. */
|
|
35
|
+
const ownerOf = (queue: QueueComments): QueueOwner | undefined =>
|
|
36
|
+
queueOwner({
|
|
37
|
+
number: 2267,
|
|
38
|
+
labels: ['merge-queued', 'skip-ci'],
|
|
39
|
+
isDraft: false,
|
|
40
|
+
fromFork: false,
|
|
41
|
+
headRef: 'fix/a-thing',
|
|
42
|
+
headSha: HEAD,
|
|
43
|
+
baseRef: 'main',
|
|
44
|
+
defaultBranch: 'main',
|
|
45
|
+
stackedOn: undefined,
|
|
46
|
+
inCycle: false,
|
|
47
|
+
setAside: queue.setAside?.says,
|
|
48
|
+
claim: queue.claim?.says,
|
|
49
|
+
nowEpochMs: NOW,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const decide = (
|
|
53
|
+
by: string,
|
|
54
|
+
...bodies: readonly string[]
|
|
55
|
+
): ReturnType<typeof decideClaim> => {
|
|
56
|
+
const queue = read(...bodies);
|
|
57
|
+
|
|
58
|
+
return decideClaim(ownerOf(queue), queue, by);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
describe(decideClaim, () => {
|
|
62
|
+
test('claims a set-aside pull request nobody holds, as a new comment', () => {
|
|
63
|
+
assert.deepStrictEqual(decide('me', SET_ASIDE), {
|
|
64
|
+
kind: 'write',
|
|
65
|
+
commentId: undefined,
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test('writes over a claim that has ended', () => {
|
|
70
|
+
assert.deepStrictEqual(
|
|
71
|
+
decide('me', SET_ASIDE, writeReleasedClaimComment('gone')),
|
|
72
|
+
{ kind: 'write', commentId: 2 },
|
|
73
|
+
);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test('renews its own claim in place', () => {
|
|
77
|
+
assert.deepStrictEqual(decide('me', SET_ASIDE, claimedBy('me')), {
|
|
78
|
+
kind: 'write',
|
|
79
|
+
commentId: 2,
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test('refuses one someone else holds', () => {
|
|
84
|
+
const decided = decide('me', SET_ASIDE, claimedBy('other'));
|
|
85
|
+
|
|
86
|
+
assert.strictEqual(decided.kind, 'refuse');
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('claims one set aside at its head after the base moved', () => {
|
|
90
|
+
// #2267: the set-aside comment is the hand-off, whatever the tip of the
|
|
91
|
+
// default branch is read as. Until the worker rewrites it as resolved it
|
|
92
|
+
// is the skill's.
|
|
93
|
+
assert.deepStrictEqual(
|
|
94
|
+
decide(
|
|
95
|
+
'me',
|
|
96
|
+
writeSetAsideComment(
|
|
97
|
+
{ reason: 'rebase-failed', headSha: HEAD, baseSha: 'b'.repeat(40) },
|
|
98
|
+
'prose',
|
|
99
|
+
),
|
|
100
|
+
),
|
|
101
|
+
{ kind: 'write', commentId: undefined },
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test('refuses one that is the worker’s or a person’s', () => {
|
|
106
|
+
// Nothing set aside, or set aside at a head that has moved: the worker
|
|
107
|
+
// is about to act on it, or already did.
|
|
108
|
+
assert.strictEqual(decide('me').kind, 'refuse');
|
|
109
|
+
|
|
110
|
+
assert.strictEqual(
|
|
111
|
+
decide(
|
|
112
|
+
'me',
|
|
113
|
+
writeSetAsideComment(
|
|
114
|
+
{ reason: 'rebase-failed', headSha: 'd'.repeat(40), baseSha: BASE },
|
|
115
|
+
'prose',
|
|
116
|
+
),
|
|
117
|
+
).kind,
|
|
118
|
+
'refuse',
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
// Only a bypass merge clears it, which no session makes.
|
|
122
|
+
assert.strictEqual(
|
|
123
|
+
decide(
|
|
124
|
+
'me',
|
|
125
|
+
writeSetAsideComment(
|
|
126
|
+
{ reason: 'awaiting-bypass', headSha: HEAD, baseSha: BASE },
|
|
127
|
+
'prose',
|
|
128
|
+
),
|
|
129
|
+
).kind,
|
|
130
|
+
'refuse',
|
|
131
|
+
);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test('refuses one whose owner could not be read', () => {
|
|
135
|
+
assert.strictEqual(
|
|
136
|
+
decideClaim(undefined, read(SET_ASIDE), 'me').kind,
|
|
137
|
+
'refuse',
|
|
138
|
+
);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
describe(parseClaimArgs, () => {
|
|
143
|
+
test('reads a claim and a release', () => {
|
|
144
|
+
assert.deepStrictEqual(parseClaimArgs(['2154', '--by', 'me']), {
|
|
145
|
+
number: 2154,
|
|
146
|
+
by: 'me',
|
|
147
|
+
release: false,
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// `pnpm run claim-pr -- …` passes the `--` on.
|
|
151
|
+
assert.deepStrictEqual(parseClaimArgs(['--', '2154', '--by', 'me']), {
|
|
152
|
+
number: 2154,
|
|
153
|
+
by: 'me',
|
|
154
|
+
release: false,
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
assert.deepStrictEqual(
|
|
158
|
+
parseClaimArgs(['--release', '--by', 'me', '#2154']),
|
|
159
|
+
{ number: 2154, by: 'me', release: true },
|
|
160
|
+
);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
test('refuses what it cannot act on', () => {
|
|
164
|
+
for (const args of [
|
|
165
|
+
[],
|
|
166
|
+
['2154'],
|
|
167
|
+
['--by', 'me'],
|
|
168
|
+
['x', '--by', 'me'],
|
|
169
|
+
['2154', '--by', 'a b'],
|
|
170
|
+
['2154', '--by'],
|
|
171
|
+
['2154', '--by', 'me', '--force'],
|
|
172
|
+
]) {
|
|
173
|
+
assert.isString(parseClaimArgs(args));
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './claim-pr.mjs';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Arr, Result, unknownToString } from 'ts-data-forge';
|
|
4
|
+
import { CLAIM_PR_HELP, claimPr, parseClaimArgs } from '../claim-pr/index.mjs';
|
|
5
|
+
|
|
6
|
+
const argv = Arr.skip(process.argv, 2);
|
|
7
|
+
|
|
8
|
+
if (argv.includes('--help') || argv.includes('-h')) {
|
|
9
|
+
console.info(CLAIM_PR_HELP);
|
|
10
|
+
|
|
11
|
+
process.exit(0);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const args = parseClaimArgs(argv);
|
|
15
|
+
|
|
16
|
+
if (typeof args === 'string') {
|
|
17
|
+
console.error(`${args}\n\n${CLAIM_PR_HELP}`);
|
|
18
|
+
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const result = await claimPr(args).catch((error: unknown) =>
|
|
23
|
+
Result.err(unknownToString(error)),
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
if (Result.isErr(result)) {
|
|
27
|
+
console.error(result.value);
|
|
28
|
+
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
console.info(result.value);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Arr, Result, unknownToString } from 'ts-data-forge';
|
|
4
|
+
import { HELP, openPullRequest, parseOptions } from '../open-pr/index.mjs';
|
|
5
|
+
|
|
6
|
+
const options = parseOptions(Arr.skip(process.argv, 2));
|
|
7
|
+
|
|
8
|
+
if (Result.isErr(options)) {
|
|
9
|
+
console.error(`${options.value}\n\n${HELP}`);
|
|
10
|
+
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (options.value === 'help') {
|
|
15
|
+
console.info(HELP);
|
|
16
|
+
} else {
|
|
17
|
+
const result = await openPullRequest(options.value).catch((error: unknown) =>
|
|
18
|
+
Result.err(unknownToString(error)),
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
if (Result.isErr(result)) {
|
|
22
|
+
console.error(result.value);
|
|
23
|
+
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
console.info(result.value);
|
|
28
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Arr, Result, unknownToString } from 'ts-data-forge';
|
|
4
|
+
import { HELP, parseOptions, prReport } from '../pr-report/index.mjs';
|
|
5
|
+
|
|
6
|
+
const options = parseOptions(Arr.skip(process.argv, 2));
|
|
7
|
+
|
|
8
|
+
if (Result.isErr(options)) {
|
|
9
|
+
console.error(`${options.value}\n\n${HELP}`);
|
|
10
|
+
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (options.value === 'help') {
|
|
15
|
+
console.info(HELP);
|
|
16
|
+
} else {
|
|
17
|
+
const result = await prReport(options.value).catch((error: unknown) =>
|
|
18
|
+
Result.err(unknownToString(error)),
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
if (Result.isErr(result)) {
|
|
22
|
+
console.error(result.value);
|
|
23
|
+
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
console.info(result.value);
|
|
28
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Arr, Result, unknownToString } from 'ts-data-forge';
|
|
4
|
+
import {
|
|
5
|
+
PUSH_FIXED_PR_HELP,
|
|
6
|
+
parsePushArgs,
|
|
7
|
+
pushFixedPr,
|
|
8
|
+
} from '../push-fixed-pr/index.mjs';
|
|
9
|
+
|
|
10
|
+
const argv = Arr.skip(process.argv, 2);
|
|
11
|
+
|
|
12
|
+
if (argv.includes('--help') || argv.includes('-h')) {
|
|
13
|
+
console.info(PUSH_FIXED_PR_HELP);
|
|
14
|
+
|
|
15
|
+
process.exit(0);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const args = parsePushArgs(argv);
|
|
19
|
+
|
|
20
|
+
if (typeof args === 'string') {
|
|
21
|
+
console.error(`${args}\n\n${PUSH_FIXED_PR_HELP}`);
|
|
22
|
+
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const result = await pushFixedPr(args).catch((error: unknown) =>
|
|
27
|
+
Result.err(unknownToString(error)),
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
if (Result.isErr(result)) {
|
|
31
|
+
console.error(result.value);
|
|
32
|
+
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
console.info(result.value);
|