cloudbuild.yamlā¢4 kB
steps:
# Install dependencies and run tests
- name: 'node:20'
entrypoint: 'npm'
args: ['ci']
# TypeScript type checking
- name: 'node:20'
entrypoint: 'npm'
args: ['run', 'typecheck']
# ESLint code quality check
- name: 'node:20'
entrypoint: 'npm'
args: ['run', 'lint']
# Run tests with coverage
- name: 'node:20'
entrypoint: 'npm'
args: ['test']
env:
- 'NODE_ENV=test'
# Build the application
- name: 'node:20'
entrypoint: 'npm'
args: ['run', 'build']
# Build Docker image
- name: 'gcr.io/cloud-builders/docker'
args: [
'build',
'-t', '${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REGISTRY_REPO}/mcp-hello-world:${COMMIT_SHA}',
'-t', '${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REGISTRY_REPO}/mcp-hello-world:latest',
'--build-arg', 'BUILD_SHA=${COMMIT_SHA}',
'.'
]
# Push Docker image to Artifact Registry
- name: 'gcr.io/cloud-builders/docker'
args: [
'push',
'--all-tags',
'${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REGISTRY_REPO}/mcp-hello-world'
]
# Generate SBOM (Software Bill of Materials)
- name: 'gcr.io/cloud-builders/gcloud'
args: [
'artifacts', 'docker', 'images', 'scan',
'${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REGISTRY_REPO}/mcp-hello-world:${COMMIT_SHA}',
'--location', '${_REGION}',
'--format', 'json',
'--quiet'
]
# Deploy to Cloud Run
- name: 'gcr.io/cloud-builders/gcloud'
args: [
'run', 'deploy', '${_SERVICE_NAME}',
'--image', '${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REGISTRY_REPO}/mcp-hello-world:${COMMIT_SHA}',
'--platform', 'managed',
'--region', '${_REGION}',
'--allow-unauthenticated',
'--port', '8080',
'--memory', '512Mi',
'--cpu', '1',
'--min-instances', '0',
'--max-instances', '10',
'--timeout', '30s',
'--set-env-vars', 'NODE_ENV=production,BUILD_SHA=${COMMIT_SHA},REGION=${_REGION}',
'--quiet'
]
# Health check the deployed service
- name: 'gcr.io/cloud-builders/curl'
args: [
'--fail',
'--retry', '3',
'--retry-delay', '5',
'$(gcloud run services describe ${_SERVICE_NAME} --platform managed --region ${_REGION} --format "value(status.url)")/healthz'
]
# Test the MCP endpoint
- name: 'gcr.io/cloud-builders/curl'
args: [
'-X', 'POST',
'-H', 'Content-Type: application/json',
'-d', '{"jsonrpc":"2.0","method":"initialize","id":1}',
'$(gcloud run services describe ${_SERVICE_NAME} --platform managed --region ${_REGION} --format "value(status.url)")/mcp'
]
# Store build artifacts
artifacts:
images:
- '${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REGISTRY_REPO}/mcp-hello-world:${COMMIT_SHA}'
- '${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REGISTRY_REPO}/mcp-hello-world:latest'
# Default substitution variables
substitutions:
_REGION: 'us-central1'
_SERVICE_NAME: 'mcp-hello-world'
_ARTIFACT_REGISTRY_REPO: 'mcp-servers'
# Build options
options:
# Use high-CPU machine for faster builds
machineType: 'E2_HIGHCPU_8'
# Store build logs in Cloud Logging
logging: CLOUD_LOGGING_ONLY
# Enable substitution validation
substitutionOption: 'ALLOW_LOOSE'
# Set build timeout to 20 minutes
timeout: '1200s'
# IAM permissions required:
# - Cloud Run Developer
# - Artifact Registry Writer
# - Cloud Build Service Account
# - Service Account User (for Cloud Run deployment)
# To set up the trigger:
# 1. Connect GitHub repository to Cloud Build
# 2. Create trigger with:
# - Event: Push to branch
# - Source: ^main$
# - Configuration: Cloud Build configuration file (yaml or json)
# - Configuration file location: cloudbuild.yaml
# 3. Set substitution variables if different from defaults
# 4. Enable required APIs and set up service account permissions