From 51b4b34c1991bfee2ef6301da6d93b3ce34aca1f Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Mon, 2 Feb 2026 00:05:45 +0100 Subject: [PATCH] feat(ci): add GitOps pipeline with Gitea Actions and ArgoCD - Add Gitea Actions workflow for building and pushing Docker images - Configure ArgoCD Application for auto-sync deployment - Update Helm values to use Gitea container registry - Add setup documentation for GitOps configuration Co-Authored-By: Claude Opus 4.5 --- .gitea/workflows/build.yaml | 63 ++++++++++++++++++++++ argocd/SETUP.md | 104 ++++++++++++++++++++++++++++++++++++ argocd/application.yaml | 61 +++++++++++++++++++++ helm/taskplaner/values.yaml | 9 ++-- 4 files changed, 233 insertions(+), 4 deletions(-) create mode 100644 .gitea/workflows/build.yaml create mode 100644 argocd/SETUP.md create mode 100644 argocd/application.yaml diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml new file mode 100644 index 0000000..fa36be2 --- /dev/null +++ b/.gitea/workflows/build.yaml @@ -0,0 +1,63 @@ +name: Build and Push + +on: + push: + branches: + - master + - main + pull_request: + branches: + - master + - main + +env: + REGISTRY: git.kube2.tricnet.de + IMAGE_NAME: tho/taskplaner + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Gitea Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=sha,prefix= + type=ref,event=branch + type=raw,value=latest,enable=${{ github.ref == 'refs/heads/master' }} + + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: . + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache + cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max + + - name: Update Helm values with new image tag + if: github.event_name != 'pull_request' + run: | + SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7) + sed -i "s/^ tag:.*/ tag: \"${SHORT_SHA}\"/" helm/taskplaner/values.yaml + git config user.name "Gitea Actions" + git config user.email "actions@git.kube2.tricnet.de" + git add helm/taskplaner/values.yaml + git commit -m "chore: update image tag to ${SHORT_SHA} [skip ci]" || echo "No changes to commit" + git push || echo "Push failed - may need to configure git credentials" diff --git a/argocd/SETUP.md b/argocd/SETUP.md new file mode 100644 index 0000000..dc798ca --- /dev/null +++ b/argocd/SETUP.md @@ -0,0 +1,104 @@ +# ArgoCD GitOps Setup for TaskPlaner + +This guide sets up automatic deployment of TaskPlaner using GitOps with ArgoCD and Gitea. + +## Prerequisites + +- Kubernetes cluster access +- Gitea instance with Packages (Container Registry) enabled +- Gitea Actions runner configured + +## 1. Install ArgoCD + +```bash +kubectl create namespace argocd +kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml +``` + +Wait for ArgoCD to be ready: +```bash +kubectl wait --for=condition=available deployment/argocd-server -n argocd --timeout=300s +``` + +## 2. Configure Gitea Registry Secrets + +### For Gitea Actions (push access) + +In Gitea repository settings, add these secrets: +- `REGISTRY_USERNAME`: Your Gitea username +- `REGISTRY_PASSWORD`: A Gitea access token with `write:package` scope + +### For Kubernetes (pull access) + +Create an image pull secret: +```bash +kubectl create secret docker-registry gitea-registry-secret \ + --docker-server=git.kube2.tricnet.de \ + --docker-username=YOUR_USERNAME \ + --docker-password=YOUR_ACCESS_TOKEN \ + -n default +``` + +## 3. Configure ArgoCD Repository Access + +Add the Gitea repository to ArgoCD: +```bash +# Get ArgoCD admin password +kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo + +# Port forward to access ArgoCD UI +kubectl port-forward svc/argocd-server -n argocd 8080:443 + +# Or use CLI +argocd login localhost:8080 --insecure +argocd repo add https://git.kube2.tricnet.de/tho/taskplaner.git \ + --username YOUR_USERNAME \ + --password YOUR_ACCESS_TOKEN +``` + +## 4. Deploy the ArgoCD Application + +```bash +kubectl apply -f argocd/application.yaml +``` + +Note: Edit `application.yaml` first to remove the example Secret or replace `REPLACE_WITH_BASE64_ENCODED_USERNAME_COLON_PASSWORD` with actual credentials. + +## 5. Verify Deployment + +```bash +# Check ArgoCD application status +kubectl get applications -n argocd + +# Watch sync status +argocd app get taskplaner + +# Check pods +kubectl get pods -l app.kubernetes.io/name=taskplaner +``` + +## Workflow + +1. Push code to `master` branch +2. Gitea Actions builds Docker image and pushes to registry +3. Workflow updates `helm/taskplaner/values.yaml` with new image tag +4. ArgoCD detects change and auto-syncs deployment + +## Troubleshooting + +### Image Pull Errors +```bash +kubectl describe pod -l app.kubernetes.io/name=taskplaner +``` +Check if the image pull secret is correctly configured. + +### ArgoCD Sync Issues +```bash +argocd app sync taskplaner --force +argocd app logs taskplaner +``` + +### Actions Runner Issues +```bash +kubectl logs -n gitea -l app=act-runner -c runner +``` diff --git a/argocd/application.yaml b/argocd/application.yaml new file mode 100644 index 0000000..2629d76 --- /dev/null +++ b/argocd/application.yaml @@ -0,0 +1,61 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: taskplaner + namespace: argocd +spec: + project: default + source: + repoURL: https://git.kube2.tricnet.de/tho/taskplaner.git + targetRevision: HEAD + path: helm/taskplaner + helm: + valueFiles: + - values.yaml + parameters: + - name: image.repository + value: git.kube2.tricnet.de/tho/taskplaner + - name: ingress.enabled + value: "true" + - name: ingress.className + value: traefik + - name: ingress.hosts[0].host + value: task.kube2.tricnet.de + - name: ingress.hosts[0].paths[0].path + value: / + - name: ingress.hosts[0].paths[0].pathType + value: Prefix + - name: ingress.tls[0].secretName + value: taskplaner-tls + - name: ingress.tls[0].hosts[0] + value: task.kube2.tricnet.de + - name: ingress.annotations.cert-manager\.io/cluster-issuer + value: letsencrypt-prod + - name: config.origin + value: https://task.kube2.tricnet.de + destination: + server: https://kubernetes.default.svc + namespace: default + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true +--- +# Secret for Gitea Container Registry access +apiVersion: v1 +kind: Secret +metadata: + name: gitea-registry-secret + namespace: default +type: kubernetes.io/dockerconfigjson +stringData: + .dockerconfigjson: | + { + "auths": { + "git.kube2.tricnet.de": { + "auth": "REPLACE_WITH_BASE64_ENCODED_USERNAME_COLON_PASSWORD" + } + } + } diff --git a/helm/taskplaner/values.yaml b/helm/taskplaner/values.yaml index 8687916..7ac52c9 100644 --- a/helm/taskplaner/values.yaml +++ b/helm/taskplaner/values.yaml @@ -3,12 +3,13 @@ replicaCount: 1 image: - repository: taskplaner - pullPolicy: IfNotPresent + repository: git.kube2.tricnet.de/tho/taskplaner + pullPolicy: Always # Overrides the image tag whose default is the chart appVersion - tag: "" + tag: "latest" -imagePullSecrets: [] +imagePullSecrets: + - name: gitea-registry-secret nameOverride: "" fullnameOverride: ""