refactor: remove CI.json from G14 CI
This commit is contained in:
@@ -21,7 +21,6 @@ const defaultProdWebEndpoint = process.env.HWLAB_G14_PROD_WEB_ENDPOINT || "http:
|
||||
const defaultProxyUrl = process.env.HWLAB_G14_PROXY_URL || "http://127.0.0.1:10808";
|
||||
const defaultAllProxyUrl = process.env.HWLAB_G14_ALL_PROXY_URL || "socks5h://127.0.0.1:10808";
|
||||
const defaultNoProxy = process.env.HWLAB_G14_NO_PROXY || "hyueapi.com,.hyueapi.com,127.0.0.1,localhost,::1,10.0.0.0/8,10.42.0.0/16,10.43.0.0/16,192.168.0.0/16,.svc,.cluster.local,kubernetes.default.svc,registry.hwlab-ci.svc,hwlab-registry.hwlab-ci.svc";
|
||||
const ciJsonRunnerImage = process.env.HWLAB_G14_CI_JSON_IMAGE || "mcr.microsoft.com/playwright@sha256:b0ab6f3cb99aa7803adbc14d9027ec1785fc6e433b97e134e0f8fe61683b6b53";
|
||||
const ciToolsRunnerImage = process.env.HWLAB_G14_CI_TOOLS_IMAGE || "127.0.0.1:5000/hwlab/hwlab-ci-node-tools:node22-alpine-v1";
|
||||
const buildkitRunnerImage = process.env.HWLAB_G14_BUILDKIT_IMAGE || "moby/buildkit:rootless";
|
||||
const defaultDevBaseImage = process.env.HWLAB_G14_DEV_BASE_IMAGE || "127.0.0.1:5000/hwlab/hwlab-node20-base:20-bookworm-slim";
|
||||
@@ -50,6 +49,29 @@ const codexApiProfileBaseUrl = process.env.HWLAB_G14_CODEX_API_PROFILE_BASE_URL
|
||||
const codexApiForwarderPort = process.env.HWLAB_G14_CODEX_API_FORWARDER_PORT || "49280";
|
||||
const codexApiForwarderUpstreamBaseUrl = process.env.HWLAB_G14_CODEX_API_UPSTREAM_BASE_URL || "https://hyueapi.com";
|
||||
const sourceCommitPattern = /^[a-f0-9]{7,40}$/u;
|
||||
const primitiveValidationTasks = Object.freeze([
|
||||
{
|
||||
name: "repo-reports-guard",
|
||||
commands: ["node scripts/repo-reports-guard.mjs"]
|
||||
},
|
||||
{
|
||||
name: "g14-contract-check",
|
||||
commands: [
|
||||
"node --check scripts/g14-gitops-render.mjs",
|
||||
"node scripts/g14-gitops-render.mjs --check",
|
||||
"node --check scripts/artifact-publish.mjs",
|
||||
"node --check scripts/g14-artifact-publish.mjs"
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "codex-api-forwarder-check",
|
||||
commands: [
|
||||
"node --check cmd/hwlab-codex-api-responses-forwarder/main.mjs",
|
||||
"node --check cmd/hwlab-codex-api-responses-forwarder/main.test.mjs",
|
||||
"node --test cmd/hwlab-codex-api-responses-forwarder/main.test.mjs"
|
||||
]
|
||||
}
|
||||
]);
|
||||
|
||||
function proxyEnv() {
|
||||
return [
|
||||
@@ -115,7 +137,7 @@ function usage() {
|
||||
return [
|
||||
"usage: node scripts/g14-gitops-render.mjs [options]",
|
||||
"",
|
||||
"Render G14-only Kubernetes-native CI/CD manifests from CI.json and deploy/deploy.json.",
|
||||
"Render G14-only Kubernetes-native CI/CD manifests from built-in Tekton CI primitives, deploy/deploy.json, and deploy/k8s/*.",
|
||||
"",
|
||||
"options:",
|
||||
` --out DIR default: ${defaultOutDir}`,
|
||||
@@ -129,7 +151,7 @@ function usage() {
|
||||
` --prod-runtime-endpoint URL default: ${defaultProdRuntimeEndpoint}`,
|
||||
` --prod-web-endpoint URL default: ${defaultProdWebEndpoint}`,
|
||||
" --use-deploy-images default: render workload images/env from deploy/deploy.json per service",
|
||||
" --legacy-source-images compatibility fallback: render every workload with the source revision tag",
|
||||
" --legacy-source-images render every workload with the source revision tag instead of per-service desired images",
|
||||
" --check verify generated files are current without writing",
|
||||
" --no-write plan and print generated file list without writing"
|
||||
].join("\n");
|
||||
@@ -590,20 +612,16 @@ curl_dependency_probe() {
|
||||
}`;
|
||||
}
|
||||
|
||||
function ciJsonScript(ci) {
|
||||
const commands = ci.commands ?? [];
|
||||
function prepareSourceScript() {
|
||||
const lines = [
|
||||
"#!/bin/sh",
|
||||
"set -eu",
|
||||
dependencyProxyProbeScript("ci-json-proxy-preflight", "http://deb.debian.org/debian/dists/bookworm/InRelease"),
|
||||
dependencyProxyProbeScript("prepare-source-proxy-preflight", "http://deb.debian.org/debian/dists/bookworm/InRelease"),
|
||||
curlDownloadProbeFunction(),
|
||||
"echo '{\"event\":\"ci-base-image\",\"policy\":\"no-runtime-apt-or-playwright-install\"}'",
|
||||
`echo '{"event":"ci-base-image","phase":"prepare-source","image":"${ciToolsRunnerImage}","policy":"no-runtime-apk"}'`,
|
||||
"for tool in node npm git python3 ssh curl; do command -v \"$tool\" >/dev/null 2>&1 || { echo '{\"event\":\"ci-base-image\",\"ok\":false,\"reason\":\"missing-tool\",\"tool\":\"'\"$tool\"'\"}'; exit 31; }; done",
|
||||
"export PLAYWRIGHT_BROWSERS_PATH=\"${PLAYWRIGHT_BROWSERS_PATH:-/ms-playwright}\"",
|
||||
"test -d \"$PLAYWRIGHT_BROWSERS_PATH\" || { echo '{\"event\":\"ci-base-image\",\"ok\":false,\"reason\":\"missing-playwright-browsers-path\"}'; exit 32; }",
|
||||
"find \"$PLAYWRIGHT_BROWSERS_PATH\" -maxdepth 2 -type d -name 'chromium-*' | grep -q . || { echo '{\"event\":\"ci-base-image\",\"ok\":false,\"reason\":\"missing-chromium-cache\"}'; exit 33; }",
|
||||
"node -e 'console.log(JSON.stringify({event:\"ci-base-image\",ok:true,node:process.version,browsersPath:process.env.PLAYWRIGHT_BROWSERS_PATH}))'",
|
||||
"curl_dependency_probe \"ci-json-pre-npm\" \"https://registry.npmjs.org/npm/latest\"",
|
||||
"node -e 'console.log(JSON.stringify({event:\"ci-base-image\",phase:\"prepare-source\",ok:true,node:process.version}))'",
|
||||
"curl_dependency_probe \"prepare-source-pre-npm\" \"https://registry.npmjs.org/npm/latest\"",
|
||||
"mkdir -p /root/.ssh",
|
||||
"cp /workspace/git-ssh/ssh-privatekey /root/.ssh/id_rsa",
|
||||
"chmod 600 /root/.ssh/id_rsa",
|
||||
@@ -611,24 +629,44 @@ function ciJsonScript(ci) {
|
||||
"rm -rf /workspace/source/repo",
|
||||
"git clone --branch \"$(params.source-branch)\" \"$(params.git-url)\" /workspace/source/repo",
|
||||
"cd /workspace/source/repo",
|
||||
"git config --global --add safe.directory /workspace/source/repo",
|
||||
"git checkout \"$(params.revision)\"",
|
||||
"test \"$(git rev-parse HEAD)\" = \"$(params.revision)\"",
|
||||
"npm ci --ignore-scripts",
|
||||
"playwright_browser_probe_url=\"$(node -e 'const fs=require(\"node:fs\"); let url=\"\"; try { const p=require.resolve(\"playwright-core/browsers.json\"); const data=JSON.parse(fs.readFileSync(p,\"utf8\")); const b=data.browsers.find((item)=>item.name===\"chromium\"); if (b?.revision) url=\"https://playwright.azureedge.net/builds/chromium/\"+b.revision+\"/chromium-linux.zip\"; } catch {} process.stdout.write(url);' 2>/dev/null || true)\"",
|
||||
"if [ -n \"$playwright_browser_probe_url\" ]; then curl_dependency_probe \"ci-json-pre-playwright\" \"$playwright_browser_probe_url\"; fi",
|
||||
"node - <<'NODE'\nconst fs = require(\"node:fs\");\nconst { chromium } = require(\"playwright\");\nconst executablePath = chromium.executablePath();\nfs.accessSync(executablePath, fs.constants.X_OK);\nconsole.log(JSON.stringify({ event: \"playwright-cache-check\", ok: true, executablePath, browsersPath: process.env.PLAYWRIGHT_BROWSERS_PATH || \"\" }));\nNODE",
|
||||
`echo ${shellSingleQuote(`CI.json ${ci.name ?? "hwlab"} command count=${commands.length}`)}`
|
||||
`echo ${shellSingleQuote(`G14 prepare-source complete; validation task count=${primitiveValidationTasks.length}`)}`
|
||||
];
|
||||
for (const command of commands) {
|
||||
lines.push(`echo ${shellSingleQuote(`CI.json command: ${command.name}`)}`);
|
||||
lines.push("(");
|
||||
lines.push("set -eu");
|
||||
lines.push(command.run);
|
||||
lines.push(")");
|
||||
}
|
||||
return `${lines.join("\n")}\n`;
|
||||
}
|
||||
|
||||
function sourceValidationScript(commands) {
|
||||
return [
|
||||
"#!/bin/sh",
|
||||
"set -eu",
|
||||
"git config --global --add safe.directory /workspace/source/repo",
|
||||
"cd /workspace/source/repo",
|
||||
"test \"$(git rev-parse HEAD)\" = \"$(params.revision)\"",
|
||||
...commands
|
||||
].join("\n") + "\n";
|
||||
}
|
||||
|
||||
function primitiveValidationTaskNames() {
|
||||
return primitiveValidationTasks.map((task) => task.name);
|
||||
}
|
||||
|
||||
function primitiveValidationTask(task) {
|
||||
return {
|
||||
name: task.name,
|
||||
runAfter: ["prepare-source"],
|
||||
workspaces: [{ name: "source", workspace: "source" }],
|
||||
taskSpec: {
|
||||
params: [{ name: "revision" }],
|
||||
workspaces: [{ name: "source" }],
|
||||
steps: [{ name: task.name, image: ciToolsRunnerImage, env: proxyEnv(), script: sourceValidationScript(task.commands) }]
|
||||
},
|
||||
params: [{ name: "revision", value: "$(params.revision)" }]
|
||||
};
|
||||
}
|
||||
|
||||
function publishScript() {
|
||||
return `#!/bin/sh
|
||||
set -eu
|
||||
@@ -1269,7 +1307,7 @@ function dockerSidecar() {
|
||||
function legacyImagePublishTask() {
|
||||
return {
|
||||
name: "image-publish",
|
||||
runAfter: ["ci-json"],
|
||||
runAfter: primitiveValidationTaskNames(),
|
||||
workspaces: [{ name: "source", workspace: "source" }],
|
||||
taskSpec: {
|
||||
params: [
|
||||
@@ -1303,7 +1341,7 @@ function legacyImagePublishTask() {
|
||||
function planArtifactsTask() {
|
||||
return {
|
||||
name: "plan-artifacts",
|
||||
runAfter: ["ci-json"],
|
||||
runAfter: primitiveValidationTaskNames(),
|
||||
workspaces: [{ name: "source", workspace: "source" }],
|
||||
taskSpec: {
|
||||
params: [
|
||||
@@ -1400,7 +1438,7 @@ function imagePublishTaskSet() {
|
||||
];
|
||||
}
|
||||
|
||||
function tektonPipeline(ci) {
|
||||
function tektonPipeline() {
|
||||
return {
|
||||
apiVersion: "tekton.dev/v1",
|
||||
kind: "Pipeline",
|
||||
@@ -1412,7 +1450,8 @@ function tektonPipeline(ci) {
|
||||
"hwlab.pikastech.local/gitops-target": "g14"
|
||||
},
|
||||
annotations: {
|
||||
"hwlab.pikastech.local/source-config": "CI.json",
|
||||
"hwlab.pikastech.local/source-config": "scripts/g14-gitops-render.mjs#tekton-native-primitive-ci",
|
||||
"hwlab.pikastech.local/ci-contract": "tekton-native-primitive-tasks",
|
||||
"hwlab.pikastech.local/policy": tektonSingleImagePublish ? "single-dind-image-publish-compat" : "native-per-service-taskrun-image-publish"
|
||||
}
|
||||
},
|
||||
@@ -1433,7 +1472,7 @@ function tektonPipeline(ci) {
|
||||
],
|
||||
tasks: [
|
||||
{
|
||||
name: "ci-json",
|
||||
name: "prepare-source",
|
||||
workspaces: [
|
||||
{ name: "source", workspace: "source" },
|
||||
{ name: "git-ssh", workspace: "git-ssh" }
|
||||
@@ -1445,7 +1484,7 @@ function tektonPipeline(ci) {
|
||||
{ name: "revision" }
|
||||
],
|
||||
workspaces: [{ name: "source" }, { name: "git-ssh" }],
|
||||
steps: [{ name: "ci-json", image: ciJsonRunnerImage, env: proxyEnv(), script: ciJsonScript(ci) }]
|
||||
steps: [{ name: "prepare-source", image: ciToolsRunnerImage, env: proxyEnv(), script: prepareSourceScript() }]
|
||||
},
|
||||
params: [
|
||||
{ name: "git-url", value: "$(params.git-url)" },
|
||||
@@ -1453,6 +1492,7 @@ function tektonPipeline(ci) {
|
||||
{ name: "revision", value: "$(params.revision)" }
|
||||
]
|
||||
},
|
||||
...primitiveValidationTasks.map(primitiveValidationTask),
|
||||
...imagePublishTaskSet(),
|
||||
{
|
||||
name: "gitops-promote",
|
||||
@@ -2201,7 +2241,7 @@ function runtimeKustomization({ profile = "dev", includeDeviceAgent = profile ==
|
||||
function readme({ source, args }) {
|
||||
return `# HWLAB G14 GitOps CI/CD
|
||||
|
||||
This directory is generated from \`CI.json\`, \`deploy/deploy.json\`, and \`deploy/k8s/*\` by \`scripts/g14-gitops-render.mjs\`.
|
||||
This directory is generated from built-in Tekton-native CI primitive declarations plus \`deploy/deploy.json\` and \`deploy/k8s/*\` by \`scripts/g14-gitops-render.mjs\`.
|
||||
|
||||
- Target: G14 k3s only.
|
||||
- CI: Tekton Pipeline \`hwlab-ci/hwlab-g14-ci-image-publish\`.
|
||||
@@ -2217,8 +2257,7 @@ This directory is generated from \`CI.json\`, \`deploy/deploy.json\`, and \`depl
|
||||
}
|
||||
|
||||
async function plannedFiles(args) {
|
||||
const [ci, deploy, namespaceTemplate, config, services, health, workloads] = await Promise.all([
|
||||
readJson("CI.json"),
|
||||
const [deploy, namespaceTemplate, config, services, health, workloads] = await Promise.all([
|
||||
readJson("deploy/deploy.json"),
|
||||
readJson("deploy/k8s/base/namespace.yaml"),
|
||||
readJson("deploy/k8s/base/code-agent-codex-config.yaml"),
|
||||
@@ -2264,7 +2303,7 @@ async function plannedFiles(args) {
|
||||
putText("README.md", readme({ source, args }));
|
||||
putJson("registry/registry.yaml", registryManifest());
|
||||
putJson("tekton/rbac.yaml", tektonRbac());
|
||||
putJson("tekton/pipeline.yaml", tektonPipeline(ci));
|
||||
putJson("tekton/pipeline.yaml", tektonPipeline());
|
||||
putJson("tekton/poller.yaml", tektonPollerCronJob(args));
|
||||
putJson("tekton/control-plane-reconciler.yaml", tektonControlPlaneReconcilerCronJob(args));
|
||||
putJson("tekton/pipelinerun.sample.yaml", tektonPipelineRunTemplate({ source, args }));
|
||||
|
||||
Reference in New Issue
Block a user