Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions factory/engine/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { join } from "node:path";
import { loadConfig } from "../config.ts";
import { runWorkflow } from "./interpret.ts";
import { type Metrics, metricsFor, metricsSchema, rollup } from "./metrics.ts";
import { pinPortable } from "./portable.ts";
import { realHost } from "./real-host.ts";
import { loadWorkflow } from "./workflow.ts";

Expand All @@ -12,6 +13,7 @@ const gh = (...a: string[]) => execFileSync("gh", a, { encoding: "utf8" });

// Runs one issue through a named workflow on the current checkout and saves metrics.json.
export async function runIssue(n: number, name: string) {
pinPortable();
const wf = loadWorkflow(readFileSync(`.factory/workflows/${name}.yaml`, "utf8"));
const issue = JSON.parse(gh("issue", "view", String(n), "--json", "title,body"));
const base = execFileSync("git", ["merge-base", "HEAD", "origin/main"], {
Expand Down
18 changes: 17 additions & 1 deletion factory/engine/models.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { mkdtempSync, readFileSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { describe, expect, it } from "vitest";
import { loadConfig } from "../config.ts";
import { badPlanLines } from "./artifacts.ts";
import { fakeHost } from "./fake-host.ts";
import { runWorkflow } from "./interpret.ts";
import { resolveModel } from "./models.ts";
import { globToRegExp, loadPortable } from "./portable.ts";
import { globToRegExp, loadPortable, pinPortable, portable } from "./portable.ts";
import { loadWorkflow } from "./workflow.ts";

const cfg = loadConfig();
Expand Down Expand Up @@ -84,3 +87,16 @@ describe("portable config", () => {
expect(globToRegExp("a/*.ts").test("a/b/c.ts")).toBe(false);
});
});

describe("pinned portable config", () => {
it("keeps the commands it read at the start when the file changes later", () => {
const dir = mkdtempSync(join(tmpdir(), "pin-"));
const file = join(dir, "config.yaml");
const original = readFileSync(".factory/config.yaml", "utf8");
writeFileSync(file, original);
const pinned = pinPortable(file);
writeFileSync(file, original.replace(/gate:.*/, "gate: [true]"));
expect(portable().gate).toEqual(pinned.gate);
pinPortable();
});
});
7 changes: 7 additions & 0 deletions factory/engine/portable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ export const portable = (): Portable => {
return cached;
};

// Called before the first agent runs, so a build that edits the file cannot change the commands
// the gate runs: the working tree is never read for this again.
export const pinPortable = (path?: string): Portable => {
cached = loadPortable(path);
return cached;
};

// ** crosses folders, * stays inside one.
export function globToRegExp(glob: string): RegExp {
const body = glob
Expand Down
Loading