Files
smartmate/deploy/impact-rules.ps1
2026-05-09 17:51:04 +08:00

152 lines
7.3 KiB
PowerShell

param(
[string]$BaseRef = "",
[string]$HeadRef = "HEAD",
[string]$OutputFile = ""
)
$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest
. (Join-Path $PSScriptRoot "service-catalog.ps1")
$repoRoot = Split-Path -Parent $PSScriptRoot
Set-Location $repoRoot
function Test-GitRef {
param([string]$Ref)
if ([string]::IsNullOrWhiteSpace($Ref)) {
return $false
}
& git rev-parse --verify --quiet "$Ref^{commit}" | Out-Null
return ($LASTEXITCODE -eq 0)
}
function Add-SelectedService {
param(
[System.Collections.Generic.List[string]]$Services,
[string]$Service
)
if (-not $Services.Contains($Service)) {
$Services.Add($Service)
}
}
if (-not (Test-GitRef -Ref $HeadRef)) {
throw ("head ref not found: {0}" -f $HeadRef)
}
$appTag = (& git rev-parse --short=12 $HeadRef).Trim()
$selectedServices = [System.Collections.Generic.List[string]]::new()
$frontendChanged = $false
$fullBackend = $false
if (Test-GitRef -Ref $BaseRef) {
$changedFiles = @(& git diff --name-only $BaseRef $HeadRef)
} else {
$changedFiles = @()
$frontendChanged = $true
$fullBackend = $true
}
foreach ($file in $changedFiles) {
switch -Wildcard ($file) {
"README.md" { continue }
"docs/*" { continue }
"frontend/*" { $frontendChanged = $true; continue }
"deploy/nginx/*" { $frontendChanged = $true; continue }
"deploy/docker-pack.*" { $frontendChanged = $true; $fullBackend = $true; continue }
"deploy/docker-load.sh" { $frontendChanged = $true; $fullBackend = $true; continue }
"deploy/stage-release.*" { $frontendChanged = $true; $fullBackend = $true; continue }
"deploy/project-release.sh" { $frontendChanged = $true; $fullBackend = $true; continue }
"deploy/project-rollback.sh" { $frontendChanged = $true; $fullBackend = $true; continue }
"deploy/impact-rules.*" { $frontendChanged = $true; $fullBackend = $true; continue }
"deploy/service-catalog.*" { $frontendChanged = $true; $fullBackend = $true; continue }
"docker-compose.full.yml" { $frontendChanged = $true; $fullBackend = $true; continue }
"frontend/nginx.conf" { $frontendChanged = $true; $fullBackend = $true; continue }
".env.full.example" { $frontendChanged = $true; $fullBackend = $true; continue }
"backend/Dockerfile" { $fullBackend = $true; continue }
"backend/config.docker.yaml" { $fullBackend = $true; continue }
"backend/shared/*" { $fullBackend = $true; continue }
"backend/client/*" { $fullBackend = $true; continue }
"backend/gateway/*" { Add-SelectedService -Services $selectedServices -Service "api"; continue }
"backend/cmd/api/*" { Add-SelectedService -Services $selectedServices -Service "api"; continue }
"backend/cmd/userauth/*" { Add-SelectedService -Services $selectedServices -Service "userauth"; continue }
"backend/services/userauth/*" { Add-SelectedService -Services $selectedServices -Service "userauth"; continue }
"backend/cmd/notification/*" { Add-SelectedService -Services $selectedServices -Service "notification"; continue }
"backend/services/notification/*" { Add-SelectedService -Services $selectedServices -Service "notification"; continue }
"backend/cmd/active-scheduler/*" { Add-SelectedService -Services $selectedServices -Service "active-scheduler"; continue }
"backend/services/active_scheduler/*" { Add-SelectedService -Services $selectedServices -Service "active-scheduler"; continue }
"backend/cmd/schedule/*" { Add-SelectedService -Services $selectedServices -Service "schedule"; continue }
"backend/services/schedule/*" { Add-SelectedService -Services $selectedServices -Service "schedule"; continue }
"backend/cmd/task/*" { Add-SelectedService -Services $selectedServices -Service "task"; continue }
"backend/services/task/*" { Add-SelectedService -Services $selectedServices -Service "task"; continue }
"backend/cmd/task-class/*" { Add-SelectedService -Services $selectedServices -Service "task-class"; continue }
"backend/services/task_class/*" { Add-SelectedService -Services $selectedServices -Service "task-class"; continue }
"backend/cmd/course/*" { Add-SelectedService -Services $selectedServices -Service "course"; continue }
"backend/services/course/*" { Add-SelectedService -Services $selectedServices -Service "course"; continue }
"backend/cmd/memory/*" { Add-SelectedService -Services $selectedServices -Service "memory"; continue }
"backend/services/memory/*" { Add-SelectedService -Services $selectedServices -Service "memory"; continue }
"backend/cmd/agent/*" { Add-SelectedService -Services $selectedServices -Service "agent"; continue }
"backend/services/agent/*" { Add-SelectedService -Services $selectedServices -Service "agent"; continue }
"backend/cmd/taskclassforum/*" { Add-SelectedService -Services $selectedServices -Service "taskclassforum"; continue }
"backend/services/taskclassforum/*" { Add-SelectedService -Services $selectedServices -Service "taskclassforum"; continue }
"backend/cmd/tokenstore/*" { Add-SelectedService -Services $selectedServices -Service "tokenstore"; continue }
"backend/services/tokenstore/*" { Add-SelectedService -Services $selectedServices -Service "tokenstore"; continue }
"backend/cmd/llm/*" { Add-SelectedService -Services $selectedServices -Service "llm"; continue }
"backend/services/llm/*" { Add-SelectedService -Services $selectedServices -Service "llm"; continue }
"backend/*" { $fullBackend = $true; continue }
}
}
if ($fullBackend) {
$selectedServices.Clear()
foreach ($service in Get-SmartFlowBackendServices) {
$selectedServices.Add($service)
}
}
if ($frontendChanged) {
Add-SelectedService -Services $selectedServices -Service "frontend"
}
$buildBackend = 0
$buildFrontend = 0
foreach ($service in $selectedServices) {
if ($service -eq "frontend") {
$buildFrontend = 1
} else {
$buildBackend = 1
}
}
$noop = if ($selectedServices.Count -eq 0) { 1 } else { 0 }
$restartCsv = [string]::Join(",", $selectedServices.ToArray())
$lines = [System.Collections.Generic.List[string]]::new()
$lines.Add("SMARTFLOW_APP_TAG=$appTag")
$lines.Add("SMARTFLOW_NOOP=$noop")
$lines.Add("SMARTFLOW_BUILD_BACKEND=$buildBackend")
$lines.Add("SMARTFLOW_BUILD_FRONTEND=$buildFrontend")
$lines.Add("SMARTFLOW_RESTART_SERVICES=$restartCsv")
foreach ($service in $selectedServices) {
$imageEnv = Get-SmartFlowImageEnvForService -Service $service
$imageRef = Get-SmartFlowDefaultImageForService -Service $service -AppTag $appTag
$lines.Add(("{0}={1}" -f $imageEnv, $imageRef))
}
$content = [string]::Join("`n", $lines.ToArray())
if (-not [string]::IsNullOrWhiteSpace($OutputFile)) {
$parent = Split-Path -Parent $OutputFile
if (-not [string]::IsNullOrWhiteSpace($parent)) {
New-Item -ItemType Directory -Force -Path $parent | Out-Null
}
$outputPath = if ([System.IO.Path]::IsPathRooted($OutputFile)) { $OutputFile } else { Join-Path (Get-Location) $OutputFile }
$utf8NoBom = [System.Text.UTF8Encoding]::new($false)
[System.IO.File]::WriteAllText($outputPath, $content, $utf8NoBom)
} else {
Write-Output $content
}