#!/usr/bin/env bash # ============================================================================= # 02-setup-project.sh (Linux) # One-time GCP project setup: # - Links a billing account to the project # - Enables required APIs (Cloud Run, Artifact Registry, Secret Manager) # - Creates an Artifact Registry Docker repository # - Grants the current user the minimum required IAM roles # # Safe to re-run — most operations are idempotent. # Windows users: run GCR/scripts/02-setup-project.ps1 in PowerShell instead. # ============================================================================= set -euo pipefail if [[ "$(uname -s)" != "Linux" ]]; then echo "ERROR: This script is for Linux only." echo "Windows users: run GCR/scripts/02-setup-project.ps1" exit 1 fi SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # ── Load .env ───────────────────────────────────────────────────────────────── ENV_FILE="$SCRIPT_DIR/../.env" if [[ ! -f "$ENV_FILE" ]]; then echo "ERROR: $ENV_FILE not found." echo "Copy GCR/.env.example to GCR/.env and fill in your values first." exit 1 fi # shellcheck disable=SC1090 source "$ENV_FILE" : "${GCP_PROJECT_ID:?GCP_PROJECT_ID is not set in .env}" : "${GCP_REGION:?GCP_REGION is not set in .env}" : "${GCP_REPOSITORY:?GCP_REPOSITORY is not set in .env}" # ── Confirm active project ──────────────────────────────────────────────────── echo ">>> Active project: $GCP_PROJECT_ID" echo ">>> Region: $GCP_REGION" echo ">>> AR repository: $GCP_REPOSITORY" echo "" # ── Step 1: Link billing account ────────────────────────────────────────────── echo ">>> Checking billing status..." BILLING_ENABLED=$(gcloud billing projects describe "$GCP_PROJECT_ID" \ --format="value(billingEnabled)" 2>/dev/null || echo "false") if [[ "$BILLING_ENABLED" == "True" ]]; then echo " Billing is already enabled — skipping." else echo "" echo " Billing is NOT enabled on this project." echo " Listing available billing accounts..." echo "" gcloud billing accounts list --format="table(name,displayName,open)" echo "" read -rp " Enter the BILLING_ACCOUNT_ID from the list above (format: XXXXXX-XXXXXX-XXXXXX): " BILLING_ACCOUNT_ID gcloud billing projects link "$GCP_PROJECT_ID" \ --billing-account="$BILLING_ACCOUNT_ID" echo " Billing linked." fi # ── Step 2: Enable required APIs ───────────────────────────────────────────── echo "" echo ">>> Enabling required Google Cloud APIs (this may take a minute)..." gcloud services enable \ run.googleapis.com \ artifactregistry.googleapis.com \ secretmanager.googleapis.com \ cloudresourcemanager.googleapis.com \ --project="$GCP_PROJECT_ID" echo " APIs enabled." # ── Step 3: Create Artifact Registry Docker repository ─────────────────────── echo "" echo ">>> Creating Artifact Registry repository: $GCP_REPOSITORY ..." if gcloud artifacts repositories describe "$GCP_REPOSITORY" \ --location="$GCP_REGION" \ --project="$GCP_PROJECT_ID" &>/dev/null; then echo " Repository already exists — skipping." else gcloud artifacts repositories create "$GCP_REPOSITORY" \ --repository-format=docker \ --location="$GCP_REGION" \ --description="Container images for Htmx app" \ --project="$GCP_PROJECT_ID" echo " Repository created." fi # ── Step 4: Grant current user the minimum required IAM roles ───────────────── CURRENT_USER="$(gcloud config get-value account)" echo "" echo ">>> Granting IAM roles to $CURRENT_USER ..." for ROLE in \ "roles/run.developer" \ "roles/artifactregistry.writer" \ "roles/iam.serviceAccountUser" \ "roles/secretmanager.admin" \ "roles/secretmanager.secretAccessor" \ "roles/secretmanager.secretVersionAdder"; do echo " Adding role: $ROLE" gcloud projects add-iam-policy-binding "$GCP_PROJECT_ID" \ --member="user:$CURRENT_USER" \ --role="$ROLE" \ --quiet done echo "" echo ">>> Project setup complete." echo "" echo ">>> Summary:" echo " Project ID: $GCP_PROJECT_ID" echo " Region: $GCP_REGION" echo " Artifact Registry: ${GCP_REGION}-docker.pkg.dev/${GCP_PROJECT_ID}/${GCP_REPOSITORY}" echo "" echo ">>> Next step: run GCR/scripts/03-create-secrets.sh"