diff --git a/cloudbuild.base.yaml b/cloudbuild.base.yaml index 20d882f..24f0c4f 100644 --- a/cloudbuild.base.yaml +++ b/cloudbuild.base.yaml @@ -1,33 +1,22 @@ -# NOTE: This is a base/reference template — not the active pipeline. -# 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: +# ARCHITECTURE NOTE: CI/CD PIPELINE REFACTOR # -# 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: - - name: 'gcr.io/cloud-builders/docker' - id: build-base - args: - - 'build' - - '-f' - - 'agents/core-logic/Dockerfile.base' - - '-t' - - 'us-central1-docker.pkg.dev/${PROJECT_ID}/osvauco-repo/osvauco-base:latest' - - 'agents/core-logic' - - - name: 'gcr.io/cloud-builders/docker' - id: push-base - waitFor: ['build-base'] - args: - - 'push' - - 'us-central1-docker.pkg.dev/${PROJECT_ID}/osvauco-repo/osvauco-base:latest' - -options: - logging: CLOUD_LOGGING_ONLY - machineType: E2_HIGHCPU_8 - -images: - - 'us-central1-docker.pkg.dev/${PROJECT_ID}/osvauco-repo/osvauco-base:latest' - +# 1. SINGLE SOURCE OF TRUTH: +# The definitive pipeline for the OPAX-MCP service is now defined in: +# /cloudbuild.opax-mcp.yaml +# +# 2. REUSABILITY: +# - To promote clarity and reuse within the pipeline, `cloudbuild.opax-mcp.yaml` +# uses YAML anchors (&) and aliases (*) for common steps like policy checks, +# building, and deploying. +# +# 3. BRANCH-AWARE LOGIC: +# - The pipeline is fully branch-aware. It tags images with both commit SHA and branch name. +# - Deployment to Cloud Run is conditional and only runs for specific branches +# (e.g., `main`, `opax-*`). +# +# 4. DEPRECATED FILES: +# - `cloudbuild.yaml` and `cloudbuild.mcp.yaml` are deprecated. They have been +# emptied and point to the new pipeline file. diff --git a/cloudbuild.mcp.yaml b/cloudbuild.mcp.yaml index 7e89b4b..6a91eb6 100644 --- a/cloudbuild.mcp.yaml +++ b/cloudbuild.mcp.yaml @@ -1,110 +1,5 @@ -# cloudbuild.mcp.yaml — CI/CD for opax-mcp Cloud Run service -# Trigger: push til main (opax-mcp/** endret) -# Service: opax-mcp (us-central1) -# SA: jason-vauger@propane-will-491900-m5.iam.gserviceaccount.com - -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 +# DEPRECATED: This pipeline is no longer in use. +# The definitive pipeline for OPAX-MCP is now located at: +# /cloudbuild.opax-mcp.yaml +# +# Please update your triggers and workflows to use the new file. diff --git a/cloudbuild.opax-mcp.yaml b/cloudbuild.opax-mcp.yaml index 84b81df..e62f8bd 100644 --- a/cloudbuild.opax-mcp.yaml +++ b/cloudbuild.opax-mcp.yaml @@ -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: -- name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'us-central1-docker.pkg.dev/propane-will-491900-m5/osvauco-repo/opax-mcp:latest', './opax-mcp'] -- name: 'gcr.io/cloud-builders/docker' - args: ['push', 'us-central1-docker.pkg.dev/propane-will-491900-m5/osvauco-repo/opax-mcp:latest'] + # 1. Run Tyr Policy Check + - <<: *tyr-policy-check + + # 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: -- 'us-central1-docker.pkg.dev/propane-will-491900-m5/osvauco-repo/opax-mcp:latest' \ No newline at end of file + - '${_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 diff --git a/cloudbuild.yaml b/cloudbuild.yaml index 586db94..6a91eb6 100644 --- a/cloudbuild.yaml +++ b/cloudbuild.yaml @@ -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: -# 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 +# Please update your triggers and workflows to use the new file.