Files
docs/standards/mcp/modules/drone_pipelines.json
Vishesh 'ironeagle' Bangotra d7c344c9aa feat: full-stack MCP surface — client template, npm CI, 13 repos
- build.py: vendor templates/client into mcp/templates/client with
  client.json manifest (16 kinds); register drone-npm as a third CI shape
  (types: pypi/npm/docker); root *.py stale doc numbers fixed
- registry.py: registry://client resource + list_client_components /
  get_client_component / get_client_template tools; build prompt gains the
  client scaffold step (docs://modules/ui_admin); compliance prompt covers
  npm packages; drone docs describe all three shapes
- repos.json (+mcp): doc-weaver, react-auth, react-openapi (npm Type B,
  package.json version source), vet (app Type C, VERSION)
- docs: 90_drone_pipelines gains Type B npm section; 91_versioning covers
  package.json as a version source; 94_repository_inventory gains the npm
  package table and services/apps Type C; lib index updated

Verified: bundle regen (24 modules, client 16, drone 3, repos 13); registry
client readers exercised against the vendored bundle.
2026-10-20 12:02:31 +05:30

8 lines
6.2 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"module": "drone_pipelines",
"content": {
"path": "drone_pipelines",
"docstring": "# Drone Pipelines\n\n## Summary\n\nEvery Aetos repository ships a Drone CI definition at `.drone.yml`. There is\nexactly **one standard per repository**, and there are **three types of file**,\nchosen by what the repository produces:\n\n| Type | File | Produces | Repos |\n|------|------|----------|-------|\n| **A — PyPI package** | `templates/drone/python-lib.yaml` | A wheel + sdist on the private index | `dagpipe`, `doc-forge`, `hexa`, `mail-intake`, `mongo-ops`, `omniread`, `openapi-first`, `py-jwt` |\n| **B — npm package** | `templates/drone/npm-lib.yaml` | A package published to the private npm registry | `doc-weaver`, `react-auth`, `react-openapi` |\n| **C — Docker deployment** | `templates/drone/service-docker.yaml` | An image pushed to the registry and run as a container | `auth-server`, `vet` |\n\nAll templates run on `platform: linux / arm64` with the workspace at\n`/drone/src`. Copy the matching template to `<repo>/.drone.yml`; the Type A and\nType B files need no edits, the Type C file needs its placeholders filled in\n(below).\n\n> Conventions: `.drone.yml` (not `.yaml`), one file per repo, secrets injected\n> with `from_secret` — never commit credentials.\n\n---\n\n## Type A — PyPI package (`python-lib.yaml`)\n\nFor internal Python libraries. The file contains **two pipelines**:\n\n1. **`build-and-publish-pypi`** — triggered on `tag`:\n - `check-version` — **guard**: fail unless `$DRONE_TAG` equals the version in\n `pyproject.toml`; then read `name` / `version` and query\n `$PIP_REPO_URL/simple/<package>/`; if that version already exists, exit\n `78` and skip the whole build (see [91 – Versioning & Changelog](91_versioning_and_changelog.md)).\n - `quality-gate` — install the package with its `[dev]` extras from the\n private index, then `black --check`, `ruff check`, `mypy`, `pydoclint`,\n `pytest`.\n - `build-package` — `python -m build` into `dist/`.\n - `upload-to-private-pypi` — `twine upload` to `$PIP_REPO_URL`.\n2. **`backfill-pypi-from-tags`** — triggered on `custom`:\n - `fetch-tags` — `git fetch --tags --force`.\n - `build-and-upload-missing` — walk every tag in version order, skip the ones\n already on the index, `git checkout` the rest, verify `tag == pyproject\n version` at that commit, build, and upload. This is the disaster-recovery /\n replay path.\n\nSecrets: `PIP_REPO_URL`, `PIP_USERNAME`, `PIP_PASSWORD`.\n\n- **Ship as-is.** Package name and version come from `pyproject.toml`, so the\n same file is reused verbatim across every library.\n\n---\n\n## Type B — npm package (`npm-lib.yaml`)\n\nFor internal npm libraries (the React packages). One pipeline,\n**`build-and-publish-npm`**, triggered on `tag`:\n\n- `check-version` — **guard**: fail unless `$DRONE_TAG` equals the version in\n `package.json`; query `$NPM_REPO_URL` for `name@version`; if it already\n exists, exit `78` and skip the whole build.\n- `quality-gate` — write `.npmrc` from the secrets, `npm install`, then\n `npm run quality-gate`.\n- `build-package` — `npm install && npm run build` into `dist/`.\n- `publish-to-private-npm` — `npm publish --access restricted` to\n `$NPM_REPO_URL`.\n\nSecrets: `NPM_REPO_URL`, `NPM_USERNAME`, `NPM_PASSWORD`. Auth is a generated\n`.npmrc` (`registry=` + `_auth=` base64 of `user:pass`) written from secrets at\nruntime — the committed `.npmrc` in a repo only points at the registry URL.\n\n- **Ship as-is.** Name and version come from `package.json`, so the same file\n is reused verbatim across every npm package.\n\n---\n\n## Type C — Docker deployment (`service-docker.yaml`)\n\nFor a service that ships a container image — a long-running API/worker, e.g.\n`auth-server`. The file contains **one pipeline**, `build-and-deploy-service`,\ntriggered on `tag`:\n\n- `fetch-tags` — resolve the latest tag into `LATEST_TAG.txt`; fail if there\n are no tags.\n- `check-version` — **guard**: fail unless `$DRONE_TAG` equals the repo-root\n `VERSION` file (see [91 – Versioning & Changelog](91_versioning_and_changelog.md)).\n- `check-remote-image` — if `aetos/<app>:<tag>` already exists locally, exit\n `78` and skip the build.\n- `quality-gate` — install from `requirements.txt` and run\n `black` / `ruff` / `mypy` / `pytest`.\n- `build-image` — `docker build` with the private-index build args, tagged\n `aetos/<app>:<tag>` and `:latest`.\n- `push-image` — login, re-tag with `$REGISTRY_HOST`, push both tags.\n- `stop-old` — `docker rm -f <app>`.\n- `run-container` — `docker run -d --name <app> -p <host>:<container>\n --restart always` with the service's `-e` environment.\n\nSecrets: `PIP_REPO_URL`, `PIP_USERNAME`, `PIP_PASSWORD` (service build args),\n`REGISTRY_HOST`, `REGISTRY_USER`, `REGISTRY_PASS`, plus the service runtime env\n(for example `MONGO_*`, `JWT_SECRET`).\n\nPlaceholders to fill in per repo:\n\n| Placeholder | Meaning | Example |\n|-------------|---------|---------|\n| `<app>` | service image / container name | `auth-server` |\n| `aetos/<app>` | image repository on the registry | `aetos/auth-server` |\n| `<host-port>` / `<container-port>` | published : in-image port | `9003:8000` |\n| `<ENV_VAR>` | runtime environment variable | `MONGO_HOST` |\n\n---\n\n## What not to do\n\n- Do not hand-roll a fourth shape. A repo is exactly one of Type A, B, or C,\n never combinations.\n- Do not inline secrets; always use `from_secret`.\n- Do not drop the `check-version` / `check-remote-image` skip — it guards the\n index and the running container against duplicate publishes.\n- Do not drop the tag↔version guard. A Python package needs its\n `pyproject.toml` version to equal the tag; an npm package needs its\n `package.json` version; a service needs a root `VERSION` file. See\n [91 – Versioning & Changelog](91_versioning_and_changelog.md).\n- Do not rename the pipelines; tooling and runbooks key off\n `build-and-publish-pypi`, `build-and-publish-npm`, and\n `build-and-deploy-service`.\n\n---\n\n## Related\n\n- [01 – Build Recipe](01_build_recipe.md) · [30 – Infra Adapters](30_infra_adaptors.md) · [91 – Versioning & Changelog](91_versioning_and_changelog.md) · [93 – Library Registry](93_library_registry.md)\n",
"objects": {}
}
}