feat: declare HWLAB production release lane

This commit is contained in:
Codex
2026-07-15 05:15:19 +02:00
parent 407ca55c70
commit cbc175014e
7 changed files with 171 additions and 4 deletions
+98
View File
@@ -268,6 +268,101 @@ lanes:
variables:
LANE: v03
NODE: NC01
production:
extends: lanes.v03
variables:
LANE: production
NODE: NC01
environment: production
version: v0.3
sourceBranch: release
workspace: /root/hwlab-release
cicdRepo: /root/hwlab-release-cicd.git
cicdRepoLock: /tmp/hwlab-release-cicd-repo.lock
app: hwlab-node-production
pipeline: hwlab-production-ci-image-publish
pipelineRunPrefix: hwlab-production-ci-poll
serviceAccountName: hwlab-production-tekton-runner
controlPlaneFieldManager: unidesk-hwlab-production-control-plane
gitopsBranch: release-gitops
catalogPath: deploy/artifact-catalog.production.json
runtime:
path: deploy/gitops/node/runtime-production
namespace: hwlab-production
renderDir: runtime-production
tektonDir: tekton-production
argoApplicationFile: application-production.yaml
public:
webUrl: https://hwlab.pikapython.com
apiUrl: https://hwlab.pikapython.com
targets:
NC01:
environment: production
workspace: /root/hwlab-release
sourceWorkspace:
install:
stateDir: /tmp/hwlab-release-source-workspace-bootstrap
sourceAuthority:
giteaMirrorRepoKey: hwlab-nc01-production
cicdRepo: /root/hwlab-release-cicd.git
cicdRepoLock: /tmp/hwlab-release-cicd-repo.lock
app: hwlab-node-production
pipeline: hwlab-nc01-production-ci-image-publish
pipelineRunPrefix: hwlab-nc01-production-ci-poll
serviceAccountName: hwlab-nc01-production-tekton-runner
controlPlaneFieldManager: unidesk-hwlab-nc01-production-control-plane
pipelineProvenance:
configRef: config/hwlab-node-lanes.yaml#lanes.production.targets.NC01
gitopsBranch: release-gitops
catalogPath: deploy/artifact-catalog.nc01-production.json
runtime:
path: deploy/gitops/node/nc01/runtime-production
namespace: hwlab-production
renderDir: runtime-production
public:
webUrl: https://hwlab.pikapython.com
apiUrl: https://hwlab.pikapython.com
bootstrapAdmin:
displayName: HWLAB Production Admin
passwordSourceRef: hwlab/nc01-production-bootstrap-admin.env
secretName: hwlab-production-bootstrap-admin
codeAgentProvider:
secretName: hwlab-production-code-agent-provider
sourceRef: hwlab/nc01-production-code-agent-provider.env
codeAgentRuntime:
kafkaEventBridge:
configRef: config/platform-infra/kafka.yaml#clients.hwlab-production-cloud-api
clientId: hwlab-production-cloud-api
transactionalProjectorConsumerGroupId: hwlab-production-agentrun-event-projector
hwlabEventConsumerGroupId: hwlab-production-workbench-live-sse
publicExposure:
extends: templates.hwlabV03.publicExposurePk01
mode: pk01-caddy-frp
publicBaseUrl: https://hwlab.pikapython.com
hostname: hwlab.pikapython.com
expectedA: 82.156.23.220
frpc:
secretName: hwlab-production-frpc-secrets
webProxy:
remotePort: 22196
apiProxy:
remotePort: 22195
externalPostgres:
database: hwlab_nc01_production
migrationLedger:
identity: hwlab-nc01-production
table: hwlab_schema_migrations
cloudApi:
secretName: hwlab-cloud-api-production-db
sourceRef: hwlab/nc01-production-cloud-api-db.env
role: hwlab_nc01_production_app
openfga:
secretName: hwlab-production-openfga
sourceRef: hwlab/nc01-production-openfga-db.env
role: hwlab_nc01_production_app
variables:
LANE: production
NODE: NC01
networkProfiles:
node-ci-egress:
proxy:
@@ -834,6 +929,9 @@ templates:
externalPostgresConsumer:
port: 5432
sslmode: require
migrationLedger:
identity: "hwlab-${nodeLower}-${lane}"
table: hwlab_schema_migrations
cloudApi:
secretName: hwlab-cloud-api-v03-db
secretKey: database-url
+16
View File
@@ -146,6 +146,22 @@ clients:
- hwlab.event.debug.v1
dlqTopics:
- agentrun.hwlab.event.dlq.v1
- id: hwlab-production-cloud-api
namespace: hwlab-production
serviceAccountName: hwlab-cloud-api
kafkaUserName: hwlab-production-cloud-api
secretName: hwlab-production-cloud-api
produceTopics:
- hwlab.event.v1
- hwlab.event.debug.v1
- hwlab.agentrun.command.v1
consumeTopics:
- agentrun.event.v1
- agentrun.event.debug.v1
- agentrun.hwlab.event.v1
- hwlab.event.debug.v1
dlqTopics:
- agentrun.hwlab.event.dlq.v1
- id: agentrun-v02-manager
namespace: agentrun-v02
serviceAccountName: agentrun-nc01-v02-mgr
@@ -178,6 +178,22 @@ repositories:
variables:
NODE: NC01
LANE: v03
- extends: templates.repositories.hwlabV03
variables:
NODE: NC01
LANE: production
id: hwlab-nc01-production
name: hwlab-nc01-production
secretName: pac-gitea-hwlab-nc01-production
params:
source_branch: release
gitops_branch: release-gitops
source_snapshot_prefix: refs/unidesk/snapshots/gitea-actions/hwlab-node-runtime/release
pipeline_name: hwlab-nc01-production-ci-image-publish
pipeline_run_prefix: hwlab-nc01-production-ci-poll
service_account: hwlab-nc01-production-tekton-runner
lane: production
runtime_namespace: hwlab-production
- id: selfmedia-nc01
name: selfmedia-nc01
namespace: selfmedia-ci
@@ -372,6 +388,27 @@ consumers:
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
fsGroup: 1000
- extends: templates.consumers.hwlabV03
variables:
NODE: NC01
LANE: production
id: hwlab-nc01-production
repositoryRef: hwlab-nc01-production
lane: production
pipeline: hwlab-nc01-production-ci-image-publish
pipelineRunPrefix: hwlab-nc01-production-ci-poll
argoApplication: hwlab-node-production
sourceArtifact:
mode: remote-pipeline-annotation
renderer: hwlab-runtime-lane
configRef: config/hwlab-node-lanes.yaml#lanes.production.targets.NC01
pipelinePath: ci/pipelines/hwlab-nc01-production-ci-image-publish.yaml
pipelineRunPath: .tekton/hwlab-nc01-production-pac.yaml
maxKeepRuns: 8
taskRunTemplate:
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
fsGroup: 1000
- id: selfmedia-nc01
repositoryRef: selfmedia-nc01
node: NC01
+2 -2
View File
@@ -8,7 +8,7 @@ import { runCommand, type CommandResult } from "./command";
import { resolveCliChildJsonCommandResult } from "./cli-child-json-recovery";
import { resolveAgentRunLaneTarget, type AgentRunLaneSpec } from "./agentrun-lanes";
import { resolveSecretSourceRoot } from "./agentrun/secrets";
import { hwlabRuntimeLaneSpecForNode, isHwlabRuntimeLane, type HwlabRuntimeLane, type HwlabRuntimeLaneSpec } from "./hwlab-node-lanes";
import { hwlabRuntimeLaneIds, hwlabRuntimeLaneSpecForNode, isHwlabRuntimeLane, type HwlabRuntimeLane, type HwlabRuntimeLaneSpec } from "./hwlab-node-lanes";
import { parseEnvFile, sha256Fingerprint, shQuote } from "./platform-infra-ops-library";
type FakeModelProviderAction = "plan" | "materialize" | "apply" | "status" | "smoke";
@@ -149,7 +149,7 @@ function parseFakeModelProviderOptions(args: string[]): FakeModelProviderOptions
const node = requiredOption(args, "--node");
if (!/^[A-Z][A-Z0-9_-]*$/u.test(node)) throw new Error("--node must be a simple node id such as NC01");
const laneRaw = requiredOption(args, "--lane");
if (!isHwlabRuntimeLane(laneRaw)) throw new Error(`--lane must be one of v02, v03; got ${laneRaw}`);
if (!isHwlabRuntimeLane(laneRaw)) throw new Error(`--lane must be one of ${hwlabRuntimeLaneIds().join(", ")}; got ${laneRaw}`);
const provider = optionValue(args, "--provider") ?? "fake-echo";
if (!/^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/u.test(provider)) throw new Error("--provider must be a Kubernetes-safe id");
const confirm = args.includes("--confirm");
+15
View File
@@ -78,6 +78,11 @@ export interface HwlabRuntimeExternalPostgresRuntimeAccessSpec {
readonly port: number;
}
export interface HwlabRuntimeExternalPostgresMigrationLedgerSpec {
readonly identity: string;
readonly table: string;
}
export interface HwlabRuntimeExternalPostgresSpec {
readonly provider: string;
readonly configRef: string;
@@ -87,6 +92,7 @@ export interface HwlabRuntimeExternalPostgresSpec {
readonly runtimeAccess?: HwlabRuntimeExternalPostgresRuntimeAccessSpec;
readonly sslmode: "require";
readonly database: string;
readonly migrationLedger: HwlabRuntimeExternalPostgresMigrationLedgerSpec;
readonly cloudApi: HwlabRuntimeExternalPostgresComponentSpec;
readonly openfga: HwlabRuntimeExternalPostgresComponentSpec;
}
@@ -1415,6 +1421,14 @@ function externalPostgresRuntimeAccessConfig(value: unknown, path: string): Hwla
};
}
function externalPostgresMigrationLedgerConfig(value: unknown, path: string): HwlabRuntimeExternalPostgresMigrationLedgerSpec {
const raw = asRecord(value, path);
return {
identity: stringField(raw, "identity", path),
table: stringField(raw, "table", path),
};
}
function externalPostgresConfig(value: unknown, path: string): HwlabRuntimeExternalPostgresSpec | undefined {
if (value === undefined) return undefined;
const raw = asRecord(value, path);
@@ -1429,6 +1443,7 @@ function externalPostgresConfig(value: unknown, path: string): HwlabRuntimeExter
...(raw.runtimeAccess === undefined ? {} : { runtimeAccess: externalPostgresRuntimeAccessConfig(raw.runtimeAccess, `${path}.runtimeAccess`) }),
sslmode,
database: stringField(raw, "database", path),
migrationLedger: externalPostgresMigrationLedgerConfig(raw.migrationLedger, `${path}.migrationLedger`),
cloudApi: externalPostgresComponentConfig(raw.cloudApi, `${path}.cloudApi`),
openfga: externalPostgresComponentConfig(raw.openfga, `${path}.openfga`),
};
+1 -1
View File
@@ -600,7 +600,7 @@ export function parseNodeObservabilityOptions(args: string[]): NodeObservability
const node = requiredOption(args, "--node");
assertNodeId(node);
const laneRaw = requiredOption(args, "--lane");
if (!isHwlabRuntimeLane(laneRaw)) throw new Error(`--lane must be one of v02, v03; got ${laneRaw}`);
if (!isHwlabRuntimeLane(laneRaw)) throw new Error(`--lane must be one of ${hwlabRuntimeLaneIds().join(", ")}; got ${laneRaw}`);
const confirm = args.includes("--confirm");
const dryRun = args.includes("--dry-run");
if (confirm && dryRun) throw new Error("observability accepts only one of --confirm or --dry-run");
+2 -1
View File
@@ -55,7 +55,7 @@ export function parseNodeScopedDelegatedOptions(domain: DelegatedNodeDomain, arg
const node = requiredOption(args, "--node");
assertNodeId(node);
const laneRaw = requiredOption(args, "--lane");
if (!isHwlabRuntimeLane(laneRaw)) throw new Error(`--lane must be one of v02, v03; got ${laneRaw}`);
if (!isHwlabRuntimeLane(laneRaw)) throw new Error(`--lane must be one of ${hwlabRuntimeLaneIds().join(", ")}; got ${laneRaw}`);
const spec = hwlabRuntimeLaneSpecForNode(laneRaw, node);
const confirm = args.includes("--confirm");
const dryRun = args.includes("--dry-run");
@@ -201,6 +201,7 @@ export function nodeRuntimeExpected(spec: HwlabRuntimeLaneSpec): Record<string,
runtimeAccess: spec.externalPostgres.runtimeAccess ?? null,
sslmode: spec.externalPostgres.sslmode,
database: spec.externalPostgres.database,
migrationLedger: spec.externalPostgres.migrationLedger,
cloudApi: {
secretName: spec.externalPostgres.cloudApi.secretName,
secretKey: spec.externalPostgres.cloudApi.secretKey,