Commit d7b7e3

2026-03-18 03:26:44 Claude (MCP): [mcp] Add CI/CD pipeline plan
/dev/null .. Plans/CI_CD_Pipeline.md
@@ 0,0 1,111 @@
+ ---
+ category: spec
+ tags: [ci, cd, github-actions, plan]
+ last_updated: 2026-03-18
+ confidence: high
+ ---
+
+ # CI/CD Pipeline Plan
+
+ ## Current State
+
+ - Five repos: `robot.wtf`, `otterwiki` (fork), `otterwiki-api`, `otterwiki-mcp`, `otterwiki-semantic-search`
+ - All have pytest suites; no GitHub Actions workflows exist in any repo
+ - Deploy: `ansible-playbook ansible/deploy.yml -i ansible/inventory.yml` from `robot.wtf/` on a laptop
+ - Ansible `deploy` role installs each plugin directly from GitHub main branch via `pip install git+https://...`
+ - Post-deploy smoke test is baked into the playbook
+
+ ## Test Infrastructure Summary
+
+ | Repo | Test runner | Dependencies |
+ |------|-------------|--------------|
+ | `robot.wtf` | pytest, no pyproject | `requirements.txt` (Flask, PyJWT, etc.) |
+ | `otterwiki` | pytest via pyproject / tox | Self-contained |
+ | `otterwiki-api` | pytest via pyproject | Requires `otterwiki` installed |
+ | `otterwiki-semantic-search` | pytest via pyproject | Requires `otterwiki` installed |
+ | `otterwiki-mcp` | pytest + pytest-asyncio | Standalone (no `otterwiki` dep) |
+
+ ## Phase 1: Per-Repo CI on PR (do this session)
+
+ Add a `.github/workflows/ci.yml` to each repo. The workflow is nearly identical across all five — differences are only in Python version and install steps.
+
+ ### Template (robot.wtf)
+
+ ```yaml
+ name: CI
+ on:
+ pull_request:
+ push:
+ branches: [main]
+
+ jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v5
+ with:
+ python-version: "3.12"
+ - run: pip install -r requirements.txt
+ - run: pip install pytest
+ - run: pytest tests/
+ ```
+
+ ### Plugin repos (otterwiki-api, otterwiki-semantic-search)
+
+ These depend on `otterwiki`. Install the fork's `wikibot-io` branch before installing the plugin:
+
+ ```yaml
+ - run: pip install "git+https://github.com/schuyler/otterwiki.git@wikibot-io"
+ - run: pip install -e ".[dev]"
+ - run: pytest
+ ```
+
+ ### otterwiki-mcp
+
+ Standalone; no otterwiki dep. Standard `pip install -e ".[dev]" && pytest`.
+
+ ### otterwiki (fork)
+
+ Uses tox config in pyproject.toml. Can run `pip install -e ".[dev]" && pytest` directly to avoid tox overhead in CI.
+
+ ## Phase 2: Deploy Script (do this session)
+
+ The Ansible command is easy to forget. Add `deploy.sh` to `robot.wtf/`:
+
+ ```bash
+ #!/usr/bin/env bash
+ set -euo pipefail
+ cd "$(dirname "$0")"
+ ansible-playbook ansible/deploy.yml -i ansible/inventory.yml "$@"
+ ```
+
+ This is the entire CD story for now. Manual deploy stays manual — that's the right call given:
+ - Deploy requires pulling from GitHub, so all plugin changes must be merged to main first
+ - No staging environment exists
+ - Smoke test is already part of the playbook
+
+ ## Phase 3: Auto-Deploy (deferred)
+
+ Options when ready:
+ 1. **Webhook receiver on VPS** — a tiny Flask endpoint that receives a GitHub `push` event and runs the Ansible playbook. Avoids needing SSH keys in GitHub Actions secrets for the orchestrating repo.
+ 2. **GitHub Actions + SSH** — store SSH key as a secret in `robot.wtf`, run `ansible-playbook` from Actions on push to main. Simpler setup but couples deploy to robot.wtf CI only.
+ 3. **Repository dispatch** — plugin repos trigger a workflow in `robot.wtf` via the GitHub API on merge to main. Preserves separation of concerns.
+
+ Option 3 is cleanest given the multi-repo dependency model: a push to `otterwiki-api` shouldn't require a commit to `robot.wtf` to trigger a deploy, but the deploy logic lives in `robot.wtf`.
+
+ ## Integration Testing
+
+ Currently not feasible without a staging environment. The per-repo tests are isolated (plugin tests install otterwiki in CI but don't test the full stack together). Accept this gap for now.
+
+ When a staging environment exists, the right approach is a separate workflow in `robot.wtf` that deploys to staging and runs the smoke test suite, triggered after all plugin CI passes.
+
+ ## Task Checklist
+
+ - [ ] Add `.github/workflows/ci.yml` to `robot.wtf`
+ - [ ] Add `.github/workflows/ci.yml` to `otterwiki` (fork)
+ - [ ] Add `.github/workflows/ci.yml` to `otterwiki-api`
+ - [ ] Add `.github/workflows/ci.yml` to `otterwiki-mcp`
+ - [ ] Add `.github/workflows/ci.yml` to `otterwiki-semantic-search`
+ - [ ] Add `deploy.sh` to `robot.wtf`
+ - [ ] Verify CI passes on each repo (push a test branch or trigger manually)
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9