next-issue 1.0.4 → 1.0.5
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/README.md +3 -2
- package/dist/state.mjs +37 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -325,8 +325,9 @@ A `setupCommand` that fails, or that does not finish in `setupTimeoutMinutes`,
|
|
|
325
325
|
hands the issue to a person. The wait for the checks has its own limit, so
|
|
326
326
|
`commandTimeoutMinutes` holds for every other `git` and `gh` command. State per
|
|
327
327
|
issue goes to `.next-issue/<issue>.json`, so a new run continues where the last
|
|
328
|
-
run stopped. A state file that is not valid JSON
|
|
329
|
-
outcome that names the file, rather than a
|
|
328
|
+
run stopped. A state file that is not valid JSON, or that does not hold a valid
|
|
329
|
+
state, gives the issue an `error` outcome that names the file, rather than a
|
|
330
|
+
silent skip.
|
|
330
331
|
|
|
331
332
|
## Retry an issue that waits for a person
|
|
332
333
|
|
package/dist/state.mjs
CHANGED
|
@@ -19,12 +19,48 @@ export async function readState(repo, issue) {
|
|
|
19
19
|
}
|
|
20
20
|
throw error;
|
|
21
21
|
}
|
|
22
|
+
let parsed;
|
|
22
23
|
try {
|
|
23
|
-
|
|
24
|
+
parsed = JSON.parse(text);
|
|
24
25
|
}
|
|
25
26
|
catch {
|
|
26
27
|
throw new Error(`the state file ${path} is not valid JSON`);
|
|
27
28
|
}
|
|
29
|
+
if (!isState(parsed)) {
|
|
30
|
+
throw new Error(`the state file ${path} does not hold a valid state`);
|
|
31
|
+
}
|
|
32
|
+
return parsed;
|
|
33
|
+
}
|
|
34
|
+
const PHASES = ["claimed", "implemented", "review"];
|
|
35
|
+
function isRecord(value) {
|
|
36
|
+
return typeof value === "object" && value !== null;
|
|
37
|
+
}
|
|
38
|
+
function isOptional(value, type) {
|
|
39
|
+
return value === undefined || typeof value === type;
|
|
40
|
+
}
|
|
41
|
+
function isBaseFix(value) {
|
|
42
|
+
return isRecord(value) && typeof value.sha === "string" && typeof value.head === "string";
|
|
43
|
+
}
|
|
44
|
+
function isReviewRound(value) {
|
|
45
|
+
return (isRecord(value) &&
|
|
46
|
+
typeof value.round === "number" &&
|
|
47
|
+
typeof value.fingerprint === "string" &&
|
|
48
|
+
typeof value.findings === "string" &&
|
|
49
|
+
isOptional(value.dispute, "string"));
|
|
50
|
+
}
|
|
51
|
+
function isState(value) {
|
|
52
|
+
return (isRecord(value) &&
|
|
53
|
+
typeof value.issue === "number" &&
|
|
54
|
+
PHASES.includes(value.phase) &&
|
|
55
|
+
typeof value.branch === "string" &&
|
|
56
|
+
isOptional(value.pr, "number") &&
|
|
57
|
+
isOptional(value.title, "string") &&
|
|
58
|
+
typeof value.ciFixes === "number" &&
|
|
59
|
+
isOptional(value.commitFixes, "number") &&
|
|
60
|
+
(value.baseFix === undefined || isBaseFix(value.baseFix)) &&
|
|
61
|
+
typeof value.reviewRounds === "number" &&
|
|
62
|
+
Array.isArray(value.reviewLog) &&
|
|
63
|
+
value.reviewLog.every(isReviewRound));
|
|
28
64
|
}
|
|
29
65
|
export async function savedIssues(repo) {
|
|
30
66
|
let names;
|