Skip to content

Commit 7daccfe

Browse files
chore: add plugin maintenance cadence, dependabot config, and playbook (#147)
* chore: add plugin maintenance cadence, dependabot config, and playbook Signed-off-by: Madhu Mohan Jaishankar <madhu.mohan.jaishankar@ibm.com> * chore: address review feedback on maintenance cadence Signed-off-by: Madhu Mohan Jaishankar <madhu.mohan.jaishankar@ibm.com> --------- Signed-off-by: Madhu Mohan Jaishankar <madhu.mohan.jaishankar@ibm.com>
1 parent 6eee653 commit 7daccfe

3 files changed

Lines changed: 296 additions & 0 deletions

File tree

‎.github/dependabot.yml‎

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
version: 2
2+
updates:
3+
# Rust/Cargo workspace dependencies
4+
- package-ecosystem: cargo
5+
directory: /
6+
schedule:
7+
interval: weekly
8+
day: monday
9+
time: "08:00"
10+
timezone: UTC
11+
groups:
12+
# Group all minor/patch bumps into one PR; major versions open individually
13+
rust-minor-patch:
14+
update-types:
15+
- minor
16+
- patch
17+
labels:
18+
- dependencies
19+
- rust
20+
open-pull-requests-limit: 5
21+
22+
# Python dependencies — root uv workspace (6 plugins via pyproject.toml)
23+
- package-ecosystem: uv
24+
directory: /
25+
schedule:
26+
interval: weekly
27+
day: monday
28+
time: "08:00"
29+
timezone: UTC
30+
groups:
31+
python-minor-patch:
32+
update-types:
33+
- minor
34+
- patch
35+
labels:
36+
- dependencies
37+
- "python:uv"
38+
open-pull-requests-limit: 5
39+
40+
# Python dependencies — sql_sanitizer (standalone uv workspace)
41+
- package-ecosystem: uv
42+
directory: /plugins/rust/python-package/sql_sanitizer
43+
schedule:
44+
interval: weekly
45+
day: monday
46+
time: "08:00"
47+
timezone: UTC
48+
groups:
49+
sql-sanitizer-minor-patch:
50+
update-types:
51+
- minor
52+
- patch
53+
labels:
54+
- dependencies
55+
- "python:uv"
56+
open-pull-requests-limit: 3
57+
58+
# GitHub Actions pinned-SHA bumps
59+
- package-ecosystem: github-actions
60+
directory: /
61+
schedule:
62+
interval: weekly
63+
day: monday
64+
time: "08:00"
65+
timezone: UTC
66+
groups:
67+
actions-minor-patch:
68+
update-types:
69+
- minor
70+
- patch
71+
labels:
72+
- dependencies
73+
open-pull-requests-limit: 5
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
name: Plugin Maintenance
2+
3+
on:
4+
schedule:
5+
- cron: '0 8 1 * *' # 1st of each month, 08:00 UTC
6+
workflow_dispatch: # manual trigger — use before any unplanned release
7+
8+
concurrency:
9+
group: plugin-maintenance
10+
cancel-in-progress: false # never cancel an in-flight maintenance run
11+
12+
permissions:
13+
contents: write
14+
pull-requests: write
15+
16+
jobs:
17+
update-and-test:
18+
runs-on: ubuntu-latest
19+
steps:
20+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
21+
22+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
23+
with:
24+
python-version: "3.12"
25+
26+
- name: Verify Rust toolchain
27+
run: |
28+
rustc --version
29+
cargo --version
30+
31+
- name: Set month label
32+
id: date
33+
run: echo "month=$(date -u +'%Y-%m')" >> "$GITHUB_OUTPUT"
34+
35+
- name: Install uv and maturin
36+
run: python -m pip install uv==0.9.30 maturin==1.12.6
37+
38+
- name: Install cargo-nextest
39+
run: |
40+
mkdir -p "${CARGO_HOME:-$HOME/.cargo}/bin"
41+
curl -LsSf https://get.nexte.st/0.9.133/linux | tar zxf - -C "${CARGO_HOME:-$HOME/.cargo}/bin"
42+
cargo nextest --version
43+
44+
- name: Install cargo-deny
45+
run: cargo install cargo-deny@0.19.0 --locked
46+
47+
# --- Update lock files ---
48+
49+
- name: Update Rust lock file
50+
run: cargo update
51+
52+
- name: Update root Python lock file
53+
run: uv lock --upgrade
54+
55+
- name: Update sql_sanitizer Python lock file
56+
# sql_sanitizer manages its own uv workspace outside the root workspace
57+
working-directory: plugins/rust/python-package/sql_sanitizer
58+
run: uv lock --upgrade
59+
60+
# --- Validate ---
61+
62+
- name: Security advisory check
63+
run: cargo deny --all-features check advisories --config deny.toml
64+
65+
- name: Test all plugins
66+
shell: bash
67+
run: |
68+
set -euo pipefail
69+
plugins=(
70+
encoded_exfil_detection
71+
pii_filter
72+
rate_limiter
73+
retry_with_backoff
74+
secrets_detection
75+
sql_sanitizer
76+
url_reputation
77+
)
78+
for plugin in "${plugins[@]}"; do
79+
echo "::group::Testing ${plugin}"
80+
pushd "plugins/rust/python-package/${plugin}"
81+
make sync
82+
NEXTEST_PROFILE=ci make ci
83+
popd
84+
echo "::endgroup::"
85+
done
86+
87+
# --- Open PR if lock files changed ---
88+
89+
- name: Open maintenance PR
90+
uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7
91+
with:
92+
commit-message: "chore: monthly dependency update ${{ steps.date.outputs.month }}"
93+
title: "chore: monthly dependency update – ${{ steps.date.outputs.month }}"
94+
body: |
95+
## Monthly Dependency Update – ${{ steps.date.outputs.month }}
96+
97+
Automated maintenance cycle per [MAINTENANCE.md](MAINTENANCE.md).
98+
99+
### Changes
100+
- `cargo update` applied to Rust workspace (`Cargo.lock`)
101+
- `uv lock --upgrade` applied to root Python workspace (`uv.lock`)
102+
- `uv lock --upgrade` applied to `sql_sanitizer` plugin lock file
103+
104+
### Validation performed in CI
105+
- All 7 plugins built and tested on `ubuntu-latest`
106+
- `cargo deny check advisories` passed — no new CVEs
107+
108+
### Reviewer checklist
109+
- [ ] Review lock file diffs for unexpected major-version jumps
110+
- [ ] Confirm gateway compatibility constraints in `pyproject.toml` remain satisfied
111+
- [ ] Record any deferred updates or new constraints in `MAINTENANCE.md` compat table
112+
113+
branch: chore/dep-update-${{ steps.date.outputs.month }}
114+
delete-branch: true
115+
labels: dependencies
116+
signoff: true

‎MAINTENANCE.md‎

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Plugin Maintenance Playbook
2+
3+
Tracks the ongoing maintenance cadence for all plugins in this repository.
4+
5+
---
6+
7+
## Cadence
8+
9+
| Cycle | Mechanism | Scope |
10+
|---|---|---|
11+
| **Weekly** | Dependabot (`.github/dependabot.yml`) | Individual package bumps — Rust, Python, GitHub Actions |
12+
| **Monthly** | Scheduled workflow (`dep-update-cadence.yaml`) | Full lock file refresh + all-plugin test run + consolidated PR |
13+
| **On demand** | `workflow_dispatch` on `dep-update-cadence.yaml` | Pre-release or emergency update |
14+
15+
---
16+
17+
## Ownership
18+
19+
| Role | Responsibility |
20+
|---|---|
21+
| **Cycle owner** | Runs or monitors the monthly automated PR; reviews and merges or defers |
22+
| **Backup** | Takes over if cycle owner is unavailable |
23+
| **Current cycle owner** | @madhu-mohan-jaishankar |
24+
| **Backup** | @lucarlig |
25+
26+
The cycle owner rotates quarterly. Update this table when ownership changes.
27+
28+
---
29+
30+
## Monthly Cycle — Step-by-Step Checklist
31+
32+
The monthly workflow runs automatically on the 1st of each month and opens a PR. If no lock file changes occurred, no PR is opened — note this in the cycle log below.
33+
34+
### When the PR is opened
35+
36+
1. **Review the lock file diffs**
37+
- `Cargo.lock` — check for any crate jumping a major version unexpectedly
38+
- `uv.lock` — check for any package bumping past the constraint bounds in `pyproject.toml`
39+
- `plugins/rust/python-package/sql_sanitizer/uv.lock` — same check
40+
41+
2. **Verify gateway compatibility constraints are still satisfied**
42+
- Open `pyproject.toml` → `[tool.uv] constraint-dependencies`
43+
- Confirm each pinned range (`cpex`, `pydantic`, `maturin`, etc.) still holds after the bump
44+
45+
3. **Check `deny.toml` advisory suppressions**
46+
- If `cargo deny check advisories` introduced new RUSTSEC advisories in the workflow log, evaluate and either update the suppress list with a justification comment or fix the dependency
47+
48+
4. **Merge or defer**
49+
- If all checks pass: approve and merge the PR
50+
- If a dependency needs deferral: close the PR, note the deferred package and reason in the **Compat Table** below, and open a follow-up issue
51+
52+
5. **Record the cycle outcome** in the **Cycle Log** below
53+
54+
---
55+
56+
## Pre-Release / Emergency Update
57+
58+
When a release is imminent and a dependency bump is needed:
59+
60+
```bash
61+
# Trigger manually from the Actions tab → "Monthly Dependency Update" → Run workflow
62+
# OR run locally:
63+
cargo update
64+
uv lock --upgrade
65+
cd plugins/rust/python-package/sql_sanitizer && uv lock --upgrade && cd -
66+
cargo deny --all-features check advisories --config deny.toml
67+
# Run tests for all plugins:
68+
for plugin in encoded_exfil_detection pii_filter rate_limiter retry_with_backoff secrets_detection sql_sanitizer url_reputation; do
69+
make plugin-test PLUGIN=$plugin
70+
done
71+
```
72+
73+
---
74+
75+
## Gateway Compatibility Table
76+
77+
Records known constraints between plugin dependencies and the gateway (`cpex`/`mcp-context-forge`). Update this when a dependency cannot be bumped due to gateway compatibility.
78+
79+
| Plugin | Constrained dependency | Pinned range | Gateway version | Notes | Last reviewed |
80+
|---|---|---|---|---|---|
81+
| all | `cpex` | `>=0.1.0,<0.2` | gateway 0.1.x | ABI boundary — major bump requires gateway coordination | 2026-07 |
82+
| all | `pydantic` | `>=2.13.4,<3` | gateway 0.1.x | Pydantic v3 not yet validated against gateway models | 2026-07 |
83+
| all | `maturin` | `>=1.13.3,<2.0` | build toolchain | Major maturin bumps may change wheel ABI tagging | 2026-07 |
84+
| all | `redis` | `>=7.4.0` | gateway 0.1.x | Lower bound — no upper constraint yet | 2026-07 |
85+
| `pii_filter` | `pyo3` | `0.29.0` (workspace) | — | ABI3-py311; bump with cross-plugin coordination | 2026-07 |
86+
| `secrets_detection` | `regex` | `1.12.3` (workspace) | — | No constraint; update freely | 2026-07 |
87+
88+
---
89+
90+
## Cycle Log
91+
92+
Record each completed cycle here. One row per month.
93+
94+
| Month | PR / Issue | Lock changes? | CVEs found | Deferrals | Merged by |
95+
|---|---|---|---|---|---|
96+
| 2026-07 | _first automated cycle pending_ | — | — | — | — |
97+
98+
---
99+
100+
## Dependabot PRs — Triage Guide
101+
102+
Dependabot opens individual PRs weekly for new package releases. Triage criteria:
103+
104+
- **Patch** (`x.y.Z`): merge if CI passes, no gateway constraint hit
105+
- **Minor** (`x.Y.z`): review changelog; merge if no breaking API changes and CI passes
106+
- **Major** (`X.y.z`): evaluate manually; update the compat table; coordinate with gateway team if the dep is in `constraint-dependencies`
107+
- **RUSTSEC advisory**: treat as P1 — either bump the dep or suppress with a justification in `deny.toml`

0 commit comments

Comments
 (0)