Skip to content

Commit 4e64858

Browse files
authored
feat!: reconcile deleted tools and helper script (#6)
1 parent 8f3160a commit 4e64858

3 files changed

Lines changed: 79 additions & 0 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,36 @@ jobs:
8686
--set image.tag="${{ github.sha }}" \
8787
$values
8888
89+
reconcile:
90+
needs: detect
91+
# Removing a toolset always touches shared paths (uv.lock, root
92+
# pyproject.toml), so any removal lands in a run with a non-empty matrix;
93+
# docs-only pushes skip, keeping kubeconfig out of no-op runs.
94+
if: needs.detect.outputs.toolsets != '[]'
95+
runs-on: ubuntu-latest
96+
steps:
97+
- uses: actions/checkout@v4
98+
- name: Configure kubeconfig
99+
run: |
100+
mkdir -p ~/.kube
101+
printf '%s' "${KUBE_CONFIG}" > ~/.kube/config
102+
chmod 600 ~/.kube/config
103+
env:
104+
KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
105+
- name: Uninstall releases whose toolset directory is gone
106+
run: |
107+
for release in $(helm list --namespace mcp-toolsets --short); do
108+
case "$release" in
109+
mcp-index) continue ;;
110+
mcp-*) toolset="${release#mcp-}" ;;
111+
*) continue ;;
112+
esac
113+
if [ ! -d "toolsets/$toolset" ]; then
114+
echo "Uninstalling $release: toolsets/$toolset no longer exists"
115+
helm uninstall "$release" --namespace mcp-toolsets
116+
fi
117+
done
118+
89119
index:
90120
needs: detect
91121
# Skip no-op pushes (e.g. docs): the index image is built from shared code,

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,22 @@ tools and merge.
9393
Conventions: directory `toolsets/<name>` (kebab-case) → module
9494
`<name_snake_case>.tools` → service `mcp-<name>`.
9595

96+
## Removing a toolset
97+
98+
```sh
99+
./scripts/remove-toolset my-toolset
100+
```
101+
102+
Merge to `main`. Removal is GitOps like everything else: the deploy
103+
workflow reconciles the cluster against `toolsets/`, uninstalling any
104+
`mcp-<name>` release whose directory no longer exists — Deployment, Service
105+
and Ingress with it; the index drops the entry automatically. Mind that
106+
this means merging a deleted directory tears down the live service.
107+
108+
Not removed automatically: out-of-band Secrets the toolset listed in its
109+
`toolset.yaml` (`kubectl -n mcp-toolsets delete secret <name>`) and its
110+
images in GHCR (delete the package from the repo settings if you care).
111+
96112
## Deployment
97113

98114
- **ci.yml** (PRs + main): lint, tests, `helm lint`, and a no-push Docker
@@ -102,6 +118,8 @@ Conventions: directory `toolsets/<name>` (kebab-case) → module
102118
root `pyproject.toml`) rebuild *all* toolsets — then per toolset: build and
103119
push `ghcr.io/<owner>/<repo>/mcp-<name>:<sha>` and
104120
`helm upgrade --install mcp-<name> charts/mcp-toolset -n mcp-toolsets`.
121+
A reconcile job also uninstalls releases whose `toolsets/<name>` directory
122+
is gone — see [Removing a toolset](#removing-a-toolset).
105123
- **Required secret**: `KUBE_CONFIG` — a kubeconfig with rights to manage the
106124
`mcp-toolsets` namespace. Images push to GHCR with the built-in
107125
`GITHUB_TOKEN`.

scripts/remove-toolset

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env sh
2+
# Remove a toolset: scripts/remove-toolset <name>
3+
#
4+
# Deletes toolsets/<name> and deregisters it from the uv workspace. Merging
5+
# the removal to main uninstalls the deployed mcp-<name> release: the deploy
6+
# workflow reconciles the cluster against the toolsets/ directory.
7+
8+
set -e
9+
10+
name="$1"
11+
if [ -z "$name" ]; then
12+
echo "usage: scripts/remove-toolset <name>" >&2
13+
exit 1
14+
fi
15+
dir="toolsets/$name"
16+
if [ ! -d "$dir" ]; then
17+
echo "error: $dir does not exist" >&2
18+
exit 1
19+
fi
20+
21+
uv remove "$name"
22+
rm -rf "$dir"
23+
# Re-lock: the removal above ran while the directory still existed, so the
24+
# lockfile still listed it as a workspace member.
25+
uv sync
26+
27+
echo
28+
echo "Removed $dir and deregistered it from the workspace."
29+
echo "Merge to main: the deploy workflow uninstalls the mcp-$name release."
30+
echo "Not removed automatically: out-of-band Secrets the toolset listed in"
31+
echo "toolset.yaml, and its images in GHCR."

0 commit comments

Comments
 (0)