Files
2026-04-18 22:04:08 +03:00

8.3 KiB
Raw Permalink Blame History

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)

  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 (M1M7)

  • 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:

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.

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.