CI/CD¶
YAAMon uses GitHub Actions for continuous integration, branch image builds, and releases. All build steps run inside Docker — no Go installation is required on the host.
Workflows¶
ci.yml — Continuous Integration¶
Triggers on pushes to main and on pull requests, but only when build-relevant files change. Pushes that touch only docs/**, *.md, contrib/**, examples/**, or other non-code files skip CI entirely — GitHub marks the workflow as passed so docs-only PRs still merge cleanly.
The path filter covers: **/*.go, go.mod, go.sum, Dockerfile, Makefile, web/**, scripts/**, e2e/**, integration_tests/**, .github/workflows/**.
Stages (in order):
- Pre-commit checks — whitespace validation +
go mod tidyverification - Unit tests —
go test ./...inside a Docker container - Docker image build — multi-arch build (amd64 + arm64) verification
- Integration tests — start the SUT container, run Go integration tests against it
- PUID/PGID test — verify the entrypoint uid/gid handling
- GoReleaser snapshot — build
.debpackages without publishing - Deb integration tests — install the
.debon Ubuntu 22.04 and run integration tests
branch.yml — Branch Image Builds¶
Triggers on pushes to any branch except main.
- Builds multi-arch Docker images (amd64 + arm64)
- Pushes to GHCR with the branch name as the tag:
ghcr.io/jchonig/yaamon:<branch-name>ghcr.io/jchonig/yaamon:<branch-name>-<sha7>(pinned SHA for reproducibility)- No GitHub Release or
latesttag update
Branch names become image tags; slashes are converted to dashes:
| Branch | Image tag |
|---|---|
feature/passkeys |
ghcr.io/jchonig/yaamon:feature-passkeys |
fix/auth-bug |
ghcr.io/jchonig/yaamon:fix-auth-bug |
Testing a branch image in production: temporarily change the image tag in your docker-compose.yml:
Restart and test. Revert to latest when done.
release.yml — Release¶
Triggers on v* tag pushes (e.g. v1.2.3).
- Runs the same pre-release tests as CI
- Executes GoReleaser:
- Cross-compiles Linux binaries for amd64 + arm64
- Builds
.debpackages (with systemd unit, post/pre-install scripts) - Builds multi-arch Docker images
- Creates tar.gz archives with binary, README, LICENSE, example config
- Publishes to GitHub Releases (with
RELEASE_NOTES.mdas release notes) - Pushes Docker images to GHCR:
ghcr.io/jchonig/yaamon:<version>(e.g.v1.2.3)ghcr.io/jchonig/yaamon:latest(multi-arch manifest, skipped for pre-releases)
GoReleaser configuration¶
Configured in .goreleaser.yml:
- builds: cross-compile to
linux/amd64andlinux/arm64 - nfpms: Debian package — maintainer, license, config file, systemd service, post-install/pre-remove scripts
- archives: tar.gz with README, LICENSE, example config, systemd unit
- dockers: multi-arch manifest push to GHCR
- changelog: auto-generated from commit messages (excludes docs/test/chore commits)
Deployment topology (reference)¶
The author's production deployment:
Internet / Tailscale
│
▼
Caddy (macvlan IP, ports 80 + 443)
├── TLS termination (Let's Encrypt)
├── HTTP → HTTPS redirect
├── oauth2-proxy sidecar (forward auth, Kanidm OIDC)
└── reverse proxy → yaamon:80 (bridge network, TLS disabled)
YAAMon is on the Docker bridge network and not directly reachable from outside. All auth headers are injected by Caddy/oauth2-proxy.