Merge pull request #2886 from pikasTech/fix/hwlab-first-materialization-scope
Pipelines as Code CI / platform-infra-gitea-nc01- Success
Pipelines as Code CI / platform-infra-gitea-nc01- Success
修复 HWLAB 首次物化发布范围审阅
This commit is contained in:
@@ -426,6 +426,9 @@ test("L2/L3 release exposes plan first and trigger only sends the PaC webhook",
|
||||
expect(planAction).toContain("imageBuildCount");
|
||||
expect(planAction).toContain("envReuse");
|
||||
expect(planAction).toContain("requestedScope");
|
||||
expect(planAction).toContain("domain?.artifactCatalog?.status === 'missing'");
|
||||
expect(planAction).toContain("mode: firstMaterialization ? 'first-materialization' : 'changed-paths'");
|
||||
expect(planAction).toContain("[...new Set([...buildServices, ...rolloutServices, ...affectedServices])].sort()");
|
||||
expect(planAction).toContain("service.envChangedPaths");
|
||||
expect(planAction).toContain("service.codeChangedPaths");
|
||||
expect(planAction).toContain("(service.reason || []).includes('gitops-render-input-changed')");
|
||||
@@ -628,6 +631,41 @@ test("PaC compact release plan keeps bounded registry probe results", () => {
|
||||
expect(JSON.stringify(compact)).not.toContain("sha256:aaaaaaaa");
|
||||
});
|
||||
|
||||
test("PaC compact release plan summarizes env reuse without duplicate service lists", () => {
|
||||
const compact = compactManualReleasePlan({
|
||||
envReuse: {
|
||||
status: "planned",
|
||||
groups: [{
|
||||
id: "shared-runtime",
|
||||
buildService: "api",
|
||||
buildRequired: true,
|
||||
services: ["api", "worker", "web"],
|
||||
buildServices: ["api"],
|
||||
consumerServices: ["worker", "web"],
|
||||
imageRepository: "registry.invalid/private/shared-runtime",
|
||||
}],
|
||||
reusedServices: ["unchanged-service"],
|
||||
reusedServiceCount: 1,
|
||||
buildSkippedServices: ["worker", "web", "unchanged-service"],
|
||||
},
|
||||
});
|
||||
expect(compact.envReuse).toEqual({
|
||||
status: "planned",
|
||||
groups: [{
|
||||
id: "shared-runtime",
|
||||
buildService: "api",
|
||||
buildRequired: true,
|
||||
serviceCount: 3,
|
||||
buildServiceCount: 1,
|
||||
consumerServiceCount: 2,
|
||||
}],
|
||||
reusedServiceCount: 1,
|
||||
buildSkippedServiceCount: 3,
|
||||
});
|
||||
expect(JSON.stringify(compact)).not.toContain("registry.invalid");
|
||||
expect(JSON.stringify(compact)).not.toContain("unchanged-service");
|
||||
});
|
||||
|
||||
test("PaC release manifest renders YAML-owned watcher startup backlog probes", () => {
|
||||
const pac = readPacConfig({ consumerId: "hwlab-nc01-v03", selectDefault: true });
|
||||
const source = readFileSync(resolve(import.meta.dir, "fixtures/pac/release-leading-comment-only.yaml"), "utf8");
|
||||
|
||||
@@ -611,7 +611,7 @@ const configuredImages = JSON.parse(process.env.UNIDESK_PAC_MANUAL_IMAGE_REPOSIT
|
||||
const affectedServices = domain?.affectedServices || (effectiveChangedPaths.length > 0 ? [process.env.UNIDESK_PAC_MANUAL_RUNTIME_SERVICE].filter(Boolean) : []);
|
||||
const rolloutServices = domain?.rolloutServices || affectedServices;
|
||||
const buildServices = domain?.buildServices || (effectiveChangedPaths.length > 0 ? configuredImages : []);
|
||||
const requestedServices = domain
|
||||
const changedRequestedServices = domain
|
||||
? (domain.services || [])
|
||||
.filter((service) => (service.changedPaths || []).length > 0
|
||||
|| (service.envChangedPaths || []).length > 0
|
||||
@@ -621,6 +621,10 @@ const requestedServices = domain
|
||||
|| (service.reason || []).includes('gitops-render-input-changed'))
|
||||
.map((service) => service.serviceId || service.id)
|
||||
: (effectiveChangedPaths.length > 0 ? [process.env.UNIDESK_PAC_MANUAL_RUNTIME_SERVICE].filter(Boolean) : []);
|
||||
const firstMaterialization = domain?.artifactCatalog?.status === 'missing';
|
||||
const requestedServices = firstMaterialization
|
||||
? [...new Set([...buildServices, ...rolloutServices, ...affectedServices])].sort()
|
||||
: changedRequestedServices;
|
||||
const expandedBuildServices = domain
|
||||
? buildServices.filter((serviceId) => !requestedServices.includes(serviceId))
|
||||
: [];
|
||||
@@ -685,6 +689,7 @@ const plan = {
|
||||
: null,
|
||||
},
|
||||
requestedScope: {
|
||||
mode: firstMaterialization ? 'first-materialization' : 'changed-paths',
|
||||
affectedServiceCount: requestedServices.length,
|
||||
affectedServices: requestedServices,
|
||||
},
|
||||
|
||||
@@ -728,7 +728,7 @@ export function compactManualReleasePlan(plan: Record<string, any>): Record<stri
|
||||
},
|
||||
rangeBaseline: plan.rangeBaseline ?? null,
|
||||
requestedScope: plan.requestedScope ?? null,
|
||||
envReuse: plan.envReuse ?? null,
|
||||
envReuse: compactManualReleaseEnvReuse(plan.envReuse),
|
||||
imageBuildCount: plan.imageBuildCount ?? null,
|
||||
buildServices: plan.buildServices ?? [],
|
||||
rolloutServiceCount: plan.rolloutServiceCount ?? null,
|
||||
@@ -740,6 +740,37 @@ export function compactManualReleasePlan(plan: Record<string, any>): Record<stri
|
||||
};
|
||||
}
|
||||
|
||||
function compactManualReleaseEnvReuse(value: unknown): Record<string, unknown> | null {
|
||||
if (value === null || typeof value !== "object") return null;
|
||||
const envReuse = value as Record<string, unknown>;
|
||||
const groups = Array.isArray(envReuse.groups)
|
||||
? envReuse.groups.map((item) => {
|
||||
const group = item !== null && typeof item === "object" ? item as Record<string, unknown> : {};
|
||||
const services = Array.isArray(group.services) ? group.services : [];
|
||||
const buildServices = Array.isArray(group.buildServices) ? group.buildServices : [];
|
||||
const consumerServices = Array.isArray(group.consumerServices) ? group.consumerServices : [];
|
||||
return {
|
||||
id: typeof group.id === "string" ? group.id : null,
|
||||
buildService: typeof group.buildService === "string" ? group.buildService : null,
|
||||
buildRequired: group.buildRequired === true,
|
||||
serviceCount: services.length,
|
||||
buildServiceCount: buildServices.length,
|
||||
consumerServiceCount: consumerServices.length,
|
||||
};
|
||||
}).filter((item) => item.id !== null)
|
||||
: [];
|
||||
const reusedServices = Array.isArray(envReuse.reusedServices) ? envReuse.reusedServices : [];
|
||||
const buildSkippedServices = Array.isArray(envReuse.buildSkippedServices) ? envReuse.buildSkippedServices : [];
|
||||
return {
|
||||
status: typeof envReuse.status === "string" ? envReuse.status : null,
|
||||
groups,
|
||||
reusedServiceCount: typeof envReuse.reusedServiceCount === "number"
|
||||
? envReuse.reusedServiceCount
|
||||
: reusedServices.length,
|
||||
buildSkippedServiceCount: buildSkippedServices.length,
|
||||
};
|
||||
}
|
||||
|
||||
function compactRegistryProbe(value: unknown): Record<string, unknown> | null {
|
||||
if (value === null || typeof value !== "object") return null;
|
||||
const probe = value as Record<string, unknown>;
|
||||
|
||||
Reference in New Issue
Block a user