@atolis-hq/wake 0.3.4 → 0.3.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.
|
@@ -620,7 +620,7 @@ function createSandboxEntrypointDependencies(root) {
|
|
|
620
620
|
resolve();
|
|
621
621
|
});
|
|
622
622
|
});
|
|
623
|
-
const drained = drainProcessOutput(child, sink, (error) => {
|
|
623
|
+
const drained = drainProcessOutput(child, sink, (value) => process.stderr.write(value), (error) => {
|
|
624
624
|
process.stderr.write(`Wake detached start log failure: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
625
625
|
});
|
|
626
626
|
const completion = closed.then(() => drained).then(() => closeStatus);
|
|
@@ -20,6 +20,7 @@ export function createGitHubWakeLabelReconciler(input) {
|
|
|
20
20
|
}
|
|
21
21
|
return open;
|
|
22
22
|
};
|
|
23
|
+
const onError = input.onError ?? defaultOnError;
|
|
23
24
|
return {
|
|
24
25
|
async runOnce() {
|
|
25
26
|
const workflows = await input.orchestration.listAll();
|
|
@@ -49,15 +50,27 @@ export function createGitHubWakeLabelReconciler(input) {
|
|
|
49
50
|
const locator = parseGitHubIssueKey(resource.externalKey.key);
|
|
50
51
|
if (locator === null)
|
|
51
52
|
continue;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
// One issue's persistent failure (rate limit, permissions, a stale
|
|
54
|
+
// resource) must not stop every other open work item from being
|
|
55
|
+
// reconciled this pass — each correlation is an independent GitHub
|
|
56
|
+
// call with no ordering dependency on the others.
|
|
57
|
+
try {
|
|
58
|
+
const current = await input.getLabels(locator.owner, locator.repo, locator.number);
|
|
59
|
+
const next = reconcileGitHubWakeLabels(current, desired);
|
|
60
|
+
if (!sameLabels(current, next))
|
|
61
|
+
await input.setLabels(locator.owner, locator.repo, locator.number, next);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
onError({ workItemId: workflow.workItemId, ...locator }, error);
|
|
65
|
+
}
|
|
56
66
|
}
|
|
57
67
|
}
|
|
58
68
|
},
|
|
59
69
|
};
|
|
60
70
|
}
|
|
71
|
+
function defaultOnError(failure, error) {
|
|
72
|
+
process.stderr.write(`GitHub label reconcile failed for ${failure.owner}/${failure.repo}#${failure.number}: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
73
|
+
}
|
|
61
74
|
function desiredWakeLabels(workflow, watching) {
|
|
62
75
|
return [
|
|
63
76
|
`wake:status.${statusLabel(workflow.status)}`,
|
|
@@ -41,8 +41,14 @@ export function createProcessLogSink(path, output, options = {}) {
|
|
|
41
41
|
* Serializes detached child output into a sink and resolves only after Node's
|
|
42
42
|
* `close` event confirms its stdio streams have closed. Sink failures are
|
|
43
43
|
* reported rather than becoming detached, unhandled promise rejections.
|
|
44
|
+
*
|
|
45
|
+
* The child's full stdout+stderr always reaches the sink (durable file), but
|
|
46
|
+
* only stderr is also handed to `onStderr` — the child already writes its
|
|
47
|
+
* actionable failures there (GitHub request failures, tick failures) and
|
|
48
|
+
* routine detail to stdout, so this lets a detached supervisor surface just
|
|
49
|
+
* the actionable half on its own stderr without re-deriving severity here.
|
|
44
50
|
*/
|
|
45
|
-
export function drainProcessOutput(process, sink, reportError) {
|
|
51
|
+
export function drainProcessOutput(process, sink, onStderr, reportError) {
|
|
46
52
|
let writes = Promise.resolve();
|
|
47
53
|
const report = (error) => {
|
|
48
54
|
try {
|
|
@@ -52,12 +58,18 @@ export function drainProcessOutput(process, sink, reportError) {
|
|
|
52
58
|
// A reporting failure must not make a detached child unhandled.
|
|
53
59
|
}
|
|
54
60
|
};
|
|
55
|
-
const enqueue = (chunk) => {
|
|
61
|
+
const enqueue = (chunk, escalate) => {
|
|
56
62
|
const value = chunk.toString();
|
|
57
|
-
writes = writes
|
|
63
|
+
writes = writes
|
|
64
|
+
.then(() => sink.write(value))
|
|
65
|
+
.then(() => {
|
|
66
|
+
if (escalate)
|
|
67
|
+
onStderr(scrubProcessLog(value));
|
|
68
|
+
})
|
|
69
|
+
.catch(report);
|
|
58
70
|
};
|
|
59
|
-
process.stdout?.on('data', enqueue);
|
|
60
|
-
process.stderr?.on('data', enqueue);
|
|
71
|
+
process.stdout?.on('data', (chunk) => enqueue(chunk, false));
|
|
72
|
+
process.stderr?.on('data', (chunk) => enqueue(chunk, true));
|
|
61
73
|
process.on('error', report);
|
|
62
74
|
return new Promise((resolve) => {
|
|
63
75
|
process.once('close', () => {
|