8.3 KiB
name, description
| name | description |
|---|---|
| monorepo-cicd | 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)
_docs/_repo-config.yamlexists.- Top-level
confirmed_by_user: true. ci.*section is populated in config (not empty).- 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.yamlassumptions_log. - M7 Drift detection: verify every file in
ci.orchestration_files,ci.install_scripts,ci.env_templateexists; 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-discoverto 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:
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:
- Read the target file.
- Locate the service block / table row / section.
- 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_configin its config entry AND no entry in config's CI mappings confirmed: falseon 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
shellcheckavailable, run on any edited*.sh. - YAML: if
yamllintorprettieravailable, 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_userorconfirmed: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.examplehas 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 tagdevelop, stop and ask.