Compare commits

...
Author SHA1 Message Date
james.maesandClaude Opus 5.5 b4a9d120eb docs: add adoption guide, security policy and code owners
Add an "Adopting in another app" section to the README (version,
.munitor.yml example, CircleCI settings, contexts and secrets, branch
model, deployment infrastructure, known limitations, 0.3.3 upgrade
notes), a tier and standards statement, and reference rows for the
previously undocumented .munitor.yml keys. Add SECURITY.md,
.github/CODEOWNERS and a CONTRIBUTING workflow section (branches,
Conventional Commits, DCO sign-off, local checks), and fix the
nonexistent `make test` target in CLAUDE.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
2026-10-12 05:29:05 -05:00
james.maes b3b90f5886 Merge pull request #24 from KofTwentyTwo/main
Merge main back into develop after 0.3.3
2026-10-11 14:50:53 -05:00
james.maes d9b4da9e9e Merge pull request #23 from KofTwentyTwo/release/0.3.3
Release 0.3.3: atomic release versions
2026-10-11 14:49:46 -05:00
5 changed files with 187 additions and 2 deletions

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
# Every path has an owner (K22-REPO-08). Add narrower rules below for areas that
# need a specific reviewer once the project has more than one maintainer.
* @KofTwentyTwo
+1 -1
View File
@@ -5,7 +5,7 @@ CircleCI orb that generates CI/CD pipeline configurations from a `.munitor.yml`
## Key Commands
```bash
make test # Run all tests (BATS)
make test-scripts # Script unit tests (bats tests for the .bats suites)
make pack # Pack orb YAML from src/
make all # lint + pack + test
make validate # Validate packed orb with CircleCI CLI
+8
View File
@@ -1,5 +1,13 @@
# Contributing to Munitor
## Workflow
- **Branches.** Branch `feature/<name>` or `hotfix/<name>` from `develop` and open a pull request back to `develop`. Releases go through `release/X.Y.Z` into `main`; pushing the `vX.Y.Z` tag publishes `kof22/munitor@X.Y.Z`, and every push to `develop` or `feature/*` publishes `dev:snapshot`. Back-merge `main` into `develop` after a release.
- **Commits.** Conventional Commits (`feat(#N): ...`, `fix: ...`, `docs: ...`), signed (`git commit -S`), with a Developer Certificate of Origin sign-off line (`git commit -s`, which adds `Signed-off-by: Name <email>`). Reference the GitHub issue (`Closes #N`) where there is one.
- **Checks.** Run `make all` (yamllint, shellcheck, pack plus `circleci orb validate`, script and template tests) and `bats tests` (the `.bats` suites) before pushing. CircleCI runs only the orb-tools lint, pack and review jobs; the script, template and BATS tests run locally, so a green CI run does not replace them.
- **Security.** Report vulnerabilities privately as described in [SECURITY.md](SECURITY.md), never in a public issue.
- **AI assistance.** Disclose AI-assisted changes in the pull request description.
## Module Inventory
Munitor organizes CI/CD pipelines into **modules** (called "pipeline types" in `.munitor.yml`). Each module is a self-contained set of templates, jobs, commands, and scripts that handle a specific application stack.
+119 -1
View File
@@ -2,6 +2,14 @@
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](https://github.com/KofTwentyTwo/standards/blob/main/MAINTAINERS.md); Product-tier requirements are being adopted |
| **Standards** | Targets [KofTwentyTwo standards](https://github.com/KofTwentyTwo/standards) 1.0.0 |
| **Orb** | [`kof22/munitor`](https://circleci.com/developer/orbs/orb/kof22/munitor), latest stable `0.3.3` |
| **Security** | [SECURITY.md](SECURITY.md) |
| **Contributing** | [CONTRIBUTING.md](CONTRIBUTING.md) |
## How It Works
Munitor uses CircleCI's [dynamic configuration](https://circleci.com/docs/dynamic-config/) 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.
@@ -58,6 +66,93 @@ Munitor validates branch names and will fail on non-conforming names.
| `sonarcloud` | `SONAR_TOKEN` | SonarCloud analysis |
| `nvd` | `NVD_API_KEY` | OWASP dependency check (Java only, optional) |
## Adopting in another app
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 service such as me-health-portal.
**Version.** Use `kof22/munitor@0.3.3` (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.
### 1. Repository files
- `.circleci/config.yml`: the setup config from [Quick Start](#quick-start), pinned to `kof22/munitor@0.3.3`.
- `.munitor.yml`: pick a [pipeline type](#pipeline-types). A Java service is `java-webapp`. KofTwentyTwo's Website-Backend is a working example; a generalized version:
```yaml
pipeline: java-webapp
orb_version: "0.3.3"
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](#health-check-requirement)).
- A Dockerfile only for `node-webapp` (`docker.use_repo_dockerfile: true`) or for `supplemental_images`; `java-webapp` and `node-api` generate theirs.
### 2. CircleCI project settings
See [Prerequisites](#prerequisites): enable dynamic config (setup workflows) and allow uncertified orbs in the consuming organization.
### 3. Contexts and secrets
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 |
### 4. Branch model
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.
### 5. Deployment infrastructure (outside Munitor)
Munitor stops at the GitOps commit. The consumer provides:
- a GitOps repository whose `kustomization.yaml` (an `images[]` entry named `<registry>/<image_name>`) or Helm `values.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 in `KofTwentyTwo/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 `migrations` supplemental image (the KofTwentyTwo website runs a pre-migration backup image and then the migrations image as init containers). `health.migrations` only exercises that image in CI.
### 6. Known limitations
- Organization defaults point at KofTwentyTwo: registry `ghcr.io/KofTwentyTwo`, npm scope `@koftwentytwo`, CI email `munitor-ci@koftwentytwo.com`, SonarCloud organization `KofTwentyTwo`. Set `docker.registry`, the `org.*` keys and `SONAR_ORG` explicitly. The `org` block is read, but the unknown-key check prints a harmless `Unknown key 'org'` warning.
- `production` builds on `main` skip the quality gates, which run on `release/*` and `hotfix/*` pull requests. Do not merge unreviewed branches straight to `main`.
- CircleCI only; there is no GitHub Actions equivalent. Docker jobs use machine executors.
### 7. Upgrade notes
`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.
## Pipeline Types
### `node-api`
@@ -475,7 +570,7 @@ Tags follow the format `vX.Y.Z` (git tag) and `X.Y.Z` (Docker tag). Tags are imm
| 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., `1`, `dev:snapshot`) |
| `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 |
@@ -486,6 +581,17 @@ Tags follow the format `vX.Y.Z` (git tag) and `X.Y.Z` (Docker tag). Tags are imm
| `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](#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 |
@@ -596,3 +702,15 @@ excepted version. Audit errors, unknown chains and expired exceptions fail. A ne
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.
## Security
Report vulnerabilities privately; see [SECURITY.md](SECURITY.md).
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md).
## License
[GPL-3.0](LICENSE)
+56
View File
@@ -0,0 +1,56 @@
# Security Policy
## Reporting a vulnerability
**Do not open a public issue for a security problem.**
Report it privately through GitHub's
[private vulnerability reporting](https://github.com/KofTwentyTwo/Munitor/security/advisories/new)
(the repository's **Security** tab, then **Report a vulnerability**). If that form is
unavailable, contact the maintainer privately through GitHub before disclosing anything.
Security contact: **James Maes** ([@KofTwentyTwo](https://github.com/KofTwentyTwo)),
maintainer.
Please include the affected orb version, the `.munitor.yml` pipeline type, how to
reproduce it, and the impact you see. Never include secrets or CircleCI context values.
## What to expect
KofTwentyTwo follows coordinated vulnerability disclosure. Timeframes are counted
from the day the report arrives and come from the
[KofTwentyTwo security program](https://github.com/KofTwentyTwo/standards/blob/main/policies/security-program.md):
| Step | Target |
| --- | --- |
| Acknowledge the report | 7 days |
| Assess it: confirm or reject, with a severity | 14 days |
| Release a fix for a CRITICAL vulnerability | 7 days |
| Release a fix for a HIGH vulnerability | 30 days |
| Release a fix for a MEDIUM vulnerability | 90 days |
| Release a fix for a LOW vulnerability | The next release |
| Publish the advisory (GitHub Security Advisory, CVE where applicable) | When the fix ships, or 90 days after the report, whichever comes first |
Reporters are credited in the advisory unless they ask not to be.
## Supported versions
| Version | Security fixes |
| --- | --- |
| 0.3.x (`kof22/munitor@0.3`) | Yes |
| Older | No; upgrade to the latest release |
Only the latest minor line receives fixes; a line ends when the next minor version is
published to the CircleCI orb registry.
## Scope notes
Munitor runs inside the consumer's CircleCI project with the consumer's contexts
(registry, GitHub, SonarCloud, NVD). Issues that let a generated pipeline leak context
secrets, push an image or GitOps change for the wrong commit, or bypass a security
gate are in scope.
## Published vulnerabilities
Fixed vulnerabilities are published as
[GitHub Security Advisories](https://github.com/KofTwentyTwo/Munitor/security/advisories).