The init-container image referenced by DockerRuntimeOrchestrator
(`gitea.siegeln.net/cameleer/cameleer-runtime-loader:latest`) had no CI
producer; it had to be built and pushed by hand. Replicates the
cameleer-saas pattern (single docker job with multiple buildx push
steps), but gates the loader build on a path-diff so unrelated commits
don't rebuild and re-tag a sidecar that didn't change.
- build job: fetch-depth=0 + Detect runtime-loader changes step that
diffs `${{ github.event.before }}..${{ github.sha }}` for paths under
cameleer-runtime-loader/. Falls back to `changed=true` when no prior
commit is reachable (first push to a branch).
- docker job: new `Build and push runtime-loader` step gated on
`needs.build.outputs.loader_changed == 'true'`. Tags with sha and
latest/branch-<slug>, --provenance=false for Gitea, no buildcache
(image is alpine + script).
- Cleanup loops in docker and cleanup-branch jobs include the new
package.
- Rules and loader README updated.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3.4 KiB
3.4 KiB
paths
| paths | ||||
|---|---|---|---|---|
|
CI/CD & Deployment
- CI workflow:
.gitea/workflows/ci.yml— build -> docker -> deploy on push to main or feature branches.paths-ignoreskips the whole pipeline for docs-only /.planning//.claude//*.mdchanges (push and PR triggers). - Build step skips integration tests (
-DskipITs) — Testcontainers needs Docker daemon - Build caches (parallel
actions/cache@v4steps in thebuildjob):~/.m2/repository(key on allpom.xml),~/.npm(key onui/package-lock.json),ui/node_modules/.vite(key onui/package-lock.json+ui/vite.config.ts). UI install usesnpm ci --prefer-offline --no-audit --fund=falseso the npm cache is the primary source. - Maven build performance (set in
pom.xmlandcameleer-server-app/pom.xml):useIncrementalCompilation=trueon the compiler plugin; Surefire usesforkCount=1C+reuseForks=true(one JVM per CPU core, reused across test classes); Failsafe keepsforkCount=1+reuseForks=true. Unit tests must not rely on per-class JVM isolation. - UI build script (
ui/package.json):buildisvite buildonly — the type-check pass was split out intonpm run typecheck(run separately when you want a fulltsc --noEmitsweep). - Docker: multi-stage build (
Dockerfile),$BUILDPLATFORMfor native Maven on ARM64 runner, amd64 runtime.docker-entrypoint.shimports/certs/ca.peminto JVM truststore before starting the app (supports custom CAs for OIDC discovery withoutCAMELEER_SERVER_SECURITY_OIDCTLSSKIPVERIFY). REGISTRY_TOKENbuild arg required forcameleer-commondependency resolution- Registry:
gitea.siegeln.net/cameleer/cameleer-server(container images) cameleer-runtime-loaderimage (init container that fetches the deployable JAR before the runtime container starts) is built and pushed by the samedockerjob, but only when files undercameleer-runtime-loader/actually changed in the push. Detection runs in thebuildjob (Detect runtime-loader changesstep, diffs${{ github.event.before }}..${{ github.sha }}) and is exposed as theloader_changedjob output. The loader build step usesif: needs.build.outputs.loader_changed == 'true'. Build job's checkout usesfetch-depth: 0so the diff has access to the prior commit.- K8s manifests in
deploy/— Kustomize base + overlays (main/feature), shared infra (PostgreSQL, ClickHouse, Logto) as top-level manifests - Deployment target: k3s at 192.168.50.86, namespace
cameleer(main),cam-<slug>(feature branches) - Feature branches: isolated namespace, PG schema; Traefik Ingress at
<slug>-api.cameleer.siegeln.net - Secrets managed in CI deploy step (idempotent
--dry-run=client | kubectl apply):cameleer-auth,cameleer-postgres-credentials,cameleer-clickhouse-credentials - K8s probes: server uses
/api/v1/health, PostgreSQL usespg_isready -U "$POSTGRES_USER"(env var, not hardcoded) - K8s security: server and database pods run with
securityContext.runAsNonRoot. UI (nginx) runs without securityContext (needs root for entrypoint setup). - Docker: server Dockerfile has no default credentials — all DB config comes from env vars at runtime
- Docker build uses buildx registry cache +
--provenance=falsefor Gitea compatibility - CI: branch slug sanitization extracted to
.gitea/sanitize-branch.sh, sourced by docker and deploy-feature jobs