Intial commit for deployment script p2
This commit is contained in:
+185
@@ -0,0 +1,185 @@
|
||||
#Requires -Version 5.1
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
param(
|
||||
[switch]$Yes
|
||||
)
|
||||
|
||||
$RootDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
$EnvFile = Join-Path $RootDir ".env"
|
||||
|
||||
function Confirm-Run {
|
||||
param(
|
||||
[string]$Label,
|
||||
[string]$ScriptPath
|
||||
)
|
||||
|
||||
if ($Yes) {
|
||||
Write-Host "[x] $Label not done yet. Running $ScriptPath (-Yes enabled)..."
|
||||
& $ScriptPath
|
||||
return
|
||||
}
|
||||
|
||||
$answer = Read-Host "[x] $Label not done yet. Run now? [y/N]"
|
||||
if ($answer -match '^[Yy]$') {
|
||||
& $ScriptPath
|
||||
}
|
||||
}
|
||||
|
||||
function Get-EnvConfig {
|
||||
if (-not (Test-Path $EnvFile)) {
|
||||
throw "GCR/.env not found. Copy GCR/.env.example to GCR/.env first."
|
||||
}
|
||||
|
||||
$cfg = @{}
|
||||
foreach ($line in Get-Content $EnvFile) {
|
||||
if ($line -match '^\s*$' -or $line -match '^\s*#') { continue }
|
||||
if ($line -match '^([^=]+)=(.*)$') {
|
||||
$cfg[$Matches[1].Trim()] = $Matches[2].Trim()
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($key in @('GCP_PROJECT_ID', 'GCP_REGION', 'GCP_REPOSITORY', 'SERVICE_NAME')) {
|
||||
if (-not $cfg[$key]) {
|
||||
throw "$key is not set in GCR/.env"
|
||||
}
|
||||
}
|
||||
|
||||
return $cfg
|
||||
}
|
||||
|
||||
function Test-GcloudInstalled {
|
||||
return [bool](Get-Command gcloud -ErrorAction SilentlyContinue)
|
||||
}
|
||||
|
||||
function Test-Login {
|
||||
param([hashtable]$Cfg)
|
||||
|
||||
$activeAccount = (gcloud auth list --filter=status:ACTIVE --format="value(account)" 2>$null | Select-Object -First 1)
|
||||
$currentProject = (gcloud config get-value project 2>$null)
|
||||
$currentRegion = (gcloud config get-value run/region 2>$null)
|
||||
|
||||
$dockerCfg = if ($env:DOCKER_CONFIG) { Join-Path $env:DOCKER_CONFIG "config.json" } else { Join-Path $HOME ".docker\config.json" }
|
||||
$dockerOk = $false
|
||||
if (Test-Path $dockerCfg) {
|
||||
$dockerOk = (Select-String -Path $dockerCfg -Pattern "\"$($Cfg['GCP_REGION'])-docker.pkg.dev\"" -SimpleMatch -Quiet)
|
||||
}
|
||||
|
||||
return (-not [string]::IsNullOrWhiteSpace($activeAccount)) -and
|
||||
($currentProject.Trim() -eq $Cfg['GCP_PROJECT_ID']) -and
|
||||
($currentRegion.Trim() -eq $Cfg['GCP_REGION']) -and
|
||||
$dockerOk
|
||||
}
|
||||
|
||||
function Test-ProjectSetup {
|
||||
param([hashtable]$Cfg)
|
||||
|
||||
$billingEnabled = (gcloud billing projects describe $Cfg['GCP_PROJECT_ID'] --format="value(billingEnabled)" 2>$null)
|
||||
if ($billingEnabled -ne 'True') { return $false }
|
||||
|
||||
try {
|
||||
gcloud artifacts repositories describe $Cfg['GCP_REPOSITORY'] --location=$Cfg['GCP_REGION'] --project=$Cfg['GCP_PROJECT_ID'] 2>$null | Out-Null
|
||||
} catch {
|
||||
return $false
|
||||
}
|
||||
|
||||
foreach ($api in @('run.googleapis.com', 'artifactregistry.googleapis.com', 'secretmanager.googleapis.com', 'cloudresourcemanager.googleapis.com')) {
|
||||
$enabled = gcloud services list --enabled --project=$Cfg['GCP_PROJECT_ID'] --format="value(config.name)" 2>$null | Select-String -Pattern "^$([regex]::Escape($api))$"
|
||||
if (-not $enabled) { return $false }
|
||||
}
|
||||
|
||||
return $true
|
||||
}
|
||||
|
||||
function Test-SecretsSetup {
|
||||
param([hashtable]$Cfg)
|
||||
|
||||
try {
|
||||
gcloud secrets describe mongodb-connection-string --project=$Cfg['GCP_PROJECT_ID'] 2>$null | Out-Null
|
||||
} catch {
|
||||
return $false
|
||||
}
|
||||
|
||||
$serviceAccount = "serviceAccount:$($Cfg['GCP_PROJECT_ID'])@appspot.gserviceaccount.com"
|
||||
$binding = gcloud secrets get-iam-policy mongodb-connection-string `
|
||||
--project=$Cfg['GCP_PROJECT_ID'] `
|
||||
--flatten="bindings[].members" `
|
||||
--filter="bindings.role=roles/secretmanager.secretAccessor AND bindings.members=$serviceAccount" `
|
||||
--format="value(bindings.members)" 2>$null
|
||||
|
||||
return ($binding -match [regex]::Escape($serviceAccount))
|
||||
}
|
||||
|
||||
function Test-DeployDone {
|
||||
param([hashtable]$Cfg)
|
||||
|
||||
try {
|
||||
gcloud run services describe $Cfg['SERVICE_NAME'] --region=$Cfg['GCP_REGION'] --project=$Cfg['GCP_PROJECT_ID'] 2>$null | Out-Null
|
||||
return $true
|
||||
} catch {
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function Write-Done {
|
||||
param([string]$Text)
|
||||
Write-Host "[v] $Text"
|
||||
}
|
||||
|
||||
Write-Host "================================================================"
|
||||
Write-Host " Htmx deployment flow runner (Windows)"
|
||||
Write-Host "================================================================"
|
||||
|
||||
if (-not (Test-Path $EnvFile)) {
|
||||
Write-Host "[x] Step 0: GCR/.env is missing"
|
||||
Write-Host " Copy GCR/.env.example to GCR/.env and fill required values."
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Done "Step 0: .env exists"
|
||||
$cfg = Get-EnvConfig
|
||||
|
||||
if (Test-GcloudInstalled) {
|
||||
Write-Done "Step 1: gcloud installed"
|
||||
} else {
|
||||
Confirm-Run "Step 1: gcloud install" (Join-Path $RootDir "scripts\00-install-gcloud.ps1")
|
||||
}
|
||||
|
||||
if (Test-Login $cfg) {
|
||||
Write-Done "Step 2: login + docker auth configured"
|
||||
} else {
|
||||
Confirm-Run "Step 2: login" (Join-Path $RootDir "scripts\01-login.ps1")
|
||||
}
|
||||
|
||||
if (Test-ProjectSetup $cfg) {
|
||||
Write-Done "Step 3: project setup complete"
|
||||
} else {
|
||||
Confirm-Run "Step 3: project setup" (Join-Path $RootDir "scripts\02-setup-project.ps1")
|
||||
}
|
||||
|
||||
if (Test-SecretsSetup $cfg) {
|
||||
Write-Done "Step 4: secrets created and access granted"
|
||||
} else {
|
||||
Confirm-Run "Step 4: secrets setup" (Join-Path $RootDir "scripts\03-create-secrets.ps1")
|
||||
}
|
||||
|
||||
if (Test-DeployDone $cfg) {
|
||||
Write-Done "Step 5: service is already deployed"
|
||||
} else {
|
||||
Confirm-Run "Step 5: deploy" (Join-Path $RootDir "scripts\04-deploy.ps1")
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "================================================================"
|
||||
Write-Host " Final verification"
|
||||
Write-Host "================================================================"
|
||||
|
||||
if (Test-GcloudInstalled) { Write-Done "Step 1" } else { Write-Host "[x] Step 1" }
|
||||
if (Test-Login $cfg) { Write-Done "Step 2" } else { Write-Host "[x] Step 2" }
|
||||
if (Test-ProjectSetup $cfg) { Write-Done "Step 3" } else { Write-Host "[x] Step 3" }
|
||||
if (Test-SecretsSetup $cfg) { Write-Done "Step 4" } else { Write-Host "[x] Step 4" }
|
||||
if (Test-DeployDone $cfg) { Write-Done "Step 5" } else { Write-Host "[x] Step 5" }
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Tip: run .\GCR\run-all.ps1 -Yes to auto-run missing steps without prompts."
|
||||
Reference in New Issue
Block a user