Merge pull request #2764 from pikasTech/fix/2835-cicd-plan
fix: 收敛HWLAB L2发布TaskRun
This commit is contained in:
@@ -9,7 +9,7 @@ metadata:
|
||||
pipelinesascode.tekton.dev/on-cel-expression: "event == 'push' && target_branch == 'v0.3' && node == 'NC01'"
|
||||
pipelinesascode.tekton.dev/max-keep-runs: "8"
|
||||
unidesk.ai/owning-config-ref: "config/hwlab-node-lanes.yaml#lanes.v03.targets.NC01"
|
||||
unidesk.ai/effective-config-sha256: sha256:885e9277542653c730816208d4a0607dae143ce9b07fb68a108e9539428162b6
|
||||
unidesk.ai/effective-config-sha256: sha256:f42181ba9c079806968bb8374967a2bc710c7a87b56030d512cc00c004be126b
|
||||
unidesk.ai/source-artifact-renderer: hwlab-runtime-lane
|
||||
unidesk.ai/source-artifact-mode: remote-pipeline-annotation
|
||||
pipelinesascode.tekton.dev/pipeline: ci/pipelines/hwlab-nc01-v03-ci-image-publish.yaml
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -129,14 +129,23 @@ test("tracked PaC remote pipelines pass selected services to catalog restore", a
|
||||
for (const target of targets) {
|
||||
const pipeline = await readStructuredFile(process.cwd(), target.pipelinePath);
|
||||
assert.equal(pipeline.metadata?.name, target.pipelineName, `${target.node} tracked Pipeline name`);
|
||||
assert.deepEqual(pipeline.spec?.tasks?.map((task) => task.name), ["plan-artifacts", "build-services", "release-artifacts"]);
|
||||
const planArtifacts = pipeline.spec?.tasks?.find((task) => task.name === "plan-artifacts");
|
||||
assert.ok(planArtifacts, `${target.node} tracked Pipeline plan-artifacts task`);
|
||||
assert.ok(planArtifacts.taskSpec?.params?.some((param) => param.name === "services"), `${target.node} plan-artifacts services param`);
|
||||
assert.ok(planArtifacts.params?.some((param) => param.name === "services" && param.value === "$(params.services)"), `${target.node} plan-artifacts services binding`);
|
||||
const script = planArtifacts.taskSpec?.steps?.[0]?.script ?? "";
|
||||
assert.deepEqual(planArtifacts.taskSpec?.steps?.map((step) => step.name), [
|
||||
"prepare-source",
|
||||
"plan"
|
||||
]);
|
||||
const script = planArtifacts.taskSpec?.steps?.find((step) => step.name === "plan")?.script ?? "";
|
||||
assert.match(script, /HWLAB_SERVICES="\$\(params\.services\)" node scripts\/ci\/restore-artifact-catalog\.mjs/u);
|
||||
assert.match(script, /rolloutWithoutImageBuildServices/u);
|
||||
assert.match(script, /artifactCatalog: plan\.artifactCatalog/u);
|
||||
const buildServices = pipeline.spec?.tasks?.find((task) => task.name === "build-services");
|
||||
assert.deepEqual(buildServices?.when, [{ input: "$(tasks.plan-artifacts.results.build-required)", operator: "in", values: ["true"] }]);
|
||||
const releaseArtifacts = pipeline.spec?.tasks?.find((task) => task.name === "release-artifacts");
|
||||
assert.deepEqual(releaseArtifacts?.taskSpec?.steps?.map((step) => step.name), ["collect", "promote"]);
|
||||
|
||||
const pac = await readStructuredFile(process.cwd(), target.pacPath);
|
||||
assert.equal(pac.metadata?.annotations?.["pipelinesascode.tekton.dev/pipeline"], target.pipelinePath, `${target.node} PaC remote Pipeline path`);
|
||||
|
||||
@@ -322,7 +322,7 @@ function planArtifactsTask({ serviceIds = defaultServiceIds } = {}) {
|
||||
results: serviceIds.flatMap((serviceId) => [
|
||||
{ name: affectedResultName(serviceId), description: `${serviceId} rollout affected according to ci-plan` },
|
||||
{ name: buildResultName(serviceId), description: `${serviceId} image build required according to ci-plan` }
|
||||
]),
|
||||
]).concat([{ name: "build-required", description: "true when at least one planned service image must be built" }]),
|
||||
workspaces: [{ name: "source" }],
|
||||
steps: [{
|
||||
name: "plan",
|
||||
@@ -402,12 +402,46 @@ function perServiceBuildTask(serviceId, { runAfter = ["plan-artifacts"] } = {})
|
||||
function perServiceBuildMatrixTask(serviceIds, { runAfter = ["plan-artifacts"] } = {}) {
|
||||
const task = perServiceBuildTask(serviceIds[0], { runAfter });
|
||||
task.name = "build-services";
|
||||
delete task.when;
|
||||
task.when = [{ input: "$(tasks.plan-artifacts.results.build-required)", operator: "in", values: ["true"] }];
|
||||
task.params = task.params.filter((param) => param.name !== "service-id");
|
||||
task.matrix = { params: [{ name: "service-id", value: serviceIds }] };
|
||||
return task;
|
||||
}
|
||||
|
||||
function mergeNamedEntries(...groups) {
|
||||
const entries = new Map();
|
||||
for (const group of groups) {
|
||||
for (const entry of group || []) {
|
||||
if (!entries.has(entry.name)) entries.set(entry.name, entry);
|
||||
}
|
||||
}
|
||||
return [...entries.values()];
|
||||
}
|
||||
|
||||
function releasePlanTask({ serviceIds = defaultServiceIds } = {}) {
|
||||
const plan = planArtifactsTask({ serviceIds });
|
||||
const prepareParams = [
|
||||
{ name: "git-url" }, { name: "git-read-url" }, { name: "gitops-read-url" }, { name: "source-branch" },
|
||||
{ name: "gitops-branch" }, { name: "lane" }, { name: "catalog-path" }, { name: "image-tag-mode" },
|
||||
{ name: "registry-prefix" }, { name: "services" }, { name: "revision" }
|
||||
];
|
||||
const prepareBindings = prepareParams.map(({ name }) => ({ name, value: `$(params.${name})` }));
|
||||
return {
|
||||
name: "plan-artifacts",
|
||||
workspaces: [{ name: "source", workspace: "source" }],
|
||||
taskSpec: {
|
||||
params: mergeNamedEntries(prepareParams, plan.taskSpec.params),
|
||||
results: plan.taskSpec.results,
|
||||
workspaces: [{ name: "source" }],
|
||||
steps: [
|
||||
{ name: "prepare-source", image: ciToolsRunnerImage, env: proxyEnv(), script: prepareSourceScript() },
|
||||
plan.taskSpec.steps[0]
|
||||
]
|
||||
},
|
||||
params: mergeNamedEntries(prepareBindings, plan.params)
|
||||
};
|
||||
}
|
||||
|
||||
function collectArtifactsTask({ serviceIds = defaultServiceIds } = {}) {
|
||||
return {
|
||||
name: "collect-artifacts",
|
||||
@@ -438,6 +472,52 @@ function collectArtifactsTask({ serviceIds = defaultServiceIds } = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
function gitopsPromoteTask() {
|
||||
return {
|
||||
name: "gitops-promote",
|
||||
workspaces: [
|
||||
{ name: "source", workspace: "source" },
|
||||
{ name: "gitea-auth", workspace: "gitea-auth" }
|
||||
],
|
||||
taskSpec: {
|
||||
params: [
|
||||
{ name: "git-url" }, { name: "git-read-url" }, { name: "gitops-read-url" }, { name: "git-write-url" }, { name: "gitops-username" },
|
||||
{ name: "source-branch" }, { name: "gitops-branch" }, { name: "lane" }, { name: "catalog-path" },
|
||||
{ name: "image-tag-mode" }, { name: "runtime-path" }, { name: "revision" }, { name: "registry-prefix" }
|
||||
],
|
||||
results: [{ name: "runtime-ready-required", description: "true when GitOps promotion changed runtime desired state and runtime readiness must be observed" }],
|
||||
workspaces: [{ name: "source" }, { name: "gitea-auth" }],
|
||||
steps: [{ name: "promote", image: ciToolsRunnerImage, env: proxyEnv(), script: gitopsPromoteScript() }]
|
||||
},
|
||||
params: [
|
||||
{ name: "git-url", value: "$(params.git-url)" }, { name: "git-read-url", value: "$(params.git-read-url)" },
|
||||
{ name: "gitops-read-url", value: "$(params.gitops-read-url)" }, { name: "git-write-url", value: "$(params.git-write-url)" },
|
||||
{ name: "gitops-username", value: "$(params.gitops-username)" }, { name: "source-branch", value: "$(params.source-branch)" },
|
||||
{ name: "gitops-branch", value: "$(params.gitops-branch)" }, { name: "lane", value: "$(params.lane)" },
|
||||
{ name: "catalog-path", value: "$(params.catalog-path)" }, { name: "image-tag-mode", value: "$(params.image-tag-mode)" },
|
||||
{ name: "runtime-path", value: "$(params.runtime-path)" }, { name: "revision", value: "$(params.revision)" },
|
||||
{ name: "registry-prefix", value: "$(params.registry-prefix)" }
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
function releaseArtifactsTask({ serviceIds = defaultServiceIds } = {}) {
|
||||
const collect = collectArtifactsTask({ serviceIds });
|
||||
const promote = gitopsPromoteTask();
|
||||
return {
|
||||
name: "release-artifacts",
|
||||
runAfter: ["build-services"],
|
||||
workspaces: promote.workspaces,
|
||||
taskSpec: {
|
||||
params: mergeNamedEntries(collect.taskSpec.params, promote.taskSpec.params),
|
||||
results: promote.taskSpec.results,
|
||||
workspaces: promote.taskSpec.workspaces,
|
||||
steps: [collect.taskSpec.steps[0], promote.taskSpec.steps[0]]
|
||||
},
|
||||
params: mergeNamedEntries(collect.params, promote.params)
|
||||
};
|
||||
}
|
||||
|
||||
function runtimeReadyScript() {
|
||||
return `#!/bin/sh
|
||||
set -eu
|
||||
@@ -549,12 +629,13 @@ function tektonTasks(args = { lane: "node" }, deploy = null) {
|
||||
|
||||
function tektonPipeline(args = { lane: "node" }, deploy = null) {
|
||||
const settings = ciLaneSettings(args, deploy);
|
||||
const serviceIds = serviceIdsForLane(args.lane, deploy);
|
||||
const runtimePath = gitopsPathForProfile(args, settings.profile, deploy);
|
||||
const preFlushRuntimeReadyTasks = isRuntimeLane(settings.lane)
|
||||
? []
|
||||
: [{
|
||||
...runtimeReadyTask({ profile: settings.profile, deploy }),
|
||||
when: [{ input: "$(tasks.gitops-promote.results.runtime-ready-required)", operator: "in", values: ["true"] }]
|
||||
when: [{ input: "$(tasks.release-artifacts.results.runtime-ready-required)", operator: "in", values: ["true"] }]
|
||||
}];
|
||||
return {
|
||||
apiVersion: "tekton.dev/v1",
|
||||
@@ -567,9 +648,9 @@ function tektonPipeline(args = { lane: "node" }, deploy = null) {
|
||||
"hwlab.pikastech.local/gitops-target": settings.gitopsTarget
|
||||
},
|
||||
annotations: {
|
||||
"hwlab.pikastech.local/source-config": "scripts/gitops-render.mjs#tekton-native-primitive-ci",
|
||||
"hwlab.pikastech.local/ci-contract": "tekton-native-primitive-tasks",
|
||||
"hwlab.pikastech.local/policy": "native-per-service-taskrun-image-publish"
|
||||
"hwlab.pikastech.local/source-config": "scripts/gitops-render.mjs#bounded-release-taskruns",
|
||||
"hwlab.pikastech.local/ci-contract": "plan-build-release-taskruns",
|
||||
"hwlab.pikastech.local/policy": "reviewed-plan-exact-scope"
|
||||
}
|
||||
},
|
||||
spec: {
|
||||
@@ -601,87 +682,9 @@ function tektonPipeline(args = { lane: "node" }, deploy = null) {
|
||||
{ name: "gitea-auth" }
|
||||
],
|
||||
tasks: [
|
||||
{
|
||||
name: "prepare-source",
|
||||
workspaces: [
|
||||
{ name: "source", workspace: "source" }
|
||||
],
|
||||
taskSpec: {
|
||||
params: [
|
||||
{ name: "git-url" },
|
||||
{ name: "git-read-url" },
|
||||
{ name: "gitops-read-url" },
|
||||
{ name: "source-branch" },
|
||||
{ name: "gitops-branch" },
|
||||
{ name: "lane" },
|
||||
{ name: "catalog-path" },
|
||||
{ name: "image-tag-mode" },
|
||||
{ name: "registry-prefix" },
|
||||
{ name: "services" },
|
||||
{ name: "revision" }
|
||||
],
|
||||
workspaces: [{ name: "source" }],
|
||||
steps: [{ name: "prepare-source", image: ciToolsRunnerImage, env: proxyEnv(), script: prepareSourceScript() }]
|
||||
},
|
||||
params: [
|
||||
{ name: "git-url", value: "$(params.git-url)" },
|
||||
{ name: "git-read-url", value: "$(params.git-read-url)" },
|
||||
{ name: "gitops-read-url", value: "$(params.gitops-read-url)" },
|
||||
{ name: "source-branch", value: "$(params.source-branch)" },
|
||||
{ name: "gitops-branch", value: "$(params.gitops-branch)" },
|
||||
{ name: "lane", value: "$(params.lane)" },
|
||||
{ name: "catalog-path", value: "$(params.catalog-path)" },
|
||||
{ name: "image-tag-mode", value: "$(params.image-tag-mode)" },
|
||||
{ name: "registry-prefix", value: "$(params.registry-prefix)" },
|
||||
{ name: "services", value: "$(params.services)" },
|
||||
{ name: "revision", value: "$(params.revision)" }
|
||||
]
|
||||
},
|
||||
...primitiveValidationTasks.map(primitiveValidationTask),
|
||||
...imagePublishTaskSet(args, deploy),
|
||||
{
|
||||
name: "gitops-promote",
|
||||
runAfter: ["collect-artifacts"],
|
||||
workspaces: [
|
||||
{ name: "source", workspace: "source" },
|
||||
{ name: "gitea-auth", workspace: "gitea-auth" }
|
||||
],
|
||||
taskSpec: {
|
||||
params: [
|
||||
{ name: "git-url" },
|
||||
{ name: "git-read-url" },
|
||||
{ name: "gitops-read-url" },
|
||||
{ name: "git-write-url" },
|
||||
{ name: "gitops-username" },
|
||||
{ name: "source-branch" },
|
||||
{ name: "gitops-branch" },
|
||||
{ name: "lane" },
|
||||
{ name: "catalog-path" },
|
||||
{ name: "image-tag-mode" },
|
||||
{ name: "runtime-path" },
|
||||
{ name: "revision" },
|
||||
{ name: "registry-prefix" }
|
||||
],
|
||||
results: [{ name: "runtime-ready-required", description: "true when GitOps promotion changed runtime desired state and runtime readiness must be observed" }],
|
||||
workspaces: [{ name: "source" }, { name: "gitea-auth" }],
|
||||
steps: [{ name: "promote", image: ciToolsRunnerImage, env: proxyEnv(), script: gitopsPromoteScript() }]
|
||||
},
|
||||
params: [
|
||||
{ name: "git-url", value: "$(params.git-url)" },
|
||||
{ name: "git-read-url", value: "$(params.git-read-url)" },
|
||||
{ name: "gitops-read-url", value: "$(params.gitops-read-url)" },
|
||||
{ name: "git-write-url", value: "$(params.git-write-url)" },
|
||||
{ name: "gitops-username", value: "$(params.gitops-username)" },
|
||||
{ name: "source-branch", value: "$(params.source-branch)" },
|
||||
{ name: "gitops-branch", value: "$(params.gitops-branch)" },
|
||||
{ name: "lane", value: "$(params.lane)" },
|
||||
{ name: "catalog-path", value: "$(params.catalog-path)" },
|
||||
{ name: "image-tag-mode", value: "$(params.image-tag-mode)" },
|
||||
{ name: "runtime-path", value: "$(params.runtime-path)" },
|
||||
{ name: "revision", value: "$(params.revision)" },
|
||||
{ name: "registry-prefix", value: "$(params.registry-prefix)" }
|
||||
]
|
||||
},
|
||||
releasePlanTask({ serviceIds }),
|
||||
perServiceBuildMatrixTask(serviceIds, { runAfter: ["plan-artifacts"] }),
|
||||
releaseArtifactsTask({ serviceIds }),
|
||||
...preFlushRuntimeReadyTasks
|
||||
]
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ const entries = allServices.map((serviceId) => {
|
||||
codeChanged: service.codeChanged ?? null
|
||||
};
|
||||
});
|
||||
fs.writeFileSync("/tekton/results/build-required", entries.some((entry) => entry.buildRequired) ? "true" : "false");
|
||||
for (const entry of entries) {
|
||||
fs.writeFileSync("/tekton/results/affected-" + entry.serviceId, entry.affected ? "true" : "false");
|
||||
fs.writeFileSync("/tekton/results/build-" + entry.serviceId, entry.buildRequired ? "true" : "false");
|
||||
|
||||
Reference in New Issue
Block a user