Files
cloud-host/.gitea/workflows/build-deploy.yaml
T
keyhan 7e66d1edf3
Build and Deploy Platform / build-and-deploy (push) Failing after 20m1s
ci: split GitOps state into cloud-host-gitops repo, add Sealed Secrets, fix pipeline auth
- Workflow now pushes image tags to the separate cloud-host-gitops repo
  (no more CI loop risk) and authenticates via CI_TOKEN secret
- Fix undefined ${REGISTRY} in Kaniko jobs, add concurrency group,
  targeted tag update, and mounted kaniko-harbor-auth docker config
- Argo CD Application is now multi-source (chart from cloud-host,
  values from cloud-host-gitops)
- Remove plaintext runner token and proxy credentials from manifests;
  secrets are now SealedSecrets in the gitops repo

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-02 14:10:46 +03:30

180 lines
7.0 KiB
YAML

name: Build and Deploy Platform
on:
push:
branches: [main]
paths-ignore:
- "**.md"
workflow_dispatch:
# Serialize builds so parallel pushes don't race on the GitOps values update.
concurrency:
group: build-deploy-platform
cancel-in-progress: false
env:
# PULL_REGISTRY: kubelet pulls via k3s mirror → harbor-core (matches registry-pull-secret)
PULL_REGISTRY: registry.abrban.com
# PUSH_REGISTRY: kaniko pushes directly to harbor-registry (internal, no TLS)
PUSH_REGISTRY: harbor-registry.cloudhost.svc.cluster.local:5000
PROJECT: abrban
BUILD_NS: cloudhost-builds
GITEA_HOST: gitea-http.gitea.svc.cluster.local:3000
# PAT of the "ci" user, stored as repo secret CI_TOKEN (names starting with GITEA_ are reserved)
GITEA_TOKEN: ${{ secrets.CI_TOKEN }}
REPO_PATH: abrban/cloud-host.git
GITOPS_REPO_PATH: abrban/cloud-host-gitops.git
jobs:
build-and-deploy:
runs-on: abrban-builder
steps:
- name: Checkout
shell: sh
run: |
git clone --depth=1 --branch main "http://oauth2:${GITEA_TOKEN}@${GITEA_HOST}/${REPO_PATH}" workspace
cd workspace
echo "Checked out $(git rev-parse --short HEAD)"
- name: Set image tag
shell: sh
run: |
cd workspace
SHA="$(git rev-parse --short HEAD)"
TAG="$(date +%Y%m%d-%H%M)-${SHA}"
echo "IMAGE_TAG=${TAG}" >> "$GITHUB_ENV"
echo "Build tag: ${TAG}"
- name: Build backend image (Kaniko Job)
shell: sh
run: |
JOB_NAME="build-be-$(echo $IMAGE_TAG | tr '.:' '-' | cut -c1-50)"
cat <<ENDJOB | kubectl apply -f -
apiVersion: batch/v1
kind: Job
metadata:
name: ${JOB_NAME}
namespace: ${BUILD_NS}
spec:
ttlSecondsAfterFinished: 600
backoffLimit: 0
template:
spec:
restartPolicy: Never
imagePullSecrets:
- name: registry-pull-secret
initContainers:
- name: clone
image: ${PULL_REGISTRY}/${PROJECT}/alpine:3
command:
- sh
- -c
- apk add --no-cache git && git clone --depth=1 --branch main http://oauth2:${GITEA_TOKEN}@${GITEA_HOST}/${REPO_PATH} /workspace
volumeMounts:
- name: ws
mountPath: /workspace
containers:
- name: kaniko
image: ${PULL_REGISTRY}/${PROJECT}/kaniko-executor:v1.27.6-debug
args:
- --dockerfile=/workspace/backend/Dockerfile
- --context=dir:///workspace/backend
- --destination=${PUSH_REGISTRY}/${PROJECT}/cloudhost-backend:${IMAGE_TAG}
- --insecure
- --skip-tls-verify
volumeMounts:
- name: ws
mountPath: /workspace
- name: docker-config
mountPath: /kaniko/.docker
volumes:
- name: ws
emptyDir: {}
- name: docker-config
secret:
secretName: kaniko-harbor-auth
items:
- key: .dockerconfigjson
path: config.json
ENDJOB
echo "Waiting for backend build job: ${JOB_NAME}"
kubectl -n ${BUILD_NS} wait --for=condition=complete job/${JOB_NAME} --timeout=20m
echo "Backend build done"
- name: Build frontend image (Kaniko Job)
shell: sh
run: |
JOB_NAME="build-fe-$(echo $IMAGE_TAG | tr '.:' '-' | cut -c1-50)"
cat <<ENDJOB | kubectl apply -f -
apiVersion: batch/v1
kind: Job
metadata:
name: ${JOB_NAME}
namespace: ${BUILD_NS}
spec:
ttlSecondsAfterFinished: 600
backoffLimit: 0
template:
spec:
restartPolicy: Never
imagePullSecrets:
- name: registry-pull-secret
initContainers:
- name: clone
image: ${PULL_REGISTRY}/${PROJECT}/alpine:3
command:
- sh
- -c
- apk add --no-cache git && git clone --depth=1 --branch main http://oauth2:${GITEA_TOKEN}@${GITEA_HOST}/${REPO_PATH} /workspace
volumeMounts:
- name: ws
mountPath: /workspace
containers:
- name: kaniko
image: ${PULL_REGISTRY}/${PROJECT}/kaniko-executor:v1.27.6-debug
args:
- --dockerfile=/workspace/frontend/Dockerfile
- --context=dir:///workspace/frontend
- --build-arg=NEXT_PUBLIC_API_URL=https://api.abrban.com
- --destination=${PUSH_REGISTRY}/${PROJECT}/cloudhost-frontend:${IMAGE_TAG}
- --insecure
- --skip-tls-verify
volumeMounts:
- name: ws
mountPath: /workspace
- name: docker-config
mountPath: /kaniko/.docker
volumes:
- name: ws
emptyDir: {}
- name: docker-config
secret:
secretName: kaniko-harbor-auth
items:
- key: .dockerconfigjson
path: config.json
ENDJOB
echo "Waiting for frontend build job: ${JOB_NAME}"
kubectl -n ${BUILD_NS} wait --for=condition=complete job/${JOB_NAME} --timeout=20m
echo "Frontend build done"
- name: Update GitOps repo and push
shell: sh
run: |
git clone --depth=1 --branch main "http://oauth2:${GITEA_TOKEN}@${GITEA_HOST}/${GITOPS_REPO_PATH}" gitops-repo
cd gitops-repo
VALUES=platform/values-abrban.yaml
if command -v yq >/dev/null 2>&1; then
IMAGE_TAG="${IMAGE_TAG}" yq -i '.images.backend.tag = strenv(IMAGE_TAG) | .images.frontend.tag = strenv(IMAGE_TAG)' "${VALUES}"
else
# Only touch the tag line directly below each cloudhost-* repository line.
sed -i "/repository: .*cloudhost-backend/{n;s|tag: \".*\"|tag: \"${IMAGE_TAG}\"|;}" "${VALUES}"
sed -i "/repository: .*cloudhost-frontend/{n;s|tag: \".*\"|tag: \"${IMAGE_TAG}\"|;}" "${VALUES}"
fi
git config user.email "ci@abrban.com"
git config user.name "Gitea Actions"
git add "${VALUES}"
if ! git diff --cached --quiet; then
git commit -m "ci: deploy platform ${IMAGE_TAG}"
git push origin HEAD:main
fi