Skip to content

Commit a522872

Browse files
committed
fix(release): recover deleted server-changes when enhancing release PR
Read .server-changes from git when the working tree copy has already been cleaned up, and log recovery failures instead of swallowing them. Folds in the fix from #4209. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014CjQVhMqLbRo3VuLaGSLfg
1 parent 90226e1 commit a522872

1 file changed

Lines changed: 80 additions & 21 deletions

File tree

scripts/enhance-release-pr.mjs

Lines changed: 80 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -183,28 +183,8 @@ async function getPrForCommit(commitSha) {
183183
// --- Parse .server-changes/ files ---
184184

185185
async function parseServerChanges() {
186-
const dir = join(ROOT_DIR, ".server-changes");
187186
const entries = [];
188-
189-
let files;
190-
try {
191-
files = await fs.readdir(dir);
192-
} catch {
193-
return entries;
194-
}
195-
196-
// Collect file info and look up commits in parallel
197-
const fileData = [];
198-
for (const file of files) {
199-
if (!file.endsWith(".md") || file === "README.md") continue;
200-
201-
const filePath = join(".server-changes", file);
202-
const content = await fs.readFile(join(dir, file), "utf-8");
203-
const parsed = parseFrontmatter(content);
204-
if (!parsed.body.trim()) continue;
205-
206-
fileData.push({ filePath, parsed });
207-
}
187+
const fileData = await getServerChangeFileData();
208188

209189
// Look up commits for all files in parallel
210190
const commits = await Promise.all(fileData.map((f) => getCommitForFile(f.filePath)));
@@ -232,6 +212,85 @@ async function parseServerChanges() {
232212
return entries;
233213
}
234214

215+
async function getServerChangeFileData() {
216+
const liveFileData = await getLiveServerChangeFileData();
217+
if (liveFileData.length > 0) return liveFileData;
218+
219+
// The changesets version command deletes .server-changes before this script
220+
// enhances the release PR body. Recover those consumed files from the release
221+
// branch diff so they still make it into the release notes handoff.
222+
return getDeletedServerChangeFileDataFromReleaseBranch();
223+
}
224+
225+
async function getLiveServerChangeFileData() {
226+
const dir = join(ROOT_DIR, ".server-changes");
227+
228+
let files;
229+
try {
230+
files = await fs.readdir(dir);
231+
} catch {
232+
return [];
233+
}
234+
235+
const fileData = [];
236+
for (const file of files.sort()) {
237+
if (!file.endsWith(".md") || file === "README.md") continue;
238+
239+
const filePath = join(".server-changes", file);
240+
const content = await fs.readFile(join(dir, file), "utf-8");
241+
const parsed = parseFrontmatter(content);
242+
if (!parsed.body.trim()) continue;
243+
244+
fileData.push({ filePath, parsed });
245+
}
246+
247+
return fileData;
248+
}
249+
250+
async function getDeletedServerChangeFileDataFromReleaseBranch() {
251+
const baseRef = process.env.SERVER_CHANGES_BASE_REF || "origin/main";
252+
const releaseRef = process.env.SERVER_CHANGES_RELEASE_REF || "origin/changeset-release/main";
253+
254+
let mergeBase;
255+
let deletedFiles;
256+
try {
257+
mergeBase = await gitExec(["merge-base", baseRef, releaseRef]);
258+
deletedFiles = await gitExec([
259+
"diff",
260+
"--name-only",
261+
"--diff-filter=D",
262+
`${mergeBase}..${releaseRef}`,
263+
"--",
264+
".server-changes",
265+
]);
266+
} catch (err) {
267+
console.error(
268+
"[enhance-release-pr] failed to recover deleted server-changes from release branch:",
269+
err
270+
);
271+
return [];
272+
}
273+
274+
const fileData = [];
275+
for (const filePath of deletedFiles.split("\n").filter(Boolean).sort()) {
276+
const file = filePath.split("/").pop();
277+
if (!file?.endsWith(".md") || file === "README.md") continue;
278+
279+
try {
280+
const content = await gitExec(["show", `${mergeBase}:${filePath}`]);
281+
const parsed = parseFrontmatter(content);
282+
if (!parsed.body.trim()) continue;
283+
fileData.push({ filePath, parsed });
284+
} catch (err) {
285+
// If an individual file cannot be recovered, skip it rather than hiding
286+
// all other server changes.
287+
console.error(`[enhance-release-pr] failed to read deleted server-change ${filePath}:`, err);
288+
}
289+
}
290+
291+
return fileData;
292+
}
293+
235294
function parseFrontmatter(content) {
236295
const match = content.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
237296
if (!match) return { frontmatter: {}, body: content };

0 commit comments

Comments
 (0)