# Gitea CI/CD Workflow ## Overview TurboVault uses Gitea Actions for fully automated builds and deployments: 1. **Push code to GitHub** (primary repository) 2. **Gitea mirrors** from GitHub automatically 3. **Gitea Actions** builds Docker image and deploys to Kubernetes All automatic! 🚀 --- ## Setup (One-Time) ### 1. Mirror GitHub Repository to Gitea In Gitea: 1. Go to `gitea.kazcloud.dev` → **New Repository** 2. Choose **"New Migration"** → **"GitHub"** 3. URL: `https://github.com/ryankazokas/turbovault-app` 4. Enable **"This repository will be a mirror"** 5. Set sync interval: **10 minutes** (or setup webhook for instant sync) 6. Click **"Migrate Repository"** **Webhook for instant sync (optional):** - In GitHub repo → Settings → Webhooks → Add webhook - Payload URL: `https://gitea.kazcloud.dev/ryankazokas/turbovault-app/mirror-sync` - Content type: `application/json` - Events: Just the push event ### 2. Configure Gitea Secrets See [GITEA_SECRETS.md](GITEA_SECRETS.md) for detailed instructions. **Required secrets:** - `GITEA_TOKEN` - For pushing images to registry - `KUBECONFIG` - For deploying to Kubernetes Add at: `gitea.kazcloud.dev/ryankazokas/turbovault-app/settings/secrets` ### 3. Initial Deployment to Kubernetes Before automation works, do initial deployment: ```bash # Build and push first image docker build -t gitea.kazcloud.dev/ryankazokas/turbovault-app:v1.0.0 . docker login gitea.kazcloud.dev docker push gitea.kazcloud.dev/ryankazokas/turbovault-app:v1.0.0 # Configure secrets and database cp k8s/secrets.yaml.example k8s/secrets.yaml nano k8s/secrets.yaml # Add SECRET_KEY_BASE, DATABASE_PASSWORD, etc. nano k8s/configmap.yaml # Add DATABASE_HOST, etc. # Deploy to Kubernetes ./scripts/deploy-k8s.sh ``` When script asks for registry credentials: - Registry: `gitea.kazcloud.dev` - Username: `ryankazokas` - Password: `` --- ## Daily Workflow After setup, deployments are fully automatic: ```bash # 1. Make changes in GitHub git add . git commit -m "Feature: add new functionality" git push origin main # 2. When ready to deploy, create version tag git tag v1.0.1 git push origin v1.0.1 # 3. That's it! ✅ # Gitea auto-syncs → builds → deploys to Kubernetes ``` **Watch build and deployment:** `https://gitea.kazcloud.dev/ryankazokas/turbovault-app/actions` --- ## How It Works ``` GitHub (code) ↓ (mirror sync) Gitea (code mirror) ↓ (on tag push) Gitea Actions: 1. Build Docker image 2. Push to gitea.kazcloud.dev registry 3. Deploy to Kubernetes (kubectl) 4. Wait for rollout 5. Show status ↓ Kubernetes pulls image and updates deployment ✅ ``` --- ## Workflow Features ### ✅ Automatic Rollout Status Workflow waits for rollout to complete before marking as success. ### ✅ Automatic Rollback on Failure If deployment fails, workflow automatically rolls back to previous version. ### ✅ Multiple Tags Each version gets two tags: - `v1.0.0` (specific version) - `latest` (always points to most recent) ### ✅ Manual Trigger Can manually trigger builds via Gitea Actions UI if needed. --- ## Manual Deployment (If Needed) If you want to deploy manually without waiting for Gitea sync: ```bash # Build and push docker build -t gitea.kazcloud.dev/ryankazokas/turbovault-app:v1.0.1 . docker push gitea.kazcloud.dev/ryankazokas/turbovault-app:v1.0.1 # Deploy ./scripts/update-deployment.sh v1.0.1 ``` --- ## Version Management ### Semantic Versioning Use semantic versioning for tags: - `v1.0.0` - Major.Minor.Patch - `v1.0.1` - Patch update (bug fixes) - `v1.1.0` - Minor update (new features) - `v2.0.0` - Major update (breaking changes) ### Viewing Deployed Version ```bash # Check current image kubectl get deployment turbovault -n turbovault -o jsonpath='{.spec.template.spec.containers[0].image}' # Check all pods kubectl get pods -n turbovault -l app=turbovault ``` --- ## Troubleshooting ### Workflow Fails at "Build and push" **Issue:** Can't push to registry **Fix:** - Check `GITEA_TOKEN` secret is set - Verify token has `write:package` scope - Test: `docker login gitea.kazcloud.dev` with token ### Workflow Fails at "Deploy to Kubernetes" **Issue:** Can't connect to Kubernetes **Fix:** - Check `KUBECONFIG` secret is set correctly - Verify base64 encoding: `echo "$SECRET" | base64 -d | kubectl --kubeconfig=/dev/stdin get nodes` - Check cluster is reachable from Gitea Actions runner ### Deployment Succeeds but Pods Not Starting **Issue:** Image pull errors or configuration issues **Check:** ```bash kubectl get pods -n turbovault kubectl describe pod -n turbovault kubectl logs -n turbovault ``` **Common causes:** - Image pull secret not configured (run `./scripts/deploy-k8s.sh` again) - Database connection issues (check `k8s/configmap.yaml` and `k8s/secrets.yaml`) - Missing environment variables --- ## Monitoring Deployments ### Watch Live Deployment ```bash # Watch pods update kubectl get pods -n turbovault -w # Watch rollout status kubectl rollout status deployment/turbovault -n turbovault # View logs kubectl logs -f -l app=turbovault -n turbovault ``` ### Deployment History ```bash # View rollout history kubectl rollout history deployment/turbovault -n turbovault # View specific revision kubectl rollout history deployment/turbovault --revision=2 -n turbovault ``` --- ## Rollback ### Automatic Rollback Workflow automatically rolls back if deployment fails. ### Manual Rollback ```bash # Rollback to previous version kubectl rollout undo deployment/turbovault -n turbovault # Rollback to specific revision kubectl rollout undo deployment/turbovault --to-revision=3 -n turbovault ``` --- ## Security Considerations ### Secrets Management - All secrets in Gitea are encrypted - Secrets never appear in logs - Use service account kubeconfig (not admin) ### Network Security - Gitea Actions runners on internal network - Can reach Kubernetes API (not exposed publicly) - Images pulled from internal registry ### Access Control - Only repository collaborators can trigger workflows - Gitea token scoped to package registry only - Kubeconfig scoped to turbovault namespace only (recommended) --- ## Advanced: Staging vs Production To add staging environment: 1. Create `v*.*.*-rc*` tags for release candidates 2. Deploy to staging namespace 3. Update workflow to detect RC tags: ```yaml - name: Determine environment id: env run: | if [[ "${{ github.ref }}" =~ -rc ]]; then echo "namespace=turbovault-staging" >> $GITHUB_OUTPUT else echo "namespace=turbovault" >> $GITHUB_OUTPUT fi ``` --- ## Quick Reference ```bash # Deploy new version git tag v1.0.1 git push origin v1.0.1 # Watch deployment kubectl get pods -n turbovault -w # View logs kubectl logs -f -l app=turbovault -n turbovault # Rollback if needed kubectl rollout undo deployment/turbovault -n turbovault # Check current version kubectl get deployment turbovault -n turbovault -o jsonpath='{.spec.template.spec.containers[0].image}' ``` --- ## Summary **Setup once:** 1. Mirror GitHub → Gitea 2. Add Gitea secrets (GITEA_TOKEN, KUBECONFIG) 3. Initial deployment with `./scripts/deploy-k8s.sh` **Daily workflow:** 1. Push code to GitHub 2. Create version tag 3. Everything else is automatic! ✅ Questions? Check [GITEA_SECRETS.md](GITEA_SECRETS.md) for secret configuration details.