chore(claude): add dev container skills for Claude Code - #2741
Conversation
Add three project skills that route development actions through the Bucketeer dev container, where the toolchain is guaranteed: - devc: detect the running dev container (local devcontainer or GitHub Codespace) and run any command inside it via scripts/devc-exec.sh - devc-generate: proto/mock generation inside the container (protoc v23.4 guaranteed; host version mismatch churns every generated file) - devc-deploy: minikube deploys inside the container, incl. the faster single-service rollout path Also update .claude/CLAUDE.md to prefer the dev container + minikube flow for these actions, with Docker Compose as the host-based alternative. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR adds Claude Code project skills to standardize Bucketeer dev workflows through the devcontainer (and its minikube cluster), reducing host-environment drift for codegen, builds, and deploys.
Changes:
- Add three Claude skills (
devc,devc-generate,devc-deploy) documenting the recommended devcontainer-based workflows. - Introduce a
devc-exec.shwrapper script to detect a running devcontainer/Codespace and execute commands inside it. - Update
.claude/CLAUDE.mdto prefer the devcontainer + minikube flow for environment-sensitive tasks.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| .claude/skills/devc/SKILL.md | Documents the devcontainer as the canonical environment and how to route commands through the wrapper script. |
| .claude/skills/devc/scripts/devc-exec.sh | Adds container/Codespace detection and a status/exec command runner for devcontainer workflows. |
| .claude/skills/devc-generate/SKILL.md | Documents proto/mock generation via the devcontainer to ensure protoc version consistency. |
| .claude/skills/devc-deploy/SKILL.md | Documents deploy/redeploy workflows targeting minikube inside the devcontainer. |
| .claude/CLAUDE.md | Updates contributor guidance to prefer the devcontainer + minikube workflow for environment-sensitive actions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Address review comments on PR #2741: - Guard kubectl get pods in the status report; print a clear message when kubectl fails while minikube is up instead of a misleading 0-pod count - Derive the repo root from the script location for an exact devcontainer.local_folder label match from any cwd; drop the fuzzy fallback that could pick the wrong container when multiple checkouts are running Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
manifests/datadog-agent.yaml was accidentally included in the previous commit; it is local work unrelated to this PR. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ence Address review comments on PR #2741: - Rename skills for clarity: devc -> devcontainer-run, devc-generate -> devcontainer-generate, devc-deploy -> devcontainer-deploy; the wrapper script is now .claude/skills/devcontainer-run/scripts/exec.sh - Move human-facing environment knowledge into DEVELOPMENT.md (working with the dev container from the host, start-minikube exit-1 note, single-service redeploy flow) and cross-reference it from the skills, which keep only the Claude-oriented operational detail Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Suppressed comments (2)
Previously missed (2) — in code that hasn't changed since the last review.
DEVELOPMENT.md:99
- The newly added single-service workflow now follows an existing instruction to install
manifests/bucketeer/charts/backend, but that chart does not exist; the actual charts/deployments are the four listed here. Remove the obsolete block so readers are not given two conflicting workflows, one of which always fails.
For faster iteration on a single service after a Go code change, rebuild and load the images, then restart only that deployment (`api`, `web`, `batch-server`, or `subscriber`):
.claude/skills/devcontainer-deploy/SKILL.md:51
- This description is incomplete:
POSTGRES_ENABLEDis true when eitherdataWarehouseoroperationalDatabaseispostgres, while only BigQuery is derived solely fromdataWarehouse(Makefile:7-11). Document both inputs so troubleshooting guidance matches what the deploy target actually enables.
and monitor. Postgres/BigQuery enablement is auto-detected from
`dataWarehouse` in `values.dev.yaml` — don't set it manually, but remember the
Address review comments on PR #2741: - Name the kube context explicitly in every cluster command (kubectl --context minikube, helm --kube-context minikube) and warn in `status` when the active context is not minikube, so a stray `kubectl config use-context` cannot redirect a deploy at a real cluster. - Route the chart-level `helm upgrade` through $DEVC like every other deploy command instead of leaving it to run on the host. - Run the protoc-header spot-check through $DEVC: in codespace mode a bare grep reads the host clone and can falsely validate a stale file. - Refuse to guess between multiple available Bucketeer codespaces; exit 2 with the list and honour an explicit BUCKETEER_CODESPACE override.
There was a problem hiding this comment.
🟡 Changes recommended
Some documented commands can target the wrong Kubernetes cluster, and the execution wrapper mishandles multi-argument commands.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (3)
Previously missed (2) — in code that hasn't changed since the last review.
.claude/skills/devcontainer-run/scripts/exec.sh:149
- Joining arguments with
$*discards argument boundaries before the command reachesbash -c; for example,exec.sh git commit -m "two words"is reconstructed asgit commit -m two words. Since the script advertises<command ...>, preserve multi-argument invocations while retaining the single-string form used for compound shell commands.
.claude/CLAUDE.md:106 make deploy-bucketeerbegins with a barehelm uninstall bucketeerindelete-bucketeer-from-minikube; merely running inside the container does not make that safe when its active context was changed. Pin the context before this example invokes the target.
.claude/skills/devcontainer-run/SKILL.md:50
- Exit code 2 is not unique to detection failures:
run_insidedeliberately passes through the invoked command's status, and many commands also return 2. Treating every 2 as “no container/ambiguity” can make the agent report the wrong remediation after a command actually ran; document that the diagnostic output must be used to distinguish these cases (or reserve a non-forwarded status).
Exit code 2 means no container was found (or the codespace was ambiguous); the
script prints how to start one.
- Files reviewed: 6/6 changed files
- Comments generated: 4
- Review effort level: Balanced
| # the wrong container when multiple checkouts are running. | ||
| local repo_root | ||
| repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd)" | ||
| CID="$(docker ps -q --filter "label=devcontainer.local_folder=$repo_root" 2>/dev/null | head -1 || true)" |
| ## 2. Full deploy | ||
|
|
||
| ```bash | ||
| $DEVC 'make deploy-bucketeer' |
|
|
||
| # Run any command in /workspaces/bucketeer inside the container | ||
| bash .claude/skills/devcontainer-run/scripts/exec.sh 'make build-api' | ||
| bash .claude/skills/devcontainer-run/scripts/exec.sh 'kubectl get pods' |
| make build-go-embed | ||
| TAG=localenv make build-docker-images | ||
| TAG=localenv make minikube-load-images | ||
| kubectl rollout restart deployment web && kubectl rollout status deployment web |
What this PR does
Adds three Claude Code project skills —
devcontainer-run,devcontainer-generate,devcontainer-deploy— that let Claude detect the running Bucketeer dev container (local devcontainer or GitHub Codespace) and run development actions inside it, and updates.claude/CLAUDE.mdto prefer the dev container + minikube flow for those actions.Background / Why this PR is needed
Codegen and deploys are environment-sensitive: generated files must be produced with exactly protoc v23.4, minikube must be started via
make start-minikube, and the*.bucketeer.iohosts entries only resolve inside the container. When Claude (or a human) runs these on the host, a protoc version mismatch silently churns every generated.pb.gofile, and barekubectl/helmcan hit the wrong cluster — the host kubectl context may point at a real GKE cluster instead of minikube. These skills route all such actions through the dev container, where the toolchain is guaranteed.Points
devcontainer-run/scripts/exec.shdetection order: already inside the container → local devcontainer (docker labeldevcontainer.local_folder) → GitHub Codespace (gh codespace ssh). When nothing is found it exits 2 with instructions to start one — deliberately no silent fallback to the host.devcontainer.local_folderlabel match against the repo root, and if several Bucketeer Codespaces are available the script exits 2 with the list and asks forBUCKETEER_CODESPACE=<name>rather than taking the first.kubectl --context minikube,helm --kube-context minikube) andstatuswarns when the active context is notminikube, so a straykubectl config use-contextcannot silently redirect a deploy at a real cluster.gh codespace cpor a push to get back to the host); a local devcontainer is a bind mount, so no sync is needed. Verification steps therefore run through$DEVCtoo, so they inspect the clone where generation actually happened.make proto-allrun through the skill reproduced the committed generated files byte-for-byte (zero diff), and the single-service rollout commands were validated against the running minikube cluster.