@opensoftware/foreman 0.0.0-stage → 0.2.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.
@@ -0,0 +1,191 @@
1
+ // A run of the factory's workflow for one work item, without I/O (ADR 0067): its ID, its first view, the next step,
2
+ // how each fact changes the view, and the events it publishes. The workflow asks for each step and applies each fact
3
+ // through local activities, so this code runs in the worker's own thread, not in Temporal's sandbox.
4
+ import { createHash } from "node:crypto";
5
+ const ENDED = new Set(["complete", "failed", "cancelled"]);
6
+ /** "run_" and 20 hex digits of the SHA-256 of the work item's ID: one run per work item. */
7
+ export const runIdOf = (workItemId) => `run_${createHash("sha256").update(workItemId).digest("hex").slice(0, 20)}`;
8
+ export function firstView(workItem, definition, version, startedAt) {
9
+ return {
10
+ runId: runIdOf(workItem.id),
11
+ workItem,
12
+ factory: definition.factory,
13
+ factoryVersion: version,
14
+ state: "running",
15
+ startedAt,
16
+ stages: definition.stages.map(({ stage, agent }) => ({ stage, agent, state: "pending" })),
17
+ };
18
+ }
19
+ export const hasEnded = (view) => ENDED.has(view.state);
20
+ /** The next step; a stage whose checks are pending reads them again after `checkPollMs`. */
21
+ export function nextStep(view, definition, checkPollMs) {
22
+ if (hasEnded(view))
23
+ return { kind: "end" };
24
+ // A run whose last stage succeeded is complete, so a run that goes on has a stage that did not succeed.
25
+ const index = view.stages.findIndex((stage) => stage.state !== "succeeded");
26
+ const stage = view.stages[index];
27
+ const plan = definition.stages[index];
28
+ if (stage.state === "blocked" && stage.gateId)
29
+ return { kind: "await-gate", index, gateId: stage.gateId };
30
+ // Checks come before the gate: nobody is asked to approve a change whose checks fail.
31
+ if (plan?.checks?.length && !stage.checks?.every((check) => check.state === "success"))
32
+ return { kind: "read-checks", index, delayMs: stage.checks ? checkPollMs : 0 };
33
+ if (plan?.gate && !stage.gateId)
34
+ return { kind: "request-gate", index };
35
+ return { kind: "run-stage", index };
36
+ }
37
+ /** The view after the fact, at the time `at`. */
38
+ export function apply(view, fact, at) {
39
+ const next = { ...view, stages: view.stages.map((stage) => ({ ...stage })) };
40
+ const end = (state) => ({ ...next, state, endedAt: at });
41
+ switch (fact.kind) {
42
+ case "gate":
43
+ return gate(next, fact, end);
44
+ case "checks":
45
+ return checks(next, fact, end);
46
+ case "stage-started": {
47
+ Object.assign(next.stages[fact.index], { state: "running", startedAt: at });
48
+ return next;
49
+ }
50
+ case "stage-ended": {
51
+ const state = stageStateOf(fact.stopReason);
52
+ const stage = next.stages[fact.index];
53
+ Object.assign(stage, { state, endedAt: at }, fact.sessionId ? { sessionId: fact.sessionId } : {});
54
+ if (fact.pullRequest)
55
+ next.pullRequest = fact.pullRequest;
56
+ if (state !== "succeeded")
57
+ return end(state === "cancelled" ? "cancelled" : "failed");
58
+ return fact.index === next.stages.length - 1 ? end("complete") : next;
59
+ }
60
+ case "cancelled":
61
+ case "error": {
62
+ const stopped = fact.kind === "cancelled" ? "cancelled" : "failed";
63
+ for (const stage of next.stages)
64
+ if (stage.state === "running" || stage.state === "blocked")
65
+ Object.assign(stage, { state: stopped, endedAt: at });
66
+ return hasEnded(view) ? view : end(fact.kind === "cancelled" ? "cancelled" : "failed");
67
+ }
68
+ }
69
+ }
70
+ function gate(next, fact, end) {
71
+ const stage = next.stages[fact.index];
72
+ stage.gateId = fact.gateId;
73
+ if (fact.state === "pending") {
74
+ stage.state = "blocked";
75
+ return { ...next, state: "blocked" };
76
+ }
77
+ if (fact.state === "approved") {
78
+ stage.state = "pending";
79
+ return { ...next, state: "running" };
80
+ }
81
+ stage.state = "rejected";
82
+ return end("failed");
83
+ }
84
+ function checks(next, fact, end) {
85
+ const stage = next.stages[fact.index];
86
+ if (fact.checks.length)
87
+ stage.checks = fact.checks;
88
+ const failed = fact.checks.find((check) => check.state === "failure" || check.state === "error");
89
+ const reason = fact.reason ?? (failed && `the check ${failed.name} ended with ${failed.state}`);
90
+ if (reason) {
91
+ Object.assign(stage, { state: "failed", reason });
92
+ return end("failed");
93
+ }
94
+ if (fact.checks.every((check) => check.state === "success")) {
95
+ stage.state = "pending";
96
+ return { ...next, state: "running" };
97
+ }
98
+ stage.state = "blocked";
99
+ return { ...next, state: "blocked" };
100
+ }
101
+ /** The states of the named checks in what the forge port's `pr` printed; a check it does not list is pending. */
102
+ export function checksOf(names, printed) {
103
+ return names.map((name) => {
104
+ const state = printed.find((check) => check.name === name)?.state;
105
+ return { name, state: state === "success" || state === "failure" || state === "error" ? state : "pending" };
106
+ });
107
+ }
108
+ // A pull request's page on GitHub (/pull/<n>) or Forgejo (/pulls/<n>), as runlog finds it.
109
+ const PULL_REQUEST = /https?:\/\/[^\s"'<>()]+\/([^/\s"'<>()]+)\/([^/\s"'<>()]+)\/pulls?\/(\d+)/g;
110
+ /** The last pull request link in the text. */
111
+ export const lastPullRequestIn = (text) => [...text.matchAll(PULL_REQUEST)].pop()?.[0];
112
+ /** The repository `<owner>/<name>` and number of a pull request link. */
113
+ export function pullRequestOf(url) {
114
+ const [, owner, name, number] = [...url.matchAll(PULL_REQUEST)][0];
115
+ return { repo: `${owner}/${name}`, number: number };
116
+ }
117
+ /** How a turn's stop reason ends its stage (harness port): only `end_turn` succeeds. */
118
+ export function stageStateOf(stopReason) {
119
+ if (stopReason === "end_turn")
120
+ return "succeeded";
121
+ if (stopReason === "cancelled")
122
+ return "cancelled";
123
+ return "failed";
124
+ }
125
+ /** The prompt of a stage: the agent's prompt, then the work item and the run's pull request. */
126
+ export function promptOf(agentPrompt, workItem, pullRequest) {
127
+ const description = workItem.description ? `\n\n${workItem.description}` : "";
128
+ const link = pullRequest ? `\n\nPull request: ${pullRequest}` : "";
129
+ return `${agentPrompt.trimEnd()}\n\n# Work item ${workItem.id}\n\n${workItem.title}${description}${link}\n`;
130
+ }
131
+ /** The signal in a request's body, or the problem with it as "<JSON Pointer>: <what is wrong>". */
132
+ export function signalOf(body) {
133
+ const { type, message } = (typeof body === "object" && body !== null ? body : {});
134
+ if (type === "cancel")
135
+ return { type };
136
+ if (type !== "steer")
137
+ return `/type: must be "steer" or "cancel"`;
138
+ if (typeof message !== "string" || message === "")
139
+ return "/message: a steering message needs the text";
140
+ return { type, message };
141
+ }
142
+ /** The summary gatekeeper shows the approvers. */
143
+ export const gateSummaryOf = (view, index) => `${view.workItem.title}: start the stage ${view.stages[index]?.stage}`;
144
+ const SOURCE = "/osf/foreman";
145
+ export function runStarted(view) {
146
+ return {
147
+ specversion: "1.0",
148
+ id: `${view.runId}.started`,
149
+ source: SOURCE,
150
+ type: "run.started@v1",
151
+ time: view.startedAt,
152
+ subject: view.runId,
153
+ datacontenttype: "application/json",
154
+ data: {
155
+ runId: view.runId,
156
+ workItemId: view.workItem.id,
157
+ factory: view.factory,
158
+ factoryVersion: view.factoryVersion,
159
+ stages: view.stages.map((stage) => stage.stage),
160
+ startedAt: view.startedAt,
161
+ requester: view.workItem.requester,
162
+ source: view.workItem.origin.source,
163
+ },
164
+ };
165
+ }
166
+ export function runCompleted(view) {
167
+ const endedAt = view.endedAt ?? view.startedAt;
168
+ const last = [...view.stages].reverse().find((stage) => stage.state !== "pending");
169
+ return {
170
+ specversion: "1.0",
171
+ id: `${view.runId}.completed`,
172
+ source: SOURCE,
173
+ type: "run.completed@v1",
174
+ time: endedAt,
175
+ subject: view.runId,
176
+ datacontenttype: "application/json",
177
+ data: {
178
+ runId: view.runId,
179
+ workItemId: view.workItem.id,
180
+ ...(last ? { stage: last.stage } : {}),
181
+ factoryVersion: view.factoryVersion,
182
+ outcome: view.state === "complete" ? "succeeded" : view.state === "cancelled" ? "cancelled" : "failed",
183
+ startedAt: view.startedAt,
184
+ endedAt,
185
+ requester: view.workItem.requester,
186
+ source: view.workItem.origin.source,
187
+ ...(view.pullRequest ? { pullRequests: [view.pullRequest] } : {}),
188
+ },
189
+ };
190
+ }
191
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/domain/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ // The time of the module: OSF_NOW, like 2026-01-01T00:00:00Z, when the testkit or a person fixes it, else the clock.
2
+ export const isoNow = (fixed) => new Date(fixed ? Date.parse(fixed) : Date.now()).toISOString();
3
+ //# sourceMappingURL=time.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time.js","sourceRoot":"","sources":["../../src/domain/time.ts"],"names":[],"mappings":"AAAA,qHAAqH;AAErH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,KAAyB,EAAU,EAAE,CAC1D,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC"}
@@ -0,0 +1,123 @@
1
+ // The activities of a run (ADR 0067). `next` and `apply` are local activities around the domain, so a run's logic runs
2
+ // in the worker's thread; the others reach outside: the sandbox, the harness, the forge, gatekeeper and NATS.
3
+ import { mkdirSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ import { Context } from "@temporalio/activity";
6
+ import { pullRequestChecks } from "../adapters/forge.js";
7
+ import { startTurn } from "../adapters/harness.js";
8
+ import { SUBJECTS } from "../adapters/nats.js";
9
+ import { createSandbox } from "../adapters/sandbox.js";
10
+ import { apply, checksOf, gateSummaryOf, lastPullRequestIn, nextStep, promptOf, pullRequestOf, runCompleted, runStarted, } from "../domain/run.js";
11
+ /** The command line of an adapter by its name, as program and arguments. */
12
+ const commandLine = (lines, name, otherwise) => (lines[name] ?? otherwise).split(" ");
13
+ export function activities(deps) {
14
+ /** The turn's stop reason; meanwhile it sends the run's new steering messages and reports that the stage lives. */
15
+ async function untilDone(turn, runId, steered) {
16
+ const context = Context.current();
17
+ context.cancellationSignal.addEventListener("abort", () => turn.cancel());
18
+ let sent = steered;
19
+ const watch = setInterval(() => {
20
+ context.heartbeat();
21
+ deps.steering(runId).then((messages) => {
22
+ for (const message of messages.slice(sent))
23
+ turn.steer(message);
24
+ sent = Math.max(sent, messages.length);
25
+ }, () => undefined);
26
+ }, deps.pollMs);
27
+ try {
28
+ return await turn.done;
29
+ }
30
+ finally {
31
+ clearInterval(watch);
32
+ await turn.close();
33
+ }
34
+ }
35
+ return {
36
+ async next(view, definition) {
37
+ return nextStep(view, definition, deps.checkPollMs);
38
+ },
39
+ async apply(view, fact) {
40
+ return apply(view, fact, deps.now());
41
+ },
42
+ async publishStarted(view) {
43
+ await deps.bus?.publish(SUBJECTS.runStarted, runStarted(view));
44
+ },
45
+ async publishCompleted(view) {
46
+ await deps.bus?.publish(SUBJECTS.runCompleted, runCompleted(view));
47
+ },
48
+ async requestGate(view, definition, index) {
49
+ const plan = definition.stages[index];
50
+ const origin = view.workItem.origin.url;
51
+ const gate = await deps.gatekeeper.request({
52
+ workItem: view.workItem.id,
53
+ stage: plan?.stage ?? "",
54
+ summary: gateSummaryOf(view, index),
55
+ ...(origin ? { links: [{ url: origin, title: "Origin" }] } : {}),
56
+ change: { factory: definition.factory, policy: plan?.gate?.policy, approvers: plan?.gate?.approvers ?? [] },
57
+ });
58
+ return { kind: "gate", index, gateId: gate.id, state: gate.state };
59
+ },
60
+ /** The stage's checks on the run's pull request, through the forge adapter that the factory names. */
61
+ async readChecks(view, definition, index) {
62
+ const names = definition.stages[index]?.checks ?? [];
63
+ if (!view.pullRequest)
64
+ return { kind: "checks", index, checks: [], reason: "no earlier stage linked a pull request" };
65
+ const { repo, number } = pullRequestOf(view.pullRequest);
66
+ const adapter = definition.forgeAdapter;
67
+ const printed = await pullRequestChecks(commandLine(deps.forges, adapter, `npx -y @opensoftware/forge-${adapter}`), { ...deps.env, ...deps.forgeEnv }, repo, number);
68
+ return { kind: "checks", index, checks: checksOf(names, printed) };
69
+ },
70
+ /** Runs the stage's agent, in a sandbox when it declares one; steering messages from the `steered`-th on are for it. */
71
+ async runStage(view, definition, index, steered) {
72
+ const plan = definition.stages[index];
73
+ if (!plan)
74
+ throw new Error(`no stage ${index}`);
75
+ const cwd = join(deps.data, "runs", view.runId);
76
+ mkdirSync(cwd, { recursive: true });
77
+ const attributes = {
78
+ "osf.run.id": view.runId,
79
+ "osf.work_item.id": view.workItem.id,
80
+ "osf.stage": plan.stage,
81
+ "osf.factory.version": view.factoryVersion,
82
+ };
83
+ const resource = Object.entries(attributes)
84
+ .map(([key, value]) => `${key}=${value}`)
85
+ .join(",");
86
+ const harness = commandLine(deps.harnesses, plan.harness, `npx -y @opensoftware/harness-${plan.harness} run`);
87
+ const adapter = definition.sandboxAdapter;
88
+ const sandbox = plan.sandbox
89
+ ? await createSandbox(commandLine(deps.sandboxes, adapter, `npx -y @opensoftware/sandbox-${adapter}`), { ...plan.sandbox, env: { OTEL_RESOURCE_ATTRIBUTES: resource } }, cwd, view.runId, deps.env)
90
+ : undefined;
91
+ try {
92
+ const prompt = promptOf(plan.prompt, view.workItem, view.pullRequest);
93
+ const turn = await startTurn(sandbox
94
+ ? { command: sandbox.exec(harness), cwd, folder: await sandbox.copyIn(), env: deps.env, prompt }
95
+ : {
96
+ command: harness,
97
+ cwd,
98
+ folder: cwd,
99
+ env: {
100
+ ...deps.env,
101
+ OSF_DATA: join(deps.data, "harness", plan.harness),
102
+ OTEL_RESOURCE_ATTRIBUTES: resource,
103
+ },
104
+ prompt,
105
+ });
106
+ const stopReason = await untilDone(turn, view.runId, steered);
107
+ await sandbox?.copyOut();
108
+ const pullRequest = lastPullRequestIn(turn.transcript());
109
+ return {
110
+ kind: "stage-ended",
111
+ index,
112
+ stopReason,
113
+ sessionId: turn.sessionId,
114
+ ...(pullRequest ? { pullRequest } : {}),
115
+ };
116
+ }
117
+ finally {
118
+ await sandbox?.destroy();
119
+ }
120
+ },
121
+ };
122
+ }
123
+ //# sourceMappingURL=activities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activities.js","sourceRoot":"","sources":["../../src/workflows/activities.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ // The Temporal workflow of a run (ADR 0004, ADR 0067). It runs in Temporal's sandbox, so it only asks the local
2
+ // activity `next` for each step, waits, and hands each fact to `apply`; the logic is in the domain.
3
+ // Stryker disable all: this file runs in Temporal's workflow sandbox, a V8 context of its own that Stryker's mutant
4
+ // switch and coverage never reach; every mutant here would count as not run (ADR 0067).
5
+ import { ActivityCancellationType, CancellationScope, condition, defineQuery, defineSignal, isCancellation, proxyActivities, proxyLocalActivities, setHandler, sleep, } from "@temporalio/workflow";
6
+ export const viewQuery = defineQuery("view");
7
+ export const steeringQuery = defineQuery("steering");
8
+ export const steerSignal = defineSignal("steer");
9
+ export const gateSignal = defineSignal("gate");
10
+ const local = proxyLocalActivities({ startToCloseTimeout: "1 minute" });
11
+ const remote = proxyActivities({
12
+ startToCloseTimeout: "1 day",
13
+ heartbeatTimeout: "1 minute",
14
+ retry: { maximumAttempts: 3 },
15
+ cancellationType: ActivityCancellationType.WAIT_CANCELLATION_COMPLETED,
16
+ });
17
+ export async function factoryRun({ view, definition }) {
18
+ let run = view;
19
+ const steering = [];
20
+ const decisions = [];
21
+ setHandler(viewQuery, () => run);
22
+ setHandler(steeringQuery, () => steering);
23
+ setHandler(steerSignal, (message) => void steering.push(message));
24
+ setHandler(gateSignal, (decision) => void decisions.push(decision));
25
+ const settle = async (fact) => {
26
+ run = await CancellationScope.nonCancellable(() => local.apply(run, fact));
27
+ };
28
+ try {
29
+ await remote.publishStarted(run);
30
+ for (let step = await local.next(run, definition); step.kind !== "end"; step = await local.next(run, definition)) {
31
+ const { index } = step;
32
+ if (step.kind === "read-checks") {
33
+ if (step.delayMs)
34
+ await sleep(step.delayMs);
35
+ run = await local.apply(run, await remote.readChecks(run, definition, index));
36
+ }
37
+ else if (step.kind === "request-gate") {
38
+ run = await local.apply(run, await remote.requestGate(run, definition, index));
39
+ }
40
+ else if (step.kind === "await-gate") {
41
+ const { gateId } = step;
42
+ await condition(() => decisions.some((decision) => decision.gateId === gateId));
43
+ const decision = decisions.find((candidate) => candidate.gateId === gateId);
44
+ run = await local.apply(run, { kind: "gate", index, ...decision });
45
+ }
46
+ else {
47
+ run = await local.apply(run, { kind: "stage-started", index });
48
+ await settle(await remote.runStage(run, definition, index, steering.length));
49
+ }
50
+ }
51
+ }
52
+ catch (error) {
53
+ await settle(isCancellation(error) ? { kind: "cancelled" } : { kind: "error", message: String(error) });
54
+ }
55
+ await CancellationScope.nonCancellable(() => remote.publishCompleted(run));
56
+ return run;
57
+ }
58
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/workflows/run.ts"],"names":[],"mappings":"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"}