feat: add devops-controlled dev ci flow
This commit is contained in:
@@ -40,7 +40,8 @@ services:
|
||||
K3SCTL_NATIVE_SERVICE_URL_CODE_QUEUE: "${K3SCTL_NATIVE_SERVICE_URL_CODE_QUEUE:-}"
|
||||
K3SCTL_NATIVE_SERVICE_URL_MDTODO: "${K3SCTL_NATIVE_SERVICE_URL_MDTODO:-}"
|
||||
K3SCTL_NATIVE_SERVICE_URL_DECISION_CENTER: "${K3SCTL_NATIVE_SERVICE_URL_DECISION_CENTER:-}"
|
||||
K3SCTL_MANIFEST_PATHS: "${K3SCTL_MANIFEST_PATHS:-k3s/code-queue.k3s.json,k3s/mdtodo.k3s.json,k3s/claudeqq.k3s.json,k3s/decision-center.k3s.json}"
|
||||
K3SCTL_NATIVE_SERVICE_URL_DEVOPS: "${K3SCTL_NATIVE_SERVICE_URL_DEVOPS:-}"
|
||||
K3SCTL_MANIFEST_PATHS: "${K3SCTL_MANIFEST_PATHS:-k3s/code-queue.k3s.json,k3s/mdtodo.k3s.json,k3s/claudeqq.k3s.json,k3s/decision-center.k3s.json,k3s/devops.k3s.json}"
|
||||
K3SCTL_SERVICES_JSON: "${K3SCTL_SERVICES_JSON:-[]}"
|
||||
UNIDESK_LOG_RETENTION_BYTES: "${UNIDESK_LOG_RETENTION_BYTES:-512MiB}"
|
||||
volumes:
|
||||
|
||||
@@ -77,6 +77,40 @@ roleRef:
|
||||
name: unidesk-ci-trigger-reader
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: unidesk-ci-dev-e2e-manager
|
||||
labels:
|
||||
app.kubernetes.io/name: unidesk-ci
|
||||
app.kubernetes.io/part-of: unidesk
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["namespaces"]
|
||||
verbs: ["get", "list", "watch", "create", "delete", "patch"]
|
||||
- apiGroups: [""]
|
||||
resources: ["configmaps", "services", "pods", "pods/log"]
|
||||
verbs: ["get", "list", "watch", "create", "delete", "patch"]
|
||||
- apiGroups: ["apps"]
|
||||
resources: ["deployments"]
|
||||
verbs: ["get", "list", "watch", "create", "delete", "patch"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: unidesk-ci-dev-e2e-manager
|
||||
labels:
|
||||
app.kubernetes.io/name: unidesk-ci
|
||||
app.kubernetes.io/part-of: unidesk
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: unidesk-ci-runner
|
||||
namespace: unidesk-ci
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: unidesk-ci-dev-e2e-manager
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: unidesk-ci-cross-namespace
|
||||
@@ -146,7 +180,7 @@ spec:
|
||||
type: string
|
||||
- name: image
|
||||
type: string
|
||||
default: unidesk-code-queue:d601
|
||||
default: unidesk-code-queue:dev
|
||||
workspaces:
|
||||
- name: source
|
||||
volumes:
|
||||
@@ -185,6 +219,7 @@ spec:
|
||||
git rev-parse HEAD | tee "$(workspaces.source.path)/commit.txt"
|
||||
- name: install-and-check
|
||||
image: "$(params.image)"
|
||||
imagePullPolicy: Never
|
||||
env:
|
||||
- name: DOCKER_HOST
|
||||
value: unix:///var/run/docker.sock
|
||||
@@ -235,12 +270,13 @@ spec:
|
||||
type: string
|
||||
- name: app-image
|
||||
type: string
|
||||
default: unidesk-code-queue:d601
|
||||
default: unidesk-code-queue:dev
|
||||
workspaces:
|
||||
- name: source
|
||||
steps:
|
||||
- name: start-read-service
|
||||
image: "$(params.app-image)"
|
||||
imagePullPolicy: Never
|
||||
env:
|
||||
- name: HTTP_PROXY
|
||||
value: ""
|
||||
@@ -499,6 +535,7 @@ spec:
|
||||
exit 1
|
||||
- name: measure
|
||||
image: "$(params.app-image)"
|
||||
imagePullPolicy: Never
|
||||
workingDir: "$(workspaces.source.path)/repo"
|
||||
env:
|
||||
- name: CI_CODE_QUEUE_URL
|
||||
@@ -550,6 +587,7 @@ spec:
|
||||
bun scripts/ci-code-queue-read-perf.ts
|
||||
- name: cleanup
|
||||
image: "$(params.app-image)"
|
||||
imagePullPolicy: Never
|
||||
env:
|
||||
- name: HTTP_PROXY
|
||||
value: ""
|
||||
@@ -588,6 +626,408 @@ spec:
|
||||
delete_resource "api/v1/namespaces/$kube_namespace/services/code-queue-ci-read"
|
||||
---
|
||||
apiVersion: tekton.dev/v1
|
||||
kind: Task
|
||||
metadata:
|
||||
name: unidesk-dev-namespace-e2e
|
||||
namespace: unidesk-ci
|
||||
labels:
|
||||
app.kubernetes.io/name: unidesk-ci
|
||||
app.kubernetes.io/component: dev-namespace-e2e
|
||||
spec:
|
||||
params:
|
||||
- name: repo-url
|
||||
type: string
|
||||
default: https://github.com/pikasTech/unidesk
|
||||
- name: desired-ref
|
||||
type: string
|
||||
default: master
|
||||
- name: deploy-commit
|
||||
type: string
|
||||
- name: environment
|
||||
type: string
|
||||
default: dev
|
||||
- name: run-id
|
||||
type: string
|
||||
- name: keep-namespace
|
||||
type: string
|
||||
default: "false"
|
||||
- name: app-image
|
||||
type: string
|
||||
default: unidesk-code-queue:dev
|
||||
workspaces:
|
||||
- name: source
|
||||
steps:
|
||||
- name: clone-deploy-manifest
|
||||
image: alpine/git:2.45.2
|
||||
env:
|
||||
- name: HTTP_PROXY
|
||||
value: "http://d601-provider-egress-proxy.unidesk.svc.cluster.local:18789"
|
||||
- name: HTTPS_PROXY
|
||||
value: "http://d601-provider-egress-proxy.unidesk.svc.cluster.local:18789"
|
||||
- name: ALL_PROXY
|
||||
value: "http://d601-provider-egress-proxy.unidesk.svc.cluster.local:18789"
|
||||
- name: NO_PROXY
|
||||
value: "localhost,127.0.0.1,::1,d601-provider-egress-proxy,d601-provider-egress-proxy.unidesk,d601-provider-egress-proxy.unidesk.svc,d601-provider-egress-proxy.unidesk.svc.cluster.local"
|
||||
- name: http_proxy
|
||||
value: "http://d601-provider-egress-proxy.unidesk.svc.cluster.local:18789"
|
||||
- name: https_proxy
|
||||
value: "http://d601-provider-egress-proxy.unidesk.svc.cluster.local:18789"
|
||||
- name: all_proxy
|
||||
value: "http://d601-provider-egress-proxy.unidesk.svc.cluster.local:18789"
|
||||
- name: no_proxy
|
||||
value: "localhost,127.0.0.1,::1,d601-provider-egress-proxy,d601-provider-egress-proxy.unidesk,d601-provider-egress-proxy.unidesk.svc,d601-provider-egress-proxy.unidesk.svc.cluster.local"
|
||||
script: |
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
run_dir="$(workspaces.source.path)/dev-e2e-$(params.run-id)"
|
||||
rm -rf "$run_dir"
|
||||
mkdir -p "$run_dir"
|
||||
git clone --filter=blob:none --no-checkout "$(params.repo-url)" "$run_dir/repo"
|
||||
cd "$run_dir/repo"
|
||||
git fetch --depth=1 origin "$(params.desired-ref)"
|
||||
actual="$(git rev-parse FETCH_HEAD)"
|
||||
expected="$(params.deploy-commit)"
|
||||
if [ "$actual" != "$expected" ]; then
|
||||
echo "desired ref commit mismatch actual=$actual expected=$expected" >&2
|
||||
exit 1
|
||||
fi
|
||||
git show FETCH_HEAD:deploy.json >"$run_dir/deploy.json"
|
||||
printf '%s\n' "$actual" >"$run_dir/deploy-commit.txt"
|
||||
- name: namespace-smoke-e2e
|
||||
image: "$(params.app-image)"
|
||||
imagePullPolicy: Never
|
||||
env:
|
||||
- name: HTTP_PROXY
|
||||
value: ""
|
||||
- name: HTTPS_PROXY
|
||||
value: ""
|
||||
- name: ALL_PROXY
|
||||
value: ""
|
||||
- name: NO_PROXY
|
||||
value: "localhost,127.0.0.1,::1,kubernetes,kubernetes.default,kubernetes.default.svc,kubernetes.default.svc.cluster.local"
|
||||
- name: http_proxy
|
||||
value: ""
|
||||
- name: https_proxy
|
||||
value: ""
|
||||
- name: all_proxy
|
||||
value: ""
|
||||
- name: no_proxy
|
||||
value: "localhost,127.0.0.1,::1,kubernetes,kubernetes.default,kubernetes.default.svc,kubernetes.default.svc.cluster.local"
|
||||
script: |
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
ns="unidesk-ci-e2e-$(params.run-id)"
|
||||
keep="$(params.keep-namespace)"
|
||||
run_dir="$(workspaces.source.path)/dev-e2e-$(params.run-id)"
|
||||
deploy_json="$run_dir/deploy.json"
|
||||
result_json="$run_dir/dev-e2e-result.json"
|
||||
kube_api="https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT_HTTPS}"
|
||||
kube_token="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
|
||||
kube_ca="/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
|
||||
kube() {
|
||||
local method="$1"
|
||||
shift
|
||||
curl -fsS --cacert "$kube_ca" -H "Authorization: Bearer $kube_token" -X "$method" "$@"
|
||||
}
|
||||
delete_path() {
|
||||
local path="$1"
|
||||
local code
|
||||
code="$(curl -sS -o /tmp/unidesk-dev-e2e-delete-response -w "%{http_code}" --cacert "$kube_ca" -H "Authorization: Bearer $kube_token" -X DELETE "$kube_api/$path")"
|
||||
if [ "$code" = "200" ] || [ "$code" = "202" ] || [ "$code" = "404" ]; then
|
||||
return 0
|
||||
fi
|
||||
cat /tmp/unidesk-dev-e2e-delete-response >&2
|
||||
return 1
|
||||
}
|
||||
cleanup() {
|
||||
if [ "$keep" = "true" ]; then
|
||||
echo "dev_e2e_namespace_retained=$ns"
|
||||
return 0
|
||||
fi
|
||||
delete_path "api/v1/namespaces/$ns" || true
|
||||
echo "dev_e2e_namespace_deleted=$ns"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
bun - "$deploy_json" "$run_dir/dev-e2e-service-commits.env" "$(params.environment)" <<'BUN'
|
||||
const [deployPath, outPath, environment] = process.argv.slice(2);
|
||||
const manifest = await Bun.file(deployPath).json();
|
||||
if (!manifest || manifest.schemaVersion !== 2 || !manifest.environments?.[environment]) {
|
||||
throw new Error(`deploy.json must contain schemaVersion=2 environments.${environment}`);
|
||||
}
|
||||
const services = manifest.environments[environment].services;
|
||||
if (!Array.isArray(services) || services.length === 0) {
|
||||
throw new Error(`deploy.json environments.${environment}.services must contain services`);
|
||||
}
|
||||
const lines = [];
|
||||
for (const service of services) {
|
||||
if (!service?.id || !service?.commitId || !service?.repo) {
|
||||
throw new Error(`each deploy.json environments.${environment} service must contain id, repo and commitId`);
|
||||
}
|
||||
const key = String(service.id).toUpperCase().replace(/[^A-Z0-9]/g, "_");
|
||||
lines.push(`${key}_COMMIT=${service.commitId}`);
|
||||
}
|
||||
await Bun.write(outPath, lines.join("\n") + "\n");
|
||||
console.log(JSON.stringify({ ok: true, environment, services: services.map((service) => ({ id: service.id, commitId: service.commitId })) }));
|
||||
BUN
|
||||
# shellcheck disable=SC1091
|
||||
source "$run_dir/dev-e2e-service-commits.env"
|
||||
backend_commit="${BACKEND_CORE_COMMIT:-unknown}"
|
||||
frontend_commit="${FRONTEND_COMMIT:-unknown}"
|
||||
code_queue_commit="${CODE_QUEUE_COMMIT:-unknown}"
|
||||
|
||||
delete_path "api/v1/namespaces/$ns"
|
||||
cat >/tmp/dev-e2e-namespace.yaml <<YAML
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: $ns
|
||||
labels:
|
||||
app.kubernetes.io/part-of: unidesk
|
||||
unidesk.ai/purpose: ci-dev-e2e
|
||||
unidesk.ai/deploy-ref: master-deploy-json-dev
|
||||
YAML
|
||||
kube PATCH \
|
||||
-H "Content-Type: application/apply-patch+yaml" \
|
||||
--data-binary @/tmp/dev-e2e-namespace.yaml \
|
||||
"$kube_api/api/v1/namespaces/$ns?fieldManager=unidesk-ci&force=true" >/dev/null
|
||||
|
||||
deploy_json_b64="$(base64 -w0 "$deploy_json")"
|
||||
cat >/tmp/dev-e2e-configmap.yaml <<YAML
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: desired-manifest
|
||||
namespace: $ns
|
||||
labels:
|
||||
app.kubernetes.io/name: unidesk-dev-namespace-e2e
|
||||
app.kubernetes.io/part-of: unidesk
|
||||
data:
|
||||
deployCommit: "$(params.deploy-commit)"
|
||||
environment: "$(params.environment)"
|
||||
backendCoreCommit: "$backend_commit"
|
||||
frontendCommit: "$frontend_commit"
|
||||
codeQueueCommit: "$code_queue_commit"
|
||||
deploy.json.b64: "$deploy_json_b64"
|
||||
YAML
|
||||
kube PATCH \
|
||||
-H "Content-Type: application/apply-patch+yaml" \
|
||||
--data-binary @/tmp/dev-e2e-configmap.yaml \
|
||||
"$kube_api/api/v1/namespaces/$ns/configmaps/desired-manifest?fieldManager=unidesk-ci&force=true" >/dev/null
|
||||
|
||||
cat >/tmp/dev-e2e-target.yaml <<YAML
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: dev-e2e-target
|
||||
namespace: $ns
|
||||
labels:
|
||||
app.kubernetes.io/name: unidesk-dev-namespace-e2e
|
||||
app.kubernetes.io/component: smoke-target
|
||||
app.kubernetes.io/part-of: unidesk
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: unidesk-dev-namespace-e2e
|
||||
app.kubernetes.io/component: smoke-target
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: unidesk-dev-namespace-e2e
|
||||
app.kubernetes.io/component: smoke-target
|
||||
app.kubernetes.io/part-of: unidesk
|
||||
spec:
|
||||
nodeSelector:
|
||||
unidesk.ai/node-id: D601
|
||||
terminationGracePeriodSeconds: 5
|
||||
containers:
|
||||
- name: smoke-target
|
||||
image: "$(params.app-image)"
|
||||
imagePullPolicy: Never
|
||||
command:
|
||||
- bun
|
||||
- -e
|
||||
- |
|
||||
const port = Number(process.env.PORT || 8080);
|
||||
const payload = {
|
||||
ok: true,
|
||||
environment: "dev",
|
||||
namespace: process.env.CI_E2E_NAMESPACE,
|
||||
deployCommit: process.env.CI_E2E_DEPLOY_COMMIT,
|
||||
backendCoreCommit: process.env.BACKEND_CORE_COMMIT,
|
||||
frontendCommit: process.env.FRONTEND_COMMIT,
|
||||
codeQueueCommit: process.env.CODE_QUEUE_COMMIT
|
||||
};
|
||||
Bun.serve({
|
||||
hostname: "0.0.0.0",
|
||||
port,
|
||||
fetch(req) {
|
||||
const url = new URL(req.url);
|
||||
if (url.pathname === "/health" || url.pathname === "/") {
|
||||
return Response.json(payload);
|
||||
}
|
||||
return new Response("not found", { status: 404 });
|
||||
}
|
||||
});
|
||||
console.log(JSON.stringify({ listening: port, ...payload }));
|
||||
await new Promise(() => {});
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
env:
|
||||
- name: PORT
|
||||
value: "8080"
|
||||
- name: CI_E2E_NAMESPACE
|
||||
value: "$ns"
|
||||
- name: CI_E2E_DEPLOY_COMMIT
|
||||
value: "$(params.deploy-commit)"
|
||||
- name: BACKEND_CORE_COMMIT
|
||||
value: "$backend_commit"
|
||||
- name: FRONTEND_COMMIT
|
||||
value: "$frontend_commit"
|
||||
- name: CODE_QUEUE_COMMIT
|
||||
value: "$code_queue_commit"
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: http
|
||||
periodSeconds: 3
|
||||
timeoutSeconds: 2
|
||||
failureThreshold: 20
|
||||
resources:
|
||||
requests:
|
||||
cpu: 20m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
memory: 256Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: dev-e2e-target
|
||||
namespace: $ns
|
||||
labels:
|
||||
app.kubernetes.io/name: unidesk-dev-namespace-e2e
|
||||
app.kubernetes.io/component: smoke-target
|
||||
app.kubernetes.io/part-of: unidesk
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app.kubernetes.io/name: unidesk-dev-namespace-e2e
|
||||
app.kubernetes.io/component: smoke-target
|
||||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: http
|
||||
YAML
|
||||
csplit -s -f /tmp/dev-e2e-target- /tmp/dev-e2e-target.yaml '/^---$/' '{*}'
|
||||
kube PATCH \
|
||||
-H "Content-Type: application/apply-patch+yaml" \
|
||||
--data-binary @/tmp/dev-e2e-target-00 \
|
||||
"$kube_api/apis/apps/v1/namespaces/$ns/deployments/dev-e2e-target?fieldManager=unidesk-ci&force=true" >/dev/null
|
||||
kube PATCH \
|
||||
-H "Content-Type: application/apply-patch+yaml" \
|
||||
--data-binary @/tmp/dev-e2e-target-01 \
|
||||
"$kube_api/api/v1/namespaces/$ns/services/dev-e2e-target?fieldManager=unidesk-ci&force=true" >/dev/null
|
||||
|
||||
deadline=$((SECONDS + 180))
|
||||
while [ "$SECONDS" -lt "$deadline" ]; do
|
||||
status="$(kube GET "$kube_api/apis/apps/v1/namespaces/$ns/deployments/dev-e2e-target")"
|
||||
available="$(printf '%s' "$status" | jq -r '.status.availableReplicas // 0')"
|
||||
observed="$(printf '%s' "$status" | jq -r '.status.observedGeneration // 0')"
|
||||
generation="$(printf '%s' "$status" | jq -r '.metadata.generation // 0')"
|
||||
if [ "$available" -ge 1 ] && [ "$observed" -ge "$generation" ]; then
|
||||
echo "dev_e2e_target_rollout=available namespace=$ns"
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
if [ "$SECONDS" -ge "$deadline" ]; then
|
||||
echo "dev_e2e_target_rollout=timeout namespace=$ns" >&2
|
||||
kube GET "$kube_api/apis/apps/v1/namespaces/$ns/deployments/dev-e2e-target" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
bun - "$ns" "$(params.deploy-commit)" "$backend_commit" "$frontend_commit" "$code_queue_commit" "$result_json" <<'BUN'
|
||||
const [ns, deployCommit, backendCommit, frontendCommit, codeQueueCommit, resultPath] = process.argv.slice(2);
|
||||
const url = `http://dev-e2e-target.${ns}.svc.cluster.local:8080/health`;
|
||||
const started = performance.now();
|
||||
const response = await fetch(url);
|
||||
const elapsedMs = Math.round(performance.now() - started);
|
||||
const body = await response.json();
|
||||
const checks = [
|
||||
response.ok,
|
||||
body.ok === true,
|
||||
body.environment === "dev",
|
||||
body.namespace === ns,
|
||||
body.deployCommit === deployCommit,
|
||||
body.backendCoreCommit === backendCommit,
|
||||
body.frontendCommit === frontendCommit,
|
||||
body.codeQueueCommit === codeQueueCommit
|
||||
];
|
||||
const result = { ok: checks.every(Boolean), elapsedMs, url, body };
|
||||
await Bun.write(resultPath, JSON.stringify(result, null, 2) + "\n");
|
||||
console.log(JSON.stringify(result));
|
||||
if (!result.ok) process.exit(1);
|
||||
BUN
|
||||
---
|
||||
apiVersion: tekton.dev/v1
|
||||
kind: Pipeline
|
||||
metadata:
|
||||
name: unidesk-dev-namespace-e2e
|
||||
namespace: unidesk-ci
|
||||
labels:
|
||||
app.kubernetes.io/name: unidesk-ci
|
||||
app.kubernetes.io/component: dev-namespace-e2e
|
||||
app.kubernetes.io/part-of: unidesk
|
||||
spec:
|
||||
params:
|
||||
- name: repo-url
|
||||
type: string
|
||||
default: https://github.com/pikasTech/unidesk
|
||||
- name: desired-ref
|
||||
type: string
|
||||
default: master
|
||||
- name: deploy-commit
|
||||
type: string
|
||||
- name: environment
|
||||
type: string
|
||||
default: dev
|
||||
- name: run-id
|
||||
type: string
|
||||
- name: keep-namespace
|
||||
type: string
|
||||
default: "false"
|
||||
- name: app-image
|
||||
type: string
|
||||
default: unidesk-code-queue:dev
|
||||
workspaces:
|
||||
- name: shared-workspace
|
||||
tasks:
|
||||
- name: dev-namespace-e2e
|
||||
taskRef:
|
||||
name: unidesk-dev-namespace-e2e
|
||||
params:
|
||||
- name: repo-url
|
||||
value: "$(params.repo-url)"
|
||||
- name: desired-ref
|
||||
value: "$(params.desired-ref)"
|
||||
- name: deploy-commit
|
||||
value: "$(params.deploy-commit)"
|
||||
- name: environment
|
||||
value: "$(params.environment)"
|
||||
- name: run-id
|
||||
value: "$(params.run-id)"
|
||||
- name: keep-namespace
|
||||
value: "$(params.keep-namespace)"
|
||||
- name: app-image
|
||||
value: "$(params.app-image)"
|
||||
workspaces:
|
||||
- name: source
|
||||
workspace: shared-workspace
|
||||
---
|
||||
apiVersion: tekton.dev/v1
|
||||
kind: Pipeline
|
||||
metadata:
|
||||
name: unidesk-ci
|
||||
@@ -604,10 +1044,10 @@ spec:
|
||||
type: string
|
||||
- name: check-image
|
||||
type: string
|
||||
default: unidesk-code-queue:d601
|
||||
default: unidesk-code-queue:dev
|
||||
- name: code-queue-image
|
||||
type: string
|
||||
default: unidesk-code-queue:d601
|
||||
default: unidesk-code-queue:dev
|
||||
workspaces:
|
||||
- name: shared-workspace
|
||||
tasks:
|
||||
|
||||
+22
-22
@@ -155,8 +155,8 @@ metadata:
|
||||
unidesk.ai/deployment-mode: k3sctl-managed
|
||||
unidesk.ai/deploy-service-id: code-queue
|
||||
annotations:
|
||||
unidesk.ai/deploy-ref: origin/deploy/dev
|
||||
unidesk.ai/image-source: deploy-dev-commit
|
||||
unidesk.ai/deploy-ref: origin/master:deploy.json#environments.dev
|
||||
unidesk.ai/image-source: deploy-env-commit
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
@@ -205,9 +205,9 @@ spec:
|
||||
- name: UNIDESK_DEPLOY_REPO
|
||||
value: https://github.com/pikasTech/unidesk
|
||||
- name: UNIDESK_DEPLOY_COMMIT
|
||||
value: replace-with-deploy-dev-commit
|
||||
value: replace-with-deploy-env-commit
|
||||
- name: UNIDESK_DEPLOY_REQUESTED_COMMIT
|
||||
value: replace-with-deploy-dev-commit
|
||||
value: replace-with-deploy-env-commit
|
||||
volumeMounts:
|
||||
- name: script
|
||||
mountPath: /etc/unidesk-provider-egress
|
||||
@@ -250,8 +250,8 @@ metadata:
|
||||
unidesk.ai/deployment-mode: k3sctl-managed
|
||||
unidesk.ai/deploy-service-id: code-queue
|
||||
annotations:
|
||||
unidesk.ai/deploy-ref: origin/deploy/dev
|
||||
unidesk.ai/image-source: deploy-dev-commit
|
||||
unidesk.ai/deploy-ref: origin/master:deploy.json#environments.dev
|
||||
unidesk.ai/image-source: deploy-env-commit
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
@@ -306,13 +306,13 @@ spec:
|
||||
- name: UNIDESK_DEPLOY_REPO
|
||||
value: https://github.com/pikasTech/unidesk
|
||||
- name: UNIDESK_DEPLOY_COMMIT
|
||||
value: replace-with-deploy-dev-commit
|
||||
value: replace-with-deploy-env-commit
|
||||
- name: UNIDESK_DEPLOY_REQUESTED_COMMIT
|
||||
value: replace-with-deploy-dev-commit
|
||||
value: replace-with-deploy-env-commit
|
||||
- name: CODE_QUEUE_DEPLOY_COMMIT
|
||||
value: replace-with-deploy-dev-commit
|
||||
value: replace-with-deploy-env-commit
|
||||
- name: CODE_QUEUE_DEPLOY_REQUESTED_COMMIT
|
||||
value: replace-with-deploy-dev-commit
|
||||
value: replace-with-deploy-env-commit
|
||||
- name: CODE_QUEUE_INSTANCE_ID
|
||||
value: D601-dev
|
||||
- name: CODE_QUEUE_SERVICE_ROLE
|
||||
@@ -460,8 +460,8 @@ metadata:
|
||||
unidesk.ai/deployment-mode: k3sctl-managed
|
||||
unidesk.ai/deploy-service-id: code-queue
|
||||
annotations:
|
||||
unidesk.ai/deploy-ref: origin/deploy/dev
|
||||
unidesk.ai/image-source: deploy-dev-commit
|
||||
unidesk.ai/deploy-ref: origin/master:deploy.json#environments.dev
|
||||
unidesk.ai/image-source: deploy-env-commit
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
@@ -514,13 +514,13 @@ spec:
|
||||
- name: UNIDESK_DEPLOY_REPO
|
||||
value: https://github.com/pikasTech/unidesk
|
||||
- name: UNIDESK_DEPLOY_COMMIT
|
||||
value: replace-with-deploy-dev-commit
|
||||
value: replace-with-deploy-env-commit
|
||||
- name: UNIDESK_DEPLOY_REQUESTED_COMMIT
|
||||
value: replace-with-deploy-dev-commit
|
||||
value: replace-with-deploy-env-commit
|
||||
- name: CODE_QUEUE_DEPLOY_COMMIT
|
||||
value: replace-with-deploy-dev-commit
|
||||
value: replace-with-deploy-env-commit
|
||||
- name: CODE_QUEUE_DEPLOY_REQUESTED_COMMIT
|
||||
value: replace-with-deploy-dev-commit
|
||||
value: replace-with-deploy-env-commit
|
||||
- name: CODE_QUEUE_INSTANCE_ID
|
||||
value: D601-dev-read
|
||||
- name: CODE_QUEUE_SERVICE_ROLE
|
||||
@@ -603,8 +603,8 @@ metadata:
|
||||
unidesk.ai/deployment-mode: k3sctl-managed
|
||||
unidesk.ai/deploy-service-id: code-queue
|
||||
annotations:
|
||||
unidesk.ai/deploy-ref: origin/deploy/dev
|
||||
unidesk.ai/image-source: deploy-dev-commit
|
||||
unidesk.ai/deploy-ref: origin/master:deploy.json#environments.dev
|
||||
unidesk.ai/image-source: deploy-env-commit
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
@@ -657,13 +657,13 @@ spec:
|
||||
- name: UNIDESK_DEPLOY_REPO
|
||||
value: https://github.com/pikasTech/unidesk
|
||||
- name: UNIDESK_DEPLOY_COMMIT
|
||||
value: replace-with-deploy-dev-commit
|
||||
value: replace-with-deploy-env-commit
|
||||
- name: UNIDESK_DEPLOY_REQUESTED_COMMIT
|
||||
value: replace-with-deploy-dev-commit
|
||||
value: replace-with-deploy-env-commit
|
||||
- name: CODE_QUEUE_DEPLOY_COMMIT
|
||||
value: replace-with-deploy-dev-commit
|
||||
value: replace-with-deploy-env-commit
|
||||
- name: CODE_QUEUE_DEPLOY_REQUESTED_COMMIT
|
||||
value: replace-with-deploy-dev-commit
|
||||
value: replace-with-deploy-env-commit
|
||||
- name: CODE_QUEUE_INSTANCE_ID
|
||||
value: D601-dev-write
|
||||
- name: CODE_QUEUE_SERVICE_ROLE
|
||||
|
||||
@@ -32,8 +32,8 @@ metadata:
|
||||
app.kubernetes.io/part-of: unidesk
|
||||
unidesk.ai/environment: dev
|
||||
annotations:
|
||||
unidesk.ai/deploy-ref: origin/deploy/dev
|
||||
unidesk.ai/image-source: deploy-dev-commit
|
||||
unidesk.ai/deploy-ref: origin/master:deploy.json#environments.dev
|
||||
unidesk.ai/image-source: deploy-env-commit
|
||||
unidesk.ai/deploy-service-id: backend-core
|
||||
spec:
|
||||
replicas: 1
|
||||
@@ -105,9 +105,9 @@ spec:
|
||||
- name: UNIDESK_DEPLOY_REPO
|
||||
value: https://github.com/pikasTech/unidesk
|
||||
- name: UNIDESK_DEPLOY_COMMIT
|
||||
value: replace-with-deploy-dev-commit
|
||||
value: replace-with-deploy-env-commit
|
||||
- name: UNIDESK_DEPLOY_REQUESTED_COMMIT
|
||||
value: replace-with-deploy-dev-commit
|
||||
value: replace-with-deploy-env-commit
|
||||
- name: LOG_FILE
|
||||
value: /var/log/unidesk-dev/backend-core-dev.jsonl
|
||||
volumeMounts:
|
||||
@@ -175,8 +175,8 @@ metadata:
|
||||
app.kubernetes.io/part-of: unidesk
|
||||
unidesk.ai/environment: dev
|
||||
annotations:
|
||||
unidesk.ai/deploy-ref: origin/deploy/dev
|
||||
unidesk.ai/image-source: deploy-dev-commit
|
||||
unidesk.ai/deploy-ref: origin/master:deploy.json#environments.dev
|
||||
unidesk.ai/image-source: deploy-env-commit
|
||||
unidesk.ai/deploy-service-id: frontend
|
||||
spec:
|
||||
replicas: 1
|
||||
@@ -250,9 +250,9 @@ spec:
|
||||
- name: UNIDESK_DEPLOY_REPO
|
||||
value: https://github.com/pikasTech/unidesk
|
||||
- name: UNIDESK_DEPLOY_COMMIT
|
||||
value: replace-with-deploy-dev-commit
|
||||
value: replace-with-deploy-env-commit
|
||||
- name: UNIDESK_DEPLOY_REQUESTED_COMMIT
|
||||
value: replace-with-deploy-dev-commit
|
||||
value: replace-with-deploy-env-commit
|
||||
- name: LOG_FILE
|
||||
value: /var/log/unidesk-dev/frontend-dev.jsonl
|
||||
volumeMounts:
|
||||
|
||||
@@ -82,7 +82,7 @@ metadata:
|
||||
data:
|
||||
UNIDESK_ENV: dev
|
||||
UNIDESK_NAMESPACE: unidesk-dev
|
||||
UNIDESK_DEPLOY_REF: origin/deploy/dev
|
||||
UNIDESK_DEPLOY_REF: origin/master:deploy.json#environments.dev
|
||||
UNIDESK_PROVIDER_ID: D601-dev
|
||||
UNIDESK_NODE_ID: D601
|
||||
UNIDESK_DEV_DATABASE_NAME: unidesk_dev
|
||||
@@ -177,7 +177,7 @@ data:
|
||||
('namespace', 'unidesk-dev', now()),
|
||||
('database', 'unidesk_dev', now()),
|
||||
('provider_id', 'D601-dev', now()),
|
||||
('deploy_ref', 'origin/deploy/dev', now())
|
||||
('deploy_ref', 'origin/master:deploy.json#environments.dev', now())
|
||||
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = now();
|
||||
|
||||
CREATE TABLE IF NOT EXISTS unidesk_nodes (
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"apiVersion": "unidesk.ai/k3s/v1",
|
||||
"kind": "ManagedKubernetesService",
|
||||
"metadata": {
|
||||
"name": "devops",
|
||||
"namespace": "unidesk-ci"
|
||||
},
|
||||
"spec": {
|
||||
"adapterServiceId": "k3sctl-adapter",
|
||||
"controlPlane": {
|
||||
"type": "kubernetes",
|
||||
"cluster": "unidesk-k3s",
|
||||
"context": "unidesk-k3s"
|
||||
},
|
||||
"route": {
|
||||
"kind": "kubernetes-service",
|
||||
"serviceName": "devops",
|
||||
"servicePort": 4286
|
||||
},
|
||||
"activeInstanceId": "D601",
|
||||
"singleWriter": true,
|
||||
"expectedNodeIds": [
|
||||
"D601"
|
||||
],
|
||||
"instances": [
|
||||
{
|
||||
"id": "D601",
|
||||
"nodeId": "D601",
|
||||
"role": "primary",
|
||||
"baseUrl": "kubernetes://unidesk-ci/services/devops:4286",
|
||||
"healthPath": "/health",
|
||||
"healthMode": "service-proxy"
|
||||
}
|
||||
],
|
||||
"requireAllInstancesHealthy": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: devops
|
||||
namespace: unidesk-ci
|
||||
labels:
|
||||
app.kubernetes.io/name: devops
|
||||
app.kubernetes.io/part-of: unidesk
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: devops
|
||||
namespace: unidesk-ci
|
||||
labels:
|
||||
app.kubernetes.io/name: devops
|
||||
app.kubernetes.io/part-of: unidesk
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods/log"]
|
||||
verbs: ["get", "list"]
|
||||
- apiGroups: ["tekton.dev"]
|
||||
resources: ["pipelines", "tasks", "taskruns"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
- apiGroups: ["tekton.dev"]
|
||||
resources: ["pipelineruns"]
|
||||
verbs: ["get", "list", "watch", "create"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: devops
|
||||
namespace: unidesk-ci
|
||||
labels:
|
||||
app.kubernetes.io/name: devops
|
||||
app.kubernetes.io/part-of: unidesk
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: devops
|
||||
namespace: unidesk-ci
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: devops
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: devops
|
||||
namespace: unidesk-ci
|
||||
labels:
|
||||
app.kubernetes.io/name: devops
|
||||
app.kubernetes.io/part-of: unidesk
|
||||
unidesk.ai/deployment-mode: k3sctl-managed
|
||||
unidesk.ai/instance-id: D601
|
||||
unidesk.ai/deploy-service-id: devops
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: devops
|
||||
unidesk.ai/instance-id: D601
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: devops
|
||||
app.kubernetes.io/part-of: unidesk
|
||||
unidesk.ai/deployment-mode: k3sctl-managed
|
||||
unidesk.ai/instance-id: D601
|
||||
unidesk.ai/node-id: D601
|
||||
unidesk.ai/deploy-service-id: devops
|
||||
annotations:
|
||||
unidesk.ai/deploy-service-id: devops
|
||||
unidesk.ai/deploy-repo: https://github.com/pikasTech/unidesk
|
||||
unidesk.ai/deploy-commit: replace-with-deploy-env-commit
|
||||
unidesk.ai/deploy-requested-commit: replace-with-deploy-env-commit
|
||||
spec:
|
||||
serviceAccountName: devops
|
||||
nodeSelector:
|
||||
unidesk.ai/node-id: D601
|
||||
terminationGracePeriodSeconds: 10
|
||||
containers:
|
||||
- name: devops
|
||||
image: unidesk-devops:dev-placeholder
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 4286
|
||||
env:
|
||||
- name: HOST
|
||||
value: "0.0.0.0"
|
||||
- name: PORT
|
||||
value: "4286"
|
||||
- name: DEVOPS_NAMESPACE
|
||||
value: "unidesk-ci"
|
||||
- name: DEVOPS_REPO_URL
|
||||
value: "https://github.com/pikasTech/unidesk"
|
||||
- name: DEVOPS_DESIRED_REF
|
||||
value: "master"
|
||||
- name: DEVOPS_ENVIRONMENT
|
||||
value: "dev"
|
||||
- name: UNIDESK_DEPLOY_SERVICE_ID
|
||||
value: "devops"
|
||||
- name: UNIDESK_DEPLOY_REPO
|
||||
value: "https://github.com/pikasTech/unidesk"
|
||||
- name: UNIDESK_DEPLOY_COMMIT
|
||||
value: replace-with-deploy-env-commit
|
||||
- name: UNIDESK_DEPLOY_REQUESTED_COMMIT
|
||||
value: replace-with-deploy-env-commit
|
||||
- name: DEVOPS_GIT_PROXY_URL
|
||||
value: "http://d601-provider-egress-proxy.unidesk.svc.cluster.local:18789"
|
||||
- name: DEVOPS_DEV_E2E_PIPELINE
|
||||
value: "unidesk-dev-namespace-e2e"
|
||||
- name: DEVOPS_PIPELINE_SERVICE_ACCOUNT
|
||||
value: "unidesk-ci-runner"
|
||||
- name: DEVOPS_PIPELINE_WORKSPACE_CLAIM
|
||||
value: "unidesk-ci-cache"
|
||||
- name: DEVOPS_DEV_E2E_APP_IMAGE
|
||||
value: "unidesk-code-queue:dev"
|
||||
- name: LOG_FILE
|
||||
value: "/var/log/unidesk/devops.jsonl"
|
||||
volumeMounts:
|
||||
- name: logs
|
||||
mountPath: /var/log/unidesk
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: http
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 2
|
||||
failureThreshold: 12
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /live
|
||||
port: http
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 2
|
||||
failureThreshold: 6
|
||||
resources:
|
||||
requests:
|
||||
cpu: 20m
|
||||
memory: 48Mi
|
||||
limits:
|
||||
memory: 160Mi
|
||||
volumes:
|
||||
- name: logs
|
||||
hostPath:
|
||||
path: /home/ubuntu/.unidesk/devops-deploy/logs
|
||||
type: DirectoryOrCreate
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: devops
|
||||
namespace: unidesk-ci
|
||||
labels:
|
||||
app.kubernetes.io/name: devops
|
||||
app.kubernetes.io/part-of: unidesk
|
||||
unidesk.ai/deployment-mode: k3sctl-managed
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app.kubernetes.io/name: devops
|
||||
unidesk.ai/instance-id: D601
|
||||
ports:
|
||||
- name: http
|
||||
port: 4286
|
||||
targetPort: http
|
||||
@@ -274,7 +274,7 @@ function mergeServices(services: ManagedService[]): ManagedService[] {
|
||||
}
|
||||
|
||||
function readConfig(): RuntimeConfig {
|
||||
const paths = manifestPaths(envString("K3SCTL_MANIFEST_PATHS", "k3s/code-queue.k3s.json,k3s/mdtodo.k3s.json,k3s/claudeqq.k3s.json,k3s/decision-center.k3s.json"));
|
||||
const paths = manifestPaths(envString("K3SCTL_MANIFEST_PATHS", "k3s/code-queue.k3s.json,k3s/mdtodo.k3s.json,k3s/claudeqq.k3s.json,k3s/decision-center.k3s.json,k3s/devops.k3s.json"));
|
||||
const inlineServices = parseServices(envString("K3SCTL_SERVICES_JSON", "[]"));
|
||||
const manifestServices = readManifestServices(paths);
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user