@oisincoveney/pipeline 1.27.12 → 1.27.13
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/dist/argo-submit.js +5 -0
- package/dist/argo-workflow.d.ts +2 -0
- package/dist/argo-workflow.js +3 -0
- package/dist/pipeline-runtime.js +46 -26
- package/package.json +1 -1
package/dist/argo-submit.js
CHANGED
|
@@ -64,6 +64,11 @@ async function submitRunnerArgoWorkflow(rawOptions, dependencies = {}) {
|
|
|
64
64
|
"pipeline.oisin.dev/workflow": compiled.workflowId
|
|
65
65
|
};
|
|
66
66
|
const workflow = buildRunnerArgoWorkflowManifest({
|
|
67
|
+
annotations: payload.task.kind === "ticket" ? {
|
|
68
|
+
"pipeline.oisin.dev/ticket-id": payload.task.id,
|
|
69
|
+
"pipeline.oisin.dev/ticket-project": payload.run.project,
|
|
70
|
+
"pipeline.oisin.dev/ticket-title": payload.task.title
|
|
71
|
+
} : {},
|
|
67
72
|
eventAuthSecretKey: options.eventAuthSecretKey,
|
|
68
73
|
eventAuthSecretName: options.eventAuthSecretName,
|
|
69
74
|
generateName: options.generateName,
|
package/dist/argo-workflow.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ declare const runnerArgoWorkflowManifestSchema: z.ZodObject<{
|
|
|
6
6
|
apiVersion: z.ZodLiteral<"argoproj.io/v1alpha1">;
|
|
7
7
|
kind: z.ZodLiteral<"Workflow">;
|
|
8
8
|
metadata: z.ZodObject<{
|
|
9
|
+
annotations: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
9
10
|
generateName: z.ZodOptional<z.ZodString>;
|
|
10
11
|
labels: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
11
12
|
name: z.ZodOptional<z.ZodString>;
|
|
@@ -112,6 +113,7 @@ declare const buildRunnerArgoWorkflowOptionsSchema: z.ZodObject<{
|
|
|
112
113
|
eventAuthSecretName: z.ZodOptional<z.ZodString>;
|
|
113
114
|
generateName: z.ZodOptional<z.ZodString>;
|
|
114
115
|
githubAuthSecretName: z.ZodOptional<z.ZodString>;
|
|
116
|
+
annotations: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodOptional<z.ZodString>>>;
|
|
115
117
|
image: z.ZodDefault<z.ZodString>;
|
|
116
118
|
imagePullPolicy: z.ZodDefault<z.ZodEnum<{
|
|
117
119
|
Always: "Always";
|
package/dist/argo-workflow.js
CHANGED
|
@@ -83,6 +83,7 @@ const runnerArgoWorkflowManifestSchema = z.object({
|
|
|
83
83
|
apiVersion: z.literal(ARGO_WORKFLOW_API_VERSION),
|
|
84
84
|
kind: z.literal(ARGO_WORKFLOW_KIND),
|
|
85
85
|
metadata: z.object({
|
|
86
|
+
annotations: z.record(z.string().min(1), z.string().min(1)).optional(),
|
|
86
87
|
generateName: z.string().min(1).optional(),
|
|
87
88
|
labels: z.record(z.string().min(1), labelValueSchema).optional(),
|
|
88
89
|
name: z.string().min(1).optional(),
|
|
@@ -110,6 +111,7 @@ const buildRunnerArgoWorkflowOptionsSchema = z.object({
|
|
|
110
111
|
eventAuthSecretName: kubernetesNameSchema.optional(),
|
|
111
112
|
generateName: z.string().min(1).optional(),
|
|
112
113
|
githubAuthSecretName: kubernetesNameSchema.optional(),
|
|
114
|
+
annotations: z.record(z.string().min(1), z.string().min(1).optional()).default({}),
|
|
113
115
|
image: z.string().min(1).default(RUNNER_WORKFLOW_IMAGE),
|
|
114
116
|
imagePullPolicy: z.enum([
|
|
115
117
|
"Always",
|
|
@@ -151,6 +153,7 @@ function buildRunnerArgoWorkflowManifest(rawOptions) {
|
|
|
151
153
|
apiVersion: ARGO_WORKFLOW_API_VERSION,
|
|
152
154
|
kind: ARGO_WORKFLOW_KIND,
|
|
153
155
|
metadata: {
|
|
156
|
+
annotations: compactRecord(options.annotations),
|
|
154
157
|
...options.name ? { name: options.name } : {},
|
|
155
158
|
...options.generateName ? { generateName: options.generateName } : {},
|
|
156
159
|
labels: compactRecord({
|
package/dist/pipeline-runtime.js
CHANGED
|
@@ -302,27 +302,22 @@ async function executeNode(node, context) {
|
|
|
302
302
|
return cycle.result;
|
|
303
303
|
}
|
|
304
304
|
retry = retryCandidateForCycle(node, cycle, last, attempt);
|
|
305
|
-
const
|
|
305
|
+
const remediation = await remediateFailedNode({
|
|
306
306
|
attempt,
|
|
307
307
|
context,
|
|
308
308
|
node,
|
|
309
309
|
retry
|
|
310
310
|
});
|
|
311
|
-
if (
|
|
311
|
+
if (remediation?.result) {
|
|
312
312
|
recordNodeEvent(context, node.id, {
|
|
313
313
|
at: now(),
|
|
314
|
-
result:
|
|
314
|
+
result: remediation.result,
|
|
315
315
|
type: "PASSED"
|
|
316
316
|
});
|
|
317
|
-
emitNodeFinish(context,
|
|
318
|
-
return
|
|
317
|
+
emitNodeFinish(context, remediation.result);
|
|
318
|
+
return remediation.result;
|
|
319
319
|
}
|
|
320
|
-
if (
|
|
321
|
-
attempt,
|
|
322
|
-
context,
|
|
323
|
-
node,
|
|
324
|
-
retry
|
|
325
|
-
})) continue;
|
|
320
|
+
if (remediation?.retryNode) continue;
|
|
326
321
|
recordNodeEvent(context, node.id, {
|
|
327
322
|
at: now(),
|
|
328
323
|
attempt,
|
|
@@ -379,6 +374,13 @@ async function executeNode(node, context) {
|
|
|
379
374
|
emitNodeFinish(context, result);
|
|
380
375
|
return result;
|
|
381
376
|
}
|
|
377
|
+
async function remediateFailedNode(input) {
|
|
378
|
+
const selfRemediation = await remediateWritableNodeFailure(input);
|
|
379
|
+
if (selfRemediation) return { result: selfRemediation };
|
|
380
|
+
if (await remediateCoverageFailure(input)) return { retryNode: true };
|
|
381
|
+
if (await remediateUpstreamImplementationFailure(input)) return { retryNode: true };
|
|
382
|
+
return null;
|
|
383
|
+
}
|
|
382
384
|
async function remediateWritableNodeFailure(input) {
|
|
383
385
|
if (input.retry.retryReason !== "gate_failure" || isRemediationNode(input.node) || !nodeCanWrite(input.context, input.node)) return null;
|
|
384
386
|
const beforeSnapshot = await snapshotChangedFiles(input.context.worktreePath);
|
|
@@ -421,23 +423,41 @@ async function executeSelfRemediation(input) {
|
|
|
421
423
|
}
|
|
422
424
|
async function remediateCoverageFailure(input) {
|
|
423
425
|
if (input.retry.retryReason !== "gate_failure" || !hasSchedulingRole(input.context, input.node, "coverage")) return false;
|
|
426
|
+
return await remediatePassedImplementationAncestors(input);
|
|
427
|
+
}
|
|
428
|
+
async function remediateUpstreamImplementationFailure(input) {
|
|
429
|
+
if (isRemediationNode(input.node) || nodeCanWrite(input.context, input.node) || hasSchedulingRole(input.context, input.node, "coverage")) return false;
|
|
430
|
+
return await remediatePassedImplementationAncestors(input);
|
|
431
|
+
}
|
|
432
|
+
async function remediatePassedImplementationAncestors(input) {
|
|
424
433
|
const implementationNodes = upstreamImplementationNodes(input.context, input.node).filter((candidate) => input.context.nodeStates.get(candidate.id)?.status === "passed");
|
|
425
434
|
if (implementationNodes.length === 0) return false;
|
|
426
|
-
for (const implementationNode of implementationNodes)
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
435
|
+
for (const implementationNode of implementationNodes) if (!await remediateImplementationAncestor(input, implementationNode)) return false;
|
|
436
|
+
return true;
|
|
437
|
+
}
|
|
438
|
+
async function remediateImplementationAncestor(input, implementationNode) {
|
|
439
|
+
if (isCancelled(input.context)) return false;
|
|
440
|
+
const beforeSnapshot = await snapshotChangedFiles(input.context.worktreePath);
|
|
441
|
+
const beforeOutput = input.context.lastOutputByNode.get(implementationNode.id);
|
|
442
|
+
const result = await executeImplementationRemediation({
|
|
443
|
+
attempt: input.attempt,
|
|
444
|
+
context: input.context,
|
|
445
|
+
coverageNode: input.node,
|
|
446
|
+
implementationNode,
|
|
447
|
+
retry: input.retry
|
|
448
|
+
});
|
|
449
|
+
if (result.status !== "passed") return false;
|
|
450
|
+
return await recordImplementationRemediationEffect({
|
|
451
|
+
beforeOutput,
|
|
452
|
+
beforeSnapshot,
|
|
453
|
+
context: input.context,
|
|
454
|
+
implementationNode,
|
|
455
|
+
result
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
async function recordImplementationRemediationEffect(input) {
|
|
459
|
+
if (diffChangedFiles(input.beforeSnapshot, await snapshotChangedFiles(input.context.worktreePath), input.context.worktreePath).files.size === 0 && input.result.output === input.beforeOutput) return false;
|
|
460
|
+
input.context.lastOutputByNode.set(input.implementationNode.id, input.result.output);
|
|
441
461
|
return true;
|
|
442
462
|
}
|
|
443
463
|
async function executeImplementationRemediation(input) {
|
package/package.json
CHANGED
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
"prepack": "bun run build:cli"
|
|
121
121
|
},
|
|
122
122
|
"type": "module",
|
|
123
|
-
"version": "1.27.
|
|
123
|
+
"version": "1.27.13",
|
|
124
124
|
"description": "Config-driven multi-agent pipeline runner for repository work",
|
|
125
125
|
"main": "./dist/index.js",
|
|
126
126
|
"types": "./dist/index.d.ts",
|