Blame

d7b7e3 Claude (MCP) 2026-03-18 03:26:44
[mcp] Add CI/CD pipeline plan
1
---
2
category: spec
3
tags: [ci, cd, github-actions, plan]
4
last_updated: 2026-03-18
5
confidence: high
6
---
7
8
# CI/CD Pipeline Plan
9
10
## Current State
11
12
- Five repos: `robot.wtf`, `otterwiki` (fork), `otterwiki-api`, `otterwiki-mcp`, `otterwiki-semantic-search`
13
- All have pytest suites; no GitHub Actions workflows exist in any repo
14
- Deploy: `ansible-playbook ansible/deploy.yml -i ansible/inventory.yml` from `robot.wtf/` on a laptop
15
- Ansible `deploy` role installs each plugin directly from GitHub main branch via `pip install git+https://...`
16
- Post-deploy smoke test is baked into the playbook
17
18
## Test Infrastructure Summary
19
20
| Repo | Test runner | Dependencies |
21
|------|-------------|--------------|
22
| `robot.wtf` | pytest, no pyproject | `requirements.txt` (Flask, PyJWT, etc.) |
23
| `otterwiki` | pytest via pyproject / tox | Self-contained |
24
| `otterwiki-api` | pytest via pyproject | Requires `otterwiki` installed |
25
| `otterwiki-semantic-search` | pytest via pyproject | Requires `otterwiki` installed |
26
| `otterwiki-mcp` | pytest + pytest-asyncio | Standalone (no `otterwiki` dep) |
27
28
## Phase 1: Per-Repo CI on PR (do this session)
29
30
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.
31
32
### Template (robot.wtf)
33
34
```yaml
35
name: CI
36
on:
37
pull_request:
38
push:
39
branches: [main]
40
41
jobs:
42
test:
43
runs-on: ubuntu-latest
44
steps:
45
- uses: actions/checkout@v4
46
- uses: actions/setup-python@v5
47
with:
48
python-version: "3.12"
49
- run: pip install -r requirements.txt
50
- run: pip install pytest
51
- run: pytest tests/
52
```
53
54
### Plugin repos (otterwiki-api, otterwiki-semantic-search)
55
56
These depend on `otterwiki`. Install the fork's `wikibot-io` branch before installing the plugin:
57
58
```yaml
59
- run: pip install "git+https://github.com/schuyler/otterwiki.git@wikibot-io"
60
- run: pip install -e ".[dev]"
61
- run: pytest
62
```
63
64
### otterwiki-mcp
65
66
Standalone; no otterwiki dep. Standard `pip install -e ".[dev]" && pytest`.
67
68
### otterwiki (fork)
69
70
Uses tox config in pyproject.toml. Can run `pip install -e ".[dev]" && pytest` directly to avoid tox overhead in CI.
71
72
## Phase 2: Deploy Script (do this session)
73
74
The Ansible command is easy to forget. Add `deploy.sh` to `robot.wtf/`:
75
76
```bash
77
#!/usr/bin/env bash
78
set -euo pipefail
79
cd "$(dirname "$0")"
80
ansible-playbook ansible/deploy.yml -i ansible/inventory.yml "$@"
81
```
82
83
This is the entire CD story for now. Manual deploy stays manual — that's the right call given:
84
- Deploy requires pulling from GitHub, so all plugin changes must be merged to main first
85
- No staging environment exists
86
- Smoke test is already part of the playbook
87
88
## Phase 3: Auto-Deploy (deferred)
89
90
Options when ready:
91
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.
92
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.
93
3. **Repository dispatch** — plugin repos trigger a workflow in `robot.wtf` via the GitHub API on merge to main. Preserves separation of concerns.
94
95
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`.
96
97
## Integration Testing
98
99
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.
100
101
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.
102
103
## Task Checklist
104
105
- [ ] Add `.github/workflows/ci.yml` to `robot.wtf`
106
- [ ] Add `.github/workflows/ci.yml` to `otterwiki` (fork)
107
- [ ] Add `.github/workflows/ci.yml` to `otterwiki-api`
108
- [ ] Add `.github/workflows/ci.yml` to `otterwiki-mcp`
109
- [ ] Add `.github/workflows/ci.yml` to `otterwiki-semantic-search`
110
- [ ] Add `deploy.sh` to `robot.wtf`
111
- [ ] Verify CI passes on each repo (push a test branch or trigger manually)