blumeops/plans/ci-cd-bootstrap/00_overview.md

146 lines
6.7 KiB
Markdown

# Forgejo Actions CI/CD Bootstrap Plan
This plan details the setup of Forgejo Actions as the CI/CD system for blumeops, starting with the bootstrapping problem: using Forgejo to build and deploy Forgejo itself.
## Goals
1. **Forgejo Actions** as the primary CI system (replaces Woodpecker from original plan)
2. **Self-hosted Forgejo** built from source, deployed as mcquack LaunchAgent on indri
3. **Container builds** for ArgoCD manifests (devpi, etc.)
4. **Cron-scheduled tasks** via k8s CronJobs (not Actions)
5. **Local development** parity using `act` for workflow testing
## Why Forgejo Actions over Woodpecker?
- Native integration with Forgejo (no OAuth setup, automatic repo detection)
- GitHub Actions compatible syntax (huge ecosystem of reusable actions)
- `act` tool for local testing on gilbert
- Single system to maintain instead of two
## Architecture Overview
```
┌─────────────────────────────────────────────────────────────────┐
│ INDRI │
│ ┌─────────────────────┐ │
│ │ Forgejo │ ← Built from source │
│ │ (mcquack agent) │ ← Deploys itself via CI │
│ │ │ │
│ │ - Web UI (3001) │ │
│ │ - SSH (2200) │ │
│ │ - Actions enabled │ │
│ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│ SSH deploy
┌─────────────────────────────────────────────────────────────────┐
│ KUBERNETES (minikube) │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ Forgejo Runner │ │ Other Services │ │
│ │ (act_runner) │ │ (via ArgoCD) │ │
│ │ │ │ │ │
│ │ - Polls Forgejo │ │ │ │
│ │ - Runs workflows │ │ │ │
│ │ - Docker-in-Docker │ │ │ │
│ └─────────────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```
## Phases
| Phase | Name | Description |
|-------|------|-------------|
| 1 | [Enable Actions](P1_enable_actions.md) | Configure Forgejo for Actions, deploy runner |
| 2 | [Mirror & Build](P2_mirror_and_build.md) | Mirror upstream Forgejo, create build workflow |
| 3 | [Self-Deploy](P3_self_deploy.md) | Forgejo deploys itself, transition to mcquack |
| 4 | [Container Builds](P4_container_builds.md) | Build custom container images (devpi, etc.) |
## The Bootstrap Problem
**Chicken-and-egg**: We need Forgejo Actions to build Forgejo, but Forgejo must be running first.
**Solution**:
1. Keep current brew-based Forgejo running during setup
2. Enable Actions, deploy runner
3. Mirror upstream Forgejo, create build workflow
4. First CI build creates the binary
5. CI deploys binary to indri as mcquack service
6. `brew services stop forgejo` and uninstall
7. Future builds: Forgejo builds and deploys itself
**Risk mitigation**: If self-deployment breaks Forgejo:
- blumeops is mirrored to GitHub
- Manual recovery: build on gilbert, scp to indri, restart service
- See Disaster Recovery section in P3
## Ansible Role Strategy
The forgejo ansible role will follow the zot/alloy pattern:
1. **Check binary exists** at expected path
2. **If missing**: Fail with message pointing to CI trigger instructions
3. **If present**: Deploy config, ensure LaunchAgent loaded
Ansible does NOT:
- Build the binary (that's CI's job)
- Deploy new versions (that's CI's job)
Ansible DOES:
- Manage app.ini configuration (sans secrets)
- Manage mcquack LaunchAgent plist
- Ensure service is running
- Collect logs via Alloy
## Files Summary
### New Files
| Path | Purpose |
|------|---------|
| `argocd/apps/forgejo-runner.yaml` | ArgoCD Application for runner |
| `argocd/manifests/forgejo-runner/` | Runner k8s manifests |
| `.forgejo/workflows/build-forgejo.yml` | Build workflow in blumeops repo |
| (on forge) `eblume/forgejo/.forgejo/workflows/` | Build workflow in forgejo mirror |
### Modified Files
| Path | Change |
|------|--------|
| `ansible/roles/forgejo/` | Complete rewrite for mcquack pattern |
| `ansible/roles/alloy/defaults/main.yml` | Update forgejo log paths |
| zk cards | Update forgejo, argocd, blumeops cards |
### Credentials Needed
| Item | Purpose | Storage |
|------|---------|---------|
| Runner registration token | Runner auth to Forgejo | 1Password |
| SSH deploy key | Runner SSH to indri | 1Password + k8s secret |
## Related Plans
- [P7_forgejo.md](../k8s-migration/P7_forgejo.md) - Original k8s migration plan (superseded for Forgejo itself, but SSH hostname split info still relevant)
- [P8_woodpecker.md](../k8s-migration/P8_woodpecker.md) - Original Woodpecker plan (superseded by Forgejo Actions)
## Decision Log
### 2026-01-23: Forgejo Actions over Woodpecker
**Decision**: Use Forgejo Actions instead of Woodpecker CI
**Rationale**:
- Native Forgejo integration (Actions is built-in)
- GitHub Actions compatible (reuse existing actions)
- `act` for local testing
- One less system to deploy and maintain
### 2026-01-23: Keep Forgejo on indri (not k8s)
**Decision**: Forgejo stays on indri as mcquack service, not migrated to k8s
**Rationale**:
- Avoid circular dependency (ArgoCD needs Forgejo to deploy Forgejo)
- Simpler SSH handling (direct port, no k8s networking complexity)
- Forgejo is critical infrastructure, benefits from isolation
- Can still use Tailscale serve for external access