Skip to content

Commit 22bae97

Browse files
committed
workflows: restore review result directories
Incomplete review checkpoints lose empty result directories when GitHub Actions serializes them as artifacts, which breaks resumed Codex reviews. - Recreate the result directory when reusing an existing generation - Ensure each chunk result parent exists before invoking Codex - Cover artifact restoration and runner-side recovery in the script tests Generated with [Codex](https://github.com/openai)
1 parent fdf179a commit 22bae97

3 files changed

Lines changed: 34 additions & 1 deletion

File tree

.github/scripts/pr-review/prepare.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ if (
152152
&& sha256(fs.readFileSync(path.join(generationDir, chunk.relative_path))) === chunk.sha256
153153
))
154154
) {
155+
fs.mkdirSync(resultsDir, { recursive: true, mode: 0o700 });
155156
appendOutput("generation_key", generationKey);
156157
appendOutput("session_key", sessionKey);
157158
appendOutput("from_sha", fromSha);

.github/scripts/pr-review/run.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ try {
134134
"results",
135135
`${String(chunk.index).padStart(4, "0")}.json`,
136136
);
137+
fs.mkdirSync(path.dirname(resultFile), { recursive: true, mode: 0o700 });
137138
const prompt = [
138139
`Review diff chunk ${chunk.index} of ${generation.chunks.length}.`,
139140
"",

.github/scripts/pr-review/test.mjs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,32 @@ try {
150150
)));
151151
}
152152
const firstGeneration = ledger.generations[0];
153+
const firstGenerationResults = path.join(
154+
state,
155+
"generations",
156+
firstGeneration.key,
157+
"results",
158+
);
159+
assert.ok(fs.existsSync(firstGenerationResults));
160+
fs.rmSync(firstGenerationResults, { recursive: true });
161+
const restored = spawnSync(process.execPath, [
162+
path.join(path.dirname(new URL(import.meta.url).pathname), "prepare.mjs"),
163+
], {
164+
cwd: repo,
165+
encoding: "utf8",
166+
env: {
167+
...process.env,
168+
REPOSITORY_DIR: repo,
169+
PR_REVIEW_STATE_DIR: state,
170+
PR_BASE_SHA: base,
171+
PR_HEAD_SHA: head,
172+
SESSION_KEY: "repo:1:pr:2:v2",
173+
MAX_DIFF_BYTES: "1000000",
174+
CHUNK_TARGET_BYTES: "600",
175+
},
176+
});
177+
assert.equal(restored.status, 0, restored.stderr);
178+
assert.ok(fs.existsSync(firstGenerationResults));
153179
firstGeneration.status = "completed";
154180
firstGeneration.completed_at = new Date().toISOString();
155181
fs.writeFileSync(
@@ -235,13 +261,18 @@ fs.appendFileSync(sessionFile, JSON.stringify({
235261
}}
236262
}
237263
}) + "\\n");
238-
fs.mkdirSync(path.dirname(outputFile), { recursive: true });
239264
fs.writeFileSync(outputFile, JSON.stringify({
240265
summary: "Fake review complete.",
241266
findings: []
242267
}));
243268
`, { mode: 0o755 });
244269
const latestGeneration = updatedLedger.generations.at(-1);
270+
fs.rmSync(path.join(
271+
state,
272+
"generations",
273+
latestGeneration.key,
274+
"results",
275+
), { recursive: true });
245276
const runResult = spawnSync(process.execPath, [
246277
path.join(path.dirname(new URL(import.meta.url).pathname), "run.mjs"),
247278
], {

0 commit comments

Comments
 (0)