OSVauco/infrastructure/06-cicd-setup.sh
Chris Christiansen 05030edf61 fix: Set executable bit on shell and python scripts
Per the task in `docs/TODO.md`, this change runs `git update-index --chmod=+x` on all relevant `.sh` and `.py` files in the repository.

This prevents intermittent 'Permission denied' errors when scripts are run in CI/CD environments or after being edited via the GitHub web interface, which can strip file permissions.
2026-05-26 13:23:18 +00:00

132 lines
5.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# 06-cicd-setup.sh — Cloud Build 2nd gen: programmatic GitHub connection + trigger
# No manual OAuth in GCP Console required.
# Prerequisites: GitHub PAT stored in Secret Manager as 'github-token'
# gcloud secrets create github-token --data-file=<(echo -n "ghp_YOUR_TOKEN")
# Source .env before running: source .env
set -euo pipefail
: "${PROJECT_ID:?Set PROJECT_ID}"
: "${REGION:?Set REGION}"
: "${GITHUB_OWNER:?Set GITHUB_OWNER}"
: "${GITHUB_REPO:?Set GITHUB_REPO}"
: "${ARTIFACT_REPO:?Set ARTIFACT_REPO}"
: "${CLOUD_RUN_SERVICE:?Set CLOUD_RUN_SERVICE}"
CONNECTION_NAME="osvauco-github-connection"
TRIGGER_NAME="${CLOUD_RUN_SERVICE}-main-trigger"
BRANCH_PATTERN="^main$"
GITHUB_TOKEN_SECRET="github-token"
echo "=== 06: CI/CD Setup (2nd gen) for ${PROJECT_ID} ==="
bash "$(dirname "$0")/00-authcheck.sh"
gcloud services enable \
cloudbuild.googleapis.com \
cloudbuildv2.googleapis.com \
artifactregistry.googleapis.com \
run.googleapis.com \
secretmanager.googleapis.com \
--project="${PROJECT_ID}" --quiet
# --- Artifact Registry (idempotent) ---
if ! gcloud artifacts repositories describe "${ARTIFACT_REPO}" \
--location="${REGION}" --project="${PROJECT_ID}" >/dev/null 2>&1; then
gcloud artifacts repositories create "${ARTIFACT_REPO}" \
--repository-format=docker \
--location="${REGION}" \
--project="${PROJECT_ID}" --quiet
echo "✓ Artifact Registry repo created: ${ARTIFACT_REPO}"
else
echo "✓ Artifact Registry repo already exists"
fi
gcloud auth configure-docker "${REGION}-docker.pkg.dev" --quiet
# --- IAM for Cloud Build SA ---
PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)")
CB_SA="${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com"
for ROLE in \
roles/run.admin \
roles/iam.serviceAccountUser \
roles/artifactregistry.writer \
roles/secretmanager.secretAccessor; do
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--member="serviceAccount:${CB_SA}" --role="${ROLE}" --quiet
done
echo "✓ Cloud Build SA IAM bindings applied"
# --- Grant Cloud Build SA access to GitHub token secret ---
gcloud secrets add-iam-policy-binding "${GITHUB_TOKEN_SECRET}" \
--project="${PROJECT_ID}" \
--member="serviceAccount:${CB_SA}" \
--role="roles/secretmanager.secretAccessor" --quiet
echo "✓ Cloud Build SA granted access to secret: ${GITHUB_TOKEN_SECRET}"
# --- Cloud Build 2nd gen: Host Connection (idempotent) ---
EXISTING_CONN=$(gcloud builds connections list \
--region="${REGION}" --project="${PROJECT_ID}" \
--format="value(name)" 2>/dev/null \
| grep -c "${CONNECTION_NAME}" || true)
if [[ "${EXISTING_CONN}" == "0" ]]; then
gcloud builds connections create github "${CONNECTION_NAME}" \
--authorizer-token-secret-version="projects/${PROJECT_ID}/secrets/${GITHUB_TOKEN_SECRET}/versions/latest" \
--app-installation-id="${GITHUB_APP_INSTALLATION_ID:-}" \
--region="${REGION}" \
--project="${PROJECT_ID}" --quiet
echo "✓ 2nd gen GitHub connection created: ${CONNECTION_NAME}"
else
echo "✓ 2nd gen GitHub connection already exists: ${CONNECTION_NAME}"
fi
# --- Cloud Build 2nd gen: Repository Link (idempotent) ---
REPO_RESOURCE="projects/${PROJECT_ID}/locations/${REGION}/connections/${CONNECTION_NAME}/repositories/${GITHUB_REPO}"
EXISTING_REPO=$(gcloud builds repositories list \
--connection="${CONNECTION_NAME}" \
--region="${REGION}" --project="${PROJECT_ID}" \
--format="value(name)" 2>/dev/null \
| grep -c "${GITHUB_REPO}" || true)
if [[ "${EXISTING_REPO}" == "0" ]]; then
gcloud builds repositories create "${GITHUB_REPO}" \
--remote-uri="https://github.com/${GITHUB_OWNER}/${GITHUB_REPO}.git" \
--connection="${CONNECTION_NAME}" \
--region="${REGION}" \
--project="${PROJECT_ID}" --quiet
echo "✓ Repository linked: ${GITHUB_OWNER}/${GITHUB_REPO}"
else
echo "✓ Repository already linked"
fi
# --- Cloud Build Trigger (2nd gen, idempotent) ---
EXISTING_TRIGGER=$(gcloud builds triggers list \
--filter="name=${TRIGGER_NAME}" \
--format="value(name)" 2>/dev/null | head -1 || true)
if [[ -z "${EXISTING_TRIGGER}" ]]; then
gcloud builds triggers create github \
--name="${TRIGGER_NAME}" \
--repository="projects/${PROJECT_ID}/locations/${REGION}/connections/${CONNECTION_NAME}/repositories/${GITHUB_REPO}" \
--branch-pattern="${BRANCH_PATTERN}" \
--build-config="cloudbuild.yaml" \
--region="${REGION}" \
--project="${PROJECT_ID}" --quiet
echo "✓ 2nd gen trigger created: ${TRIGGER_NAME}"
else
echo "✓ Trigger already exists: ${TRIGGER_NAME}"
fi
echo ""
echo "=== 06: CI/CD Setup COMPLETE (2nd gen) ==="
echo " Connection: ${CONNECTION_NAME}"
echo " Repo: ${GITHUB_OWNER}/${GITHUB_REPO}"
echo " Trigger: ${TRIGGER_NAME}"
echo ""
echo " PREREQUISITE: GitHub PAT must exist in Secret Manager:"
echo " gcloud secrets create github-token --data-file=<(echo -n \"ghp_TOKEN\")"
echo " OQ-04 resolved — no manual OAuth in Console required."
echo " After first deploy, switch traffic manually:"
echo " gcloud run services update-traffic ${CLOUD_RUN_SERVICE} --to-latest --region=${REGION}"