mirror of
https://github.com/azaion/detections-semantic.git
synced 2026-04-23 09:16:37 +00:00
165 lines
8.3 KiB
Markdown
165 lines
8.3 KiB
Markdown
---
|
||
name: monorepo-cicd
|
||
description: Syncs CI/CD and infrastructure configuration at the monorepo root (compose files, install scripts, env templates, CI service tables) after one or more components changed. Reads `_docs/_repo-config.yaml` (produced by monorepo-discover) to know which CI artifacts are in play and how they're structured. Touches ONLY CI/infra files — never documentation, component directories, or per-component CI configs. Use when a component added/changed a Dockerfile path, port, env var, image tag format, or runtime dependency.
|
||
---
|
||
|
||
# Monorepo CI/CD
|
||
|
||
Propagates component changes into the repo-level CI/CD and infrastructure artifacts. Strictly scoped — never edits docs, component internals, or per-component CI configs.
|
||
|
||
## Scope — explicit
|
||
|
||
| In scope | Out of scope |
|
||
| -------- | ------------ |
|
||
| `docker-compose.*.yml` at repo root | Unified docs in `_docs/*.md` → use `monorepo-document` |
|
||
| `.env.example` / `.env.template` | Root `README.md` documentation → `monorepo-document` |
|
||
| Install scripts (`ci-*.sh`, `setup.sh`, etc.) | Per-component CI configs (`<component>/.woodpecker/*`, `<component>/.github/*`) |
|
||
| CI service-registry docs (`ci_steps.md` or similar — the human-readable index of pipelines; in scope only if the config says so under `ci.service_registry_doc`) | Component source code, Dockerfiles, or internal docs |
|
||
| Kustomization / Helm manifests at repo root | `_docs/_repo-config.yaml` itself (only `monorepo-discover` and `monorepo-onboard` write it) |
|
||
|
||
If a component change needs doc updates too, tell the user to also run `monorepo-document`.
|
||
|
||
**Special case**: `ci.service_registry_doc` (e.g., `ci_steps.md`) is a **CI artifact that happens to be markdown**. It's in this skill's scope, not `monorepo-document`'s, because it describes the pipeline/service topology — not user-facing feature docs.
|
||
|
||
## Preconditions (hard gates)
|
||
|
||
1. `_docs/_repo-config.yaml` exists.
|
||
2. Top-level `confirmed_by_user: true`.
|
||
3. `ci.*` section is populated in config (not empty).
|
||
4. Components-in-scope have confirmed CI mappings, OR user explicitly approves inferred ones.
|
||
|
||
If any gate fails, redirect to `monorepo-discover` or ask for confirmation.
|
||
|
||
## Mitigations (M1–M7)
|
||
|
||
- **M1** Separation: this skill only touches CI/infra files; no docs, no component internals.
|
||
- **M3** Factual vs. interpretive: image tag format, port numbers, env var names — FACTUAL, read from code. Doc cross-references — out of scope entirely (belongs to `monorepo-document`).
|
||
- **M4** Batch questions at checkpoints.
|
||
- **M5** Skip over guess: component with no CI mapping → skip and report.
|
||
- **M6** Assumptions footer + append to `_repo-config.yaml` `assumptions_log`.
|
||
- **M7** Drift detection: verify every file in `ci.orchestration_files`, `ci.install_scripts`, `ci.env_template` exists; stop if not.
|
||
|
||
## Workflow
|
||
|
||
### Phase 1: Drift check (M7)
|
||
|
||
Verify every CI file listed in config exists on disk. Missing file → stop, ask user:
|
||
- Run `monorepo-discover` to refresh, OR
|
||
- Skip the missing file (recorded in report)
|
||
|
||
Do NOT recreate missing infra files automatically.
|
||
|
||
### Phase 2: Determine scope
|
||
|
||
Ask the user (unless specified):
|
||
|
||
> Which components changed? (a) list them, (b) auto-detect, (c) skip detection (I'll apply specific changes).
|
||
|
||
For **auto-detect**, for each component:
|
||
|
||
```bash
|
||
git -C <path> log --oneline -20 # submodule
|
||
# or
|
||
git log --oneline -20 -- <path> # monorepo subfolder
|
||
```
|
||
|
||
Flag commits that touch CI-relevant concerns:
|
||
|
||
- Dockerfile additions, renames, or path changes
|
||
- CI pipeline files (`<component>/.woodpecker/*`, `<component>/.github/workflows/*`, etc.)
|
||
- New exposed ports
|
||
- New environment variables consumed by the component
|
||
- Changes to image name / tag format
|
||
- New dependency on another service (e.g., new DB, new broker)
|
||
|
||
Present the flagged list; confirm.
|
||
|
||
### Phase 3: Classify changes per component
|
||
|
||
| Change type | Target CI files |
|
||
| ----------- | --------------- |
|
||
| Dockerfile path moved/renamed | `ci.service_registry_doc` service table; per-component CI is OUT OF SCOPE (tell user to update it) |
|
||
| New port exposed | `ci.service_registry_doc` ports section (if infra port); component's service block in orchestration file |
|
||
| Registry URL changed | `ci.install_scripts` (all of them); `ci.env_template`; `ci.service_registry_doc` |
|
||
| Branch naming convention changed | All `ci.install_scripts`; all `ci.orchestration_files` referencing the branch; `ci.service_registry_doc` |
|
||
| New runtime env var | `ci.env_template`; component's service block in orchestration file |
|
||
| New infrastructure component (DB, cache, broker) | Relevant `ci.orchestration_files`; `ci.service_registry_doc` architecture section |
|
||
| New image tag format | All `ci.orchestration_files`; `ci.install_scripts`; `ci.service_registry_doc` |
|
||
| Watchtower/polling config change | Specific `ci.orchestration_files`; `ci.service_registry_doc` |
|
||
|
||
If a change type isn't covered here or in the config, add to an unresolved list and skip (M5).
|
||
|
||
### Phase 4: Apply edits
|
||
|
||
For each (change → target file) pair:
|
||
|
||
1. Read the target file.
|
||
2. Locate the service block / table row / section.
|
||
3. Edit carefully:
|
||
- **Orchestration files (compose/kustomize/helm)**: YAML; preserve indentation, anchors, and references exactly. Match existing service-block structure. Never reformat unchanged lines.
|
||
- **Install scripts (`*.sh`)**: shell; any edit must remain **idempotent**. Re-running the script on an already-configured host must not break it. If an edit cannot be made idempotent, flag for the user and skip.
|
||
- **`.env.example`**: append new vars at the appropriate section; never remove user's local customizations (file is in git, so comments may be significant).
|
||
- **`ci.service_registry_doc`** (markdown): preserve column widths, ordering (alphabetical or compose-order — whichever existed), ASCII diagrams.
|
||
|
||
### Phase 5: Skip-and-report (M5)
|
||
|
||
Skip a component if:
|
||
|
||
- No `ci_config` in its config entry AND no entry in config's CI mappings
|
||
- `confirmed: false` on its mapping and user didn't approve
|
||
- Component's Dockerfile path declared in config doesn't exist on disk — surface contradiction
|
||
- Change type unrecognized — skip, report for manual handling
|
||
|
||
### Phase 6: Idempotency / lint check
|
||
|
||
- Shell: if `shellcheck` available, run on any edited `*.sh`.
|
||
- YAML: if `yamllint` or `prettier` available, run on edited `*.yml` / `*.yaml`.
|
||
- For edited install scripts, **mentally re-run** the logic: would a second invocation crash, duplicate, or corrupt? Flag anything that might.
|
||
|
||
Skip linters silently if none configured — don't install tools.
|
||
|
||
### Phase 7: Report + assumptions footer (M6)
|
||
|
||
```
|
||
monorepo-cicd run complete.
|
||
|
||
CI files updated (N):
|
||
- docker-compose.run.yml — added `loader` service block
|
||
- .env.example — added LOADER_BUCKET_NAME placeholder
|
||
- ci_steps.md — added `loader` row in service table
|
||
|
||
Skipped (K):
|
||
- satellite-provider: no ci_config in repo-config.yaml
|
||
- detections: Dockerfile path in config (admin/src/Dockerfile) does not exist on disk
|
||
|
||
Manual actions needed (M):
|
||
- Update `<submodule>/.woodpecker/*.yml` inside the submodule's own workspace
|
||
(per-component CI is not maintained by this skill)
|
||
|
||
Assumptions used this run:
|
||
- image tag format: ${REGISTRY}/${NAME}:${BRANCH}-${ARCH_TAG} (confirmed in config)
|
||
- target branch for triggers: [stage, main] (confirmed in config)
|
||
|
||
Next step: review the diff, then commit with
|
||
`<commit_prefix> Sync CI after <components>` (or your own message).
|
||
```
|
||
|
||
Append run entry to `_docs/_repo-config.yaml` `assumptions_log:`.
|
||
|
||
## What this skill will NEVER do
|
||
|
||
- Modify files inside component directories
|
||
- Edit unified docs under `docs.root`
|
||
- Edit per-component CI configs (`.woodpecker/*`, `.github/*`, etc.)
|
||
- Auto-generate CI pipeline YAML for components (only provide template guidance)
|
||
- Set `confirmed_by_user` or `confirmed:` flags
|
||
- Auto-commit
|
||
- Install tools (shellcheck, yamllint, etc.) — use if present, skip if absent
|
||
|
||
## Edge cases
|
||
|
||
- **Compose file has service blocks for components NOT in config**: note in report; ask user whether to rediscover (`monorepo-discover`) or leave them alone.
|
||
- **`.env.example` has entries for removed components**: don't auto-remove; flag to user.
|
||
- **Install script edit cannot be made idempotent**: don't save; ask user to handle manually.
|
||
- **Branch trigger vs. runtime branch mismatch**: if config says triggers are `[stage, main]` but a compose file references a branch tag `develop`, stop and ask.
|