@plainconceptsplatform/workflows 0.4.3 → 0.4.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.
|
@@ -43,6 +43,7 @@ export async function installCatalog(repositoryPath, options = {}) {
|
|
|
43
43
|
processedContents = injectStackIntoWorkers(processedContents, defaults);
|
|
44
44
|
processedContents = transformOpencodeFiles(processedContents, options.inspection);
|
|
45
45
|
}
|
|
46
|
+
processedContents = await preserveConsumerWorkerEnv(repositoryPath, processedContents);
|
|
46
47
|
const updates = [...processedContents.entries()]
|
|
47
48
|
.filter(([target]) => filtered.find((file) => file.target === target)?.managed ?? true)
|
|
48
49
|
.map(([target, content]) => ({ target, content }));
|
|
@@ -62,6 +63,37 @@ function injectStackIntoWorkers(files, defaults) {
|
|
|
62
63
|
}
|
|
63
64
|
return result;
|
|
64
65
|
}
|
|
66
|
+
async function preserveConsumerWorkerEnv(repositoryPath, files) {
|
|
67
|
+
const result = new Map(files);
|
|
68
|
+
for (const [target, content] of result) {
|
|
69
|
+
if (!target.startsWith(".github/workflows/agent-") || !target.endsWith(".md"))
|
|
70
|
+
continue;
|
|
71
|
+
const existingPath = join(repositoryPath, target);
|
|
72
|
+
if (!await exists(existingPath))
|
|
73
|
+
continue;
|
|
74
|
+
result.set(target, mergeWorkerEnv(content, await readFile(existingPath, "utf8")));
|
|
75
|
+
}
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
function mergeWorkerEnv(packageContent, consumerContent) {
|
|
79
|
+
const consumerEnv = workerEnvValues(consumerContent);
|
|
80
|
+
if (consumerEnv.size === 0)
|
|
81
|
+
return packageContent;
|
|
82
|
+
return packageContent.replace(/^ ([A-Z][A-Z0-9_]*): .+$/gm, (line, key) => consumerEnv.has(key) ? ` ${key}: ${consumerEnv.get(key)}` : line);
|
|
83
|
+
}
|
|
84
|
+
function workerEnvValues(content) {
|
|
85
|
+
const frontmatter = /^---\r?\n([\s\S]*?)\r?\n---/m.exec(content)?.[1];
|
|
86
|
+
const envBlock = frontmatter === undefined ? undefined : /^env:\r?\n((?: .*\r?\n?)*)/m.exec(frontmatter)?.[1];
|
|
87
|
+
const values = new Map();
|
|
88
|
+
if (envBlock === undefined)
|
|
89
|
+
return values;
|
|
90
|
+
for (const line of envBlock.split(/\r?\n/)) {
|
|
91
|
+
const match = /^ ([A-Z][A-Z0-9_]*): (.+)$/.exec(line);
|
|
92
|
+
if (match !== null)
|
|
93
|
+
values.set(match[1], match[2]);
|
|
94
|
+
}
|
|
95
|
+
return values;
|
|
96
|
+
}
|
|
65
97
|
function transformOpencodeFiles(files, inspection) {
|
|
66
98
|
const result = new Map(files);
|
|
67
99
|
for (const [key, content] of result) {
|
|
@@ -154,6 +186,7 @@ async function validateStagedCatalog(repositoryPath, updates, compileOverride) {
|
|
|
154
186
|
try {
|
|
155
187
|
await copyCompilationInputs(repositoryPath, stagingPath);
|
|
156
188
|
await writeUpdates(stagingPath, updates);
|
|
189
|
+
await initializeStagingRepository(stagingPath);
|
|
157
190
|
const compiler = compileOverride ?? await packageCompiler(stagingPath);
|
|
158
191
|
if (compiler === undefined)
|
|
159
192
|
return [];
|
|
@@ -169,6 +202,9 @@ async function copyCompilationInputs(repositoryPath, stagingPath) {
|
|
|
169
202
|
if (await exists(githubPath))
|
|
170
203
|
await cp(githubPath, join(stagingPath, ".github"), { recursive: true });
|
|
171
204
|
}
|
|
205
|
+
async function initializeStagingRepository(stagingPath) {
|
|
206
|
+
await execFileAsync("git", ["init", "--quiet"], { cwd: stagingPath, windowsHide: true });
|
|
207
|
+
}
|
|
172
208
|
async function packageCompiler(repositoryPath) {
|
|
173
209
|
const scriptPath = join(repositoryPath, "scripts", "compile-agent-workflows.mjs");
|
|
174
210
|
if (!await exists(scriptPath))
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
1
|
+
import { access, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import { constants } from "node:fs";
|
|
2
3
|
import { tmpdir } from "node:os";
|
|
3
4
|
import { dirname, join } from "node:path";
|
|
4
5
|
import { afterEach, describe, expect, it } from "vitest";
|
|
@@ -285,6 +286,19 @@ describe("catalog installation", () => {
|
|
|
285
286
|
.resolves.toBe("consumer compiler\n");
|
|
286
287
|
await expect(readFile(join(repositoryPath, ".husky", "pre-commit"), "utf8")).rejects.toThrow();
|
|
287
288
|
});
|
|
289
|
+
it("preserves consumer-specific worker environment values during a forced update", async () => {
|
|
290
|
+
const sourcePath = await createDirectory({
|
|
291
|
+
"actions/check/action.yml": "name: Check\n",
|
|
292
|
+
"workflows/agent-check.md": "---\nenv:\n VERIFY_COMMANDS: \"package verify\"\n REPO_RULES: \"package rules\"\n OPENAI_BASE_URL: https://forge.plainconcepts.com/v1\n---\n",
|
|
293
|
+
"scripts/compile-agent-workflows.mjs": "compile\n",
|
|
294
|
+
"templates/opencode/opencode.ci.json": "{}\n",
|
|
295
|
+
});
|
|
296
|
+
const repositoryPath = await createDirectory({
|
|
297
|
+
".github/workflows/agent-check.md": "---\nenv:\n VERIFY_COMMANDS: \"consumer verify\"\n REPO_RULES: \"consumer rules\"\n OPENAI_BASE_URL: https://consumer.example/v1\n---\n",
|
|
298
|
+
});
|
|
299
|
+
await installCatalog(repositoryPath, { force: true, sourcePath });
|
|
300
|
+
await expect(readFile(join(repositoryPath, ".github/workflows/agent-check.md"), "utf8")).resolves.toContain(" REPO_RULES: \"consumer rules\"\n OPENAI_BASE_URL: https://consumer.example/v1\n");
|
|
301
|
+
});
|
|
288
302
|
it("applies staged generated locks with managed sources", async () => {
|
|
289
303
|
const sourcePath = await createDirectory({
|
|
290
304
|
"actions/check/action.yml": "package action\n",
|
|
@@ -296,6 +310,7 @@ describe("catalog installation", () => {
|
|
|
296
310
|
await installCatalog(repositoryPath, {
|
|
297
311
|
sourcePath,
|
|
298
312
|
compile: async (stagingPath) => {
|
|
313
|
+
await expect(access(join(stagingPath, ".git"), constants.F_OK)).resolves.toBeUndefined();
|
|
299
314
|
await writeFile(join(stagingPath, ".github", "workflows", "agent-check.lock.yml"), "opencode run --log-level ERROR\n", "utf8");
|
|
300
315
|
},
|
|
301
316
|
});
|