ci: keep gateway watch skip-build artifact fresh

This commit is contained in:
Peter Steinberger
2026-04-23 03:11:42 +01:00
parent bae057fd77
commit 688a6ef4fd
2 changed files with 70 additions and 4 deletions

View File

@@ -95,6 +95,17 @@ function removePathIfExists(targetPath) {
fs.rmSync(targetPath, { recursive: true, force: true });
}
function lstatIfExists(targetPath) {
try {
return fs.lstatSync(targetPath);
} catch (error) {
if (error?.code === "ENOENT") {
return null;
}
throw error;
}
}
function normalizePath(filePath) {
return filePath.replaceAll("\\", "/");
}
@@ -112,7 +123,15 @@ function listTreeEntries(rootName) {
if (!current) {
continue;
}
const dirents = fs.readdirSync(current, { withFileTypes: true });
let dirents;
try {
dirents = fs.readdirSync(current, { withFileTypes: true });
} catch (error) {
if (error?.code === "ENOENT") {
continue;
}
throw error;
}
for (const dirent of dirents) {
const fullPath = path.join(current, dirent.name);
const relativePath = normalizePath(path.relative(process.cwd(), fullPath));
@@ -159,7 +178,10 @@ function snapshotTree(rootName) {
if (!current) {
continue;
}
const currentStats = fs.lstatSync(current);
const currentStats = lstatIfExists(current);
if (!currentStats) {
continue;
}
stats.entries += 1;
if (currentStats.isDirectory()) {
stats.directories += 1;
@@ -579,6 +601,14 @@ function buildRunNodeDeps(env) {
};
}
export function shouldRefreshBuildStampForRestoredArtifacts(params) {
return (
params.skipBuild === true &&
params.buildRequirement?.shouldBuild === true &&
params.buildRequirement.reason === "config_newer"
);
}
async function main() {
const options = parseArgs(process.argv.slice(2));
ensureDir(options.outputDir);
@@ -594,7 +624,19 @@ async function main() {
writeBuildStamp({ cwd: process.cwd() });
}
const preflightBuildRequirement = resolveBuildRequirement(buildRunNodeDeps(process.env));
let preflightBuildRequirement = resolveBuildRequirement(buildRunNodeDeps(process.env));
if (
shouldRefreshBuildStampForRestoredArtifacts({
skipBuild: options.skipBuild,
buildRequirement: preflightBuildRequirement,
})
) {
// CI's skip-build path restores a built dist artifact after checkout.
// Refresh the stamp so checkout mtimes for package/config files do not
// force a duplicate build during the bounded gateway:watch window.
writeBuildStamp({ cwd: process.cwd() });
preflightBuildRequirement = resolveBuildRequirement(buildRunNodeDeps(process.env));
}
if (
preflightBuildRequirement.shouldBuild &&
preflightBuildRequirement.reason === "dirty_watched_tree"

View File

@@ -1,5 +1,8 @@
import { describe, expect, it } from "vitest";
import { isIgnoredDistRuntimeWatchPath } from "../../scripts/check-gateway-watch-regression.mjs";
import {
isIgnoredDistRuntimeWatchPath,
shouldRefreshBuildStampForRestoredArtifacts,
} from "../../scripts/check-gateway-watch-regression.mjs";
describe("check-gateway-watch-regression", () => {
it("ignores top-level dist-runtime extension dependency repairs", () => {
@@ -19,4 +22,25 @@ describe("check-gateway-watch-regression", () => {
),
).toBe(false);
});
it("refreshes restored build stamps only for skip-build config mtime drift", () => {
expect(
shouldRefreshBuildStampForRestoredArtifacts({
skipBuild: true,
buildRequirement: { shouldBuild: true, reason: "config_newer" },
}),
).toBe(true);
expect(
shouldRefreshBuildStampForRestoredArtifacts({
skipBuild: false,
buildRequirement: { shouldBuild: true, reason: "config_newer" },
}),
).toBe(false);
expect(
shouldRefreshBuildStampForRestoredArtifacts({
skipBuild: true,
buildRequirement: { shouldBuild: true, reason: "source_mtime_newer" },
}),
).toBe(false);
});
});