pr-report-core 0.1.0 → 0.2.1

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.
Files changed (83) hide show
  1. package/dist/checks.d.mts +61 -62
  2. package/dist/checks.d.mts.map +1 -1
  3. package/dist/checks.mjs +8 -9
  4. package/dist/checks.mjs.map +1 -1
  5. package/dist/claim.d.mts +13 -14
  6. package/dist/claim.d.mts.map +1 -1
  7. package/dist/claim.mjs +0 -1
  8. package/dist/claim.mjs.map +1 -1
  9. package/dist/closing-issues.d.mts +18 -19
  10. package/dist/closing-issues.d.mts.map +1 -1
  11. package/dist/closing-issues.mjs +0 -1
  12. package/dist/closing-issues.mjs.map +1 -1
  13. package/dist/code-owners.d.mts +48 -49
  14. package/dist/code-owners.d.mts.map +1 -1
  15. package/dist/code-owners.mjs +41 -43
  16. package/dist/code-owners.mjs.map +1 -1
  17. package/dist/labels.d.mts +38 -40
  18. package/dist/labels.d.mts.map +1 -1
  19. package/dist/labels.mjs +0 -2
  20. package/dist/labels.mjs.map +1 -1
  21. package/dist/merge-after.d.mts +22 -16
  22. package/dist/merge-after.d.mts.map +1 -1
  23. package/dist/merge-after.mjs +97 -34
  24. package/dist/merge-after.mjs.map +1 -1
  25. package/dist/queue-comments.d.mts +2 -2
  26. package/dist/queue-order.d.mts +43 -30
  27. package/dist/queue-order.d.mts.map +1 -1
  28. package/dist/queue-order.mjs +33 -18
  29. package/dist/queue-order.mjs.map +1 -1
  30. package/dist/queue-owner.d.mts +30 -30
  31. package/dist/queue-owner.d.mts.map +1 -1
  32. package/dist/queue-owner.mjs +51 -51
  33. package/dist/queue-owner.mjs.map +1 -1
  34. package/dist/report.d.mts +9 -9
  35. package/dist/report.d.mts.map +1 -1
  36. package/dist/report.mjs +23 -23
  37. package/dist/report.mjs.map +1 -1
  38. package/dist/review-hold.d.mts +14 -14
  39. package/dist/ruleset.d.mts +10 -11
  40. package/dist/ruleset.d.mts.map +1 -1
  41. package/dist/ruleset.mjs +0 -1
  42. package/dist/ruleset.mjs.map +1 -1
  43. package/dist/set-aside.d.mts +28 -28
  44. package/dist/stack.d.mts +14 -15
  45. package/dist/stack.d.mts.map +1 -1
  46. package/dist/stack.mjs +0 -1
  47. package/dist/stack.mjs.map +1 -1
  48. package/dist/start-after.d.mts +20 -21
  49. package/dist/start-after.d.mts.map +1 -1
  50. package/dist/start-after.mjs +0 -1
  51. package/dist/start-after.mjs.map +1 -1
  52. package/dist/summarize.d.mts +2 -2
  53. package/dist/timestamp.d.mts +10 -10
  54. package/dist/tree.d.mts +5 -5
  55. package/dist/types.d.mts +32 -33
  56. package/dist/types.d.mts.map +1 -1
  57. package/package.json +8 -8
  58. package/src/checks.mts +74 -75
  59. package/src/checks.test.mts +30 -31
  60. package/src/claim.mts +13 -14
  61. package/src/closing-issues.mts +18 -19
  62. package/src/closing-issues.test.mts +2 -2
  63. package/src/code-owners.mts +107 -109
  64. package/src/labels.mts +38 -40
  65. package/src/merge-after.mts +164 -71
  66. package/src/merge-after.test.mts +80 -3
  67. package/src/queue-comments.mts +2 -2
  68. package/src/queue-order.mts +103 -83
  69. package/src/queue-order.test.mts +41 -4
  70. package/src/queue-owner.mts +103 -103
  71. package/src/queue-owner.test.mts +2 -2
  72. package/src/report.mts +49 -49
  73. package/src/review-hold.mts +14 -14
  74. package/src/review-hold.test.mts +3 -3
  75. package/src/ruleset.mts +10 -11
  76. package/src/set-aside.mts +28 -28
  77. package/src/stack.mts +14 -15
  78. package/src/stack.test.mts +4 -4
  79. package/src/start-after.mts +20 -21
  80. package/src/summarize.mts +2 -2
  81. package/src/timestamp.mts +14 -14
  82. package/src/tree.mts +5 -5
  83. package/src/types.mts +32 -33
@@ -19,15 +19,14 @@ export type ClosingIssueNode = Readonly<{
19
19
  /**
20
20
  * The closing issues that belong to `repo`, in GitHub's order.
21
21
  *
22
- * **Only this repository's.** A pull request can close an issue anywhere,
23
- * and a report lists each as `#N` — which for another repository's issue
24
- * names a different issue of this one, and for a private repository's may
25
- * put a title the report's reader cannot see into a report someone else
26
- * reads. The body parser `pr-report` falls back on without a token draws the
27
- * same line.
22
+ * **Only this repository's.** A pull request can close an issue anywhere, and a
23
+ * report lists each as `#N` — which for another repository's issue names a
24
+ * different issue of this one, and for a private repository's may put a title
25
+ * the report's reader cannot see into a report someone else reads. The body
26
+ * parser `pr-report` falls back on without a token draws the same line.
28
27
  *
29
- * `null` entries are skipped rather than rejected: one issue the token may
30
- * not see is no reason to lose the rest.
28
+ * `null` entries are skipped rather than rejected: one issue the token may not
29
+ * see is no reason to lose the rest.
31
30
  */
32
31
  export const closingIssuesIn = (
33
32
  repo: RepoRef,
@@ -55,21 +54,21 @@ export const closingIssuesIn = (
55
54
  };
56
55
 
57
56
  /**
58
- * The issues of `repo` a pull request body closes by keyword, as GitHub
59
- * itself read the body: first appearance order, each once.
57
+ * The issues of `repo` a pull request body closes by keyword, as GitHub itself
58
+ * read the body: first appearance order, each once.
60
59
  *
61
60
  * **Read from GitHub's rendering, not from the text.** GitHub wraps each
62
- * closing keyword it recognized in `<span class="issue-keyword">` and puts
63
- * the reference right after it, and it does so whatever the base branch.
64
- * `closingIssuesReferences` does not: it links a keyword only on a pull
65
- * request into the default branch, so a stacked one lists nothing until the
66
- * layers below it merge. Which spellings count, whether a reference inside
67
- * code or after a comma is closed, is GitHub's to decide, and this takes its
68
- * decision rather than copying the grammar. A body cannot forge the mark:
61
+ * closing keyword it recognized in `<span class="issue-keyword">` and puts the
62
+ * reference right after it, and it does so whatever the base branch.
63
+ * `closingIssuesReferences` does not: it links a keyword only on a pull request
64
+ * into the default branch, so a stacked one lists nothing until the layers
65
+ * below it merge. Which spellings count, whether a reference inside code or
66
+ * after a comma is closed, is GitHub's to decide, and this takes its decision
67
+ * rather than copying the grammar. A body cannot forge the mark:
69
68
  * GitHub strips `class` from HTML written in one.
70
69
  *
71
- * A reference to another repository's issue, or to a pull request, is left
72
- * out, for the reasons {@link closingIssuesIn} gives.
70
+ * A reference to another repository's issue, or to a pull request, is left out,
71
+ * for the reasons {@link closingIssuesIn} gives.
73
72
  */
74
73
  export const closingKeywordIssuesIn = (
75
74
  repo: RepoRef,
@@ -145,8 +145,8 @@ describe(closingKeywordIssuesIn, () => {
145
145
  });
146
146
 
147
147
  /**
148
- * A reference as GitHub renders it in a pull request's `bodyHTML`, with
149
- * the attributes in the order GitHub writes them.
148
+ * A reference as GitHub renders it in a pull request's `bodyHTML`, with the
149
+ * attributes in the order GitHub writes them.
150
150
  */
151
151
  const link = (
152
152
  nameWithOwner: string,
@@ -3,18 +3,18 @@
3
3
  *
4
4
  * Read because GitHub will not say. `main`'s ruleset has
5
5
  * `require_code_owner_review` on, so a pull request touching an owned path
6
- * waits for an owner to approve it — and nothing on a pull request reports
7
- * that wait: `reviewDecision` answers `null` for every pull request here,
8
- * owned paths or not, because it describes branch protection rather than a
9
- * ruleset. So it is worked out the way GitHub does, from the file — by the
10
- * Pull Requests Manager page, to show the wait, and by `unblock-prs`, to
11
- * leave a pull request that waits in the queue rather than run its checks.
6
+ * waits for an owner to approve it — and nothing on a pull request reports that
7
+ * wait: `reviewDecision` answers `null` for every pull request here, owned
8
+ * paths or not, because it describes branch protection rather than a ruleset.
9
+ * So it is worked out the way GitHub does, from the file — by the
10
+ * Pull Requests Manager page, to show the wait, and by `unblock-prs`, to leave
11
+ * a pull request that waits in the queue rather than run its checks.
12
12
  *
13
- * The patterns are the subset of `.gitignore` syntax GitHub documents for
14
- * this file: a leading `/` or a `/` in the middle anchors a pattern to the
15
- * root, a trailing `/` makes it a directory, `*` and `?` stay inside one path
16
- * segment and `**` crosses them. Negation and character ranges are not
17
- * supported by GitHub here either.
13
+ * The patterns are the subset of `.gitignore` syntax GitHub documents for this
14
+ * file: a leading `/` or a `/` in the middle anchors a pattern to the root, a
15
+ * trailing `/` makes it a directory, `*` and `?` stay inside one path segment
16
+ * and `**` crosses them. Negation and character ranges are not supported by
17
+ * GitHub here either.
18
18
  */
19
19
 
20
20
  import { Arr } from 'ts-data-forge';
@@ -22,8 +22,8 @@ import { Arr } from 'ts-data-forge';
22
22
  export type CodeOwnersRule = Readonly<{
23
23
  pattern: string;
24
24
  /**
25
- * Without the leading `@`. Empty for a pattern that clears the owners of
26
- * what an earlier line matched.
25
+ * Without the leading `@`. Empty for a pattern that clears the owners of what
26
+ * an earlier line matched.
27
27
  */
28
28
  owners: readonly string[];
29
29
  }>;
@@ -45,9 +45,9 @@ export const parseCodeOwners = (text: string): readonly CodeOwnersRule[] =>
45
45
  });
46
46
 
47
47
  /**
48
- * The owners of one path: those of the **last** pattern that matches it,
49
- * which is how GitHub reads the file — a later line overrides an earlier one
50
- * rather than adding to it.
48
+ * The owners of one path: those of the **last** pattern that matches it, which
49
+ * is how GitHub reads the file — a later line overrides an earlier one rather
50
+ * than adding to it.
51
51
  */
52
52
  export const ownersOf = (
53
53
  path: string,
@@ -55,102 +55,20 @@ export const ownersOf = (
55
55
  ): readonly string[] =>
56
56
  rules.findLast((rule) => toRegExp(rule.pattern).test(path))?.owners ?? [];
57
57
 
58
- const stripComment = (line: string): string => {
59
- const at = line.indexOf('#');
60
-
61
- return at === -1 ? line : line.slice(0, at);
62
- };
63
-
64
- const toRegExp = (pattern: string): RegExp => {
65
- const directory = pattern.endsWith('/');
66
-
67
- const trimmed = pattern.replaceAll(/^\/|\/$/gu, '');
68
-
69
- // `.gitignore`'s rule: a slash anywhere but at the end ties the pattern to
70
- // the root, and a pattern without one may match at any depth.
71
- const anchored = pattern.startsWith('/') || trimmed.includes('/');
72
-
73
- const body = globToRegExpSource(trimmed);
74
-
75
- // A directory owns what is under it and never matches as a file. A name
76
- // with no trailing slash may be either, so it matches itself and what is
77
- // under it — unless its last segment is a wildcard, which GitHub reads as
78
- // files at that level only: `docs/*` owns `docs/a.md` and not
79
- // `docs/build/a.md`.
80
- const tail = directory
81
- ? '/.+'
82
- : (trimmed.split('/').at(-1) ?? '').includes('*')
83
- ? ''
84
- : '(?:/.+)?';
85
-
86
- // eslint-disable-next-line security/detect-non-literal-regexp
87
- return new RegExp(`^${anchored ? '' : '(?:.+/)?'}${body}${tail}$`, 'u');
88
- };
89
-
90
- const globToRegExpSource = (glob: string): string =>
91
- glob
92
- .split('/')
93
- .map((segment, index, segments) =>
94
- segment === '**'
95
- ? // `a/**/b` is `a/b` as well as `a/x/y/b`, so the separator that
96
- // follows is part of what `**` may leave out.
97
- index === segments.length - 1
98
- ? '.*'
99
- : '(?:.*/)?'
100
- : `${segment
101
- .split('')
102
- .map((char) =>
103
- char === '*' ? '[^/]*' : char === '?' ? '[^/]' : escapeChar(char),
104
- )
105
- .join('')}${index === segments.length - 1 ? '' : '/'}`,
106
- )
107
- .join('');
108
-
109
- // Not `RegExp.escape`: it arrived in Node 24, and `ws:check:test` also runs
110
- // on the `engines.node` floor (`test-node-versions (minimum)`), which is 22.
111
- // Under the `u` flag only the syntax characters and `/` may be escaped, and
112
- // everything else is a literal as it stands.
113
- const escapeChar = (char: string): string =>
114
- String.raw`^$\.*+?()[]{}|/`.includes(char) ? (`\\${char}` as const) : char;
115
-
116
- /**
117
- * Where a pull request stands with the code owners.
118
- *
119
- * `required` lists what is still waiting — the owned paths no owner has
120
- * approved yet, and who could approve them. `authorOwns` is the case that
121
- * waits for ever: GitHub does not let an author approve their own pull
122
- * request, so when the author is the only owner nothing but a ruleset bypass
123
- * will merge it. `unknown` is a pull request whose changed files were more
124
- * than could be read, where the unread ones might be owned — or, with
125
- * `teams`, one approved by someone these teams might have as a member.
126
- */
127
- export type CodeOwnerReview = Readonly<
128
- | { state: 'approved' }
129
- | { state: 'not-required' }
130
- | { state: 'unknown'; teams?: readonly string[] }
131
- | {
132
- state: 'required';
133
- paths: readonly string[];
134
- owners: readonly string[];
135
- authorOwns: boolean;
136
- }
137
- >;
138
-
139
58
  /**
140
59
  * What GitHub would say, worked out the way GitHub does: every changed path
141
- * that has owners needs an approval from one of them. An approval is the
142
- * latest review of an owner that says so; one dismissed by a later push —
143
- * the ruleset dismisses stale approvals — no longer counts, and GitHub has
144
- * already stopped calling it an approval by the time this reads it.
60
+ * that has owners needs an approval from one of them. An approval is the latest
61
+ * review of an owner that says so; one dismissed by a later push — the ruleset
62
+ * dismisses stale approvals — no longer counts, and GitHub has already stopped
63
+ * calling it an approval by the time this reads it.
145
64
  *
146
- * Owners are compared by login, case-insensitively, as GitHub compares
147
- * them. A team owner (`@org/team`) cannot be: telling who is on the team
148
- * takes `read:org`, which neither reader asks for. So a path a team owns
149
- * waits while nobody at all has approved, is approved by a person owning it
150
- * beside the team, and otherwise — someone approved, and might be on the
151
- * team — cannot be told, which makes the whole `unknown` unless another
152
- * path is plainly still waiting. `CODEOWNERS` in this repository names no
153
- * team.
65
+ * Owners are compared by login, case-insensitively, as GitHub compares them. A
66
+ * team owner (`@org/team`) cannot be: telling who is on the team takes
67
+ * `read:org`, which neither reader asks for. So a path a team owns waits while
68
+ * nobody at all has approved, is approved by a person owning it beside the
69
+ * team, and otherwise — someone approved, and might be on the team — cannot be
70
+ * told, which makes the whole `unknown` unless another path is plainly still
71
+ * waiting. `CODEOWNERS` in this repository names no team.
154
72
  */
155
73
  export const codeOwnerReview = ({
156
74
  required,
@@ -225,5 +143,85 @@ export const codeOwnerReview = ({
225
143
  return owned ? { state: 'approved' } : { state: 'not-required' };
226
144
  };
227
145
 
146
+ const stripComment = (line: string): string => {
147
+ const at = line.indexOf('#');
148
+
149
+ return at === -1 ? line : line.slice(0, at);
150
+ };
151
+
152
+ // Not `RegExp.escape`: it arrived in Node 24, and `ws:check:test` also runs on
153
+ // the `engines.node` floor (`test-node-versions (minimum)`), which is 22.
154
+ // Under the `u` flag only the syntax characters and `/` may be escaped, and
155
+ // everything else is a literal as it stands.
156
+ const escapeChar = (char: string): string =>
157
+ String.raw`^$\.*+?()[]{}|/`.includes(char) ? (`\\${char}` as const) : char;
158
+
159
+ const globToRegExpSource = (glob: string): string =>
160
+ glob
161
+ .split('/')
162
+ .map((segment, index, segments) =>
163
+ segment === '**'
164
+ ? // `a/**/b` is `a/b` as well as `a/x/y/b`, so the separator that
165
+ // follows is part of what `**` may leave out.
166
+ index === segments.length - 1
167
+ ? '.*'
168
+ : '(?:.*/)?'
169
+ : `${segment
170
+ .split('')
171
+ .map((char) =>
172
+ char === '*' ? '[^/]*' : char === '?' ? '[^/]' : escapeChar(char),
173
+ )
174
+ .join('')}${index === segments.length - 1 ? '' : '/'}`,
175
+ )
176
+ .join('');
177
+
178
+ const toRegExp = (pattern: string): RegExp => {
179
+ const directory = pattern.endsWith('/');
180
+
181
+ const trimmed = pattern.replaceAll(/^\/|\/$/gu, '');
182
+
183
+ // `.gitignore`'s rule: a slash anywhere but at the end ties the pattern to
184
+ // the root, and a pattern without one may match at any depth.
185
+ const anchored = pattern.startsWith('/') || trimmed.includes('/');
186
+
187
+ const body = globToRegExpSource(trimmed);
188
+
189
+ // A directory owns what is under it and never matches as a file. A name with
190
+ // no trailing slash may be either, so it matches itself and what is under it
191
+ // — unless its last segment is a wildcard, which GitHub reads as files at
192
+ // that level only: `docs/*` owns `docs/a.md` and not `docs/build/a.md`.
193
+ const tail = directory
194
+ ? '/.+'
195
+ : (trimmed.split('/').at(-1) ?? '').includes('*')
196
+ ? ''
197
+ : '(?:/.+)?';
198
+
199
+ // eslint-disable-next-line security/detect-non-literal-regexp
200
+ return new RegExp(`^${anchored ? '' : '(?:.+/)?'}${body}${tail}$`, 'u');
201
+ };
202
+
203
+ /**
204
+ * Where a pull request stands with the code owners.
205
+ *
206
+ * `required` lists what is still waiting — the owned paths no owner has
207
+ * approved yet, and who could approve them. `authorOwns` is the case that waits
208
+ * for ever: GitHub does not let an author approve their own pull request, so
209
+ * when the author is the only owner nothing but a ruleset bypass will merge it.
210
+ * `unknown` is a pull request whose changed files were more than could be read,
211
+ * where the unread ones might be owned — or, with `teams`, one approved by
212
+ * someone these teams might have as a member.
213
+ */
214
+ export type CodeOwnerReview = Readonly<
215
+ | { state: 'approved' }
216
+ | { state: 'not-required' }
217
+ | { state: 'unknown'; teams?: readonly string[] }
218
+ | {
219
+ state: 'required';
220
+ paths: readonly string[];
221
+ owners: readonly string[];
222
+ authorOwns: boolean;
223
+ }
224
+ >;
225
+
228
226
  /** `org/team`, as opposed to a person's login or an email address. */
229
227
  const isTeam = (owner: string): boolean => owner.includes('/');
package/src/labels.mts CHANGED
@@ -1,23 +1,23 @@
1
1
  /**
2
- * The labels this repository's queue is made of. They exist only on GitHub,
3
- * so these strings, and the ones in `.github/workflows/`, are the whole of
4
- * their declaration: `unblock-prs` and `open-pr` act on them, and
5
- * `pr-report` and the Pull Requests Manager page report them.
2
+ * The labels this repository's queue is made of. They exist only on GitHub, so
3
+ * these strings, and the ones in `.github/workflows/`, are the whole of their
4
+ * declaration: `unblock-prs` and `open-pr` act on them, and `pr-report` and the
5
+ * Pull Requests Manager page report them.
6
6
  */
7
7
 
8
8
  /**
9
- * The label that says "not yet": the check workflows skip while it is on
10
- * and `skip-ci-label.yml` holds the merge with a `pending` `no-skip-ci-label`
11
- * status. It is a label, deliberately — a `skip-ci` in the title means
12
- * nothing to any workflow.
9
+ * The label that says "not yet": the check workflows skip while it is on and
10
+ * `skip-ci-label.yml` holds the merge with a `pending` `no-skip-ci-label`
11
+ * status. It is a label, deliberately — a `skip-ci` in the title means nothing
12
+ * to any workflow.
13
13
  */
14
14
  export const SKIP_CI_LABEL = 'skip-ci';
15
15
 
16
16
  /**
17
- * The label that says a pull request has been reviewed and is waiting its
18
- * turn. It is the whole of `unblock-prs`'s scope rule: a pull request without
19
- * it is passed over in silence, and one with it is rebased, released from
20
- * `skip-ci` and watched when its turn comes.
17
+ * The label that says a pull request has been reviewed and is waiting its turn.
18
+ * It is the whole of `unblock-prs`'s scope rule: a pull request without it is
19
+ * passed over in silence, and one with it is rebased, released from `skip-ci`
20
+ * and watched when its turn comes.
21
21
  */
22
22
  export const MERGE_QUEUED_LABEL = 'merge-queued';
23
23
 
@@ -25,17 +25,16 @@ export const MERGE_QUEUED_LABEL = 'merge-queued';
25
25
  * The label a pull request carries to say the next release must contain it:
26
26
  * while it is open, the version pull request is not picked.
27
27
  *
28
- * It exists because the version pull request is the one pull request whose
29
- * body cannot declare a `Merge-After:` — `changesets/action` overwrites the
30
- * title and body of it on every push to the base — so the ordering is
31
- * declared from the other side, by the pull request the release is waiting
32
- * for. A label rather than a trailer for the same reason `merge-queued` is
33
- * one: this repository is public, and a label needs write access while a
34
- * comment does not.
28
+ * It exists because the version pull request is the one pull request whose body
29
+ * cannot declare a `Merge-After:` — `changesets/action` overwrites the title
30
+ * and body of it on every push to the base — so the ordering is declared from
31
+ * the other side, by the pull request the release is waiting for. A label
32
+ * rather than a trailer for the same reason `merge-queued` is one: this
33
+ * repository is public, and a label needs write access while a comment does
34
+ * not.
35
35
  *
36
- * Nothing ever takes it off. The constraint is "open", so it ends when the
37
- * pull request merges or is closed, and there is no state left behind to
38
- * clean up.
36
+ * Nothing ever takes it off. The constraint is "open", so it ends when the pull
37
+ * request merges or is closed, and there is no state left behind to clean up.
39
38
  */
40
39
  export const BLOCKS_RELEASE_LABEL = 'blocks-release';
41
40
 
@@ -43,22 +42,22 @@ export const BLOCKS_RELEASE_LABEL = 'blocks-release';
43
42
  * The label that asks `unblock-prs` to keep a pull request on the tip of the
44
43
  * default branch while it waits, so that its diff stays readable for review.
45
44
  * It is honoured only together with `skip-ci`, under which the push runs no
46
- * checks, and only when the queue has nothing to do. `open-pr` puts it on
47
- * every layer of a stack: one above the bottom is carried along by the layer
48
- * below, and needs the label of its own once that layer merges and it is
49
- * moved onto the default branch.
45
+ * checks, and only when the queue has nothing to do. `open-pr` puts it on every
46
+ * layer of a stack: one above the bottom is carried along by the layer below,
47
+ * and needs the label of its own once that layer merges and it is moved onto
48
+ * the default branch.
50
49
  */
51
50
  export const AUTO_REBASE_LABEL = 'auto-rebase';
52
51
 
53
52
  /**
54
53
  * The labels that move a pull request within `unblock-prs`'s pick order:
55
- * among the ones it may pick, those labelled `priority:high` go first and
56
- * those labelled `priority:low` last, the version pull request included.
57
- * They decide nothing else — what `Merge-After:`, a stack or
58
- * `blocks-release` holds back stays held, and a pull request already in
59
- * flight is watched whatever it carries. One carrying both counts as
60
- * neither. {@link PRIORITY_MID_LABEL} is not read there: it is the same as
61
- * carrying neither.
54
+ * among the ones it may pick, those labelled `priority:high` go first and those
55
+ * labelled `priority:low` last, the version pull request included.
56
+ * They decide nothing else — what `Merge-After:`, a stack or `blocks-release`
57
+ * holds back stays held, and a pull request already in flight is watched
58
+ * whatever it carries. One carrying both counts as neither.
59
+ * {@link PRIORITY_MID_LABEL} is not read there: it is the same as carrying
60
+ * neither.
62
61
  */
63
62
  export const PRIORITY_HIGH_LABEL = 'priority:high';
64
63
 
@@ -72,8 +71,8 @@ export const PRIORITY_MID_LABEL = 'priority:mid';
72
71
 
73
72
  /**
74
73
  * The label that says the author is holding a pull request back for now.
75
- * Also on GitHub, and read only by the Pull Requests Manager page, whose
76
- * merge order counts it and can hide what carries it. It asks nothing of
74
+ * Also on GitHub, and read only by the Pull Requests Manager page, whose merge
75
+ * order counts it and can hide what carries it. It asks nothing of
77
76
  * `unblock-prs`: what is held is simply not labelled `merge-queued`.
78
77
  */
79
78
  export const PENDING_LABEL = 'pending';
@@ -82,8 +81,8 @@ export const PENDING_LABEL = 'pending';
82
81
  * The label that says someone has started an issue, before there is a pull
83
82
  * request to say so. `start-issue` puts it on, and refuses an issue that
84
83
  * already carries it, so that two sessions do not pick up the same one; the
85
- * Pull Requests Manager page and `pr-report` show a startable issue carrying
86
- * it as in progress, as they show one an open pull request closes
84
+ * Pull Requests Manager page and `pr-report` show a startable issue carrying it
85
+ * as in progress, as they show one an open pull request closes
87
86
  * (`start-after.mts`'s `progressOf`). Nothing takes it off when the work
88
87
  * merges: the issue closes, and the label with it stops mattering.
89
88
  */
@@ -92,8 +91,7 @@ export const IN_PROGRESS_LABEL = 'in-progress';
92
91
  /**
93
92
  * The label that says someone means to start an issue next. It holds nothing
94
93
  * back — `start-issue` takes it off as it puts {@link IN_PROGRESS_LABEL} on —
95
- * and only tells whoever is choosing what to start that this one is spoken
96
- * for; the page and `pr-report` show a startable issue carrying it as
97
- * planned.
94
+ * and only tells whoever is choosing what to start that this one is spoken for;
95
+ * the page and `pr-report` show a startable issue carrying it as planned.
98
96
  */
99
97
  export const PLANNED_LABEL = 'planned';