# CI/CD Pipeline (Forgejo + Argo CD) **Git Forge:** `https://forgejo.riotpiao.com` **Deployments:** `https://argocd.riotpiao.com` (or `kubectl port-forward`) **Namespaces:** `cicd`, `forge` ## When to Use - **Build & test** — Forgejo Actions CI (GitHub Actions syntax) - **Image push** — Build OCI images, push to Forgejo registry - **GitOps deployment** — Argo CD syncs deploy repo to cluster - **Secrets in CI** — ci-bot JWT tokens, never kubeconfig ## Quick Start **1. Clone a repo from Forgejo:** ```bash git clone https://forgejo.riotpiao.com/rock/source.git cd source ``` **2. Create workflow:** ```bash mkdir -p .forgejo/workflows cat > .forgejo/workflows/ci.yml < deployment/ # Or check Argo CD UI kubectl port-forward -n argocd svc/argocd-server 8443:443 # https://localhost:8443 (login via Authentik) ``` ## Workflow Syntax (GitHub Actions) **Basic structure:** ```yaml name: CI on: push: branches: [main, develop] pull_request: jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - run: npm ci - run: npm test build: needs: test # wait for test job runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - run: docker build -t myapp:${{ github.sha }} . - run: docker push forgejo.riotpiao.com/rock/myapp:${{ github.sha }} ``` **Available variables:** ```bash ${{ github.sha }} # commit hash ${{ github.ref_name }} # branch name ${{ github.run_number }} # build # ${{ secrets.CI_BOT_TOKEN }} # injected from Forgejo ``` ## Secrets & Authentication **ci-bot JWT token (auto-injected):** ```yaml - run: | echo "${{ secrets.CI_BOT_TOKEN }}" | docker login \ forgejo.riotpiao.com \ -u ci-bot \ --password-stdin docker push forgejo.riotpiao.com/rock/myapp:latest ``` **API token (for pushing commits):** ```yaml - run: | git config user.name "ci-bot" git config user.email "ci-bot@homelab" git commit --allow-empty -m "bump: version" git push https://ci-bot:${{ secrets.CI_BOT_TOKEN }}@forgejo.riotpiao.com/rock/deploy.git main ``` **Vault secrets (via talos CLI):** ```bash # Not available in CI runner — use Argo CD post-sync hooks instead # Or inject via init container before workflow runs ``` ## Argo CD GitOps **Create app (one-time):** ```bash argocd app create story-crater \ --repo https://forgejo.riotpiao.com/rock/deploy.git \ --path k8s/ \ --dest-server https://kubernetes.default.svc \ --dest-namespace story-crater-backend \ --sync-policy automated ``` **Monitor sync:** ```bash # CLI argocd app get story-crater argocd app logs story-crater # UI: https://argocd.riotpiao.com # Login: Authentik SSO (homelab-admins group only) ``` **Manual sync:** ```bash argocd app sync story-crater argocd app wait story-crater ``` ## Security Rules ✅ **DO:** - Store credentials in Forgejo Secrets (auto-injected) - Use ci-bot JWT for image push only - Commit to deploy repo (triggers Argo CD) - Enable branch protection (require CI pass) ❌ **DON'T:** - Put kubeconfig in CI (Argo CD bridges gap) - Commit secrets to source repo - Use admin-bot in CI workflows (over-privileged) - Push images directly to cluster (use Argo CD) ## Monitoring **Grafana dashboard:** `svc-forgejo`, `svc-argocd` **Key metrics:** - `forgejo_workflows_running` — active workflows - `argocd_app_sync_duration_seconds` — deployment time - `argocd_app_info{sync_status="OutOfSync"}` — drift detection ## Troubleshooting **Workflow fails silently:** ```bash # Check runner logs k logs -n cicd -f deploy/forgejo-runner # Check if runner pod is healthy k get pods -n cicd -l app=forgejo-runner ``` **Image push fails (401 Unauthorized):** ```bash # Verify ci-bot token in Forgejo # Settings → Applications → ci-bot → check scopes (package:write) # Or re-create token core put cluster/iam/agents/ci-bot-token TOKEN="$(openssl rand -hex 32)" ``` **Argo CD out-of-sync:** ```bash # Check deploy repo changes argocd app diff story-crater # Manual sync argocd app sync story-crater --prune ``` **Webhook not triggering:** ```bash # Verify Forgejo webhook config # Repo Settings → Webhooks → Check delivery logs # Or manually trigger argocd app sync story-crater ``` See `/TROUBLESHOOTING.md` for full incident guide.