fix: 将 production release 归并回 v0.3 单线历史
This commit is contained in:
+43
-18
@@ -24,6 +24,7 @@ import {
|
||||
generatedPath,
|
||||
gitopsPathForProfile,
|
||||
imageTagForSource,
|
||||
isNamedRuntimeLane,
|
||||
isRuntimeLane,
|
||||
jsonManifest,
|
||||
label,
|
||||
@@ -79,7 +80,7 @@ import {
|
||||
} from "./src/gitops-render/tekton-manifests.mjs";
|
||||
import { CLOUD_CORE_MIGRATIONS } from "../internal/db/schema.ts";
|
||||
|
||||
function runtimeKustomization({ profile = "dev", includeDeviceAgent = profile === "dev", externalPostgres = false, workbenchRedis = false, runtimeConfigMaps = false, externalSecrets = false } = {}) {
|
||||
function runtimeKustomization({ profile = "dev", includeDeviceAgent = profile === "dev", externalPostgres = false, workbenchRedis = false, runtimeConfigMaps = false, externalSecrets = false, deploy = null } = {}) {
|
||||
const resources = ["namespace.yaml", "services.yaml", "health-contract.yaml", "workloads.yaml", "deepseek-proxy.yaml"];
|
||||
if (!isRuntimeLane(profile)) resources.splice(1, 0, "code-agent-codex-config.yaml");
|
||||
if (runtimeConfigMaps) resources.splice(3, 0, "configmaps.yaml");
|
||||
@@ -95,12 +96,12 @@ function runtimeKustomization({ profile = "dev", includeDeviceAgent = profile ==
|
||||
return {
|
||||
apiVersion: "kustomize.config.k8s.io/v1beta1",
|
||||
kind: "Kustomization",
|
||||
namespace: namespaceNameForProfile(profile),
|
||||
namespace: namespaceNameForProfile(profile, deploy),
|
||||
resources
|
||||
};
|
||||
}
|
||||
|
||||
function readme({ source, args }) {
|
||||
function readme({ source, args, deploy }) {
|
||||
if (args.lane === "v02") {
|
||||
return `# HWLAB v0.2 GitOps CI/CD
|
||||
|
||||
@@ -117,6 +118,21 @@ This directory is generated by \`scripts/gitops-render.mjs --lane v02\` from sou
|
||||
- node DEV/PROD boundary: this lane does not modify archived DEV/PROD branches, \`hwlab-dev\`, \`hwlab-prod\`, 17666/17667 or 18666/18667.
|
||||
- CronJob policy: v0.2 does not generate \`hwlab-v02-branch-poller\` or \`hwlab-v02-control-plane-reconciler\`; obsolete live CronJobs should be deleted by the UniDesk control-plane apply command.
|
||||
- Gate policy: old DEV/D601/main gates do not enter this lane; new checks stay limited to the fixed branch, namespace, catalog, runtime path and Argo boundaries.
|
||||
`;
|
||||
}
|
||||
if (isNamedRuntimeLane(args.lane)) {
|
||||
const namespace = namespaceNameForProfile(args.lane, deploy);
|
||||
const runtimePath = gitopsPathForProfile(args, args.lane, deploy);
|
||||
return `# HWLAB ${args.lane} GitOps CI/CD
|
||||
|
||||
This directory is generated by \`scripts/gitops-render.mjs --lane ${args.lane}\` from the owning runtime lane declaration in \`deploy/deploy.yaml\`.
|
||||
|
||||
- Source: \`${args.sourceRepo}\` branch \`${args.sourceBranch}\` at \`${source.full}\`.
|
||||
- GitOps: generated desired state is promoted to \`${args.gitWriteUrl}\` branch \`${args.gitopsBranch}\`.
|
||||
- Artifact contract: runtime images come from \`${args.catalogPath}\`.
|
||||
- Runtime: Argo CD consumes \`${args.gitReadUrl}:${args.gitopsBranch}:${runtimePath}\` and deploys only to namespace \`${namespace}\`.
|
||||
- Public endpoints: web \`${args.webEndpoint}\`; API \`${args.runtimeEndpoint}\`.
|
||||
- Authority: branch, catalog, runtime path, namespace, public services and endpoints are read from \`deploy/deploy.yaml\`; missing named-lane fields fail closed.
|
||||
`;
|
||||
}
|
||||
return `# HWLAB node GitOps CI/CD
|
||||
@@ -161,7 +177,7 @@ async function plannedFiles(args) {
|
||||
let artifactCatalog = await readJsonIfPresent(args.catalogPath, null);
|
||||
if (!artifactCatalog && isRuntimeLane(args.lane)) artifactCatalog = artifactCatalogSkeleton({ args, deploy, source });
|
||||
if (!artifactCatalog) artifactCatalog = await readJson(args.catalogPath);
|
||||
const settings = ciLaneSettings(args);
|
||||
const settings = ciLaneSettings(args, deploy);
|
||||
const profiles = laneRuntimeProfiles(args);
|
||||
const migrationSources = isRuntimeLane(args.lane)
|
||||
? await Promise.all(CLOUD_CORE_MIGRATIONS.map(async (migration) => ({
|
||||
@@ -196,9 +212,9 @@ async function plannedFiles(args) {
|
||||
gitReadUrl: args.gitReadUrl,
|
||||
gitWriteUrl: args.gitWriteUrl,
|
||||
registryPrefix: args.registryPrefix,
|
||||
runtimePaths: profiles.map((profile) => gitopsPathForProfile(args, profile)),
|
||||
runtimePaths: profiles.map((profile) => gitopsPathForProfile(args, profile, deploy)),
|
||||
publicEndpoints,
|
||||
frpDeployments: Object.fromEntries(profiles.map((profile) => [profile, `${namespaceNameForProfile(profile)}/${isRuntimeLane(profile) ? `hwlab-${profile}-frpc` : profile === "prod" ? "hwlab-node-prod-frpc" : "hwlab-node-frpc"}`])),
|
||||
frpDeployments: Object.fromEntries(profiles.map((profile) => [profile, `${namespaceNameForProfile(profile, deploy)}/${isRuntimeLane(profile) ? `hwlab-${profile}-frpc` : profile === "prod" ? "hwlab-node-prod-frpc" : "hwlab-node-frpc"}`])),
|
||||
tektonPipeline: `hwlab-ci/${settings.pipelineName}`,
|
||||
argoApplications: profiles.map((profile) => `argocd/${argoApplicationName(profile)}`)
|
||||
};
|
||||
@@ -210,22 +226,22 @@ async function plannedFiles(args) {
|
||||
};
|
||||
}
|
||||
putJson("source.json", sourceDescriptor);
|
||||
putText("README.md", readme({ source, args }));
|
||||
putText("README.md", readme({ source, args, deploy }));
|
||||
putJson("registry/registry.yaml", registryManifest());
|
||||
if (isRuntimeLane(args.lane)) putJson("devops-infra/git-mirror.yaml", devopsInfraGitMirrorManifest(args, deploy));
|
||||
putJson(`${settings.tektonDir}/rbac.yaml`, tektonRbac(args));
|
||||
putJson(`${settings.tektonDir}/rbac.yaml`, tektonRbac(args, deploy));
|
||||
putJson(`${settings.tektonDir}/tasks.yaml`, { apiVersion: "v1", kind: "List", items: tektonTasks(args, deploy) });
|
||||
putJson(`${settings.tektonDir}/pipeline.yaml`, tektonPipeline(args, deploy));
|
||||
if (!isRuntimeLane(args.lane)) {
|
||||
putJson(`${settings.tektonDir}/poller.yaml`, tektonPollerCronJob(args, deploy));
|
||||
putJson(`${settings.tektonDir}/control-plane-reconciler.yaml`, tektonControlPlaneReconcilerCronJob(args));
|
||||
}
|
||||
putJson(`${settings.tektonDir}/pipelinerun.sample.yaml`, tektonPipelineRunTemplate({ source, args }));
|
||||
putJson("argocd/project.yaml", argoProject(args));
|
||||
for (const profile of profiles) putJson(`argocd/application-${profile}.yaml`, argoApplication(args, profile));
|
||||
putJson(`${settings.tektonDir}/pipelinerun.sample.yaml`, tektonPipelineRunTemplate({ source, args, deploy }));
|
||||
putJson("argocd/project.yaml", argoProject(args, deploy));
|
||||
for (const profile of profiles) putJson(`argocd/application-${profile}.yaml`, argoApplication(args, profile, deploy));
|
||||
|
||||
for (const profile of profiles) {
|
||||
const namespace = namespaceNameForProfile(profile);
|
||||
const namespace = namespaceNameForProfile(profile, deploy);
|
||||
const includeDeviceAgent = profile === "dev";
|
||||
const externalPostgres = externalPostgresConfigForLane(deploy, profile, args);
|
||||
const workbenchRedis = workbenchRuntimeRedisConfigForProfile(deploy, profile);
|
||||
@@ -236,9 +252,9 @@ async function plannedFiles(args) {
|
||||
runtimeNamespace.metadata.name = namespace;
|
||||
label(runtimeNamespace.metadata, profileLabels);
|
||||
annotate(runtimeNamespace.metadata, annotations);
|
||||
const runtimePath = runtimePathForProfile(profile);
|
||||
const runtimePath = runtimePathForProfile(profile, deploy);
|
||||
const endpoints = profileEndpoint(args, profile);
|
||||
putJson(`${runtimePath}/kustomization.yaml`, runtimeKustomization({ profile, includeDeviceAgent, externalPostgres: Boolean(externalPostgres), workbenchRedis: Boolean(workbenchRedis), runtimeConfigMaps: runtimeConfigMaps.length > 0, externalSecrets: Boolean(runtimeSecretPlane) }));
|
||||
putJson(`${runtimePath}/kustomization.yaml`, runtimeKustomization({ profile, includeDeviceAgent, externalPostgres: Boolean(externalPostgres), workbenchRedis: Boolean(workbenchRedis), runtimeConfigMaps: runtimeConfigMaps.length > 0, externalSecrets: Boolean(runtimeSecretPlane), deploy }));
|
||||
putJson(`${runtimePath}/namespace.yaml`, runtimeNamespace);
|
||||
if (!isRuntimeLane(profile)) putJson(`${runtimePath}/code-agent-codex-config.yaml`, transformListNamespace(config, namespace, profileLabels, annotations));
|
||||
putJson(`${runtimePath}/services.yaml`, transformServices({ services, namespace, labels: profileLabels, annotations, profile, deploy, nodeId: args.nodeId }));
|
||||
@@ -247,10 +263,19 @@ async function plannedFiles(args) {
|
||||
if (runtimeSecretPlane) putJson(`${runtimePath}/external-secrets.yaml`, runtimeSecretPlaneManifest({ config: runtimeSecretPlane, namespace, labels: profileLabels, annotations }));
|
||||
putJson(`${runtimePath}/workloads.yaml`, transformWorkloads({ workloads, deploy, catalog: artifactCatalog, source, sourceBranch: args.sourceBranch, gitReadUrl: args.gitReadUrl, registryPrefix: args.registryPrefix, runtimeEndpoint: endpoints.runtimeEndpoint, webEndpoint: endpoints.webEndpoint, profile, nodeId: args.nodeId, useDeployImages: args.useDeployImages, metricsSidecarSha256 }));
|
||||
putJson(`${runtimePath}/deepseek-proxy.yaml`, deepSeekProxyManifest({ profile, source, sourceBranch: args.sourceBranch, sourceRepo: args.sourceRepo, gitReadUrl: args.gitReadUrl, deploy, registryPrefix: args.registryPrefix, catalog: artifactCatalog, useDeployImages: args.useDeployImages, metricsSidecarSha256 }));
|
||||
if (isRuntimeLane(profile) && externalPostgres) putJson(`${runtimePath}/external-postgres.yaml`, externalPostgresManifest({ profile, config: externalPostgres, source }));
|
||||
if (isRuntimeLane(profile) && !externalPostgres) putJson(`${runtimePath}/postgres.yaml`, v02PostgresManifest({ profile, migrationSources, source, image: runtimePostgresImageForProfile(deploy, profile) }));
|
||||
if (workbenchRedis) putJson(`${runtimePath}/workbench-redis.yaml`, workbenchRuntimeRedisManifest({ profile, config: workbenchRedis, source }));
|
||||
if (isRuntimeLane(profile)) putJson(`${runtimePath}/openfga.yaml`, v02OpenFgaManifest({ profile, source }));
|
||||
if (isRuntimeLane(profile) && externalPostgres) putJson(`${runtimePath}/external-postgres.yaml`, externalPostgresManifest({
|
||||
profile,
|
||||
config: externalPostgres,
|
||||
source,
|
||||
deploy,
|
||||
migrationSources,
|
||||
catalog: artifactCatalog,
|
||||
registryPrefix: args.registryPrefix,
|
||||
useDeployImages: args.useDeployImages
|
||||
}));
|
||||
if (isRuntimeLane(profile) && !externalPostgres) putJson(`${runtimePath}/postgres.yaml`, v02PostgresManifest({ profile, migrationSources, source, image: runtimePostgresImageForProfile(deploy, profile), deploy }));
|
||||
if (workbenchRedis) putJson(`${runtimePath}/workbench-redis.yaml`, workbenchRuntimeRedisManifest({ profile, config: workbenchRedis, source, deploy }));
|
||||
if (isRuntimeLane(profile)) putJson(`${runtimePath}/openfga.yaml`, v02OpenFgaManifest({ profile, source, deploy }));
|
||||
if (isRuntimeLane(profile)) putJson(`${runtimePath}/observability.yaml`, observabilityManifest({ deploy, profile, namespace, labels: profileLabels, annotations, metricsSidecarScript }));
|
||||
if (isRuntimeLane(profile)) putJson(`${runtimePath}/opencode.yaml`, opencodeServerManifest({ profile, source, deploy, catalog: artifactCatalog, registryPrefix: args.registryPrefix, useDeployImages: args.useDeployImages, sourceBranch: args.sourceBranch, gitReadUrl: args.gitReadUrl, sourceRepo: args.sourceRepo }));
|
||||
if (includeDeviceAgent) putJson(`${runtimePath}/device-agent-71-freq.yaml`, deviceAgent71FreqManifest({ profile, source, registryPrefix: args.registryPrefix, catalog: artifactCatalog, useDeployImages: args.useDeployImages }));
|
||||
|
||||
Reference in New Issue
Block a user