diff --git a/.env.quickstart.example b/.env.quickstart.example index a092448..6b40172 100644 --- a/.env.quickstart.example +++ b/.env.quickstart.example @@ -204,6 +204,12 @@ ROSETTA_MCP_ENABLED=false # How: Keep as-is. Only change if you mount a custom plugin. ROSETTA_PLUGIN_PATH=/opt/rosetta-plugin # +# ROSETTA_MARKETPLACE_REF +# What: Git tag/branch/SHA of the public griddynamics/rosetta marketplace to bake into +# the image at BUILD time (build arg, not a runtime setting). Pins the plugin version. +# How: Bump to a newer tag and rebuild the backend image to upgrade the bundled KB plugin. +ROSETTA_MARKETPLACE_REF=v2.0.55 +# # ROSETTA_API_KEY / ROSETTA_USER_EMAIL / ROSETTA_SERVER_URL # What: Credentials for the live IMS-MCP Rosetta service. # Only needed when ROSETTA_MCP_ENABLED=true. diff --git a/backend/Dockerfile b/backend/Dockerfile index 78166ba..3f78f40 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -124,15 +124,21 @@ COPY claude-settings.json /root/.claude/settings.json # the codegen agents use). We invoke it by absolute path (it is not a uv/venv entry point). # The install path is read back from the CLI's own installed_plugins.json (via jq) and copied # to a stable /opt/rosetta-plugin so the runtime path never depends on the resolved version. -# Plugin versions cannot be pinned via the CLI, so the build takes the marketplace's current version. +# +# The marketplace catalog is PINNED to a git tag via the `#` syntax. `plugin install` +# has no version flag, so pinning the marketplace ref is what pins the installed plugin version. +# The ref is a build arg (ROSETTA_MARKETPLACE_REF); docker-compose supplies it from .env +# (falling back to the default below), so it can be bumped without editing this Dockerfile: +# docker build --build-arg ROSETTA_MARKETPLACE_REF=v2.0.56 ... # # The guard asserts the staged plugin actually ships the offline toolset (manifest + skills + # workflows), failing the build if the marketplace ever serves an empty/MCP-only plugin. # --------------------------------------------------------------------------- ENV HOME=/root +ARG ROSETTA_MARKETPLACE_REF=v2.0.55 RUN CLAUDE_BIN="$(find /app/.venv -type f -path '*/claude_agent_sdk/_bundled/claude' | head -1)" \ && test -n "$CLAUDE_BIN" \ - && "$CLAUDE_BIN" plugin marketplace add griddynamics/rosetta \ + && "$CLAUDE_BIN" plugin marketplace add "https://github.com/griddynamics/rosetta.git#${ROSETTA_MARKETPLACE_REF}" \ && "$CLAUDE_BIN" plugin install "rosetta@rosetta" --scope user \ && installed="$(jq -r '.plugins["rosetta@rosetta"][] | select(.scope=="user") | .installPath' /root/.claude/plugins/installed_plugins.json | head -1)" \ && test -n "$installed" && test -d "$installed" \ diff --git a/docker-compose.yml b/docker-compose.yml index 8f348f5..04ca177 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -77,6 +77,10 @@ services: build: context: ./backend dockerfile: Dockerfile + args: + # Git tag/branch/SHA of the griddynamics/rosetta marketplace to bake in. + # Sourced from .env; falls back to the Dockerfile's own pinned default. + ROSETTA_MARKETPLACE_REF: ${ROSETTA_MARKETPLACE_REF:-v2.0.55} image: specflow-backend:latest container_name: ${SPECFLOW_BACKEND_CONTAINER:-specflow-backend} ports: