Skip to content

Commit 688a6ef

Browse files
committed
ci: keep gateway watch skip-build artifact fresh
1 parent bae057f commit 688a6ef

2 files changed

Lines changed: 70 additions & 4 deletions

File tree

scripts/check-gateway-watch-regression.mjs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,17 @@ function removePathIfExists(targetPath) {
9595
fs.rmSync(targetPath, { recursive: true, force: true });
9696
}
9797

98+
function lstatIfExists(targetPath) {
99+
try {
100+
return fs.lstatSync(targetPath);
101+
} catch (error) {
102+
if (error?.code === "ENOENT") {
103+
return null;
104+
}
105+
throw error;
106+
}
107+
}
108+
98109
function normalizePath(filePath) {
99110
return filePath.replaceAll("\\", "/");
100111
}
@@ -112,7 +123,15 @@ function listTreeEntries(rootName) {
112123
if (!current) {
113124
continue;
114125
}
115-
const dirents = fs.readdirSync(current, { withFileTypes: true });
126+
let dirents;
127+
try {
128+
dirents = fs.readdirSync(current, { withFileTypes: true });
129+
} catch (error) {
130+
if (error?.code === "ENOENT") {
131+
continue;
132+
}
133+
throw error;
134+
}
116135
for (const dirent of dirents) {
117136
const fullPath = path.join(current, dirent.name);
118137
const relativePath = normalizePath(path.relative(process.cwd(), fullPath));
@@ -159,7 +178,10 @@ function snapshotTree(rootName) {
159178
if (!current) {
160179
continue;
161180
}
162-
const currentStats = fs.lstatSync(current);
181+
const currentStats = lstatIfExists(current);
182+
if (!currentStats) {
183+
continue;
184+
}
163185
stats.entries += 1;
164186
if (currentStats.isDirectory()) {
165187
stats.directories += 1;
@@ -579,6 +601,14 @@ function buildRunNodeDeps(env) {
579601
};
580602
}
581603

604+
export function shouldRefreshBuildStampForRestoredArtifacts(params) {
605+
return (
606+
params.skipBuild === true &&
607+
params.buildRequirement?.shouldBuild === true &&
608+
params.buildRequirement.reason === "config_newer"
609+
);
610+
}
611+
582612
async function main() {
583613
const options = parseArgs(process.argv.slice(2));
584614
ensureDir(options.outputDir);
@@ -594,7 +624,19 @@ async function main() {
594624
writeBuildStamp({ cwd: process.cwd() });
595625
}
596626

597-
const preflightBuildRequirement = resolveBuildRequirement(buildRunNodeDeps(process.env));
627+
let preflightBuildRequirement = resolveBuildRequirement(buildRunNodeDeps(process.env));
628+
if (
629+
shouldRefreshBuildStampForRestoredArtifacts({
630+
skipBuild: options.skipBuild,
631+
buildRequirement: preflightBuildRequirement,
632+
})
633+
) {
634+
// CI's skip-build path restores a built dist artifact after checkout.
635+
// Refresh the stamp so checkout mtimes for package/config files do not
636+
// force a duplicate build during the bounded gateway:watch window.
637+
writeBuildStamp({ cwd: process.cwd() });
638+
preflightBuildRequirement = resolveBuildRequirement(buildRunNodeDeps(process.env));
639+
}
598640
if (
599641
preflightBuildRequirement.shouldBuild &&
600642
preflightBuildRequirement.reason === "dirty_watched_tree"

test/scripts/check-gateway-watch-regression.test.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { describe, expect, it } from "vitest";
2-
import { isIgnoredDistRuntimeWatchPath } from "../../scripts/check-gateway-watch-regression.mjs";
2+
import {
3+
isIgnoredDistRuntimeWatchPath,
4+
shouldRefreshBuildStampForRestoredArtifacts,
5+
} from "../../scripts/check-gateway-watch-regression.mjs";
36

47
describe("check-gateway-watch-regression", () => {
58
it("ignores top-level dist-runtime extension dependency repairs", () => {
@@ -19,4 +22,25 @@ describe("check-gateway-watch-regression", () => {
1922
),
2023
).toBe(false);
2124
});
25+
26+
it("refreshes restored build stamps only for skip-build config mtime drift", () => {
27+
expect(
28+
shouldRefreshBuildStampForRestoredArtifacts({
29+
skipBuild: true,
30+
buildRequirement: { shouldBuild: true, reason: "config_newer" },
31+
}),
32+
).toBe(true);
33+
expect(
34+
shouldRefreshBuildStampForRestoredArtifacts({
35+
skipBuild: false,
36+
buildRequirement: { shouldBuild: true, reason: "config_newer" },
37+
}),
38+
).toBe(false);
39+
expect(
40+
shouldRefreshBuildStampForRestoredArtifacts({
41+
skipBuild: true,
42+
buildRequirement: { shouldBuild: true, reason: "source_mtime_newer" },
43+
}),
44+
).toBe(false);
45+
});
2246
});

0 commit comments

Comments
 (0)