Latin: munitor (fortifier, protector) -- KofTwentyTwo's unified CircleCI orb for building, testing, and deploying all repositories. Pipeline changes happen in one place instead of 80+ repos.
| Tier | Internal until classified -- listed under Awaiting classification in the KofTwentyTwo standards MAINTAINERS.md; Product-tier requirements are being adopted |
| Standards | Targets KofTwentyTwo standards 1.0.0 |
| Orb | kof22/munitor, latest stable 0.3.11 |
| Security | SECURITY.md |
| Contributing | CONTRIBUTING.md |
Munitor uses CircleCI's dynamic configuration to generate your full CI/CD pipeline at runtime. Each repo has a minimal .circleci/config.yml that triggers Munitor, and a .munitor.yml that declares what your project needs. Munitor reads your config, selects the right template, and generates a complete CircleCI workflow.
repo/.munitor.yml --> Munitor setup job --> Generated pipeline --> Build/Test/Deploy
This file is identical across all repos:
version: 2.1
setup: true
orbs:
munitor: kof22/munitor@0.3
workflows:
setup:
jobs:
- munitor/generate_pipelinePick your pipeline type and create the config in your repo root. See Pipeline Types below.
Munitor validates branch names and will fail on non-conforming names.
| Pattern | Purpose |
|---|---|
main |
Production releases |
develop |
Integration |
staging |
Staging environment branch |
feature/<name> |
Feature work |
release/<version> |
Release prep |
hotfix/<name> |
Production fixes |
The new java-webapp docs-only path is opt-in and must be adopted after the
aggregate required check is published and verified. Do not enable it against an
older orb or while individual build jobs remain required:
ci:
docs_only: trueOnly changes confined to root README.md, CHANGELOG.md, CONTRIBUTING.md, or
Markdown files under docs/ (including nested directories) qualify. Feature and
hotfix branches use their complete diff from the merge base with main; main
uses its first-parent diff. Tags, release and other branches, shallow history,
failed comparisons, empty diffs, and any uncertain classification keep the full
pipeline. The docs path retains secret scanning and emits the aggregate gate;
it does not build or deploy an image.
Migration order: publish the gate-capable orb, adopt it with docs-only disabled,
and verify the real GitHub context ci/circleci: ci-ready on a consumer run. Then
replace that repository's required-check list with the verified aggregate gate,
preserving all other branch rules. A single adoption PR may update both orb pins
and enable ci.docs_only: those config changes force full CI. Verify the gate
and migrate required checks before merging it or opening a docs-only PR. Munitor's
own native no-op gate reports ci/circleci: lint-pack/ci-ready. Both features
ship in 0.3.11. Verify each consumer's actual successful context before changing
its rules; see the adoption record.
Use native Website-Backend Insights,
PR timings,
and Test Insights
to measure results. Compare matching branches/windows and track the docs-checks
median separately from full builds. The historical local report
C:/Users/james/.cache/ci-insights-report.md ends October 17 and does not establish
the speed of this change. No additional reporting job is needed.
Native auto-cancel is enabled for Website-Backend, whose default main is exempt.
It remains disabled for Munitor: its default is develop, so main release work
would not receive that exemption.
- CircleCI project: Add your repo at https://app.circleci.com
- Enable dynamic config: Project Settings > Advanced > "Enable dynamic config using setup workflows"
- Allow uncertified orbs: Organization Settings > Security > "Allow uncertified orbs"
- CircleCI contexts (Organization Settings > Contexts):
| Context | Secrets | Used By |
|---|---|---|
ghcr |
GHCR_TOKEN, GHCR_USERNAME |
Docker push to GitHub Container Registry |
github |
GITHUB_TOKEN |
Git operations, CD repo updates, SBOM, GitHub Releases |
sonarcloud |
SONAR_TOKEN |
SonarCloud analysis |
nvd |
NVD_API_KEY |
OWASP dependency check (Java only, optional) |
Munitor is a public CircleCI orb: any CircleCI organization can use it without forking. This checklist covers what a new consumer needs, for example a Java/Maven web service. A QQQ application should also read the QQQ adoption checklist (section 7 covers release tooling).
Version. Use kof22/munitor@0.3.11 (or @0.3 to float on the 0.3 line) in .circleci/config.yml, and the same value as orb_version in .munitor.yml. Keep the setup orb and the generated pipeline on the same line.
.circleci/config.yml: the setup config from Quick Start, pinned tokof22/munitor@0.3.11..munitor.yml: pick a pipeline type. A Java service isjava-webapp. KofTwentyTwo's Website-Backend is a working example; a generalized version:
pipeline: java-webapp
orb_version: "0.3.11"
image_name: my-service
java_version: "21"
docker:
registry: ghcr.io/my-org # the org default is ghcr.io/KofTwentyTwo -- always set this
cd:
repo: my-org/my-gitops-repo # omit to skip GitOps write-back
format: kustomize # default is helm (image.tag in values.yaml)
path: apps/my-service/kustomization.yaml # optional explicit file in a consolidated repo
production_only: true # only main updates the GitOps repo
supplemental_images: # optional extra images built from the same commit and version
- name: migrations
dockerfile: docker/Dockerfile.migrations
cd:
image_name: ghcr.io/my-org/my-service-migrations
health:
path: /health
port: "8000"
db: "true" # start a PostgreSQL sidecar for the health gate
migrations: migrations # run the <image>-migrations image against it first
smoke_paths: [/health]
sonar:
project_key: my-org_my-service # omit to skip SonarCloud
contexts:
registry: ghcr
github: github
sonar: sonarcloud # required only with sonar.project_key
nvd: nvd # optional
org: # organization defaults (see Known limitations)
ci_email: ci@example.com
ci_name: My CI- A health endpoint that returns HTTP 200 within 30 seconds of container start (see Health Check Requirement).
- A Dockerfile only for
node-webapp(docker.use_repo_dockerfile: true) or forsupplemental_images;java-webappandnode-apigenerate theirs.
See Prerequisites: enable dynamic config (setup workflows) and allow uncertified orbs in the consuming organization.
CircleCI organization contexts; the context names are set through contexts.*.
| Context | Variables | Needed for |
|---|---|---|
registry (e.g. ghcr) |
GHCR_USERNAME, GHCR_TOKEN (write:packages) |
Pushing images and inspecting existing tags; the immutable-tag guard fails closed without registry access |
| github | GITHUB_TOKEN with contents write on the app repository and on the GitOps repository |
Reserving vX.Y.Z tags on main (required by production), GitHub Releases, GitOps write-back |
| sonar (optional) | SONAR_TOKEN; SonarCloud organization from SONAR_ORG (default KofTwentyTwo) |
SonarCloud analysis |
| nvd (optional) | NVD_API_KEY |
OWASP dependency check; owasp: false disables the check |
Branch names are enforced: main, develop, staging, feature/*, release/*, hotfix/*. A merge to main is a production release: it reserves the next vX.Y.Z tag, pushes the image, updates the GitOps repository and creates the GitHub Release. Protect main accordingly.
Munitor stops at the GitOps commit. The consumer provides:
- a GitOps repository whose
kustomization.yaml(animages[]entry named<registry>/<image_name>) or Helmvalues.yaml(image.tag) Munitor edits; - Argo CD (or another controller) syncing that repository, with pull access to the registry;
- the runtime database and its backups. KofTwentyTwo's website uses a CloudNativePG cluster with an object-store backup and a
ScheduledBackup, declared inKofTwentyTwo/cluster-gitops(tenants/kof22/website). Munitor only starts a throwaway PostgreSQL sidecar for the CI health gate and never touches a real database; - schema migrations. Either the application migrates at start-up, or the deployment runs the
migrationssupplemental image (the KofTwentyTwo website runs a pre-migration backup image and then the migrations image as init containers).health.migrationsonly exercises that image in CI.
- Organization defaults point at KofTwentyTwo: registry
ghcr.io/KofTwentyTwo, npm scope@koftwentytwo, CI emailmunitor-ci@koftwentytwo.com, SonarCloud organizationKofTwentyTwo. Setdocker.registry, theorg.*keys andSONAR_ORGexplicitly. Theorgblock is read, but the unknown-key check prints a harmlessUnknown key 'org'warning. productionbuilds onmainskip the quality gates, which run onrelease/*andhotfix/*pull requests. Do not merge unreviewed branches straight tomain.- CircleCI only; there is no GitHub Actions equivalent. Docker jobs use machine executors.
0.3.3 reserves release tags atomically on main (needs the github context on build-and-test, which generated production workflows include), refuses to overwrite a version image tag built from another commit, and checks tag ownership before the GitOps bump. A consumer moving from a Munitor-derived orb with a tag-driven production trigger should compare that model with Munitor's merge-to-main model before switching.
For Node.js/Next.js applications with Docker deployment.
Minimal config:
pipeline: node-api
orb_version: "0.3"
image_name: my-app
docker:
registry: ghcr.io/KofTwentyTwo
contexts:
registry: ghcr
github: githubFull config with all options:
pipeline: node-api
orb_version: "0.3"
image_name: my-app
node_version: "22" # default: 20
sonar:
project_key: KofTwentyTwo_my-app # omit to skip SonarCloud
docker:
registry: ghcr.io/KofTwentyTwo
cd:
repo: KofTwentyTwo/my-app-cd # omit to skip GitOps CD updates
env:
release: staging # default: staging (CD target for release/* branches)
coverage:
min_instruction: 80 # default: 70
e2e: true # default: false (Playwright)
sbom: true # default: false
sast: true # default: false (Semgrep)
health:
path: /api/health # default: /api/health
port: 3000 # default: 3000 (node-api), 8080 (java-webapp)
npm:
private_registry: true # authenticate to private npm before install
services: # start containers before tests
- image: postgres:17
port: 5432
healthcheck: "pg_isready -U test -d mydb"
env:
POSTGRES_USER: test
POSTGRES_PASSWORD: test
POSTGRES_DB: mydb
test:
setup: scripts/ci-setup.sh # script to run before tests
commands: # replaces default Jest runner
- npx playwright install --with-deps chromium
- npx playwright test
coverage:
tool: nyc # default: jest
command: npm run coverage # custom coverage command
min_instruction: 80 # overrides top-level coverage.min_instruction
contexts:
registry: ghcr
github: github
sonar: sonarcloudDockerfile: Auto-generated multi-stage build. Default framework is nextjs, targeting Next.js standalone output (requires output: 'standalone' in next.config.js). Set node: { framework: express } for Express apps (production deps only, uses node . entrypoint). If you need full control over the Dockerfile, use node-webapp instead.
For Node.js applications that provide their own Dockerfile (unlike node-api which auto-generates one). Use this when your app needs a custom Docker build process.
Minimal config:
pipeline: node-webapp
orb_version: "0.3"
image_name: my-webapp
docker:
registry: ghcr.io/KofTwentyTwo
use_repo_dockerfile: true
contexts:
registry: ghcr
github: githubFull config with all options:
pipeline: node-webapp
orb_version: "0.3"
image_name: my-webapp
node_version: "22" # default: 20
sonar:
project_key: KofTwentyTwo_my-webapp # omit to skip SonarCloud
docker:
registry: ghcr.io/KofTwentyTwo
use_repo_dockerfile: true # preserve the repository Dockerfile
cd:
repo: KofTwentyTwo/cluster-gitops # omit to skip GitOps CD updates
format: kustomize
production_only: true # only main writes this production target
path: tenants/my-app/website/kustomization.yaml
env:
release: staging # default: staging (CD target for release/* branches)
coverage:
min_instruction: 80 # default: 70
e2e: true # default: false (Playwright)
sbom: true # default: false
sast: true # default: false (Semgrep)
health:
path: /api/health # default: /api/health
port: 3000 # default: 3000
npm:
private_registry: true # authenticate to private npm before install
services: # start containers before tests
- image: postgres:17
port: 5432
healthcheck: "pg_isready -U test -d mydb"
env:
POSTGRES_USER: test
POSTGRES_PASSWORD: test
POSTGRES_DB: mydb
test:
setup: scripts/ci-setup.sh # script to run before tests
commands: # replaces default Jest runner
- npx playwright install --with-deps chromium
- npx playwright test
coverage:
tool: nyc # default: jest
command: npm run coverage # custom coverage command
min_instruction: 80 # overrides top-level coverage.min_instruction
contexts:
registry: ghcr
github: github
sonar: sonarcloudDockerfile: Set docker.use_repo_dockerfile: true and provide Dockerfile in the repo root when the application owns its runtime contract. Munitor preserves and builds it, runs a health check, scans with Trivy, and pushes to the registry. Without the option, Munitor retains the legacy generated Dockerfile behavior. Use node-api when an always-generated framework Dockerfile is preferred.
For Java/Maven applications with Docker deployment.
Minimal config:
pipeline: java-webapp
orb_version: "0.3"
image_name: my-service
docker:
registry: ghcr.io/KofTwentyTwo
contexts:
registry: ghcr
github: github
nvd: nvd # optional, for OWASP dependency checkFull config with all options:
pipeline: java-webapp
orb_version: "0.3"
image_name: my-service
java_version: "21" # default: 21
sonar:
project_key: KofTwentyTwo_my-service # omit to skip SonarCloud
docker:
registry: ghcr.io/KofTwentyTwo
cd:
repo: KofTwentyTwo/my-service-cd # omit to skip GitOps CD updates
env:
release: staging # default: staging (CD target for release/* branches)
coverage:
min_instruction: 80 # default: 70
e2e: true # default: false
sbom: true # default: false
sast: # or just `sast: true` to fail on findings
fail_on_findings: false # warn-only mode during migration
health:
path: /api/health # default: /api/health
port: 8080 # default: 8080
contexts:
registry: ghcr
github: github
sonar: sonarcloud
nvd: nvd # optional, for OWASP dependency checkWhat runs: Maven build/test, Checkstyle, SpotBugs, PMD, JaCoCo coverage, OWASP + Trivy security, Docker build/push (Dockerfile auto-generated), gitleaks. OWASP dependency check requires the nvd context; if omitted, the security scan runs without NVD database enrichment.
Dockerfile: Auto-generated production-ready image using Eclipse Temurin JRE Alpine. Includes non-root user (uid 1001), JVM container tuning flags, Docker HEALTHCHECK, and configurable port via health.port. The pre-built JAR from CI is copied directly (no redundant Maven build stage). PR and release image builds pull the current base and bypass Docker layer caching for generated Java/Gradle runtime images, ensuring the Alpine package upgrade runs on every build. Node builds retain their layer cache. Trivy gates remain required.
For Terraform/Terragrunt infrastructure repos.
Minimal config:
pipeline: terraform
orb_version: "0.3"
terraform:
path: terraform/Full config:
pipeline: terraform
orb_version: "0.3"
terraform:
path: terraform/ # default: terraform/
live_path: terraform/live # default: terraform/live
environments: # default: [production]
- production
- staging
checkov_skip: "CKV_AWS_144,CKV_AWS_145"
sast: true # default: false (Semgrep)What runs: tofu fmt check, terragrunt init/validate per environment, Checkov, tfsec, Trivy, gitleaks.
For CD/GitOps repositories containing Kubernetes manifests, Kustomize overlays, sealed secrets, and ArgoCD application definitions. No application code, no Docker builds, no CD updates.
Minimal config:
pipeline: validate-cd-repo
orb_version: "0.3"Full config:
pipeline: validate-cd-repo
orb_version: "0.3"
kustomize:
version: "5.5.0" # default: 5.5.0
base_path: base/ # default: base/
overlays: # default: auto-detect from overlays/*/kustomization.yaml
- dev
- staging
- production
load_restrictor: true # default: true (--load-restrictor LoadRestrictionsNone)
scan_overlay: production # default: production
kube_linter_config: .kube-linter.yaml # default: none (auto-detect if file exists)What runs: YAML lint, kustomize build validation (base + all overlays), kubesec security scan, kube-linter best practices check, gitleaks secrets scan.
For ArgoCD app-of-apps repositories that use environment directories (envs/) instead of the standard base/ + overlays/ kustomize layout. Functionally identical to validate-cd-repo but with a different default directory structure.
Minimal config:
pipeline: argocd-apps
orb_version: "0.3"Full config:
pipeline: argocd-apps
orb_version: "0.3"
kustomize:
version: "5.5.0" # default: 5.5.0
base_path: "" # empty string skips base build
overlay_dir: envs # default: overlays
overlays: # default: auto-detect from {overlay_dir}/*/kustomization.yaml
- dev
- staging
- production
load_restrictor: true # default: true (--load-restrictor LoadRestrictionsNone)
scan_overlay: production # default: production
kube_linter_config: .kube-linter.yaml # default: none
yamllint_paths: "envs/ apps/" # default: bootstrap/ projects/ credentials/ envs/ apps/ infra/What runs: YAML lint, kustomize build validation (overlays only when base_path is empty), kubesec security scan, kube-linter best practices check, gitleaks secrets scan.
For SDK packaging and GitHub Releases. Triggered by semver tags (v1.2.3).
pipeline: sdk-distribution
orb_version: "0.3"
contexts:
github: githubWhat runs: Tag validation, SDK assembly/scrub/validate/package, SHA-256 checksums, GitHub Release with artifacts.
Each workflow runs on specific branches and includes jobs based on your config:
| Workflow | Branches | Jobs |
|---|---|---|
pr-checks |
feature/*, hotfix/* |
Build, test, lint, coverage, security scans, container image scan (Docker modules) |
develop |
develop |
All pr-checks + Docker build/push + CD update (dev env) |
staging |
staging |
All pr-checks + Docker build/push + CD update (staging env) |
release-candidate |
release/* |
All pr-checks + Docker, CD (staging), SonarCloud, SBOM, GitHub Release (pre-release) |
production |
main |
Build + Docker + CD (prod) + GitHub Release (no quality gates) |
For validate-cd-repo and argocd-apps, all three workflows (pr-checks, develop, release) run the same 5-job set: yaml-lint, kustomize-validate, kubesec-scan, kube-linter, secrets-scan.
For java-webapp, gradle-webapp, node-api, and node-webapp, PRs run
image-scan after build-and-test: build the application and any supplemental
images locally, then fail on HIGH/CRITICAL CVEs with the same Trivy policy and
repository-root .trivyignore as release builds. JSON reports are saved as
artifacts. This job does not log in, publish images, reserve tags, or update CD.
Release candidates already scan through docker-build-push and do not run a
second image scan job.
checkout
--> build-and-test
--> image-scan (local build + Trivy, including supplemental images)
--> code-quality
--> coverage
--> security-scan
--> e2e-tests (if enabled)
--> secrets-scan (parallel)
--> sast-scan (parallel)
For release-candidate workflows, docker-build-push runs after all quality checks pass, followed by sbom, update-cd-repo (targeting staging), and github-release (marked as pre-release). For production workflows, docker-build-push runs directly after build-and-test (no quality gates -- those were enforced on the release branch), followed by update-cd-repo (targeting prod) and github-release (full release). The github-release job creates the GitHub Release for the version tag reserved during build-and-test (see Release version integrity).
Production versions on main are unique per commit, even when merges land minutes apart:
- Atomic reservation --
build-and-testonmainreservesvX.Y.Zby creating the git tag through the GitHub API before the version is baked into artifacts. Tag creation is create-if-absent, so concurrent pipelines serialize on it: if another commit already owns the tag, the build takes the next patch version. A rerun of the same commit reuses its tag. Existing tags are never moved. Requires the GitHub context onbuild-and-test(present in the generatedproductionworkflows). - Immutable image tags -- images carry an
org.opencontainers.image.revisionlabel.docker-build-pushrefuses to push a version tag (main or supplemental) that already exists for a different commit, and fails closed if the registry cannot be inspected. Environment tags such asdevelopstay mutable. - Ownership-checked GitOps bump --
update-cd-repoverifies thatvX.Y.Zpoints at the pipeline's commit before writing the version to the CD repository. - Signed GitOps commits --
update-cd-repocreates the CD repository commit through the GitHub GraphQL API (createCommitOnBranch) instead ofgit push. GitHub signs API-created commits, so they show as Verified and pass a CD repository ruleset that requires signed commits, with no bypass actor. The commit is authored by the identity behindGITHUB_TOKEN; the source repository and commit are recorded in the commit body. Concurrent bumps retry against the new branch head (expectedHeadOid). Theci_git_email/ci_git_nameparameters andorg.ci_email/org.ci_nameno longer affect these commits. - Release targets the built commit --
github-releasetargetsCIRCLE_SHA1, not the movingmainhead, and refuses if the tag points elsewhere.
cd_path is rendered into generated pipelines only when cd.path is set, so manifests that pin an older orb_version keep validating.
Munitor follows a three-environment GitFlow model: dev, staging, prod. Release candidates on staging serve as the QA/UAT gate -- there is no separate UAT environment.
| Environment | Branch | Version Format | Purpose |
|---|---|---|---|
| Dev | develop |
X.Y.Z-SNAPSHOT.SHA |
Integration testing, continuous builds |
| Staging | release/* |
X.Y.Z-RC.N |
QA validation, UAT, release candidate testing |
| Prod | main |
X.Y.Z |
Production release |
- Develop -- Merge feature branches into
develop. Each push builds a SNAPSHOT image and deploys to the dev environment. - Create release branch -- When ready to release, create
release/X.Y.Zfromdevelop. This triggers therelease-candidateworkflow:- Full quality pipeline (build, test, lint, coverage, security, SAST, SonarCloud)
- Docker image tagged
X.Y.Z-RC.1pushed to registry - CD repo updated targeting staging environment
- GitHub pre-release created (
vX.Y.Z-RC.1)
- QA on staging -- Test the RC on staging. If fixes are needed, commit directly to the release branch. Each push increments the RC number (
RC.2,RC.3, etc.) and re-deploys to staging. - Promote to production -- Merge the release branch into
main. This triggers theproductionworkflow:- Build + Docker image tagged
X.Y.Z(no quality gates -- already passed on the release branch) - CD repo updated targeting prod environment
- Full GitHub Release created (
vX.Y.Z)
- Build + Docker image tagged
- Back-merge -- Merge
mainback intodevelopto carry forward the version bump.
For emergency production fixes: create hotfix/<name> from main, fix, then merge directly to main. The production workflow runs the same fast-path (build + Docker + CD + release). Back-merge to develop after.
Munitor manages versioning automatically via GitVersion. You do not need a GitVersion.yml in your repo -- Munitor writes a standard SDLC-compliant config at CI time. Version bumps follow commit conventions:
- Patch (default): every merge to main
- Minor: feature branch merge to develop
- Major: commit message containing
+semver: major
Tags follow the format vX.Y.Z (git tag) and X.Y.Z (Docker tag). Tags are immutable and only created on main (full releases) or release branches (pre-releases).
| Field | Type | Default | Pipelines | Description |
|---|---|---|---|---|
pipeline |
string | required | all | Pipeline type: node-api, node-webapp, java-webapp, terraform, sdk-distribution, validate-cd-repo, argocd-apps |
orb_version |
string | required | all | Orb version for the generated pipeline (e.g., "0.3.3", "0.3", dev:snapshot) |
image_name |
string | required* | node-api, node-webapp, java-webapp | Docker image name (without registry prefix) |
node_version |
string | 20 |
node-api, node-webapp | Node.js major version |
java_version |
string | 21 |
java-webapp | Java major version |
sonar.project_key |
string | -- | node-api, node-webapp, java-webapp | SonarCloud project key. Omit to skip |
docker.registry |
string | required* | node-api, node-webapp, java-webapp | Container registry URL |
docker.use_repo_dockerfile |
bool | false |
node-webapp | Preserve and build the repository-root Dockerfile instead of generating one |
cd.repo |
string | -- | node-api, node-webapp, java-webapp | GitOps CD repo (org/repo). Omit to skip |
cd.path |
string | -- | node-api, node-webapp, java-webapp | Explicit repository-relative kustomization.yaml path for consolidated GitOps repositories |
cd.production_only |
bool | false |
node-api, node-webapp, java-webapp | Disable CD write-back from develop, staging, and release workflows |
cd.env.release |
string | staging |
node-api, node-webapp, java-webapp | CD target environment for release branches |
cd.env.develop / cd.env.staging / cd.env.prod |
string | develop / staging / prod |
node-api, node-webapp, java-webapp | CD target environment names for the develop, staging and main workflows |
cd.format |
string | helm |
node-api, node-webapp, java-webapp | helm (sets image.tag in values.yaml, per environment under environments/<env>/ when present) or kustomize (sets images[].newTag) |
server_module |
string | -- | gradle-webapp | Gradle module whose build/libs JAR goes into the generated image (multi-module builds) |
owasp |
bool | true |
java-webapp | Run the OWASP dependency check |
package_manager |
string | npm |
node-api, node-webapp | npm or pnpm |
supplemental_images |
list | [] |
node-api, node-webapp, java-webapp | Extra images (name, dockerfile, cd.image_name) built and tagged with the same version |
health.db |
bool | false |
node-api, node-webapp, java-webapp | Start a PostgreSQL sidecar for the health check |
health.migrations |
string | -- | node-api, node-webapp, java-webapp | Supplemental image suffix run against the sidecar before the health check |
health.smoke_paths |
list | [] |
node-api, node-webapp, java-webapp | Extra paths that must return HTTP 200 during the health check |
test.coverage.summary_path |
string | coverage/coverage-summary.json |
node-api, node-webapp | Coverage summary file read by the coverage gate |
org.docker_registry / org.npm_scope / org.ci_email / org.ci_name / org.orb_slug |
string | KofTwentyTwo values | all | Organization defaults; see Adopting in another app |
coverage.min_instruction |
int | 70 |
node-api, node-webapp, java-webapp | Minimum coverage percentage |
e2e |
bool | false |
node-api, node-webapp, java-webapp | Enable Playwright E2E tests |
sbom |
bool | false |
node-api, node-webapp, java-webapp | Enable SBOM generation |
sast |
bool/object | false |
all except sdk | Enable Semgrep SAST scanning. Use true/false or object form |
sast.fail_on_findings |
bool | true |
all except sdk | Fail build on SAST findings. Set false for warn-only mode |
node.framework |
string | nextjs |
node-api | Node framework: nextjs or express (not used by node-webapp) |
health.path |
string | /api/health |
node-api, node-webapp, java-webapp | Health check endpoint path |
health.port |
int | 3000/8080 |
node-api, node-webapp, java-webapp | Health check port (3000 for node-, 8080 for java-) |
npm.private_registry |
bool | false |
node-api, node-webapp | Authenticate to private npm registry |
services |
list | [] |
node-api, node-webapp | Service containers to start before tests |
test.setup |
string | -- | node-api, node-webapp | Script to run before tests |
test.commands |
list | [] |
node-api, node-webapp | Custom test commands (replaces default Jest) |
test.coverage.tool |
string | jest |
node-api, node-webapp | Coverage tool (jest or nyc) |
test.coverage.command |
string | -- | node-api, node-webapp | Custom coverage generation command |
terraform.path |
string | terraform/ |
terraform | Root Terraform directory |
terraform.live_path |
string | terraform/live |
terraform | Terragrunt live directory |
terraform.environments |
list | [production] |
terraform | Environments to validate |
terraform.checkov_skip |
string | -- | terraform | Comma-separated Checkov rules to skip |
kustomize.version |
string | 5.5.0 |
validate-cd-repo, argocd-apps | Kustomize version to install |
kustomize.base_path |
string | base/ |
validate-cd-repo, argocd-apps | Path to kustomize base directory. Empty string skips base build |
kustomize.overlay_dir |
string | overlays |
validate-cd-repo, argocd-apps | Directory containing overlay subdirectories (e.g. overlays, envs) |
kustomize.overlays |
list | auto-detect | validate-cd-repo, argocd-apps | Overlay names to validate |
kustomize.load_restrictor |
bool | true |
validate-cd-repo, argocd-apps | Use --load-restrictor LoadRestrictionsNone |
kustomize.scan_overlay |
string | production |
validate-cd-repo, argocd-apps | Overlay to scan with kubesec/kube-linter |
kube_linter_config |
string | -- | validate-cd-repo, argocd-apps | Path to kube-linter config file |
yamllint_paths |
string | pipeline-dependent | validate-cd-repo, argocd-apps | Space-separated directories for YAML linting |
contexts.registry |
string | -- | node-api, node-webapp, java-webapp | CircleCI context for Docker push (e.g., ghcr) |
contexts.github |
string | -- | all | CircleCI context for Git/GitHub operations. Enables GitHub Releases when set |
contexts.sonar |
string | -- | node-api, node-webapp, java-webapp | CircleCI context for SonarCloud. Required if sonar.project_key is set |
contexts.nvd |
string | -- | java-webapp | CircleCI context for OWASP NVD database. Optional; security scan runs without it |
* Required for pipelines that build Docker images.
Every container built by Munitor must expose a health endpoint. After the Docker image is built, Munitor starts the container and validates the endpoint returns HTTP 200. This is a mandatory gate; builds fail if the health check does not pass within 30 seconds.
Default endpoint: GET /api/health on port 3000 (node-api, node-webapp) or 8080 (java-webapp). Override via health.path and health.port in .munitor.yml.
"Missing required fields: orb_version" -- Add orb_version to your .munitor.yml. Use dev:snapshot for unreleased feature testing or 0.3 for the current stable line.
"munitor_header: command not found" -- You're using an older orb version. Update to dev:snapshot or wait for the next stable release.
Empty output + exit code 1 on npm ci -- Usually a PATH issue. Munitor exports node/npm to BASH_ENV; if this breaks, all subsequent steps fail silently. Check that install_node succeeded in the build logs.
"Unknown key 'xxx' in .munitor.yml" -- Munitor warns on unrecognized top-level keys to catch typos. Check spelling against the reference table above.
Interactive prompt hangs (debconf/dpkg) -- If test commands install system packages via apt, add DEBIAN_FRONTEND=noninteractive as a prefix. Munitor sets this automatically in the test runner, but explicit is safer for custom commands.
"No template found for pipeline type" -- The pipeline field must be one of: node-api, node-webapp, java-webapp, terraform, sdk-distribution, validate-cd-repo, argocd-apps.
Setup succeeds but no continuation workflow appears -- The generated config may contain invalid YAML that CircleCI accepts but can't execute. Common cause: an empty context list item from an unset optional context (e.g., contexts.nvd). Check the generated config by running make publish-snapshot and retriggering.
Branch name rejected -- Munitor enforces GitFlow naming. Rename your branch to match an allowed pattern.
Tests pass locally but fail in CI -- Check Node/Java version alignment. Add an .nvmrc file to keep local and CI versions in sync. Munitor will warn if .nvmrc and .munitor.yml versions differ.
make lint # yamllint + shellcheck
make validate # pack + circleci validate
make test-scripts # structural + unit tests
make test-templates # template rendering tests
make all # run everythingPushes to develop auto-publish kof22/munitor@dev:snapshot. Production releases are tagged on main (v1.2.3).
src/
@orb.yml # Orb metadata
commands/*.yml # 56 reusable commands (each wraps a script)
jobs/*.yml # 22 jobs composing commands into workflows
executors/*.yml # Machine executor definitions
scripts/
*.sh # 55+ bash scripts (the actual logic)
munitor_helpers.sh # Shared library (header, tool checks, download retry)
templates/*.yml.tpl # Pipeline templates with conditional blocks
templates/partials/ # Reusable deploy workflow fragments
Pipeline generation flow:
generate_pipelinejob runsgenerate_config.sh- Reads
.munitor.yml, extracts variables viaextract_munitor_vars.sh - Selects template based on
pipelinetype - Expands
##INCLUDE_DEPLOY##markers with partial templates - Runs
envsubstfor variable substitution - Processes
##IF_*##/##ENDIF_*##conditional blocks - Validates output YAML and passes to CircleCI continuation
The default npm audit gate remains unchanged. For a reviewed development-only HIGH
advisory with no patched package release, a repository may commit
.npm-audit-exceptions.json with schemaVersion 1 and an exceptions array. Each entry
requires a register ID, exact GHSA advisory ID, package, version, development scope
and UTC expiry date. See Website-Frontend's EX-0008 for the first consumer.
The full npm audit runs alongside a production audit. All production HIGH/CRITICAL and all CRITICAL findings fail. Only the named advisory and its propagated HIGH findings can pass, and every affected lockfile path must have dev true and the exact excepted version. Audit errors, unknown chains and expired exceptions fail. A new upstream package release also fails and requires review. Trivy remains unchanged. This mechanism requires npm audit report version 2 and a package-path lockfile; unsupported reports fail. BATS and Node are required for the audit regression tests.
Report vulnerabilities privately; see SECURITY.md.
See CONTRIBUTING.md.