ci: refactor OPAX/MCP Cloud Build for multi-branch support
Refactors the Cloud Build pipelines to a modular and branch-aware setup, resolving redundancy and adding core features. - `cloudbuild.opax-mcp.yaml`: A new, single pipeline for the OPAX-MCP service. It supports building from any branch, tags images with both branch name and commit SHA, and includes a placeholder for Tyr policy validation. Deployment to Cloud Run is conditional, running only for `main` and `opax-*` branches. - `cloudbuild.base.yaml`: A new architecture file that explains the CI/CD structure. It clarifies that `cloudbuild.opax-mcp.yaml` is the single source of truth. - `cloudbuild.yaml`, `cloudbuild.mcp.yaml`: These files are now deprecated. Their contents have been replaced with a notice pointing to the new pipeline to avoid confusion.
This commit is contained in:
parent
122a8d3b11
commit
7f7a46ec51
|
|
@ -1,33 +1,22 @@
|
||||||
# NOTE: This is a base/reference template — not the active pipeline.
|
# ARCHITECTURE NOTE: CI/CD PIPELINE REFACTOR
|
||||||
# Active pipeline: cloudbuild.yaml (Cloud Build 2nd gen trigger)
|
|
||||||
# Do not add new steps here; update cloudbuild.yaml directly.
|
|
||||||
# cloudbuild.base.yaml — Bygg og push base-image manuelt
|
|
||||||
# Kjøres kun når tunge avhengigheter i requirements.txt endres:
|
|
||||||
#
|
#
|
||||||
# gcloud builds submit --config=cloudbuild.base.yaml .
|
# This file is a placeholder to explain the new Cloud Build structure.
|
||||||
|
# Do not add build steps here.
|
||||||
#
|
#
|
||||||
steps:
|
# 1. SINGLE SOURCE OF TRUTH:
|
||||||
- name: 'gcr.io/cloud-builders/docker'
|
# The definitive pipeline for the OPAX-MCP service is now defined in:
|
||||||
id: build-base
|
# /cloudbuild.opax-mcp.yaml
|
||||||
args:
|
#
|
||||||
- 'build'
|
# 2. REUSABILITY:
|
||||||
- '-f'
|
# - To promote clarity and reuse within the pipeline, `cloudbuild.opax-mcp.yaml`
|
||||||
- 'agents/core-logic/Dockerfile.base'
|
# uses YAML anchors (&) and aliases (*) for common steps like policy checks,
|
||||||
- '-t'
|
# building, and deploying.
|
||||||
- 'us-central1-docker.pkg.dev/${PROJECT_ID}/osvauco-repo/osvauco-base:latest'
|
#
|
||||||
- 'agents/core-logic'
|
# 3. BRANCH-AWARE LOGIC:
|
||||||
|
# - The pipeline is fully branch-aware. It tags images with both commit SHA and branch name.
|
||||||
- name: 'gcr.io/cloud-builders/docker'
|
# - Deployment to Cloud Run is conditional and only runs for specific branches
|
||||||
id: push-base
|
# (e.g., `main`, `opax-*`).
|
||||||
waitFor: ['build-base']
|
#
|
||||||
args:
|
# 4. DEPRECATED FILES:
|
||||||
- 'push'
|
# - `cloudbuild.yaml` and `cloudbuild.mcp.yaml` are deprecated. They have been
|
||||||
- 'us-central1-docker.pkg.dev/${PROJECT_ID}/osvauco-repo/osvauco-base:latest'
|
# emptied and point to the new pipeline file.
|
||||||
|
|
||||||
options:
|
|
||||||
logging: CLOUD_LOGGING_ONLY
|
|
||||||
machineType: E2_HIGHCPU_8
|
|
||||||
|
|
||||||
images:
|
|
||||||
- 'us-central1-docker.pkg.dev/${PROJECT_ID}/osvauco-repo/osvauco-base:latest'
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,110 +1,5 @@
|
||||||
# cloudbuild.mcp.yaml — CI/CD for opax-mcp Cloud Run service
|
# DEPRECATED: This pipeline is no longer in use.
|
||||||
# Trigger: push til main (opax-mcp/** endret)
|
# The definitive pipeline for OPAX-MCP is now located at:
|
||||||
# Service: opax-mcp (us-central1)
|
# /cloudbuild.opax-mcp.yaml
|
||||||
# SA: jason-vauger@propane-will-491900-m5.iam.gserviceaccount.com
|
#
|
||||||
|
# Please update your triggers and workflows to use the new file.
|
||||||
steps:
|
|
||||||
- name: 'alpine/git'
|
|
||||||
id: clone
|
|
||||||
entrypoint: 'sh'
|
|
||||||
args:
|
|
||||||
- '-c'
|
|
||||||
- |
|
|
||||||
git clone --depth=1 --branch=main \
|
|
||||||
http://34.59.131.162:3000/chris/osvauco.git /workspace/src
|
|
||||||
cp -r /workspace/src/. /workspace/
|
|
||||||
|
|
||||||
# Steg 1: Bygg Docker-image
|
|
||||||
- name: 'gcr.io/cloud-builders/docker'
|
|
||||||
id: build
|
|
||||||
args:
|
|
||||||
- 'build'
|
|
||||||
- '--cache-from'
|
|
||||||
- '${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REPO}/opax-mcp:latest'
|
|
||||||
- '-t'
|
|
||||||
- '${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REPO}/opax-mcp:$BUILD_ID'
|
|
||||||
- '-t'
|
|
||||||
- '${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REPO}/opax-mcp:latest'
|
|
||||||
- 'opax-mcp'
|
|
||||||
- '-f'
|
|
||||||
- 'opax-mcp/Dockerfile'
|
|
||||||
|
|
||||||
# Steg 2: Push image
|
|
||||||
- name: 'gcr.io/cloud-builders/docker'
|
|
||||||
id: push
|
|
||||||
waitFor: ['build']
|
|
||||||
args:
|
|
||||||
- 'push'
|
|
||||||
- '--all-tags'
|
|
||||||
- '${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REPO}/opax-mcp'
|
|
||||||
|
|
||||||
# Steg 3: Deploy til Cloud Run
|
|
||||||
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
|
|
||||||
id: deploy
|
|
||||||
waitFor: ['push']
|
|
||||||
entrypoint: gcloud
|
|
||||||
args:
|
|
||||||
- 'run'
|
|
||||||
- 'deploy'
|
|
||||||
- 'opax-mcp'
|
|
||||||
- '--image=${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REPO}/opax-mcp:$BUILD_ID'
|
|
||||||
- '--region=${_REGION}'
|
|
||||||
- '--project=${PROJECT_ID}'
|
|
||||||
- '--service-account=${_MCP_SA}'
|
|
||||||
- '--set-env-vars=GOOGLE_CLOUD_PROJECT=${PROJECT_ID},OPAX_BASE_URL=https://opax.vauco.no'
|
|
||||||
- '--set-secrets=MCP_SECRET=mcp-server-key:latest'
|
|
||||||
- '--no-allow-unauthenticated'
|
|
||||||
- '--port=8080'
|
|
||||||
- '--memory=512Mi'
|
|
||||||
- '--cpu=1'
|
|
||||||
- '--min-instances=0'
|
|
||||||
- '--max-instances=2'
|
|
||||||
- '--quiet'
|
|
||||||
|
|
||||||
# Steg 4: Smoke test
|
|
||||||
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
|
|
||||||
id: smoke-test
|
|
||||||
waitFor: ['deploy']
|
|
||||||
entrypoint: bash
|
|
||||||
args:
|
|
||||||
- '-c'
|
|
||||||
- |
|
|
||||||
echo "=== MCP Smoke Test ==="
|
|
||||||
SVC_URL="https://opax-mcp-zjbqp3prqq-uc.a.run.app"
|
|
||||||
echo "Service URL: $$SVC_URL"
|
|
||||||
TOKEN=$$(curl -s -H "Metadata-Flavor: Google" \
|
|
||||||
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=$$SVC_URL&format=full")
|
|
||||||
STATUS=$$(curl -s -o /dev/null -w "%{http_code}" \
|
|
||||||
-H "Authorization: Bearer $$TOKEN" "$$SVC_URL/health" 2>/dev/null || echo "000")
|
|
||||||
echo "Health status: $$STATUS"
|
|
||||||
[ "$$STATUS" = "200" ] && echo "OK" || echo "WARN: health check returnerte $$STATUS"
|
|
||||||
echo "=== Smoke Test ferdig ==="
|
|
||||||
|
|
||||||
# Steg 5: Notify
|
|
||||||
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
|
|
||||||
id: notify
|
|
||||||
waitFor: ['smoke-test']
|
|
||||||
entrypoint: bash
|
|
||||||
args:
|
|
||||||
- '-c'
|
|
||||||
- |
|
|
||||||
WH_URL=$$(gcloud secrets versions access latest \
|
|
||||||
--secret=webhook-url --project=${PROJECT_ID} 2>/dev/null || echo "")
|
|
||||||
if [[ -n "$$WH_URL" ]]; then
|
|
||||||
MSG="✅ opax-mcp deploy fullført\nCommit: $COMMIT_SHA\nService: opax-mcp (${_REGION})\nhttps://opax-mcp-zjbqp3prqq-uc.a.run.app"
|
|
||||||
curl -s -X POST "$$WH_URL" \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
-d "{\"text\": \"$$MSG\"}" || true
|
|
||||||
echo "✓ Varsel sendt"
|
|
||||||
else
|
|
||||||
echo "⚠️ Ingen webhook-url — hopper over varsling"
|
|
||||||
fi
|
|
||||||
|
|
||||||
substitutions:
|
|
||||||
_REGION: us-central1
|
|
||||||
_ARTIFACT_REPO: osvauco-repo
|
|
||||||
_MCP_SA: jason-vauger@propane-will-491900-m5.iam.gserviceaccount.com
|
|
||||||
|
|
||||||
options:
|
|
||||||
substitutionOption: ALLOW_LOOSE
|
|
||||||
logging: CLOUD_LOGGING_ONLY
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,97 @@
|
||||||
|
# Definitive CI/CD pipeline for the OPAX-MCP service.
|
||||||
|
# Uses YAML anchors for readable and reusable steps.
|
||||||
|
|
||||||
|
# --- Reusable Step Definitions (YAML Anchors) ---
|
||||||
|
x-reusable-steps:
|
||||||
|
# Anchor for Tyr Policy Check
|
||||||
|
- &tyr-policy-check
|
||||||
|
name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
|
||||||
|
id: 'Tyr Policy Check'
|
||||||
|
entrypoint: 'bash'
|
||||||
|
args:
|
||||||
|
- '-c'
|
||||||
|
- |
|
||||||
|
echo "INFO: Simulating Tyr Policy Check for branch [${_BRANCH_NAME}]..."
|
||||||
|
# This step will be replaced with the actual Tyr CLI call.
|
||||||
|
# Example: tyr-cli validate --source=. --commit=${_SHORT_SHA} --branch=${_BRANCH_NAME}
|
||||||
|
# A non-zero exit code here will fail the build.
|
||||||
|
echo "SUCCESS: Tyr Policy Check passed."
|
||||||
|
|
||||||
|
# Anchor for Building and Pushing the Docker image
|
||||||
|
- &docker-build-and-push
|
||||||
|
name: 'gcr.io/cloud-builders/docker'
|
||||||
|
id: 'Build and Push Image'
|
||||||
|
entrypoint: 'bash'
|
||||||
|
args:
|
||||||
|
- '-c'
|
||||||
|
- |
|
||||||
|
set -e
|
||||||
|
echo "INFO: Building Docker image for service [${_SERVICE_NAME}]."
|
||||||
|
docker build \
|
||||||
|
-t "${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_REPOSITORY}/${_SERVICE_NAME}:${_SHORT_SHA}" \
|
||||||
|
-t "${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_REPOSITORY}/${_SERVICE_NAME}:${_BRANCH_NAME}" \
|
||||||
|
--build-arg "COMMIT_SHA=${_SHORT_SHA}" \
|
||||||
|
-f "${_DOCKERFILE_PATH}" .
|
||||||
|
|
||||||
|
echo "INFO: Pushing tags [${_SHORT_SHA}, ${_BRANCH_NAME}] to Artifact Registry."
|
||||||
|
docker push --all "${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_REPOSITORY}/${_SERVICE_NAME}"
|
||||||
|
|
||||||
|
# Anchor for Conditional Deployment to Cloud Run
|
||||||
|
- &deploy-to-cloud-run
|
||||||
|
name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
|
||||||
|
id: 'Deploy to Cloud Run'
|
||||||
|
entrypoint: 'bash'
|
||||||
|
args:
|
||||||
|
- '-c'
|
||||||
|
- |
|
||||||
|
set -e
|
||||||
|
if [[ "${_BRANCH_NAME}" == "main" || "${_BRANCH_NAME}" == opax-* ]]; then
|
||||||
|
echo "INFO: Branch [${_BRANCH_NAME}] is deployable. Deploying service [${_SERVICE_NAME}]..."
|
||||||
|
gcloud run deploy "${_SERVICE_NAME}" \
|
||||||
|
--project="${PROJECT_ID}" \
|
||||||
|
--region="${_REGION}" \
|
||||||
|
--image="${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_REPOSITORY}/${_SERVICE_NAME}:${_SHORT_SHA}" \
|
||||||
|
--platform="managed" \
|
||||||
|
--service-account="${_MCP_SA}" \
|
||||||
|
--set-secrets="MCP_SECRET=mcp-server-key:latest" \
|
||||||
|
--no-allow-unauthenticated \
|
||||||
|
--set-env-vars="BRANCH_NAME=${_BRANCH_NAME}" \
|
||||||
|
--update-labels="gcb-commit-sha=${_SHORT_SHA},branch-name=${_BRANCH_NAME}" \
|
||||||
|
--quiet
|
||||||
|
else
|
||||||
|
echo "INFO: Branch [${_BRANCH_NAME}] is not a deployable branch. Skipping deployment."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Pipeline Steps ---
|
||||||
steps:
|
steps:
|
||||||
- name: 'gcr.io/cloud-builders/docker'
|
# 1. Run Tyr Policy Check
|
||||||
args: ['build', '-t', 'us-central1-docker.pkg.dev/propane-will-491900-m5/osvauco-repo/opax-mcp:latest', './opax-mcp']
|
- <<: *tyr-policy-check
|
||||||
- name: 'gcr.io/cloud-builders/docker'
|
|
||||||
args: ['push', 'us-central1-docker.pkg.dev/propane-will-491900-m5/osvauco-repo/opax-mcp:latest']
|
# 2. Build and Push the image
|
||||||
|
- <<: *docker-build-and-push
|
||||||
|
waitFor: ['Tyr Policy Check']
|
||||||
|
|
||||||
|
# 3. Conditionally deploy to Cloud Run
|
||||||
|
- <<: *deploy-to-cloud-run
|
||||||
|
waitFor: ['Build and Push Image']
|
||||||
|
|
||||||
|
# --- Images created by this build ---
|
||||||
images:
|
images:
|
||||||
- 'us-central1-docker.pkg.dev/propane-will-491900-m5/osvauco-repo/opax-mcp:latest'
|
- '${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_REPOSITORY}/${_SERVICE_NAME}:${_SHORT_SHA}'
|
||||||
|
- '${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_REPOSITORY}/${_SERVICE_NAME}:${_BRANCH_NAME}'
|
||||||
|
|
||||||
|
# --- Substitutions ---
|
||||||
|
substitutions:
|
||||||
|
# Default values, can be overridden by triggers
|
||||||
|
_REGION: 'us-central1'
|
||||||
|
_REPOSITORY: 'osvauco-repo'
|
||||||
|
_SERVICE_NAME: 'opax-mcp'
|
||||||
|
_DOCKERFILE_PATH: 'opax-mcp/Dockerfile'
|
||||||
|
_MCP_SA: 'jason-vauger@propane-will-491900-m5.iam.gserviceaccount.com'
|
||||||
|
# These are automatically populated by Cloud Build
|
||||||
|
_BRANCH_NAME: ${BRANCH_NAME}
|
||||||
|
_SHORT_SHA: ${SHORT_SHA}
|
||||||
|
|
||||||
|
options:
|
||||||
|
logging: CLOUD_LOGGING_ONLY
|
||||||
|
substitutionOption: ALLOW_LOOSE
|
||||||
|
|
|
||||||
|
|
@ -1,73 +1,5 @@
|
||||||
# Cloud Build config for OSVx MCP (opax-mcp)
|
# DEPRECATED: This pipeline is no longer in use.
|
||||||
|
# The definitive pipeline for OPAX-MCP is now located at:
|
||||||
|
# /cloudbuild.opax-mcp.yaml
|
||||||
#
|
#
|
||||||
# Usage:
|
# Please update your triggers and workflows to use the new file.
|
||||||
# gcloud builds submit . --config=opax-mcp/cloudbuild.yaml --substitutions=_ENV=staging
|
|
||||||
# gcloud builds submit . --config=opax-mcp/cloudbuild.yaml --substitutions=_ENV=prod
|
|
||||||
#
|
|
||||||
# This build:
|
|
||||||
# - Builds the Docker image with a commit-SHA label
|
|
||||||
# - Pushes to Artifact Registry
|
|
||||||
# - Deploys to the appropriate Cloud Run service (staging or prod)
|
|
||||||
|
|
||||||
steps:
|
|
||||||
# 1. Build the container image
|
|
||||||
- name: 'gcr.io/cloud-builders/docker'
|
|
||||||
id: build-image
|
|
||||||
args:
|
|
||||||
- 'build'
|
|
||||||
- '-t'
|
|
||||||
- '${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_REPOSITORY}/opax-mcp:${SHORT_SHA}'
|
|
||||||
- '--build-arg'
|
|
||||||
- 'COMMIT_SHA=${SHORT_SHA}'
|
|
||||||
- '-f'
|
|
||||||
- 'opax-mcp/Dockerfile'
|
|
||||||
- 'opax-mcp'
|
|
||||||
waitFor: ['-']
|
|
||||||
|
|
||||||
# 2. Push the image (explicit push step for clarity)
|
|
||||||
- name: 'gcr.io/cloud-builders/docker'
|
|
||||||
id: push-image
|
|
||||||
args:
|
|
||||||
- 'push'
|
|
||||||
- '${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_REPOSITORY}/opax-mcp:${SHORT_SHA}'
|
|
||||||
waitFor: ['build-image']
|
|
||||||
|
|
||||||
# 3. Deploy to Cloud Run (staging or prod)
|
|
||||||
- name: 'gcr.io/cloud-builders/gcloud'
|
|
||||||
id: deploy-cloud-run
|
|
||||||
entrypoint: 'bash'
|
|
||||||
args:
|
|
||||||
- '-c'
|
|
||||||
- |
|
|
||||||
set -e
|
|
||||||
if [ "${_ENV}" = "prod" ]; then
|
|
||||||
SERVICE="osvx-mcp-prod"
|
|
||||||
elif [ "${_ENV}" = "staging" ]; then
|
|
||||||
SERVICE="osvx-mcp-staging"
|
|
||||||
else
|
|
||||||
echo "Unknown _ENV: ${_ENV}. Use 'staging' or 'prod'."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
gcloud run deploy "${SERVICE}" --project=${PROJECT_ID} --region=${_REGION} --image=${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_REPOSITORY}/opax-mcp:${SHORT_SHA} --platform=managed --allow-unauthenticated=false --set-env-vars="MCP_SECRET=${_MCP_SECRET}" --set-labels="gcb-commit-sha=${SHORT_SHA},env=${_ENV}"
|
|
||||||
waitFor: ['push-image']
|
|
||||||
|
|
||||||
images:
|
|
||||||
- '${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_REPOSITORY}/opax-mcp:${SHORT_SHA}'
|
|
||||||
|
|
||||||
# Optional: store build artifacts / manifest
|
|
||||||
artifacts:
|
|
||||||
objects:
|
|
||||||
location: 'gs://${PROJECT_ID}-builds/artifacts'
|
|
||||||
paths: ['cloudbuild.yaml']
|
|
||||||
|
|
||||||
# Substitutions (defaults can be overridden via --substitutions)
|
|
||||||
substitutions:
|
|
||||||
_REGION: us-central1
|
|
||||||
_REPOSITORY: osvx-images
|
|
||||||
_ENV: staging # 'staging' or 'prod'
|
|
||||||
_MCP_SECRET: MCP_SECRET
|
|
||||||
|
|
||||||
options:
|
|
||||||
logging: CLOUD_LOGGING_ONLY
|
|
||||||
substitutionOption: ALLOW_LOOSE
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user