Files
docs/standards/mcp/modules/drone_pipelines.json
Vishesh 'ironeagle' Bangotra a754366901 feat(standards): add Drone CI standard (PyPI package + Docker deployment)
Document the two `.drone.yml` shapes used across the org, derived from the
repos:

- Type A `python-lib.yaml`: build-and-publish-pypi + backfill-pypi-from-tags
- Type B `service-docker.yaml`: build-and-deploy-service + build-and-deploy-site

- add reference page `10_drone_pipelines`
- vendor `src/templates/drone/` into the MCP bundle (`drone.json`)
- expose `registry://drone` + `list_drone_templates` / `get_drone_template`
- wire `build.py` to vendor drone templates; rebuild nav/index (14 modules)
2026-10-15 00:52:38 +05:30

8 lines
4.7 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 **two 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 — Docker deployment** | `templates/drone/service-docker.yaml` | An image pushed to the registry and run as a container | `auth-server`, `docs`, `mcp` |\n\nBoth templates run on `platform: linux / arm64` with the workspace at\n`/drone/src`. Copy the matching template to `<repo>/.drone.yml`; the Type A file\nneeds no edits, the Type B file needs its placeholders filled in (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 libraries. The file contains **two pipelines**:\n\n1. **`build-and-publish-pypi`** — triggered on `tag`:\n - `check-version` — read `name` / `version` from `pyproject.toml` and query\n `$PIP_REPO_URL/simple/<package>/`; if that version already exists, exit\n `78` and skip the whole build.\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, build, and upload. This is\n the disaster-recovery / 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 — Docker deployment (`service-docker.yaml`)\n\nFor services and sites that ship a container image. The file contains **two\npipelines**, each mirroring a repo family:\n\n1. **`build-and-deploy-service`** — triggered on `tag` (a long-running\n API/worker service, e.g. `auth-server`):\n - `fetch-tags` — resolve the latest tag into `LATEST_TAG.txt`; fail if there\n are no tags.\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.\n2. **`build-and-deploy-site`** — triggered on `push` (a static/HTTP site, e.g.\n `docs`, `mcp`): `build-image` → `push-image` → `stop-old` → `run-container`,\n with no tag resolution and no quality gate.\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| `<site>` | site image / container name | `docs` |\n| `<ENV_VAR>` | runtime environment variable | `MONGO_HOST` |\n\n---\n\n## What not to do\n\n- Do not hand-roll a third shape. A repo is either Type A or Type B, never both.\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 rename the pipelines; tooling and runbooks key off\n `build-and-publish-pypi`, `build-and-deploy-service`, and\n `build-and-deploy-site`.\n\n---\n\n## Related\n\n- [01 – Build Recipe](01_build_recipe.md) · [09 – Infra Adapters](09_infra_adaptors.md) · [13 – Library Registry](13_library_registry.md)\n",
"objects": {}
}
}