ADR-022 — CI strategy¶
Context¶
AKKO needs a path from git push to an updated Netcup cluster. Three options
were on the table:
- GitHub Actions — mature, free for public repos, widespread tooling.
- Woodpecker CI (self-hosted, Apache 2.0) — already packaged as
akko-woodpeckersub-chart (disabled by default). - Manual script —
helm/scripts/deploy-netcup-full.shSSH'd on the Netcup host.
Current reality (2026-04-19): - One maintainer. - One production cluster (Netcup). - No external client depending on release artefacts yet. - Self-hosted CI surface adds attack area (even when private).
Decision¶
- Reject GitHub Actions. The AKKO stack is sovereign; a public CI vendor with undocumented observability of source is off-model.
- Keep Woodpecker as an opt-in, private-by-default, future-ready
option.
akko-woodpecker.ingress.enabled=false(ADR commit47f43b7). Operators access it viakubectl port-forwardor a private mesh. Exposure happens only through oauth2-proxy + IP allowlist. - Default CI path is
deploy-netcup-full.shfor now. SSH to Netcup →cd akko && git pull && bash helm/scripts/deploy-netcup-full.sh. Direct terminal logs, one layer of indirection, 5-minute feedback loop. Sufficient for solo dev + single cluster. - Switch to Woodpecker when one of four thresholds hits (Sprint 46 in the roadmap, task #188):
- A 2nd contributor opens PRs
- A 2nd deployment target appears (staging, pilot customer)
- A commercial audit requires CI-traceable release evidence
- A public signed release (
v*tag, Cosign OIDC-verifiable signatures from a known issuer)
Consequences¶
Positive¶
- Zero wasted time debugging CI layers when there is no gain yet.
- Operators get direct
helm upgradelogs, shortest feedback loop. .woodpecker/*.ymlpipelines stay in the repo as executable specifications of what a full build looks like — a future contributor or auditor reads them as the build recipe even without Woodpecker running.- Security posture: no public CI URL, no OAuth App sitting idle.
- No commercial CI dependency on a US vendor for a sovereign stack.
Negative¶
- No PR gate — a push to
mainis accepted without automated lint. Mitigation:pre-commithook locally + the user runshelm lint+lint-no-hardcoding.sh+check-licenses.shas part of the commit workflow. - No auditable history of CI runs beyond terminal output. Mitigation:
capture
deploy-netcup-full.shoutput withteeand store under/var/log/akko-deploys/<date>.log. - Slightly more friction when onboarding the 2nd maintainer.
Mitigation: Sprint 46 trigger is explicit — once a 2nd contributor
arrives, turning on Woodpecker is a 45-minute lift documented in
docs/admin/woodpecker-access.md.
Alternatives considered but rejected¶
- Drone CI — very similar to Woodpecker but Apache 2.0 is only the Drone OSS (Harness commercial pressure). Chose Woodpecker for license clarity.
- Jenkins — too heavy (1.5 Gi RAM minimum), plugin security surface, XML configuration tax.
- Forgejo Actions / Gitea Actions — interesting but would pull in a full Forgejo/Gitea install we don't otherwise need.
- Argo Workflows / Tekton — excellent for k8s-native CI but stronger argument for automation at the commercial scale, not solo.
When to revisit¶
- First external contributor pull request (Sprint 46 trigger 1).
- First client demonstration of the release pipeline (Sprint 46 trigger 3).
- Release
v2026.07or later if distributed signed artefacts become a contractual requirement (trigger 4).
Status¶
Accepted 2026-04-19. Revisit at the Sprint 46 kick-off meeting.