5.1 KiB
5.1 KiB
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:
git clone https://forgejo.riotpiao.com/rock/source.git
cd source
2. Create workflow:
mkdir -p .forgejo/workflows
cat > .forgejo/workflows/ci.yml <<EOF
name: CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: npm test
- run: docker build -t myapp:latest .
- run: |
docker login forgejo.riotpiao.com \
-u ci-bot \
-p ${{ secrets.CI_BOT_TOKEN }}
docker push forgejo.riotpiao.com/rock/myapp:latest
EOF
git add .forgejo/workflows/ci.yml
git commit -m "ci: add build workflow"
git push
3. Trigger deployment:
# Update deployment repo (rock/deploy)
git clone https://forgejo.riotpiao.com/rock/deploy.git
cd deploy
# Update image tag
sed -i 's|forgejo.riotpiao.com/rock/myapp:.*|forgejo.riotpiao.com/rock/myapp:abc123|' k8s/deployment.yaml
git add k8s/deployment.yaml
git commit -m "deploy: bump myapp to abc123"
git push
4. Argo CD auto-syncs:
# Watch deployment
k rollout status -n <app-namespace> deployment/<app-name>
# 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:
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:
${{ 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):
- 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):
- 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):
# 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):
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:
# 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:
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 workflowsargocd_app_sync_duration_seconds— deployment timeargocd_app_info{sync_status="OutOfSync"}— drift detection
Troubleshooting
Workflow fails silently:
# 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):
# 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:
# Check deploy repo changes
argocd app diff story-crater
# Manual sync
argocd app sync story-crater --prune
Webhook not triggering:
# 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.