diff --git a/scripts/hwlab-g14-contract-test.ts b/scripts/hwlab-g14-contract-test.ts index abda262d..1cf4baf5 100644 --- a/scripts/hwlab-g14-contract-test.ts +++ b/scripts/hwlab-g14-contract-test.ts @@ -1,4 +1,4 @@ -import { activeV02PipelineRuns, cleanupPipelineRunTargetCandidateFromTextForTest, g14ObservabilityQueryAssertion, gitMirrorFlushJobManifest, gitMirrorStatusSummary, gitMirrorSyncJobManifest, gitMirrorV02SyncRequirement, hwlabG14Help, hwlabG14MonitorStateFileName, parseGitMirrorStatusRefs, parseK8sCpuMillicores, parseK8sMemoryMiB, parsePipelineTaskRunMetrics, parseV02TriggerSnapshot, rolloutRecordBody, runtimeLanePipelineRunManifest, semanticChangelogBullets, summarizeV02CdStatus, v02CloseoutVerdict, v02CommitAlignment, v02ControlPlaneRefreshScriptHash, v02ControlPlaneRenderScript, v02ExistingPipelineRunReuseDecision, v02FalseGreenGuard, v02GitMirrorPreSyncWaitMs, v02LatestOnlyTargetValidation, v02PipelineServiceIds, v02PrAutomationCommentBody, v02ReusableGitMirrorPreSyncMarker, v02ReusableRefreshMarker, v02StatusHistoryPolicy, v02TaskRunPerformanceSummary } from "./src/hwlab-g14"; +import { activeV02PipelineRuns, cleanupPipelineRunTargetCandidateFromTextForTest, g14ObservabilityQueryAssertion, gitMirrorFlushJobManifest, gitMirrorStatusSummary, gitMirrorSyncJobManifest, gitMirrorV02SyncRequirement, hwlabG14Help, hwlabG14MonitorStateFileName, parseGitMirrorStatusRefs, parseK8sCpuMillicores, parseK8sMemoryMiB, parsePipelineTaskRunMetrics, parseV02TriggerSnapshot, rolloutRecordBody, runtimeLaneGitMirrorSourceInSyncForTest, runtimeLanePipelineRunManifest, semanticChangelogBullets, summarizeV02CdStatus, v02CloseoutVerdict, v02CommitAlignment, v02ControlPlaneRefreshScriptHash, v02ControlPlaneRenderScript, v02ExistingPipelineRunReuseDecision, v02FalseGreenGuard, v02GitMirrorPreSyncWaitMs, v02LatestOnlyTargetValidation, v02PipelineServiceIds, v02PrAutomationCommentBody, v02ReusableGitMirrorPreSyncMarker, v02ReusableRefreshMarker, v02StatusHistoryPolicy, v02TaskRunPerformanceSummary } from "./src/hwlab-g14"; import { hwlabNodeHelp, nodeSecretStatusFromTextForTest } from "./src/hwlab-node"; import { hwlabRequiredNoProxyEntries, hwlabRuntimeLaneConfigPath, hwlabRuntimeLaneIds, hwlabRuntimeLaneSpec } from "./src/hwlab-node-lanes"; import { runCommand } from "./src/command"; @@ -102,6 +102,17 @@ assertCondition( "runtime lane PipelineRun manifest must preserve node/network/download profile provenance", v03PipelineRunAnnotations, ); +assertCondition( + runtimeLaneGitMirrorSourceInSyncForTest("v03", "1912c321606a63fbabb8ee019f2e9a3a16222f23", { + localV03: "1912c321606a63fbabb8ee019f2e9a3a16222f23", + githubV03: "1912c321606a63fbabb8ee019f2e9a3a16222f23", + localV03Gitops: "5ce7152d2f51fcab66754bb4a38052b2f0d8ca44", + githubV03Gitops: "02f808937075ed25e50bd6127a8aa8c651661d68", + pendingFlush: true, + }) === true + && runtimeLaneGitMirrorSourceInSyncForTest("v03", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", { localV03: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" }) === false, + "runtime lane trigger should be able to skip GitHub sync when the local mirror already has the exact source commit, even if gitops flush is pending", +); assertCondition( hwlabHelpUsage.some((line) => line.includes("monitor-prs --lane v02")) && hwlabHelpUsage.some((line) => line.includes("monitor-prs --lane v02 --status")) diff --git a/scripts/src/hwlab-g14.ts b/scripts/src/hwlab-g14.ts index 7f9f4737..75782e7c 100644 --- a/scripts/src/hwlab-g14.ts +++ b/scripts/src/hwlab-g14.ts @@ -4151,14 +4151,25 @@ function runRuntimeLaneControlPlane(spec: HwlabRuntimeLaneSpec, options: G14Cont sourceCommit, pipelineRun, }); - const gitMirrorSync = runGitMirrorSync({ - action: "sync", - lane: spec.lane, - confirm: true, - dryRun: false, - wait: true, - timeoutSeconds: options.timeoutSeconds, - }); + const gitMirrorPreSyncStatus = runGitMirrorStatus(); + const gitMirrorSourceAlreadyCurrent = runtimeLaneGitMirrorSourceInSync(spec, sourceCommit, gitMirrorPreSyncStatus); + const gitMirrorSync = gitMirrorSourceAlreadyCurrent + ? { + ok: true, + command: "hwlab nodes git-mirror sync", + mode: "skipped-source-already-current", + skipped: true, + reason: "local-mirror-source-current", + status: gitMirrorPreSyncStatus, + } + : runGitMirrorSync({ + action: "sync", + lane: spec.lane, + confirm: true, + dryRun: false, + wait: true, + timeoutSeconds: options.timeoutSeconds, + }); printRuntimeLaneTriggerProgress(spec, { stage: "git-mirror-sync", status: gitMirrorSync.ok === true ? "succeeded" : "failed", @@ -5241,10 +5252,19 @@ export function gitMirrorV02SyncRequirement(sourceCommit: string, rawStatus: str }; } +export function runtimeLaneGitMirrorSourceInSyncForTest(lane: string, sourceCommit: string, summary: Record): boolean { + const localKey = lane === "v02" ? "localV02" : lane === "v03" ? "localV03" : null; + return localKey !== null && typeof summary[localKey] === "string" && summary[localKey] === sourceCommit; +} + function gitMirrorStatusCacheRaw(status: Record): string { return String(nested(status, ["cache", "raw"]) ?? ""); } +function runtimeLaneGitMirrorSourceInSync(spec: HwlabRuntimeLaneSpec, sourceCommit: string, status: Record): boolean { + return runtimeLaneGitMirrorSourceInSyncForTest(spec.lane, sourceCommit, record(nested(status, ["cache", "summary"]))); +} + function compactGitMirrorStatus(status: Record, sourceCommit: string): Record { const requirement = gitMirrorV02SyncRequirement(sourceCommit, gitMirrorStatusCacheRaw(status)); return { @@ -5271,6 +5291,8 @@ function compactGitMirrorSync(sync: Record): Record