feat: support env reuse and git mirror in v0.1 cicd
This commit is contained in:
@@ -11,6 +11,12 @@ spec:
|
||||
- name: git-url
|
||||
type: string
|
||||
default: git@github.com:pikasTech/agentrun.git
|
||||
- name: git-read-url
|
||||
type: string
|
||||
default: http://git-mirror-http.devops-infra.svc.cluster.local/pikasTech/agentrun.git
|
||||
- name: git-write-url
|
||||
type: string
|
||||
default: http://git-mirror-write.devops-infra.svc.cluster.local/pikasTech/agentrun.git
|
||||
- name: source-branch
|
||||
type: string
|
||||
default: v0.1
|
||||
@@ -33,17 +39,13 @@ spec:
|
||||
workspaces:
|
||||
- name: source
|
||||
workspace: source
|
||||
- name: git-ssh
|
||||
workspace: git-ssh
|
||||
taskSpec:
|
||||
params:
|
||||
- name: git-url
|
||||
- name: source-branch
|
||||
- name: git-read-url
|
||||
- name: revision
|
||||
- name: tools-image
|
||||
workspaces:
|
||||
- name: source
|
||||
- name: git-ssh
|
||||
steps:
|
||||
- name: clone-and-check
|
||||
image: $(params.tools-image)
|
||||
@@ -60,37 +62,132 @@ spec:
|
||||
value: http://127.0.0.1:10808
|
||||
- name: no_proxy
|
||||
value: hyueapi.com,.hyueapi.com,127.0.0.1,localhost,::1,10.42.0.0/16,10.43.0.0/16,.svc,.cluster.local
|
||||
- name: GIT_TERMINAL_PROMPT
|
||||
value: "0"
|
||||
script: |
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
apk add --no-cache git openssh-client curl
|
||||
mkdir -p /root/.ssh
|
||||
cp /workspace/git-ssh/ssh-privatekey /root/.ssh/id_rsa
|
||||
chmod 600 /root/.ssh/id_rsa
|
||||
ssh-keyscan github.com >> /root/.ssh/known_hosts 2>/dev/null
|
||||
apk add --no-cache git curl
|
||||
rm -rf /workspace/source/repo
|
||||
git clone --branch "$(params.source-branch)" "$(params.git-url)" /workspace/source/repo
|
||||
mkdir -p /workspace/source/repo
|
||||
git init /workspace/source/repo
|
||||
cd /workspace/source/repo
|
||||
git config --global --add safe.directory /workspace/source/repo
|
||||
git checkout "$(params.revision)"
|
||||
git remote add origin "$(params.git-read-url)"
|
||||
git fetch --depth=1 origin "$(params.revision)"
|
||||
git checkout --detach FETCH_HEAD
|
||||
test "$(git rev-parse HEAD)" = "$(params.revision)"
|
||||
bun install
|
||||
bun install --frozen-lockfile
|
||||
bun run check
|
||||
bun scripts/agentrun-gitops-render.ts --out /tmp/agentrun-gitops-render-check --source-commit "$(params.revision)" --check
|
||||
AGENTRUN_SELFTEST_CODEX_COMMAND="$(command -v bun)" \
|
||||
AGENTRUN_SELFTEST_CODEX_ARGS="[\"$PWD/src/selftest/fake-codex-app-server.ts\"]" \
|
||||
bun run self-test
|
||||
params:
|
||||
- name: git-url
|
||||
value: $(params.git-url)
|
||||
- name: source-branch
|
||||
value: $(params.source-branch)
|
||||
- name: git-read-url
|
||||
value: $(params.git-read-url)
|
||||
- name: revision
|
||||
value: $(params.revision)
|
||||
- name: tools-image
|
||||
value: $(params.tools-image)
|
||||
- name: image-publish
|
||||
- name: plan-artifacts
|
||||
runAfter: [prepare-source]
|
||||
workspaces:
|
||||
- name: source
|
||||
workspace: source
|
||||
taskSpec:
|
||||
params:
|
||||
- name: git-read-url
|
||||
- name: gitops-branch
|
||||
- name: revision
|
||||
- name: registry-prefix
|
||||
results:
|
||||
- name: env-identity
|
||||
- name: build-count
|
||||
- name: reuse-count
|
||||
- name: summary
|
||||
workspaces:
|
||||
- name: source
|
||||
steps:
|
||||
- name: plan
|
||||
image: oven/bun:1.2.15-alpine
|
||||
env:
|
||||
- name: GIT_TERMINAL_PROMPT
|
||||
value: "0"
|
||||
script: |
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
apk add --no-cache git nodejs
|
||||
cd /workspace/source/repo
|
||||
node <<'NODE' > /workspace/source/env-identity
|
||||
const { createHash } = require("node:crypto");
|
||||
const { readFileSync } = require("node:fs");
|
||||
const inputs = [
|
||||
["baseImage", "oven/bun:1.2.15-alpine"],
|
||||
["systemPackages", "ca-certificates git kubectl nodejs openssh-client"],
|
||||
["containerfile", readFileSync("deploy/container/Containerfile", "utf8")],
|
||||
["bootScript", readFileSync("deploy/runtime/boot/agentrun-boot.sh", "utf8")],
|
||||
["bootMgr", readFileSync("deploy/runtime/boot/agentrun-mgr.sh", "utf8")],
|
||||
["bootRunner", readFileSync("deploy/runtime/boot/agentrun-runner.sh", "utf8")],
|
||||
["packageJson", readFileSync("package.json", "utf8")],
|
||||
["bunLock", readFileSync("bun.lock", "utf8")],
|
||||
["tsconfig", readFileSync("tsconfig.json", "utf8")],
|
||||
];
|
||||
process.stdout.write(createHash("sha256").update(JSON.stringify(inputs)).digest("hex").slice(0, 20));
|
||||
NODE
|
||||
env_identity="$(cat /workspace/source/env-identity)"
|
||||
rm -rf /workspace/source/gitops-prev
|
||||
if git clone --depth=1 --branch "$(params.gitops-branch)" "$(params.git-read-url)" /workspace/source/gitops-prev >/tmp/agentrun-prev-gitops.log 2>&1; then
|
||||
prev_catalog=/workspace/source/gitops-prev/deploy/artifact-catalog.v01.json
|
||||
else
|
||||
prev_catalog=/dev/null
|
||||
fi
|
||||
AGENTRUN_ENV_IDENTITY="$env_identity" \
|
||||
AGENTRUN_PREV_CATALOG="$prev_catalog" \
|
||||
AGENTRUN_REVISION="$(params.revision)" \
|
||||
AGENTRUN_GITOPS_BRANCH="$(params.gitops-branch)" \
|
||||
AGENTRUN_REGISTRY_PREFIX="$(params.registry-prefix)" \
|
||||
node <<'NODE'
|
||||
const { readFileSync, writeFileSync } = require("node:fs");
|
||||
const envIdentity = process.env.AGENTRUN_ENV_IDENTITY;
|
||||
const revision = process.env.AGENTRUN_REVISION;
|
||||
const gitopsBranch = process.env.AGENTRUN_GITOPS_BRANCH;
|
||||
let previousService = null;
|
||||
try {
|
||||
const catalog = JSON.parse(readFileSync(process.env.AGENTRUN_PREV_CATALOG, "utf8"));
|
||||
previousService = (catalog.services || []).find((item) => item.serviceId === "agentrun-mgr" && item.envIdentity === envIdentity && /^sha256:[a-f0-9]{64}$/.test(item.envDigest || item.digest || "")) || null;
|
||||
} catch {}
|
||||
const reused = previousService !== null;
|
||||
const plan = {
|
||||
lane: "v0.1",
|
||||
sourceBranch: "v0.1",
|
||||
gitopsBranch,
|
||||
sourceCommitId: revision,
|
||||
envIdentity,
|
||||
toolchainInputs: ["oven/bun:1.2.15-alpine", "deploy/container/Containerfile", "deploy/runtime/boot/*.sh", "package.json", "bun.lock", "tsconfig.json", "apk:ca-certificates git kubectl nodejs openssh-client"],
|
||||
buildServices: reused ? [] : ["agentrun-mgr"],
|
||||
reusedServices: reused ? ["agentrun-mgr"] : [],
|
||||
unsafeReuseServices: [],
|
||||
previousService,
|
||||
summary: `build=${reused ? 0 : 1} reuse=${reused ? 1 : 0} unsafeReuse=0`,
|
||||
};
|
||||
writeFileSync("/workspace/source/ci-plan.json", `${JSON.stringify(plan, null, 2)}\n`);
|
||||
writeFileSync("/tekton/results/env-identity", envIdentity);
|
||||
writeFileSync("/tekton/results/build-count", String(plan.buildServices.length));
|
||||
writeFileSync("/tekton/results/reuse-count", String(plan.reusedServices.length));
|
||||
writeFileSync("/tekton/results/summary", plan.summary);
|
||||
console.log(JSON.stringify({ event: "agentrun-ci-plan", status: "succeeded", sourceCommitId: revision, envIdentity, buildServices: plan.buildServices, reusedServices: plan.reusedServices, unsafeReuseServices: [], summary: plan.summary }));
|
||||
NODE
|
||||
params:
|
||||
- name: git-read-url
|
||||
value: $(params.git-read-url)
|
||||
- name: gitops-branch
|
||||
value: $(params.gitops-branch)
|
||||
- name: revision
|
||||
value: $(params.revision)
|
||||
- name: registry-prefix
|
||||
value: $(params.registry-prefix)
|
||||
- name: image-publish
|
||||
runAfter: [plan-artifacts]
|
||||
workspaces:
|
||||
- name: source
|
||||
workspace: source
|
||||
@@ -102,6 +199,8 @@ spec:
|
||||
- name: image
|
||||
- name: digest
|
||||
- name: repository-digest
|
||||
- name: env-identity
|
||||
- name: status
|
||||
sidecars:
|
||||
- name: buildkitd
|
||||
image: moby/buildkit:rootless
|
||||
@@ -145,7 +244,7 @@ spec:
|
||||
volumeMounts:
|
||||
- name: buildkit-bin
|
||||
mountPath: /workspace/buildkit-bin
|
||||
- name: build-and-push
|
||||
- name: build-or-reuse
|
||||
image: oven/bun:1.2.15-alpine
|
||||
env:
|
||||
- name: HTTP_PROXY
|
||||
@@ -157,9 +256,28 @@ spec:
|
||||
script: |
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
apk add --no-cache curl
|
||||
apk add --no-cache curl nodejs
|
||||
cd /workspace/source/repo
|
||||
image="$(params.registry-prefix)/agentrun-mgr:$(params.revision)"
|
||||
env_identity="$(cat /workspace/source/env-identity)"
|
||||
if node -e 'const p=require("/workspace/source/ci-plan.json"); process.exit((p.buildServices||[]).length===0 ? 0 : 1)'; then
|
||||
node <<'NODE'
|
||||
const { readFileSync, writeFileSync } = require("node:fs");
|
||||
const plan = JSON.parse(readFileSync("/workspace/source/ci-plan.json", "utf8"));
|
||||
const service = plan.previousService;
|
||||
if (!service) throw new Error("reuse plan missing previousService");
|
||||
const image = service.envImage || service.image;
|
||||
const digest = service.envDigest || service.digest;
|
||||
const repositoryDigest = service.envRepositoryDigest || service.repositoryDigest;
|
||||
writeFileSync("/tekton/results/image", image);
|
||||
writeFileSync("/tekton/results/digest", digest);
|
||||
writeFileSync("/tekton/results/repository-digest", repositoryDigest);
|
||||
writeFileSync("/tekton/results/env-identity", plan.envIdentity);
|
||||
writeFileSync("/tekton/results/status", "reused");
|
||||
console.log(JSON.stringify({ event: "agentrun-env-image", status: "reused", serviceId: "agentrun-mgr", envIdentity: plan.envIdentity, image, digest, summary: plan.summary }));
|
||||
NODE
|
||||
exit 0
|
||||
fi
|
||||
image="$(params.registry-prefix)/agentrun-mgr-env:${env_identity}"
|
||||
buildctl=/workspace/buildkit-bin/buildctl
|
||||
for attempt in $(seq 1 60); do
|
||||
if "$buildctl" --addr unix:///workspace/buildkit-run/buildkitd.sock debug workers >/dev/null 2>&1; then break; fi
|
||||
@@ -174,12 +292,15 @@ spec:
|
||||
--opt build-arg:HTTPS_PROXY=http://127.0.0.1:10808 \
|
||||
--opt build-arg:NO_PROXY=hyueapi.com,.hyueapi.com,127.0.0.1,localhost,::1,10.42.0.0/16,10.43.0.0/16,.svc,.cluster.local \
|
||||
--output type=image,name="$image",push=true,registry.insecure=true
|
||||
digest="$(curl -fsSI -H "Accept: application/vnd.docker.distribution.manifest.v2+json" "http://127.0.0.1:5000/v2/agentrun/agentrun-mgr/manifests/$(params.revision)" | awk -F': ' 'tolower($1)=="docker-content-digest" {gsub(/\r/,"",$2); print $2; exit}')"
|
||||
digest="$(curl -fsSI -H "Accept: application/vnd.docker.distribution.manifest.v2+json" "http://127.0.0.1:5000/v2/agentrun/agentrun-mgr-env/manifests/$env_identity" | awk -F': ' 'tolower($1)=="docker-content-digest" {gsub(/\r/,"",$2); print $2; exit}')"
|
||||
test -n "$digest"
|
||||
curl -fsSI -H "Accept: application/vnd.docker.distribution.manifest.v2+json" "http://127.0.0.1:5000/v2/agentrun/agentrun-mgr/manifests/$digest" >/dev/null
|
||||
curl -fsSI -H "Accept: application/vnd.docker.distribution.manifest.v2+json" "http://127.0.0.1:5000/v2/agentrun/agentrun-mgr-env/manifests/$digest" >/dev/null
|
||||
printf '%s' "$image" > /tekton/results/image
|
||||
printf '%s' "$digest" > /tekton/results/digest
|
||||
printf '%s' "$(params.registry-prefix)/agentrun-mgr@$digest" > /tekton/results/repository-digest
|
||||
printf '%s' "$(params.registry-prefix)/agentrun-mgr-env@$digest" > /tekton/results/repository-digest
|
||||
printf '%s' "$env_identity" > /tekton/results/env-identity
|
||||
printf '%s' built > /tekton/results/status
|
||||
printf '{"event":"agentrun-env-image","status":"built","serviceId":"agentrun-mgr","envIdentity":"%s","image":"%s","digest":"%s"}\n' "$env_identity" "$image" "$digest"
|
||||
volumeMounts:
|
||||
- name: buildkit-bin
|
||||
mountPath: /workspace/buildkit-bin
|
||||
@@ -200,47 +321,85 @@ spec:
|
||||
workspaces:
|
||||
- name: source
|
||||
workspace: source
|
||||
- name: git-ssh
|
||||
workspace: git-ssh
|
||||
taskSpec:
|
||||
params:
|
||||
- name: git-url
|
||||
- name: git-write-url
|
||||
- name: gitops-branch
|
||||
- name: revision
|
||||
- name: registry-prefix
|
||||
- name: image
|
||||
- name: digest
|
||||
- name: repository-digest
|
||||
- name: env-identity
|
||||
- name: image-status
|
||||
workspaces:
|
||||
- name: source
|
||||
- name: git-ssh
|
||||
steps:
|
||||
- name: promote
|
||||
image: oven/bun:1.2.15-alpine
|
||||
env:
|
||||
- name: HTTP_PROXY
|
||||
value: http://127.0.0.1:10808
|
||||
- name: HTTPS_PROXY
|
||||
value: http://127.0.0.1:10808
|
||||
- name: NO_PROXY
|
||||
value: hyueapi.com,.hyueapi.com,127.0.0.1,localhost,::1,10.42.0.0/16,10.43.0.0/16,.svc,.cluster.local
|
||||
- name: GIT_TERMINAL_PROMPT
|
||||
value: "0"
|
||||
- name: AGENTRUN_IMAGE
|
||||
value: $(params.image)
|
||||
- name: AGENTRUN_DIGEST
|
||||
value: $(params.digest)
|
||||
- name: AGENTRUN_REPOSITORY_DIGEST
|
||||
value: $(params.repository-digest)
|
||||
- name: AGENTRUN_ENV_IDENTITY
|
||||
value: $(params.env-identity)
|
||||
- name: AGENTRUN_IMAGE_STATUS
|
||||
value: $(params.image-status)
|
||||
- name: AGENTRUN_REVISION
|
||||
value: $(params.revision)
|
||||
- name: AGENTRUN_GITOPS_BRANCH
|
||||
value: $(params.gitops-branch)
|
||||
script: |
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
apk add --no-cache git openssh-client
|
||||
mkdir -p /root/.ssh
|
||||
cp /workspace/git-ssh/ssh-privatekey /root/.ssh/id_rsa
|
||||
chmod 600 /root/.ssh/id_rsa
|
||||
ssh-keyscan github.com >> /root/.ssh/known_hosts 2>/dev/null
|
||||
apk add --no-cache git openssh-client nodejs
|
||||
cd /workspace/source/repo
|
||||
cat > /workspace/source/artifact-catalog.v01.json <<EOF
|
||||
{"lane":"v0.1","sourceBranch":"v0.1","gitopsBranch":"$(params.gitops-branch)","sourceCommitId":"$(params.revision)","services":[{"serviceId":"agentrun-mgr","image":"$(params.image)","digest":"$(params.digest)","repositoryDigest":"$(params.repository-digest)","imageTag":"$(params.revision)"}]}
|
||||
EOF
|
||||
node <<'NODE' > /workspace/source/artifact-catalog.v01.json
|
||||
const { readFileSync } = require("node:fs");
|
||||
const plan = JSON.parse(readFileSync("/workspace/source/ci-plan.json", "utf8"));
|
||||
const service = {
|
||||
serviceId: "agentrun-mgr",
|
||||
artifactKind: "env-reuse",
|
||||
status: process.env.AGENTRUN_IMAGE_STATUS,
|
||||
image: process.env.AGENTRUN_IMAGE,
|
||||
digest: process.env.AGENTRUN_DIGEST,
|
||||
repositoryDigest: process.env.AGENTRUN_REPOSITORY_DIGEST,
|
||||
imageTag: process.env.AGENTRUN_ENV_IDENTITY,
|
||||
envIdentity: process.env.AGENTRUN_ENV_IDENTITY,
|
||||
envImage: process.env.AGENTRUN_IMAGE,
|
||||
envDigest: process.env.AGENTRUN_DIGEST,
|
||||
envRepositoryDigest: process.env.AGENTRUN_REPOSITORY_DIGEST,
|
||||
bootCommit: process.env.AGENTRUN_REVISION,
|
||||
bootScript: "deploy/runtime/boot/agentrun-boot.sh",
|
||||
provenance: {
|
||||
sourceCommitId: process.env.AGENTRUN_REVISION,
|
||||
toolchainInputs: plan.toolchainInputs,
|
||||
buildServices: plan.buildServices,
|
||||
reusedServices: plan.reusedServices,
|
||||
unsafeReuseServices: plan.unsafeReuseServices,
|
||||
previousSourceCommitId: plan.previousService?.bootCommit || null,
|
||||
},
|
||||
};
|
||||
const catalog = {
|
||||
lane: "v0.1",
|
||||
sourceBranch: "v0.1",
|
||||
gitopsBranch: process.env.AGENTRUN_GITOPS_BRANCH,
|
||||
sourceCommitId: process.env.AGENTRUN_REVISION,
|
||||
summary: plan.summary,
|
||||
services: [service],
|
||||
};
|
||||
console.log(JSON.stringify(catalog, null, 2));
|
||||
NODE
|
||||
rm -rf /workspace/source/rendered
|
||||
bun scripts/agentrun-gitops-render.ts --out /workspace/source/rendered --source-commit "$(params.revision)" --registry-prefix "$(params.registry-prefix)" --catalog /workspace/source/artifact-catalog.v01.json --require-catalog
|
||||
rm -rf /workspace/source/gitops
|
||||
git clone --branch "$(params.gitops-branch)" "$(params.git-url)" /workspace/source/gitops || {
|
||||
git clone "$(params.git-url)" /workspace/source/gitops
|
||||
git clone --branch "$(params.gitops-branch)" "$(params.git-write-url)" /workspace/source/gitops || {
|
||||
git clone "$(params.git-write-url)" /workspace/source/gitops
|
||||
cd /workspace/source/gitops
|
||||
git checkout --orphan "$(params.gitops-branch)"
|
||||
git rm -rf . >/dev/null 2>&1 || true
|
||||
@@ -256,9 +415,10 @@ spec:
|
||||
git add deploy
|
||||
git commit -m "gitops: promote agentrun v0.1 $(params.revision)" || true
|
||||
git push origin "$(params.gitops-branch)"
|
||||
printf '{"event":"agentrun-gitops-promote","status":"succeeded","sourceCommitId":"%s","envIdentity":"%s","imageStatus":"%s","summary":%s}\n' "$(params.revision)" "$(params.env-identity)" "$(params.image-status)" "$(node -e 'const p=require("/workspace/source/ci-plan.json"); console.log(JSON.stringify(p.summary))')"
|
||||
params:
|
||||
- name: git-url
|
||||
value: $(params.git-url)
|
||||
- name: git-write-url
|
||||
value: $(params.git-write-url)
|
||||
- name: gitops-branch
|
||||
value: $(params.gitops-branch)
|
||||
- name: revision
|
||||
@@ -271,3 +431,7 @@ spec:
|
||||
value: $(tasks.image-publish.results.digest)
|
||||
- name: repository-digest
|
||||
value: $(tasks.image-publish.results.repository-digest)
|
||||
- name: env-identity
|
||||
value: $(tasks.image-publish.results.env-identity)
|
||||
- name: image-status
|
||||
value: $(tasks.image-publish.results.status)
|
||||
|
||||
@@ -16,6 +16,10 @@ spec:
|
||||
params:
|
||||
- name: revision
|
||||
value: REPLACE_WITH_FULL_SOURCE_COMMIT
|
||||
- name: git-read-url
|
||||
value: http://git-mirror-http.devops-infra.svc.cluster.local/pikasTech/agentrun.git
|
||||
- name: git-write-url
|
||||
value: http://git-mirror-write.devops-infra.svc.cluster.local/pikasTech/agentrun.git
|
||||
workspaces:
|
||||
- name: source
|
||||
volumeClaimTemplate:
|
||||
|
||||
Reference in New Issue
Block a user