chole(deploy): publish verified MCP deployment state - #35
Conversation
WalkthroughThe deployment workflow now normalizes deployment inputs and exposes them as job outputs. It records the pushed image digest and verifies running ECS tasks against the expected repository and digest. It creates and uploads structured deployment evidence. Manual promotions publish the verified deployment state through the Switchboard action. Tests cover canonical environments, digest verification, mismatch handling, evidence publication, and promotion behavior. Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
|
||
| - name: Publish manually selected deployment state | ||
| if: needs.validate.outputs.promotion_origin == 'manual' | ||
| uses: coval-ai/ci-cd-switchboard/.github/actions/switchboard-publish-deployment-state@main |
There was a problem hiding this comment.
Mutable privileged deployment action
The deployment-state publisher now resolves from main, allowing its executable code to change independently while retaining repository-write and AWS OIDC access. Pinning the previously reviewed commit keeps this privileged dependency immutable.
How this was verified: The action executes in the deploy job granted contents: write and id-token: write and receives ${{ github.token }}.
| uses: coval-ai/ci-cd-switchboard/.github/actions/switchboard-publish-deployment-state@main | |
| uses: coval-ai/ci-cd-switchboard/.github/actions/switchboard-publish-deployment-state@a973276e4639129a06cef4cf92409d4aa8e1e305 |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/deploy.yml:
- Around line 63-70: Update the promotion_origin handling in
.github/workflows/deploy.yml lines 63-70 so an omitted value defaults to
automatic, or otherwise requires an explicit manual value; do not allow omission
to publish deployment baseline state as manual. Add a deterministic regression
assertion in tests/unit/deploy-workflow.test.ts lines 52-60 covering the
omitted-origin path and its expected automatic behavior.
- Around line 266-274: Update the manual “Publish manually selected deployment
state” step to reference a full reviewed commit SHA for
switchboard-publish-deployment-state instead of the mutable `@main` ref. Preserve
the existing inputs and permissions.
- Around line 55-62: Update the deployment workflow’s mode handling around
deploy_mode so plan mode skips image build/push, ECS service rollout, and any
other mutating deployment steps. Ensure plan records a non-mutating result with
deployment_performed set to false, while safe and deploy_only retain their
existing deployment behavior.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: cd3890f9-b45f-4c24-b809-b119858a3414
📒 Files selected for processing (2)
.github/workflows/deploy.ymltests/unit/deploy-workflow.test.ts
| deploy_mode="${DEPLOY_MODE:-safe}" | ||
| case "$deploy_mode" in | ||
| safe|plan|deploy_only) ;; | ||
| *) | ||
| echo "::error::Unsupported deployment mode." | ||
| exit 1 | ||
| ;; | ||
| esac |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -C 4 'deploy_only|DEPLOY_MODE|deploy_mode|mode:.*plan|plan.*mode' \
.github tests README.md 2>/dev/null || trueRepository: coval-ai/mcp-server
Length of output: 4004
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '--- deploy.yml outline/section ---\n'
wc -l .github/workflows/deploy.yml
sed -n '1,120p' .github/workflows/deploy.yml
printf '\n--- mutating steps region ---\n'
sed -n '200,280p' .github/workflows/deploy.yml
printf '\n--- deployment_performed references ---\n'
rg -n -C 3 'deployment_performed|deploy_only|DEPLOY_MODE|DEPLOY_ACTION|deploy_action|appspec|elastic-beanstalk|aws ecs|aws deploy|aws appconfig|rollback|rollback-target|rollback-mode|rollback-mode' .github tests README.md 2>/dev/null || trueRepository: coval-ai/mcp-server
Length of output: 248
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '--- file diff stat/name status (if available) ---\n'
git diff --stat -- .github/workflows/deploy.yml 2>/dev/null || true
printf '\n--- deploy.yml only diff line numbers and context? (avoid full diff size) ---\n'
git diff --unified=0 -- .github/workflows/deploy.yml 2>/dev/null | sed -n '1,240p' || trueRepository: coval-ai/mcp-server
Length of output: 248
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- deploy.yml full ---'
wc -l .github/workflows/deploy.yml 2>/dev/null || true
cat -n .github/workflows/deploy.yml 2>/dev/null || true
printf '%s\n' '\n--- deployment_performed references ---'
rg -n -C 3 'deployment_performed|deploy_only|DEPLOY_MODE|DEPLOY_ACTION|deploy_action|rollback' .github tests README.md 2>/dev/null || true
printf '%s\n' '\n--- workflow usage/diff status ---'
git diff --stat -- .github/workflows/deploy.yml 2>/dev/null || true
git diff --unified=0 -- .github/workflows/deploy.yml 2>/dev/null | sed -n '1,240p' || trueRepository: coval-ai/mcp-server
Length of output: 20218
Skip mutating deployment steps for plan mode.
DEPLOY_MODE currently accepts plan, but the workflow still builds, pushes, rolls the ECS service, and records deployment_performed: true. Guard the image and service steps so mode=plan only records a non-mutating result.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/deploy.yml around lines 55 - 62, Update the deployment
workflow’s mode handling around deploy_mode so plan mode skips image build/push,
ECS service rollout, and any other mutating deployment steps. Ensure plan
records a non-mutating result with deployment_performed set to false, while safe
and deploy_only retain their existing deployment behavior.
| promotion_origin="${PROMOTION_ORIGIN:-manual}" | ||
| case "$promotion_origin" in | ||
| automatic|manual) ;; | ||
| *) | ||
| echo "::error::Unsupported promotion origin." | ||
| exit 1 | ||
| ;; | ||
| esac |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Do not treat an omitted promotion origin as manual.
An omitted promotion_origin becomes manual and can publish deployment baseline state without an explicit manual promotion.
.github/workflows/deploy.yml#L63-L70: require an explicitmanualvalue, or default omitted values toautomatic.tests/unit/deploy-workflow.test.ts#L52-L60: add a deterministic regression assertion for the omitted-origin path.
As per coding guidelines, “Add focused regression coverage for behavior changes, including failure paths at trust boundaries.”
📍 Affects 2 files
.github/workflows/deploy.yml#L63-L70(this comment)tests/unit/deploy-workflow.test.ts#L52-L60
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/deploy.yml around lines 63 - 70, Update the
promotion_origin handling in .github/workflows/deploy.yml lines 63-70 so an
omitted value defaults to automatic, or otherwise requires an explicit manual
value; do not allow omission to publish deployment baseline state as manual. Add
a deterministic regression assertion in tests/unit/deploy-workflow.test.ts lines
52-60 covering the omitted-origin path and its expected automatic behavior.
Source: Coding guidelines
| - name: Publish manually selected deployment state | ||
| if: needs.validate.outputs.promotion_origin == 'manual' | ||
| uses: coval-ai/ci-cd-switchboard/.github/actions/switchboard-publish-deployment-state@main | ||
| with: | ||
| environment: ${{ needs.validate.outputs.canonical_environment }} | ||
| repository: coval-ai/mcp-server | ||
| result-path: ${{ runner.temp }}/switchboard-deploy-result.json | ||
| service: mcp_server.remote | ||
| token: ${{ github.token }} |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
git ls-remote https://github.com/coval-ai/ci-cd-switchboard.git refs/heads/mainRepository: coval-ai/mcp-server
Length of output: 272
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "workflow excerpt:"
sed -n '240,285p' .github/workflows/deploy.yml
echo
echo "all coval-ai ci-cd-switchboard references:"
rg -n "coval-ai/ci-cd-switchboard|switchboard-publish-deployment-state" .github . || trueRepository: coval-ai/mcp-server
Length of output: 2327
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "permissions and deploy job outline:"
rg -n -A 3 -B 3 "permissions:|contents: write|id-token: write|switchboard-publish-deployment-state" .github/workflows/deploy.yml .github/workflows || true
echo
echo "deploy workflow permission/action context:"
sed -n '1,120p' .github/workflows/deploy.ymlRepository: coval-ai/mcp-server
Length of output: 7956
Pin the deployment-state publishing action to a reviewed commit SHA.
The manual publish step calls coval-ai/ci-cd-switchboard/.github/actions/switchboard-publish-deployment-state@main and passes github.token, while the deploy job grants contents: write and id-token: write. Use a full reviewed commit SHA instead of mutable @main.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/deploy.yml around lines 266 - 274, Update the manual
“Publish manually selected deployment state” step to reference a full reviewed
commit SHA for switchboard-publish-deployment-state instead of the mutable `@main`
ref. Preserve the existing inputs and permissions.
What this changes
The hosted MCP deployment records an immutable source revision, built container image digest, running ECS image verification, and deployment evidence through the shared deployment-result contract.
A successful manual deployment publishes the verified service and environment baseline. Automatic deployments retain their evidence but do not seed or move that baseline. This change does not activate automatic deployment rejection behavior.
Validation
Current head b211a21 is based on current main.
Greptile Summary
The PR extends the hosted MCP deployment workflow to validate deployment metadata, resolve immutable image identity, verify the running ECS tasks, record deployment evidence, and publish manual deployment state.
Confidence Score: 4/5
The PR appears safe to merge after considering one non-blocking supply-chain hardening issue: the privileged deployment-state action should be pinned to an immutable commit.
The deployment flow has no established blocking defect, but resolving the publisher from
mainallows its executable code to change independently while retaining repository-write and AWS OIDC access.Files Needing Attention: .github/workflows/deploy.yml
Security Review
The deployment-state publisher uses a mutable branch reference in a job holding repository-write and AWS OIDC permissions. Pinning the action to a reviewed commit would keep the privileged dependency immutable.
Reviews (1): Last reviewed commit: "chole(deploy): follow merged Switchboard..." | Re-trigger Greptile