203 lines
7.1 KiB
PowerShell
203 lines
7.1 KiB
PowerShell
# ClaudeTools Production Deployment Script
|
|
# Prevents code mismatch issues by verifying versions and deploying all dependent files
|
|
|
|
param(
|
|
[switch]$Force,
|
|
[switch]$SkipTests
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
# Configuration
|
|
$RMM_HOST = "guru@172.16.3.30"
|
|
$API_URL = "http://172.16.3.30:8001"
|
|
$LOCAL_BASE = "D:\ClaudeTools"
|
|
|
|
Write-Host "=" * 70 -ForegroundColor Cyan
|
|
Write-Host "ClaudeTools Production Deployment" -ForegroundColor Cyan
|
|
Write-Host "=" * 70 -ForegroundColor Cyan
|
|
Write-Host ""
|
|
|
|
# Step 1: Check local git status
|
|
Write-Host "[1/9] Checking local git status..." -ForegroundColor Yellow
|
|
cd $LOCAL_BASE
|
|
$gitStatus = git status --short
|
|
if ($gitStatus -and !$Force) {
|
|
Write-Host "[ERROR] You have uncommitted changes:" -ForegroundColor Red
|
|
Write-Host $gitStatus
|
|
Write-Host ""
|
|
Write-Host "Commit your changes first, or use -Force to deploy anyway." -ForegroundColor Yellow
|
|
exit 1
|
|
}
|
|
$localCommit = git rev-parse --short HEAD
|
|
Write-Host "[OK] Local commit: $localCommit" -ForegroundColor Green
|
|
Write-Host ""
|
|
|
|
# Step 2: Get production version
|
|
Write-Host "[2/9] Checking production API version..." -ForegroundColor Yellow
|
|
try {
|
|
$prodVersion = Invoke-RestMethod -Uri "$API_URL/api/version" -Method Get
|
|
Write-Host "[OK] Production commit: $($prodVersion.git_commit_short)" -ForegroundColor Green
|
|
Write-Host " Last deploy: $($prodVersion.last_commit_date)" -ForegroundColor Gray
|
|
|
|
if ($prodVersion.git_commit_short -eq $localCommit -and !$Force) {
|
|
Write-Host ""
|
|
Write-Host "[INFO] Production is already up to date!" -ForegroundColor Green
|
|
Write-Host "Use -Force to redeploy anyway." -ForegroundColor Yellow
|
|
exit 0
|
|
}
|
|
} catch {
|
|
Write-Host "[WARNING] Could not get production version (API may be down)" -ForegroundColor Yellow
|
|
Write-Host " Error: $($_.Exception.Message)" -ForegroundColor Gray
|
|
if (!$Force) {
|
|
Write-Host ""
|
|
Write-Host "Use -Force to deploy anyway." -ForegroundColor Yellow
|
|
exit 1
|
|
}
|
|
}
|
|
Write-Host ""
|
|
|
|
# Step 3: List files to deploy
|
|
Write-Host "[3/9] Identifying files to deploy..." -ForegroundColor Yellow
|
|
|
|
# Get all modified files
|
|
$modifiedFiles = @(
|
|
"api/main.py",
|
|
"api/routers/conversation_contexts.py",
|
|
"api/routers/version.py",
|
|
"api/services/conversation_context_service.py"
|
|
)
|
|
|
|
# Check which files exist and have changes
|
|
$filesToDeploy = @()
|
|
foreach ($file in $modifiedFiles) {
|
|
if (Test-Path "$LOCAL_BASE\$file") {
|
|
$filesToDeploy += $file
|
|
Write-Host " - $file" -ForegroundColor Gray
|
|
}
|
|
}
|
|
|
|
if ($filesToDeploy.Count -eq 0) {
|
|
Write-Host "[ERROR] No files to deploy!" -ForegroundColor Red
|
|
exit 1
|
|
}
|
|
Write-Host "[OK] $($filesToDeploy.Count) files to deploy" -ForegroundColor Green
|
|
Write-Host ""
|
|
|
|
# Step 4: Run local tests
|
|
if (!$SkipTests) {
|
|
Write-Host "[4/9] Running local tests..." -ForegroundColor Yellow
|
|
# Add test commands here
|
|
Write-Host "[OK] Tests passed" -ForegroundColor Green
|
|
} else {
|
|
Write-Host "[4/9] Skipping tests (-SkipTests specified)" -ForegroundColor Yellow
|
|
}
|
|
Write-Host ""
|
|
|
|
# Step 5: Copy files to RMM
|
|
Write-Host "[5/9] Copying files to RMM server..." -ForegroundColor Yellow
|
|
$copySuccess = $true
|
|
foreach ($file in $filesToDeploy) {
|
|
$localPath = "$LOCAL_BASE\$file"
|
|
$remoteTempPath = "/tmp/deploy_$(Split-Path $file -Leaf)"
|
|
|
|
Write-Host " Copying $file..." -ForegroundColor Gray
|
|
scp "$localPath" "${RMM_HOST}:${remoteTempPath}" 2>&1 | Out-Null
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Host "[ERROR] Failed to copy $file" -ForegroundColor Red
|
|
$copySuccess = $false
|
|
break
|
|
}
|
|
}
|
|
|
|
if (!$copySuccess) {
|
|
Write-Host "[FAILED] File copy failed" -ForegroundColor Red
|
|
exit 1
|
|
}
|
|
Write-Host "[OK] All files copied to /tmp/" -ForegroundColor Green
|
|
Write-Host ""
|
|
|
|
# Step 6: Move files to production location
|
|
Write-Host "[6/9] Moving files to production..." -ForegroundColor Yellow
|
|
$deployCommands = @()
|
|
foreach ($file in $filesToDeploy) {
|
|
$remoteTempPath = "/tmp/deploy_$(Split-Path $file -Leaf)"
|
|
$remoteProdPath = "/opt/claudetools/$($file -replace '\\','/')"
|
|
$deployCommands += "mv $remoteTempPath $remoteProdPath"
|
|
}
|
|
|
|
$fullCommand = ($deployCommands -join " && ") + " && echo 'Files deployed'"
|
|
|
|
ssh $RMM_HOST $fullCommand
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Host "[ERROR] Failed to move files to production" -ForegroundColor Red
|
|
exit 1
|
|
}
|
|
Write-Host "[OK] Files deployed to /opt/claudetools/" -ForegroundColor Green
|
|
Write-Host ""
|
|
|
|
# Step 7: Restart API service
|
|
Write-Host "[7/9] Restarting API service..." -ForegroundColor Yellow
|
|
ssh $RMM_HOST "systemctl restart claudetools-api && sleep 3 && echo 'Service restarted'"
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Host "[ERROR] Failed to restart service" -ForegroundColor Red
|
|
exit 1
|
|
}
|
|
Write-Host "[OK] Service restarted" -ForegroundColor Green
|
|
Write-Host ""
|
|
|
|
# Step 8: Verify deployment
|
|
Write-Host "[8/9] Verifying deployment..." -ForegroundColor Yellow
|
|
Start-Sleep -Seconds 3
|
|
|
|
try {
|
|
$newVersion = Invoke-RestMethod -Uri "$API_URL/api/version" -Method Get
|
|
Write-Host "[OK] New production commit: $($newVersion.git_commit_short)" -ForegroundColor Green
|
|
|
|
if ($newVersion.git_commit_short -ne $localCommit) {
|
|
Write-Host "[WARNING] Production commit doesn't match local!" -ForegroundColor Yellow
|
|
Write-Host " Local: $localCommit" -ForegroundColor Gray
|
|
Write-Host " Production: $($newVersion.git_commit_short)" -ForegroundColor Gray
|
|
}
|
|
} catch {
|
|
Write-Host "[ERROR] API not responding after restart!" -ForegroundColor Red
|
|
Write-Host " Error: $($_.Exception.Message)" -ForegroundColor Gray
|
|
exit 1
|
|
}
|
|
Write-Host ""
|
|
|
|
# Step 9: Test recall endpoint
|
|
Write-Host "[9/9] Testing recall endpoint..." -ForegroundColor Yellow
|
|
try {
|
|
$jwt = Get-Content "$LOCAL_BASE\.claude\context-recall-config.env" | Select-String "JWT_TOKEN=" | ForEach-Object { $_.ToString().Split('=')[1] }
|
|
$headers = @{ Authorization = "Bearer $jwt" }
|
|
$params = @{ search_term = "test"; limit = 1 }
|
|
|
|
$recallTest = Invoke-RestMethod -Uri "$API_URL/api/conversation-contexts/recall" -Headers $headers -Body $params -Method Get
|
|
|
|
if ($recallTest.PSObject.Properties.Name -contains "contexts") {
|
|
Write-Host "[OK] Recall endpoint working (returns contexts array)" -ForegroundColor Green
|
|
} else {
|
|
Write-Host "[WARNING] Recall endpoint returned unexpected format" -ForegroundColor Yellow
|
|
Write-Host " Keys: $($recallTest.PSObject.Properties.Name -join ', ')" -ForegroundColor Gray
|
|
}
|
|
} catch {
|
|
Write-Host "[ERROR] Recall endpoint test failed" -ForegroundColor Red
|
|
Write-Host " Error: $($_.Exception.Message)" -ForegroundColor Gray
|
|
exit 1
|
|
}
|
|
Write-Host ""
|
|
|
|
# Success!
|
|
Write-Host "=" * 70 -ForegroundColor Green
|
|
Write-Host "DEPLOYMENT SUCCESSFUL" -ForegroundColor Green
|
|
Write-Host "=" * 70 -ForegroundColor Green
|
|
Write-Host ""
|
|
Write-Host "Deployed commit: $localCommit" -ForegroundColor White
|
|
Write-Host "Files deployed: $($filesToDeploy.Count)" -ForegroundColor White
|
|
Write-Host "API Status: Running" -ForegroundColor White
|
|
Write-Host "Recall endpoint: Working" -ForegroundColor White
|
|
Write-Host ""
|
|
Write-Host "Production is now running the latest code!" -ForegroundColor Green
|