From f5ed8728d4785d35187c4f6ab50325c002379ba4 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Tue, 14 Oct 2025 18:41:28 +0300 Subject: [PATCH] Split deploying to prod and staging (#666) ## Motivation and Context The following PR splits the workflows for deploying to prod and staging easing the use of gitops flows for promotions. ## How Has This Been Tested? ## Breaking Changes ## Types of changes - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update ## Checklist - [ ] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [ ] My code follows the repository's style guidelines - [ ] New and existing tests pass locally - [ ] I have added appropriate error handling - [ ] I have added or updated documentation as needed ## Additional context Signed-off-by: Radoslav Dimitrov --- .github/workflows/deploy-production.yml | 56 +++++++++++++++++++ .../{deploy.yml => deploy-staging.yml} | 46 +-------------- deploy/README.md | 31 ++++++++-- docs/guides/contributing/releasing.md | 8 ++- 4 files changed, 91 insertions(+), 50 deletions(-) create mode 100644 .github/workflows/deploy-production.yml rename .github/workflows/{deploy.yml => deploy-staging.yml} (67%) diff --git a/.github/workflows/deploy-production.yml b/.github/workflows/deploy-production.yml new file mode 100644 index 0000000..32103ce --- /dev/null +++ b/.github/workflows/deploy-production.yml @@ -0,0 +1,56 @@ +name: Deploy to Production + +on: + push: + branches: + - main + paths: + - 'deploy/Pulumi.gcpProd.yaml' + +permissions: + contents: read + +env: + PULUMI_VERSION: "3.188.0" + +jobs: + deploy-production: + name: Deploy to Production + runs-on: ubuntu-latest + environment: production + concurrency: + group: deploy-production + cancel-in-progress: false + steps: + - name: Checkout code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 + + - name: Setup Go + uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 + with: + go-version-file: 'go.mod' + cache: true + + - name: Setup Pulumi + uses: pulumi/actions@d7ceb0215da5a14ec84f50b703365ddf0194a9c8 + with: + pulumi-version: ${{ env.PULUMI_VERSION }} + + - name: Authenticate to Google Cloud + uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 + with: + credentials_json: ${{ secrets.GCP_PROD_SERVICE_ACCOUNT_KEY }} + + - name: Setup Google Cloud SDK + uses: google-github-actions/setup-gcloud@aa5489c8933f4cc7a4f7d45035b3b1440c9c10db + with: + project_id: mcp-registry-prod + install_components: gke-gcloud-auth-plugin + + - name: Deploy to Production + working-directory: ./deploy + env: + PULUMI_PROD_PASSPHRASE: ${{ secrets.PULUMI_PROD_PASSPHRASE }} + run: | + echo "$PULUMI_PROD_PASSPHRASE" > passphrase.prod.txt + make prod-up \ No newline at end of file diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy-staging.yml similarity index 67% rename from .github/workflows/deploy.yml rename to .github/workflows/deploy-staging.yml index 62c0f6b..906463f 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy-staging.yml @@ -1,9 +1,11 @@ -name: Deploy +name: Deploy to Staging on: push: branches: - main + paths-ignore: + - 'deploy/Pulumi.gcpProd.yaml' permissions: contents: read @@ -94,45 +96,3 @@ jobs: run: | echo "$PULUMI_STAGING_PASSPHRASE" > passphrase.staging.txt make staging-up - - deploy-production: - name: Deploy to Production - runs-on: ubuntu-latest - environment: production - needs: deploy-staging - concurrency: - group: deploy-production - cancel-in-progress: false - steps: - - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 - - - name: Setup Go - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 - with: - go-version-file: 'go.mod' - cache: true - - - name: Setup Pulumi - uses: pulumi/actions@d7ceb0215da5a14ec84f50b703365ddf0194a9c8 - with: - pulumi-version: ${{ env.PULUMI_VERSION }} - - - name: Authenticate to Google Cloud - uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 - with: - credentials_json: ${{ secrets.GCP_PROD_SERVICE_ACCOUNT_KEY }} - - - name: Setup Google Cloud SDK - uses: google-github-actions/setup-gcloud@aa5489c8933f4cc7a4f7d45035b3b1440c9c10db - with: - project_id: mcp-registry-prod - install_components: gke-gcloud-auth-plugin - - - name: Deploy to Production - working-directory: ./deploy - env: - PULUMI_PROD_PASSPHRASE: ${{ secrets.PULUMI_PROD_PASSPHRASE }} - run: | - echo "$PULUMI_PROD_PASSPHRASE" > passphrase.prod.txt - make prod-up diff --git a/deploy/README.md b/deploy/README.md index 3e4142d..b8da9e1 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -29,15 +29,34 @@ PULUMI_CONFIG_PASSPHRASE="" pulumi config set mcp-registry:githubClientSecret -- ### Production Deployment (GCP) -**Note:** The production deployment is automatically handled by GitHub Actions. All merges to the `main` branch trigger an automatic deployment the `staging` environment at GCP via [the configured GitHub Actions workflow](../.github/workflows/deploy.yml). +**Note:** Deployments are automatically handled by GitHub Actions with separate workflows for staging and production: -**Important:** Deployment to `prod` require explicit configuration of the Docker image tag in `Pulumi.gcpProd.yaml`. This prevents automatic promotion of new releases and provides manual control over production versions. To deploy a specific version: +- **Staging:** All merges to the `main` branch automatically build and deploy the latest code to the `staging` environment via [deploy-staging.yml](../.github/workflows/deploy-staging.yml). Staging always uses the `:main` Docker image tag. -1. Update `mcp-registry:imageTag` in `Pulumi.gcpProd.yaml` to the desired version (e.g., `v1.0.0`, `main-20250930-abc123d`) -2. Commit the changes and open a PR to `main` -3. Once merged, the GitHub Actions workflow will deploy the specified version +- **Production:** Deployment requires explicit configuration of the Docker image tag in `Pulumi.gcpProd.yaml` and is triggered automatically via [deploy-production.yml](../.github/workflows/deploy-production.yml) when this config file is pushed to `main`. This GitOps-style approach provides manual control and an audit trail for production versions. -The steps below are preserved as a log of what we did, or if a manual override is needed. +**To deploy a specific version to production:** + +1. Cut a release (if deploying a new version): + ```bash + # Via GitHub UI: https://github.com/modelcontextprotocol/registry/releases + # Or via gh CLI: + gh release create v1.2.3 --generate-notes + ``` + This builds Docker images tagged as `v1.2.3` and `latest` + +2. Update the production image tag in `Pulumi.gcpProd.yaml`: + ```bash + # Edit deploy/Pulumi.gcpProd.yaml + # Change line: mcp-registry:imageTag: v1.2.3 + git add deploy/Pulumi.gcpProd.yaml + git commit -m "Deploy v1.2.3 to production" + git push + ``` + +3. The production deployment workflow will automatically trigger and deploy the specified version + +**Manual Override:** The steps below are preserved if a manual deployment override is needed. Pre-requisites: - [Pulumi CLI installed](https://www.pulumi.com/docs/iac/download-install/) diff --git a/docs/guides/contributing/releasing.md b/docs/guides/contributing/releasing.md index 9ce96f8..470cb12 100644 --- a/docs/guides/contributing/releasing.md +++ b/docs/guides/contributing/releasing.md @@ -21,7 +21,13 @@ The release workflow will automatically: - `ghcr.io/modelcontextprotocol/registry:vX.Y.Z` - Specific release version - Binaries can be downloaded from the GitHub release page -**Note:** Releases do not automatically deploy to production. See the [deployment documentation](../../deploy/README.md) for production deployment instructions. +**Note:** Releases do not automatically deploy to production. To deploy a release to production: + +1. Update `mcp-registry:imageTag` in `deploy/Pulumi.gcpProd.yaml` to the desired version (e.g., `v1.2.3`) +2. Commit and push the change to the `main` branch +3. The [deploy-production.yml](../../../.github/workflows/deploy-production.yml) workflow will automatically trigger and deploy the specified version + +See the [deployment documentation](../../../deploy/README.md) for more details. ## Docker Image Tags