@bluewombat/manager-github 0.3.0 → 0.4.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/README.md +28 -0
- package/dist/emitter/run/run-emitter.d.ts.map +1 -1
- package/dist/emitter/run/run-emitter.js +9 -2
- package/dist/emitter/run/run-emitter.js.map +1 -1
- package/dist/github/client.d.ts +19 -2
- package/dist/github/client.d.ts.map +1 -1
- package/dist/github/client.js +78 -4
- package/dist/github/client.js.map +1 -1
- package/dist/github/etag-cache.d.ts +23 -0
- package/dist/github/etag-cache.d.ts.map +1 -0
- package/dist/github/etag-cache.js +27 -0
- package/dist/github/etag-cache.js.map +1 -0
- package/dist/listener/delivery/process-tree.d.ts +19 -0
- package/dist/listener/delivery/process-tree.d.ts.map +1 -0
- package/dist/listener/delivery/process-tree.js +137 -0
- package/dist/listener/delivery/process-tree.js.map +1 -0
- package/dist/listener/delivery/run-hook.d.ts.map +1 -1
- package/dist/listener/delivery/run-hook.js +4 -7
- package/dist/listener/delivery/run-hook.js.map +1 -1
- package/dist/manager.d.ts.map +1 -1
- package/dist/manager.js +9 -6
- package/dist/manager.js.map +1 -1
- package/dist/settled.d.ts +10 -0
- package/dist/settled.d.ts.map +1 -0
- package/dist/settled.js +16 -0
- package/dist/settled.js.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -102,6 +102,34 @@ account; commits are `commitAuthor`; pushes and fetches use the token. A copy
|
|
|
102
102
|
made before `remote` changed (SSH to HTTPS, say) no longer matches: delete it
|
|
103
103
|
and the next run clones again.
|
|
104
104
|
|
|
105
|
+
## Talking to GitHub
|
|
106
|
+
|
|
107
|
+
Every call goes through `src/github/client.ts`: `@octokit/core` with its retry
|
|
108
|
+
and throttling plugins, under the invocation's own duration. Each attempt also
|
|
109
|
+
has a clock of its own, 30 seconds (`REQUEST_TIMEOUT_MS`): a connection that
|
|
110
|
+
goes silent fails as a transport error and is tried again, rather than holding
|
|
111
|
+
the call — and the work waiting on it — until the invocation runs out. A stop
|
|
112
|
+
or the invocation's deadline aborts the call and is not retried.
|
|
113
|
+
|
|
114
|
+
Reads are conditional. The manager keeps, for its whole life — one `mason
|
|
115
|
+
run` — the last answer to each GET URL with its `etag`
|
|
116
|
+
(`src/github/etag-cache.ts`, the 64 most recently used). The next read of that
|
|
117
|
+
URL sends `If-None-Match`; when GitHub answers 304, the kept answer is handed
|
|
118
|
+
back whole, as the full read would have been. A 304 sent with an
|
|
119
|
+
Authorization header does not count against the token's hourly budget
|
|
120
|
+
(GitHub's [REST best practices](https://docs.github.com/en/rest/using-the-rest-api/best-practices-for-using-the-rest-api);
|
|
121
|
+
measured: three 304s in a row left `x-ratelimit-used` unchanged). So a tick
|
|
122
|
+
where nothing moved on the watched issues — the listing, a probe of a Feature
|
|
123
|
+
in flight — costs a round trip and no budget. Handing the answer back rather
|
|
124
|
+
than reading a 304 as "nothing" matters: when Host did not commit its Cursor,
|
|
125
|
+
the same listing is asked again and the issues not consumed yet must come back.
|
|
126
|
+
|
|
127
|
+
What it does not change: the latency of a read (a 304 is still a round trip),
|
|
128
|
+
and anything outside this manager — `ci-green` is its own process, run once
|
|
129
|
+
per judgement, with nothing to remember an `etag` in. Anything this manager
|
|
130
|
+
writes on an issue (a comment, a label) changes the listing, so the next read
|
|
131
|
+
after a report is a full one.
|
|
132
|
+
|
|
105
133
|
## Prepare the repository
|
|
106
134
|
|
|
107
135
|
`mason setup` reads the config and says what the repository still needs;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-emitter.d.ts","sourceRoot":"","sources":["../../../src/emitter/run/run-emitter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAI3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG1D,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,UAAU,CAAC;IACpB,uEAAuE;IACvE,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,UAAU,EAAE,UAAU,CAAC;IACvB,wEAAwE;IACxE,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE;QAAE,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC;CAC1C,CAAC;AAiBF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAQxF;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"run-emitter.d.ts","sourceRoot":"","sources":["../../../src/emitter/run/run-emitter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAI3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG1D,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,UAAU,CAAC;IACpB,uEAAuE;IACvE,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,UAAU,EAAE,UAAU,CAAC;IACvB,wEAAwE;IACxE,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE;QAAE,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC;CAC1C,CAAC;AAiBF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAQxF;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CA4GxE"}
|
|
@@ -92,6 +92,9 @@ export async function runEmitter(options) {
|
|
|
92
92
|
return finish("unreportable", listed.detail);
|
|
93
93
|
}
|
|
94
94
|
if (hasEventId(listed.value, invocation.eventId)) {
|
|
95
|
+
// Said already, but the label may have moved since — a fresh ledger
|
|
96
|
+
// re-admitting the issue, a human — and it must show this Event again.
|
|
97
|
+
await syncLabel();
|
|
95
98
|
return finish("duplicate");
|
|
96
99
|
}
|
|
97
100
|
}
|
|
@@ -105,7 +108,12 @@ export async function runEmitter(options) {
|
|
|
105
108
|
commentUrl = created.value.url;
|
|
106
109
|
// The Event is committed. The label is a rendering of it: failing to move it
|
|
107
110
|
// leaves the report standing, the way a missing section leaves the truth.
|
|
108
|
-
|
|
111
|
+
await syncLabel();
|
|
112
|
+
return finish("reported");
|
|
113
|
+
async function syncLabel() {
|
|
114
|
+
if (invocation.labelPrefix === undefined) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
109
117
|
const synced = await syncStateLabel(invocation, github, context, invocation.labelPrefix);
|
|
110
118
|
write({
|
|
111
119
|
event: "labels-finished",
|
|
@@ -116,6 +124,5 @@ export async function runEmitter(options) {
|
|
|
116
124
|
...(synced.kind === "unreportable" ? { detail: synced.detail } : {}),
|
|
117
125
|
});
|
|
118
126
|
}
|
|
119
|
-
return finish("reported");
|
|
120
127
|
}
|
|
121
128
|
//# sourceMappingURL=run-emitter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-emitter.js","sourceRoot":"","sources":["../../../src/emitter/run/run-emitter.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"run-emitter.js","sourceRoot":"","sources":["../../../src/emitter/run/run-emitter.ts"],"names":[],"mappings":"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"}
|
package/dist/github/client.d.ts
CHANGED
|
@@ -4,11 +4,20 @@
|
|
|
4
4
|
*
|
|
5
5
|
* The transport is `@octokit/core` with its retry and throttling plugins — not
|
|
6
6
|
* a hand-written HTTP client. What lives here is only what this package owes on
|
|
7
|
-
* top of it: a token in one place, the wait budget of one invocation,
|
|
8
|
-
* mapping from a failure to this package's own vocabulary
|
|
7
|
+
* top of it: a token in one place, the wait budget of one invocation, the
|
|
8
|
+
* mapping from a failure to this package's own vocabulary, and — given a cache —
|
|
9
|
+
* reads that cost nothing when nothing changed.
|
|
9
10
|
*/
|
|
10
11
|
import { Octokit } from "@octokit/core";
|
|
12
|
+
import type { EtagCache } from "./etag-cache.js";
|
|
11
13
|
declare const GithubOctokit: typeof Octokit & import("@octokit/core/types").Constructor<import("@octokit/plugin-retry").RetryPlugin>;
|
|
14
|
+
/**
|
|
15
|
+
* How long one attempt may wait for GitHub to answer. Past it the attempt is a
|
|
16
|
+
* transport failure, which the retry plugin tries again. Without it, the only
|
|
17
|
+
* bound was the whole invocation's: a connection that went silent held a
|
|
18
|
+
* report — and the work waiting on it — for minutes.
|
|
19
|
+
*/
|
|
20
|
+
export declare const REQUEST_TIMEOUT_MS = 30000;
|
|
12
21
|
/** The authenticated channel. Injected, so a run is testable with no network. */
|
|
13
22
|
export type GithubClient = InstanceType<typeof GithubOctokit>;
|
|
14
23
|
/** Identifies the caller to GitHub; the API rejects a request without one. */
|
|
@@ -25,12 +34,20 @@ export type ClientOptions = {
|
|
|
25
34
|
shouldInterrupt?: () => boolean;
|
|
26
35
|
/** Replaces the network in tests. */
|
|
27
36
|
fetch?: typeof globalThis.fetch;
|
|
37
|
+
/** One attempt's wait for an answer. Default {@link REQUEST_TIMEOUT_MS}. */
|
|
38
|
+
requestTimeoutMs?: number;
|
|
28
39
|
/**
|
|
29
40
|
* Space writes out the way GitHub asks, and wait out a rate limit. On by
|
|
30
41
|
* default. Turning it off is a test seam: it also gives up the waiting, so a
|
|
31
42
|
* real run must leave it alone.
|
|
32
43
|
*/
|
|
33
44
|
throttle?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Where the last answer to each GET is kept. Given, a read is sent with its
|
|
47
|
+
* `If-None-Match` and a 304 hands the kept answer back. Absent: every read
|
|
48
|
+
* is a full one.
|
|
49
|
+
*/
|
|
50
|
+
etags?: EtagCache;
|
|
34
51
|
};
|
|
35
52
|
/**
|
|
36
53
|
* Build the channel. Retrying a 5xx and honouring a rate limit are the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/github/client.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/github/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAGxC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,QAAA,MAAM,aAAa,yGAAoC,CAAC;AAExD;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAEzC,iFAAiF;AACjF,MAAM,MAAM,YAAY,GAAG,YAAY,CAAC,OAAO,aAAa,CAAC,CAAC;AAE9D,8EAA8E;AAC9E,eAAO,MAAM,UAAU,8BAA8B,CAAC;AAEtD,MAAM,MAAM,aAAa,GAAG;IAC1B,kFAAkF;IAClF,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,sFAAsF;IACtF,cAAc,EAAE,MAAM,CAAC;IACvB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC;IAChC,qCAAqC;IACrC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,YAAY,CAiCjE;AA8DD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,MAAM,MAAM,OAAO,GAAG;IACpB,8EAA8E;IAC9E,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAIF;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAcnD;AAsBD,MAAM,MAAM,IAAI,GAAG;IACjB,0DAA0D;IAC1D,MAAM,EAAE,WAAW,CAAC;IACpB,gFAAgF;IAChF,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,iDAAiD;AACjD,wBAAgB,UAAU,CACxB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,MAAM,EACjB,eAAe,EAAE,MAAM,OAAO,GAC7B,IAAI,CAYN"}
|
package/dist/github/client.js
CHANGED
|
@@ -4,13 +4,21 @@
|
|
|
4
4
|
*
|
|
5
5
|
* The transport is `@octokit/core` with its retry and throttling plugins — not
|
|
6
6
|
* a hand-written HTTP client. What lives here is only what this package owes on
|
|
7
|
-
* top of it: a token in one place, the wait budget of one invocation,
|
|
8
|
-
* mapping from a failure to this package's own vocabulary
|
|
7
|
+
* top of it: a token in one place, the wait budget of one invocation, the
|
|
8
|
+
* mapping from a failure to this package's own vocabulary, and — given a cache —
|
|
9
|
+
* reads that cost nothing when nothing changed.
|
|
9
10
|
*/
|
|
10
11
|
import { Octokit } from "@octokit/core";
|
|
11
12
|
import { retry } from "@octokit/plugin-retry";
|
|
12
13
|
import { throttling } from "@octokit/plugin-throttling";
|
|
13
14
|
const GithubOctokit = Octokit.plugin(retry, throttling);
|
|
15
|
+
/**
|
|
16
|
+
* How long one attempt may wait for GitHub to answer. Past it the attempt is a
|
|
17
|
+
* transport failure, which the retry plugin tries again. Without it, the only
|
|
18
|
+
* bound was the whole invocation's: a connection that went silent held a
|
|
19
|
+
* report — and the work waiting on it — for minutes.
|
|
20
|
+
*/
|
|
21
|
+
export const REQUEST_TIMEOUT_MS = 30_000;
|
|
14
22
|
/** Identifies the caller to GitHub; the API rejects a request without one. */
|
|
15
23
|
export const USER_AGENT = "bluewombat-manager-github";
|
|
16
24
|
/**
|
|
@@ -27,7 +35,7 @@ export function createClient(options) {
|
|
|
27
35
|
}
|
|
28
36
|
return now() + retryAfterSeconds * 1_000 < options.deadlineMs;
|
|
29
37
|
};
|
|
30
|
-
|
|
38
|
+
const client = new GithubOctokit({
|
|
31
39
|
auth: options.token,
|
|
32
40
|
baseUrl: trimBase(options.apiBase),
|
|
33
41
|
userAgent: USER_AGENT,
|
|
@@ -37,9 +45,75 @@ export function createClient(options) {
|
|
|
37
45
|
onRateLimit: (retryAfter, _options, _octokit, retryCount) => mayWait(retryAfter, retryCount),
|
|
38
46
|
onSecondaryRateLimit: (retryAfter, _options, _octokit, retryCount) => mayWait(retryAfter, retryCount),
|
|
39
47
|
},
|
|
40
|
-
|
|
48
|
+
request: {
|
|
49
|
+
fetch: boundedFetch(options.fetch ?? globalThis.fetch, options.requestTimeoutMs ?? REQUEST_TIMEOUT_MS),
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
if (options.etags !== undefined) {
|
|
53
|
+
readConditionally(client, options.etags);
|
|
54
|
+
}
|
|
55
|
+
return client;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Every GET asks GitHub whether its last answer still holds.
|
|
59
|
+
*
|
|
60
|
+
* A 304 with an Authorization header does not count against the token's
|
|
61
|
+
* budget (GitHub's REST best practices; measured on 2026-10-04: three 304s in a
|
|
62
|
+
* row left `x-ratelimit-used` where it was). The kept answer is returned whole,
|
|
63
|
+
* as the full read would have been: what a caller has not consumed yet is
|
|
64
|
+
* there again.
|
|
65
|
+
*/
|
|
66
|
+
function readConditionally(client, cache) {
|
|
67
|
+
client.hook.wrap("request", async (request, options) => {
|
|
68
|
+
if (String(options.method).toUpperCase() !== "GET") {
|
|
69
|
+
return await request(options);
|
|
70
|
+
}
|
|
71
|
+
const url = client.request.endpoint(options).url;
|
|
72
|
+
const kept = cache.get(url);
|
|
73
|
+
if (kept !== undefined) {
|
|
74
|
+
options.headers = { ...options.headers, "if-none-match": kept.etag };
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
const response = await request(options);
|
|
78
|
+
const etag = response.headers.etag;
|
|
79
|
+
if (typeof etag === "string" && etag.length > 0) {
|
|
80
|
+
cache.set(url, { etag, response });
|
|
81
|
+
}
|
|
82
|
+
return response;
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
if (kept !== undefined && statusOf(error) === 304) {
|
|
86
|
+
return kept.response;
|
|
87
|
+
}
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
41
90
|
});
|
|
42
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Each attempt gets its own clock, on top of whatever bound the caller set.
|
|
94
|
+
*
|
|
95
|
+
* Run out, it fails the way a dropped connection does: the request layer
|
|
96
|
+
* passes an abort through untouched and the retry plugin only retries what that
|
|
97
|
+
* layer wrapped. A caller's own abort — the deadline, an interrupt — stays an
|
|
98
|
+
* abort, and is not retried.
|
|
99
|
+
*/
|
|
100
|
+
function boundedFetch(base, timeoutMs) {
|
|
101
|
+
return async (input, init = {}) => {
|
|
102
|
+
const timeout = AbortSignal.timeout(timeoutMs);
|
|
103
|
+
const signal = init.signal ? AbortSignal.any([init.signal, timeout]) : timeout;
|
|
104
|
+
try {
|
|
105
|
+
return await base(input, { ...init, signal });
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
if (timeout.aborted && init.signal?.aborted !== true) {
|
|
109
|
+
throw new TypeError("fetch failed", {
|
|
110
|
+
cause: new Error(`GitHub did not answer within ${timeoutMs} ms`),
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
throw error;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
}
|
|
43
117
|
export function trimBase(apiBase) {
|
|
44
118
|
return apiBase.replace(/\/+$/, "");
|
|
45
119
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/github/client.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/github/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The last answer GitHub gave to each URL this manager read, with its `etag`.
|
|
3
|
+
*
|
|
4
|
+
* Asked again with `If-None-Match`, GitHub answers 304 when nothing changed —
|
|
5
|
+
* and a 304 sent with an Authorization header does not count against the
|
|
6
|
+
* token's hourly budget. The answer kept here is then handed back as is, so a
|
|
7
|
+
* caller sees exactly what a full read would have given it: a page of issues
|
|
8
|
+
* not yet consumed is delivered again, never skipped.
|
|
9
|
+
*
|
|
10
|
+
* Lives as long as the manager does: one `mason run`. Bounded, least recently
|
|
11
|
+
* used out first.
|
|
12
|
+
*/
|
|
13
|
+
export type CachedAnswer = {
|
|
14
|
+
etag: string;
|
|
15
|
+
/** The response a full read returned, handed back on a 304. */
|
|
16
|
+
response: unknown;
|
|
17
|
+
};
|
|
18
|
+
export type EtagCache = {
|
|
19
|
+
get(url: string): CachedAnswer | undefined;
|
|
20
|
+
set(url: string, answer: CachedAnswer): void;
|
|
21
|
+
};
|
|
22
|
+
export declare function createEtagCache(limit?: number): EtagCache;
|
|
23
|
+
//# sourceMappingURL=etag-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"etag-cache.d.ts","sourceRoot":"","sources":["../../src/github/etag-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAIF,MAAM,MAAM,SAAS,GAAG;IACtB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAAC;IAC3C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;CAC9C,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,SAAgB,GAAG,SAAS,CAwBhE"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const DEFAULT_LIMIT = 64;
|
|
2
|
+
export function createEtagCache(limit = DEFAULT_LIMIT) {
|
|
3
|
+
const answers = new Map();
|
|
4
|
+
return {
|
|
5
|
+
get(url) {
|
|
6
|
+
const answer = answers.get(url);
|
|
7
|
+
if (answer !== undefined) {
|
|
8
|
+
// Read again: the most recently used goes to the back of the line.
|
|
9
|
+
answers.delete(url);
|
|
10
|
+
answers.set(url, answer);
|
|
11
|
+
}
|
|
12
|
+
return answer;
|
|
13
|
+
},
|
|
14
|
+
set(url, answer) {
|
|
15
|
+
answers.delete(url);
|
|
16
|
+
answers.set(url, answer);
|
|
17
|
+
while (answers.size > limit) {
|
|
18
|
+
const oldest = answers.keys().next().value;
|
|
19
|
+
if (oldest === undefined) {
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
answers.delete(oldest);
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=etag-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"etag-cache.js","sourceRoot":"","sources":["../../src/github/etag-cache.ts"],"names":[],"mappings":"AAkBA,MAAM,aAAa,GAAG,EAAE,CAAC;AAOzB,MAAM,UAAU,eAAe,CAAC,KAAK,GAAG,aAAa;IACnD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAwB,CAAC;IAChD,OAAO;QACL,GAAG,CAAC,GAAG;YACL,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAChC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,mEAAmE;gBACnE,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACpB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC3B,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,GAAG,CAAC,GAAG,EAAE,MAAM;YACb,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACzB,OAAO,OAAO,CAAC,IAAI,GAAG,KAAK,EAAE,CAAC;gBAC5B,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;gBAC3C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBACzB,MAAM;gBACR,CAAC;gBACD,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ChildProcess } from "node:child_process";
|
|
2
|
+
/** Spread into the options of `spawn`: the child leads its own group. */
|
|
3
|
+
export declare function ownGroup(): {
|
|
4
|
+
detached: boolean;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Remember a running child so it does not outlive this process: a group of its
|
|
8
|
+
* own no longer shares the terminal's Ctrl-C, nor dies by accident with us.
|
|
9
|
+
* Forgotten on its own once it closes.
|
|
10
|
+
*/
|
|
11
|
+
export declare function track(child: ChildProcess): void;
|
|
12
|
+
/**
|
|
13
|
+
* SIGKILL to the child's whole group and to every descendant, wherever its
|
|
14
|
+
* group; to the child alone where there are no groups. Once per child.
|
|
15
|
+
*/
|
|
16
|
+
export declare function killTree(child: ChildProcess): void;
|
|
17
|
+
/** `killTree`, then the pipes are cut after the grace period. Once per child. */
|
|
18
|
+
export declare function killAndCut(child: ChildProcess): void;
|
|
19
|
+
//# sourceMappingURL=process-tree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-tree.d.ts","sourceRoot":"","sources":["../../../src/listener/delivery/process-tree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAgB,MAAM,oBAAoB,CAAC;AAoCrE,yEAAyE;AACzE,wBAAgB,QAAQ,IAAI;IAAE,QAAQ,EAAE,OAAO,CAAA;CAAE,CAEhD;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAe/C;AAiCD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CA8BlD;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CASpD"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
// Canonical source of every `process-tree.ts` in this repository. Edit it here,
|
|
3
|
+
// then run `node scripts/check-process-tree.mjs --write`; `npm run lint` fails
|
|
4
|
+
// when a copy differs. A package stands alone, so each carries its own copy.
|
|
5
|
+
//
|
|
6
|
+
// The rule it keeps: whoever starts a child and owns its deadline — a
|
|
7
|
+
// supervisor — starts it as the leader of its own process group, and ends it by
|
|
8
|
+
// signalling that group. A child is rarely alone: a producer is `node producer`
|
|
9
|
+
// → `node agent` → the vendor CLI → its shells. Killing only the first leaves
|
|
10
|
+
// the rest running, holding the pipes open, until they end on their own; the
|
|
11
|
+
// deadline then means nothing and a finished job is reported as lost.
|
|
12
|
+
//
|
|
13
|
+
// A layer in the middle of such a chain (a producer, an agent runner) is not a
|
|
14
|
+
// supervisor: it starts its child in its own group, so the supervisor's signal
|
|
15
|
+
// reaches it too.
|
|
16
|
+
//
|
|
17
|
+
// The group is not the whole tree. A vendor CLI may start each shell command
|
|
18
|
+
// in a group of its own (cursor-agent does), out of the group's reach. So the
|
|
19
|
+
// descendants are read from `ps` first — once their parent dies they are
|
|
20
|
+
// re-parented and the link is lost — and each is killed too.
|
|
21
|
+
/** Windows has no process groups: there a child is killed alone. */
|
|
22
|
+
const OWN_GROUP = process.platform !== "win32";
|
|
23
|
+
/**
|
|
24
|
+
* After a kill the pipes are cut this long afterwards, so a grandchild that
|
|
25
|
+
* left the group (setsid) and still holds one cannot hold the outcome back.
|
|
26
|
+
*/
|
|
27
|
+
const PIPE_GRACE_MS = 2_000;
|
|
28
|
+
const live = new Set();
|
|
29
|
+
/** Already killed: a supervisor polling its interrupt asks again every tick. */
|
|
30
|
+
const ended = new WeakSet();
|
|
31
|
+
let exitHookInstalled = false;
|
|
32
|
+
/** Spread into the options of `spawn`: the child leads its own group. */
|
|
33
|
+
export function ownGroup() {
|
|
34
|
+
return { detached: OWN_GROUP };
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Remember a running child so it does not outlive this process: a group of its
|
|
38
|
+
* own no longer shares the terminal's Ctrl-C, nor dies by accident with us.
|
|
39
|
+
* Forgotten on its own once it closes.
|
|
40
|
+
*/
|
|
41
|
+
export function track(child) {
|
|
42
|
+
if (OWN_GROUP && !exitHookInstalled) {
|
|
43
|
+
exitHookInstalled = true;
|
|
44
|
+
process.on("exit", () => {
|
|
45
|
+
for (const running of live) {
|
|
46
|
+
killTree(running);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
live.add(child);
|
|
51
|
+
const forget = () => {
|
|
52
|
+
live.delete(child);
|
|
53
|
+
};
|
|
54
|
+
child.once("close", forget);
|
|
55
|
+
child.once("error", forget);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Every process below `pid`, as `ps` lists them now. Empty where `ps` cannot be
|
|
59
|
+
* read: the group kill still stands.
|
|
60
|
+
*/
|
|
61
|
+
function descendants(pid) {
|
|
62
|
+
let table;
|
|
63
|
+
try {
|
|
64
|
+
table = execFileSync("ps", ["-A", "-o", "pid=,ppid="], {
|
|
65
|
+
encoding: "utf8",
|
|
66
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
const childrenOf = new Map();
|
|
73
|
+
for (const line of table.split("\n")) {
|
|
74
|
+
const match = /^\s*(\d+)\s+(\d+)\s*$/.exec(line);
|
|
75
|
+
if (match !== null) {
|
|
76
|
+
const parent = Number(match[2]);
|
|
77
|
+
childrenOf.set(parent, [...(childrenOf.get(parent) ?? []), Number(match[1])]);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const found = [];
|
|
81
|
+
let frontier = [pid];
|
|
82
|
+
while (frontier.length > 0) {
|
|
83
|
+
frontier = frontier.flatMap((each) => childrenOf.get(each) ?? []);
|
|
84
|
+
found.push(...frontier);
|
|
85
|
+
}
|
|
86
|
+
return found;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* SIGKILL to the child's whole group and to every descendant, wherever its
|
|
90
|
+
* group; to the child alone where there are no groups. Once per child.
|
|
91
|
+
*/
|
|
92
|
+
export function killTree(child) {
|
|
93
|
+
if (ended.has(child)) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
ended.add(child);
|
|
97
|
+
if (OWN_GROUP && child.pid !== undefined) {
|
|
98
|
+
const below = descendants(child.pid);
|
|
99
|
+
let grouped = true;
|
|
100
|
+
try {
|
|
101
|
+
process.kill(-child.pid, "SIGKILL");
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// no such group: the child itself, below
|
|
105
|
+
grouped = false;
|
|
106
|
+
}
|
|
107
|
+
for (const pid of below) {
|
|
108
|
+
try {
|
|
109
|
+
process.kill(pid, "SIGKILL");
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// already gone, with the group
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (grouped) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
child.kill("SIGKILL");
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// already gone
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/** `killTree`, then the pipes are cut after the grace period. Once per child. */
|
|
127
|
+
export function killAndCut(child) {
|
|
128
|
+
if (ended.has(child)) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
killTree(child);
|
|
132
|
+
setTimeout(() => {
|
|
133
|
+
child.stdout?.destroy();
|
|
134
|
+
child.stderr?.destroy();
|
|
135
|
+
}, PIPE_GRACE_MS).unref();
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=process-tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-tree.js","sourceRoot":"","sources":["../../../src/listener/delivery/process-tree.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-hook.d.ts","sourceRoot":"","sources":["../../../src/listener/delivery/run-hook.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-hook.d.ts","sourceRoot":"","sources":["../../../src/listener/delivery/run-hook.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,oEAAoE;AACpE,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAsC9E"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
+
import { killTree, ownGroup, track } from "./process-tree.js";
|
|
2
3
|
/** Soft cap: --on-intention must not hold the subscription open forever. */
|
|
3
4
|
const HOOK_TIMEOUT_MS = 5_000;
|
|
4
5
|
/**
|
|
@@ -28,19 +29,15 @@ export function runHook(argv, cwd) {
|
|
|
28
29
|
};
|
|
29
30
|
let child;
|
|
30
31
|
try {
|
|
31
|
-
child = spawn(file, args, { cwd, stdio: ["ignore", "ignore", "ignore"] });
|
|
32
|
+
child = spawn(file, args, { cwd, stdio: ["ignore", "ignore", "ignore"], ...ownGroup() });
|
|
33
|
+
track(child);
|
|
32
34
|
}
|
|
33
35
|
catch {
|
|
34
36
|
finish();
|
|
35
37
|
return;
|
|
36
38
|
}
|
|
37
39
|
timer = setTimeout(() => {
|
|
38
|
-
|
|
39
|
-
child.kill("SIGKILL");
|
|
40
|
-
}
|
|
41
|
-
catch {
|
|
42
|
-
// already gone
|
|
43
|
-
}
|
|
40
|
+
killTree(child);
|
|
44
41
|
finish();
|
|
45
42
|
}, HOOK_TIMEOUT_MS);
|
|
46
43
|
child.on("error", finish);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-hook.js","sourceRoot":"","sources":["../../../src/listener/delivery/run-hook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE9D,4EAA4E;AAC5E,MAAM,eAAe,GAAG,KAAK,CAAC;AAE9B;;;;GAIG;AACH,oEAAoE;AACpE,MAAM,UAAU,OAAO,CAAC,IAAc,EAAE,GAAuB;IAC7D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;QAC7B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QAED,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,KAAiC,CAAC;QACtC,MAAM,MAAM,GAAG,GAAS,EAAE;YACxB,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO;YACT,CAAC;YACD,OAAO,GAAG,IAAI,CAAC;YACf,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,YAAY,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;QAEF,IAAI,KAAmB,CAAC;QACxB,IAAI,CAAC;YACH,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"run-hook.js","sourceRoot":"","sources":["../../../src/listener/delivery/run-hook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE9D,4EAA4E;AAC5E,MAAM,eAAe,GAAG,KAAK,CAAC;AAE9B;;;;GAIG;AACH,oEAAoE;AACpE,MAAM,UAAU,OAAO,CAAC,IAAc,EAAE,GAAuB;IAC7D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;QAC7B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QAED,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,KAAiC,CAAC;QACtC,MAAM,MAAM,GAAG,GAAS,EAAE;YACxB,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO;YACT,CAAC;YACD,OAAO,GAAG,IAAI,CAAC;YACf,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,YAAY,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;QAEF,IAAI,KAAmB,CAAC;QACxB,IAAI,CAAC;YACH,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,GAAG,QAAQ,EAAE,EAAE,CAAC,CAAC;YACzF,KAAK,CAAC,KAAK,CAAC,CAAC;QACf,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,EAAE,CAAC;YACT,OAAO;QACT,CAAC;QAED,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YACtB,QAAQ,CAAC,KAAK,CAAC,CAAC;YAChB,MAAM,EAAE,CAAC;QACX,CAAC,EAAE,eAAe,CAAC,CAAC;QAEpB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/manager.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../src/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,WAAW,EAKZ,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../src/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,WAAW,EAKZ,MAAM,yBAAyB,CAAC;AAUjC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAoB5C,eAAO,MAAM,gBAAgB,2BAA2B,CAAC;AACzD,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAChD,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAC3C,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE;QAAE,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+EAA+E;IAC/E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yCAAyC;IACzC,WAAW,CAAC,EAAE,OAAO,KAAK,CAAC;CAC5B,CAAC;AAEF;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,WAAW,CA4M9E"}
|
package/dist/manager.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { runAdapter } from "./adapter/run/run-adapter.js";
|
|
2
2
|
import { runEmitter } from "./emitter/run/run-emitter.js";
|
|
3
3
|
import { createClient } from "./github/client.js";
|
|
4
|
+
import { createEtagCache } from "./github/etag-cache.js";
|
|
4
5
|
import { issueNumberFromExternalId, issueNumberFromPayload } from "./issue-number.js";
|
|
5
6
|
import { payloadHasLabel } from "./labels.js";
|
|
6
7
|
import { runListener } from "./listener/run/run-listener.js";
|
|
7
8
|
import { probeIssue } from "./probe/probe-issue.js";
|
|
9
|
+
import { settledAlready } from "./settled.js";
|
|
8
10
|
import { foldPullRequest, submitPullRequest, } from "./submission/submission.js";
|
|
9
11
|
import { writtenFingerprint } from "./written-fingerprint.js";
|
|
10
12
|
const silent = () => { };
|
|
@@ -30,6 +32,9 @@ export function createGithubManager(options) {
|
|
|
30
32
|
const defaultPriority = options.defaultPriority ?? DEFAULT_PRIORITY;
|
|
31
33
|
const labels = options.labels ?? [];
|
|
32
34
|
const testNetwork = options.githubFetch !== undefined;
|
|
35
|
+
// One for the life of this manager — one `mason run` — shared by every call,
|
|
36
|
+
// so a tick that finds nothing changed costs no budget.
|
|
37
|
+
const etags = createEtagCache();
|
|
33
38
|
function channelOptions() {
|
|
34
39
|
const now = () => Date.now();
|
|
35
40
|
return {
|
|
@@ -40,6 +45,7 @@ export function createGithubManager(options) {
|
|
|
40
45
|
now,
|
|
41
46
|
shouldInterrupt: () => options.interruptFlag.interrupted,
|
|
42
47
|
throttle: !testNetwork,
|
|
48
|
+
etags,
|
|
43
49
|
...(options.githubFetch !== undefined ? { fetch: options.githubFetch } : {}),
|
|
44
50
|
};
|
|
45
51
|
}
|
|
@@ -68,8 +74,8 @@ export function createGithubManager(options) {
|
|
|
68
74
|
},
|
|
69
75
|
async listen(input) {
|
|
70
76
|
const deliveries = [];
|
|
71
|
-
const
|
|
72
|
-
|
|
77
|
+
const alreadySettled = (payload) => options.stateLabelPrefix !== undefined &&
|
|
78
|
+
settledAlready(payload, options.stateLabelPrefix, readyLabel);
|
|
73
79
|
const listenerInvocation = {
|
|
74
80
|
manager: MANAGER,
|
|
75
81
|
repo: options.repo,
|
|
@@ -92,7 +98,7 @@ export function createGithubManager(options) {
|
|
|
92
98
|
if (line.event === "intention" &&
|
|
93
99
|
typeof line.cursor === "string" &&
|
|
94
100
|
isObject(line.payload)) {
|
|
95
|
-
if (!
|
|
101
|
+
if (!alreadySettled(line.payload)) {
|
|
96
102
|
deliveries.push({ cursor: line.cursor, payload: line.payload });
|
|
97
103
|
}
|
|
98
104
|
}
|
|
@@ -222,9 +228,6 @@ export function createGithubManager(options) {
|
|
|
222
228
|
* cheaper than rebuilding a Feature that is already merged. The resume signal
|
|
223
229
|
* overrides it, so a human still has a way to ask for more.
|
|
224
230
|
*/
|
|
225
|
-
function doneAlready(payload, prefix, ready) {
|
|
226
|
-
return payloadHasLabel(payload, `${prefix}done`) && !payloadHasLabel(payload, ready);
|
|
227
|
-
}
|
|
228
231
|
function keyFromPayload(payload, repo) {
|
|
229
232
|
const number = issueNumberFromPayload(payload);
|
|
230
233
|
return number === undefined
|
package/dist/manager.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../src/manager.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACtF,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EACL,eAAe,EAEf,iBAAiB,GAClB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,MAAM,MAAM,GAAG,GAAS,EAAE,GAAE,CAAC,CAAC;AAC9B,MAAM,OAAO,GAAG,QAAQ,CAAC;AACzB,MAAM,eAAe,GAAG,SAAS,CAAC;AAClC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAClC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AACrC,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAC7B,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAClC,MAAM,4BAA4B,GAAG,UAAU,CAAC;AAChD,MAAM,6BAA6B,GAAG,WAAW,CAAC;AAClD,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAE/B,MAAM,CAAC,MAAM,gBAAgB,GAAG,wBAAwB,CAAC;AACzD,MAAM,CAAC,MAAM,iBAAiB,GAAG,cAAc,CAAC;AAChD,MAAM,CAAC,MAAM,mBAAmB,GAAG,OAAO,CAAC;AAC3C,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAmBnC;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAA6B;IAC/D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,gBAAgB,CAAC;IACpD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,mBAAmB,CAAC;IAC7D,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,gBAAgB,CAAC;IACpE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;IACpC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,KAAK,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../src/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether the tracker already says this issue reached an end — `done` or
|
|
3
|
+
* `cancelled` under the state-label prefix — and nobody asked to resume it.
|
|
4
|
+
*
|
|
5
|
+
* The WorkLedger is the truth; this is the tracker's own memory read as a
|
|
6
|
+
* guard for when the ledger is gone, so a fresh one neither rebuilds merged
|
|
7
|
+
* work nor takes up an abandoned issue again. The ready label still resumes.
|
|
8
|
+
*/
|
|
9
|
+
export declare function settledAlready(payload: Record<string, unknown>, prefix: string, ready: string): boolean;
|
|
10
|
+
//# sourceMappingURL=settled.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settled.d.ts","sourceRoot":"","sources":["../src/settled.ts"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,CAKT"}
|
package/dist/settled.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { payloadHasLabel } from "./labels.js";
|
|
2
|
+
/** The states that end a Feature: nothing more is done for it unless resumed. */
|
|
3
|
+
const SETTLED_STATES = ["done", "cancelled"];
|
|
4
|
+
/**
|
|
5
|
+
* Whether the tracker already says this issue reached an end — `done` or
|
|
6
|
+
* `cancelled` under the state-label prefix — and nobody asked to resume it.
|
|
7
|
+
*
|
|
8
|
+
* The WorkLedger is the truth; this is the tracker's own memory read as a
|
|
9
|
+
* guard for when the ledger is gone, so a fresh one neither rebuilds merged
|
|
10
|
+
* work nor takes up an abandoned issue again. The ready label still resumes.
|
|
11
|
+
*/
|
|
12
|
+
export function settledAlready(payload, prefix, ready) {
|
|
13
|
+
return (SETTLED_STATES.some((state) => payloadHasLabel(payload, `${prefix}${state}`)) &&
|
|
14
|
+
!payloadHasLabel(payload, ready));
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=settled.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settled.js","sourceRoot":"","sources":["../src/settled.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,iFAAiF;AACjF,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,WAAW,CAAU,CAAC;AAEtD;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAgC,EAChC,MAAc,EACd,KAAa;IAEb,OAAO,CACL,cAAc,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,eAAe,CAAC,OAAO,EAAE,GAAG,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC;QAC7E,CAAC,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,CACjC,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bluewombat/manager-github",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "GitHub Issues FeatureManager: issues in, comments and labels out; pull requests as Authority.",
|
|
6
6
|
"keywords": [
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"build": "tsc -p tsconfig.build.json"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@bluewombat/manager-kit": "^0.
|
|
46
|
+
"@bluewombat/manager-kit": "^0.4.0",
|
|
47
47
|
"@octokit/core": "^7.0.8",
|
|
48
48
|
"@octokit/plugin-retry": "^8.1.1",
|
|
49
49
|
"@octokit/plugin-throttling": "^11.0.5"
|