225 lines
4.9 KiB
Markdown
225 lines
4.9 KiB
Markdown
# CI/CD for All Poimen Repos — Standardized Pattern
|
|||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
All Poimen repos should follow the same CI/CD pattern for consistency and maintainability.
|
||
|
|
|
||
|
|
**Pattern**: Test locally → Build image → Push to registry → ArgoCD deploys
|
||
|
|
|
||
|
|
**Based on**: homelab-frontend (proven production pattern)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Repos & Status
|
||
|
|
|
||
|
|
### Repos That Need Docker Deployment
|
||
|
|
|
||
|
|
| Repo | Status | Dockerfile | Notes |
|
||
|
|
|------|--------|-----------|-------|
|
||
|
|
| **poimen-memory** | ✅ Ready | Yes | This repo - see `.forgejo/workflows/build.yaml` |
|
||
|
|
| **poimen** | ⏳ TBD | Yes (assumed) | Orchestrator - needs deployment |
|
||
|
|
| **poimen-workflows** | ⏳ TBD | Maybe | Check if containerized |
|
||
|
|
|
||
|
|
### Repos That Don't Need Docker
|
||
|
|
|
||
|
|
| Repo | Status | Type | Notes |
|
||
|
|
|------|--------|------|-------|
|
||
|
|
| **homelab** | ✅ Done | K8s manifests | Validates with yamllint + kubeval |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Implementation Checklist for Each Repo
|
||
|
|
|
||
|
|
### Step 0: Prerequisites
|
||
|
|
- [ ] Repo has a `Dockerfile`
|
||
|
|
- [ ] Repo has a `.forgejo/` or `.gitea/` directory
|
||
|
|
- [ ] Docker builds successfully: `docker build -t test:latest .`
|
||
|
|
- [ ] Tests pass: `cargo test` / `npm test` / etc
|
||
|
|
|
||
|
|
### Step 1: Create Workflow File
|
||
|
|
```bash
|
||
|
|
# Copy from poimen-memory:
|
||
|
|
cp ~/workplace/Poimen/memory/.forgejo/workflows/build.yaml \
|
||
|
|
~/workplace/Poimen/<repo>/.forgejo/workflows/build.yaml
|
||
|
|
|
||
|
|
# Edit if needed:
|
||
|
|
# - Change IMAGE_NAME from "rock/poimen-memory" to "rock/<your-repo>"
|
||
|
|
# - Adjust test command if not Rust (cargo test)
|
||
|
|
```
|
||
|
|
|
||
|
|
### Step 2: Set Repository Secret
|
||
|
|
```
|
||
|
|
https://git.riotpiao.com/rock/<repo>/settings/secrets
|
||
|
|
|
||
|
|
Add:
|
||
|
|
- Name: REGISTRY_PAT
|
||
|
|
- Value: <org-token-or-personal-token>
|
||
|
|
```
|
||
|
|
|
||
|
|
### Step 3: Commit & Push
|
||
|
|
```bash
|
||
|
|
git add .forgejo/workflows/build.yaml
|
||
|
|
git commit -m "Add CI/CD: auto-build and push to registry"
|
||
|
|
git push origin main
|
||
|
|
```
|
||
|
|
|
||
|
|
### Step 4: Create ArgoCD Application
|
||
|
|
```bash
|
||
|
|
# Create k8s/argocd/<repo>-app.yaml
|
||
|
|
|
||
|
|
apiVersion: argoproj.io/v1alpha1
|
||
|
|
kind: Application
|
||
|
|
metadata:
|
||
|
|
name: poimen-<repo>-app
|
||
|
|
namespace: argocd
|
||
|
|
spec:
|
||
|
|
project: homelab
|
||
|
|
source:
|
||
|
|
repoURL: https://forgejo.riotpiao.com/rock/poimen-<repo>.git
|
||
|
|
targetRevision: main
|
||
|
|
path: k8s/app # adjust if different
|
||
|
|
destination:
|
||
|
|
server: https://kubernetes.default.svc
|
||
|
|
namespace: poimen
|
||
|
|
syncPolicy:
|
||
|
|
automated:
|
||
|
|
prune: true
|
||
|
|
selfHeal: true
|
||
|
|
```
|
||
|
|
|
||
|
|
### Step 5: Apply Application
|
||
|
|
```bash
|
||
|
|
kubectl apply -f k8s/argocd/<repo>-app.yaml
|
||
|
|
```
|
||
|
|
|
||
|
|
### Done! ✅
|
||
|
|
- Every push to main triggers:
|
||
|
|
1. Test suite
|
||
|
|
2. Docker build
|
||
|
|
3. Push to `forgejo.riotpiao.com/rock/<repo>:latest`
|
||
|
|
4. ArgoCD auto-deploys
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## File Reference
|
||
|
|
|
||
|
|
### Workflow Comparison
|
||
|
|
|
||
|
|
**poimen-memory** (current):
|
||
|
|
```yaml
|
||
|
|
runs-on: golang
|
||
|
|
container:
|
||
|
|
image: docker:27-cli
|
||
|
|
volumes:
|
||
|
|
- /docker-certs/client:/docker-certs/client:ro
|
||
|
|
env:
|
||
|
|
DOCKER_HOST: tcp://localhost:2376
|
||
|
|
DOCKER_TLS_VERIFY: "1"
|
||
|
|
DOCKER_CERT_PATH: /docker-certs/client
|
||
|
|
```
|
||
|
|
|
||
|
|
**Why this setup:**
|
||
|
|
- Runs on `golang` runner (has Docker daemon)
|
||
|
|
- Uses Docker CLI in container with DinD (Docker-in-Docker)
|
||
|
|
- TLS certs mounted for secure daemon access
|
||
|
|
- Allows building AND pushing in same job
|
||
|
|
|
||
|
|
### Test Job
|
||
|
|
|
||
|
|
Adjust for your language:
|
||
|
|
|
||
|
|
**Rust** (poimen-memory):
|
||
|
|
```yaml
|
||
|
|
runs-on: rust
|
||
|
|
steps:
|
||
|
|
- uses: actions/checkout@v4
|
||
|
|
- run: cargo test --all
|
||
|
|
```
|
||
|
|
|
||
|
|
**Go**:
|
||
|
|
```yaml
|
||
|
|
runs-on: golang
|
||
|
|
steps:
|
||
|
|
- uses: actions/checkout@v4
|
||
|
|
- run: go test ./...
|
||
|
|
```
|
||
|
|
|
||
|
|
**Node.js**:
|
||
|
|
```yaml
|
||
|
|
runs-on: docker
|
||
|
|
steps:
|
||
|
|
- uses: actions/checkout@v4
|
||
|
|
- run: npm install && npm test
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Organization-Wide Setup
|
||
|
|
|
||
|
|
### One-Time: Set Organization Secret
|
||
|
|
Instead of per-repo secrets, Forgejo supports organization secrets.
|
||
|
|
|
||
|
|
**If available**, set `REGISTRY_PAT` at org level:
|
||
|
|
```
|
||
|
|
https://git.riotpiao.com/rock/settings/secrets
|
||
|
|
```
|
||
|
|
|
||
|
|
Then all repos automatically inherit it (no per-repo setup needed).
|
||
|
|
|
||
|
|
**Check**: Try accessing org secrets settings
|
||
|
|
- If available: set once, use everywhere
|
||
|
|
- If not: set per-repo (5 minutes per repo)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Monitoring & Troubleshooting
|
||
|
|
|
||
|
|
### Build Failures
|
||
|
|
|
||
|
|
**Check logs:**
|
||
|
|
```
|
||
|
|
https://git.riotpiao.com/rock/<repo>/actions
|
||
|
|
```
|
||
|
|
|
||
|
|
**Common issues:**
|
||
|
|
- Test failures → Fix tests locally
|
||
|
|
- Docker build error → Check Dockerfile syntax
|
||
|
|
- Push fails → Verify REGISTRY_PAT token
|
||
|
|
|
||
|
|
### Deployment Issues
|
||
|
|
|
||
|
|
**Watch ArgoCD:**
|
||
|
|
```bash
|
||
|
|
kubectl get application -n argocd poimen-<repo>-app -w
|
||
|
|
kubectl logs -n argocd argocd-application-controller | grep poimen
|
||
|
|
```
|
||
|
|
|
||
|
|
**Check pods:**
|
||
|
|
```bash
|
||
|
|
kubectl get pods -n poimen -l app.kubernetes.io/name=poimen-<repo> -w
|
||
|
|
kubectl describe pod -n poimen <pod-name>
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Summary
|
||
|
|
|
||
|
|
**Effort**: ~10 minutes per repo (once)
|
||
|
|
|
||
|
|
**Benefit**:
|
||
|
|
- Zero-touch deployments
|
||
|
|
- Every commit automatically tested & deployed
|
||
|
|
- Consistent across organization
|
||
|
|
- No manual image pushes ever
|
||
|
|
|
||
|
|
**Best practice**: Use org-level secret if available (1 setup, unlimited repos)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Next Steps
|
||
|
|
|
||
|
|
1. **poimen-memory**: ✅ Done (this repo)
|
||
|
|
2. **poimen**: Set up workflow + secret
|
||
|
|
3. **poimen-workflows**: Set up workflow + secret
|
||
|
|
4. **Document in**: homelab-poimen-standard.md (org wiki)
|