ops:切换离线发布为本地构建上传
This commit is contained in:
@@ -1,90 +1,177 @@
|
||||
param(
|
||||
[string]$AppTag = "latest",
|
||||
[string]$BackendImage = "smartflow/backend-suite",
|
||||
[string]$FrontendImage = "smartflow/frontend",
|
||||
[string]$OutputDir = ".docker-bundles",
|
||||
[switch]$IncludeInfra
|
||||
[string]$PlanFile = "",
|
||||
[string]$Services = "",
|
||||
[switch]$IncludeInfra,
|
||||
[switch]$SkipBackend,
|
||||
[switch]$SkipFrontend,
|
||||
[string]$BackendImage = "",
|
||||
[string]$FrontendImage = ""
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
Set-StrictMode -Version Latest
|
||||
. (Join-Path $PSScriptRoot "service-catalog.ps1")
|
||||
|
||||
function Get-ImageRef {
|
||||
param(
|
||||
[string]$EnvName,
|
||||
[string]$DefaultValue
|
||||
)
|
||||
function Read-ReleasePlan {
|
||||
param([string]$Path)
|
||||
|
||||
$value = [Environment]::GetEnvironmentVariable($EnvName)
|
||||
if ([string]::IsNullOrWhiteSpace($value)) {
|
||||
return $DefaultValue
|
||||
$values = @{}
|
||||
if ([string]::IsNullOrWhiteSpace($Path)) {
|
||||
return $values
|
||||
}
|
||||
if (-not (Test-Path -LiteralPath $Path)) {
|
||||
throw ("release plan not found: {0}" -f $Path)
|
||||
}
|
||||
|
||||
return $value.Trim()
|
||||
foreach ($line in Get-Content -LiteralPath $Path -Encoding UTF8) {
|
||||
if ([string]::IsNullOrWhiteSpace($line) -or $line.TrimStart().StartsWith("#")) {
|
||||
continue
|
||||
}
|
||||
|
||||
$parts = $line -split "=", 2
|
||||
if ($parts.Count -ne 2) {
|
||||
throw ("invalid release plan line: {0}" -f $line)
|
||||
}
|
||||
$values[$parts[0].Trim()] = $parts[1].Trim()
|
||||
}
|
||||
|
||||
return $values
|
||||
}
|
||||
|
||||
function Get-ImageRefForService {
|
||||
param(
|
||||
[string]$Service,
|
||||
[hashtable]$Plan,
|
||||
[string]$Tag
|
||||
)
|
||||
|
||||
$imageEnv = Get-SmartFlowImageEnvForService -Service $Service
|
||||
if ($Plan.ContainsKey($imageEnv) -and -not [string]::IsNullOrWhiteSpace($Plan[$imageEnv])) {
|
||||
return $Plan[$imageEnv]
|
||||
}
|
||||
|
||||
return Get-SmartFlowDefaultImageForService -Service $Service -AppTag $Tag
|
||||
}
|
||||
|
||||
function Invoke-Docker {
|
||||
param([string[]]$Arguments)
|
||||
|
||||
& docker @Arguments
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw ("docker command failed: docker {0}" -f ($Arguments -join " "))
|
||||
}
|
||||
}
|
||||
|
||||
$repoRoot = Split-Path -Parent $PSScriptRoot
|
||||
$bundleDir = Join-Path $repoRoot $OutputDir
|
||||
$backendRef = "{0}:{1}" -f $BackendImage, $AppTag
|
||||
$frontendRef = "{0}:{1}" -f $FrontendImage, $AppTag
|
||||
$appBundlePath = Join-Path $bundleDir ("smartflow-app-{0}.tar" -f $AppTag)
|
||||
$infraBundlePath = Join-Path $bundleDir ("smartflow-infra-{0}.tar" -f $AppTag)
|
||||
$plan = Read-ReleasePlan -Path $PlanFile
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $bundleDir | Out-Null
|
||||
|
||||
Write-Host "==> Build backend image $backendRef"
|
||||
docker build --platform linux/amd64 -f (Join-Path $repoRoot "backend\Dockerfile") -t $backendRef (Join-Path $repoRoot "backend")
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Backend image build failed."
|
||||
if ($plan.ContainsKey("SMARTFLOW_APP_TAG") -and -not [string]::IsNullOrWhiteSpace($plan["SMARTFLOW_APP_TAG"])) {
|
||||
$AppTag = $plan["SMARTFLOW_APP_TAG"]
|
||||
}
|
||||
|
||||
Write-Host "==> Build frontend image $frontendRef"
|
||||
docker build --platform linux/amd64 -f (Join-Path $repoRoot "frontend\Dockerfile") -t $frontendRef (Join-Path $repoRoot "frontend")
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Frontend image build failed."
|
||||
if ([string]::IsNullOrWhiteSpace($Services) -and $plan.ContainsKey("SMARTFLOW_RESTART_SERVICES")) {
|
||||
$Services = $plan["SMARTFLOW_RESTART_SERVICES"]
|
||||
}
|
||||
|
||||
if (Test-Path $appBundlePath) {
|
||||
Remove-Item -LiteralPath $appBundlePath -Force
|
||||
}
|
||||
|
||||
Write-Host "==> Export app bundle to $appBundlePath"
|
||||
docker save -o $appBundlePath $backendRef $frontendRef
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "App bundle export failed."
|
||||
}
|
||||
|
||||
if (-not $IncludeInfra) {
|
||||
Write-Host "==> Done. App bundle exported."
|
||||
return
|
||||
}
|
||||
|
||||
$infraImages = @(
|
||||
(Get-ImageRef -EnvName "SMARTFLOW_MYSQL_IMAGE" -DefaultValue "mysql:8.0"),
|
||||
(Get-ImageRef -EnvName "SMARTFLOW_REDIS_IMAGE" -DefaultValue "redis:7"),
|
||||
(Get-ImageRef -EnvName "SMARTFLOW_KAFKA_IMAGE" -DefaultValue "apache/kafka:3.7.2"),
|
||||
(Get-ImageRef -EnvName "SMARTFLOW_ETCD_IMAGE" -DefaultValue "quay.io/coreos/etcd:v3.5.5"),
|
||||
(Get-ImageRef -EnvName "SMARTFLOW_MINIO_IMAGE" -DefaultValue "minio/minio:RELEASE.2023-03-20T20-16-18Z"),
|
||||
(Get-ImageRef -EnvName "SMARTFLOW_MILVUS_IMAGE" -DefaultValue "milvusdb/milvus:v2.4.4"),
|
||||
(Get-ImageRef -EnvName "SMARTFLOW_ATTU_IMAGE" -DefaultValue "zilliz/attu:v2.4.3")
|
||||
)
|
||||
|
||||
foreach ($imageRef in $infraImages) {
|
||||
Write-Host "==> Pull infra image $imageRef"
|
||||
docker pull $imageRef
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw ("Infra image pull failed: {0}" -f $imageRef)
|
||||
$selectedServices = @()
|
||||
if (-not [string]::IsNullOrWhiteSpace($Services)) {
|
||||
$selectedServices = @($Services.Split(",") | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | ForEach-Object { $_.Trim() })
|
||||
} elseif ([string]::IsNullOrWhiteSpace($PlanFile)) {
|
||||
if (-not $SkipBackend) {
|
||||
$selectedServices += @(Get-SmartFlowBackendServices)
|
||||
}
|
||||
if (-not $SkipFrontend) {
|
||||
$selectedServices += "frontend"
|
||||
}
|
||||
}
|
||||
|
||||
if (Test-Path $infraBundlePath) {
|
||||
New-Item -ItemType Directory -Force -Path $bundleDir | Out-Null
|
||||
$appBundlePath = Join-Path $bundleDir ("smartflow-app-{0}.tar" -f $AppTag)
|
||||
$infraBundlePath = Join-Path $bundleDir ("smartflow-infra-{0}.tar" -f $AppTag)
|
||||
|
||||
if (Test-Path -LiteralPath $appBundlePath) {
|
||||
Remove-Item -LiteralPath $appBundlePath -Force
|
||||
}
|
||||
|
||||
$appImages = @()
|
||||
foreach ($service in $selectedServices) {
|
||||
if ($service -eq "frontend") {
|
||||
if ($SkipFrontend) {
|
||||
continue
|
||||
}
|
||||
|
||||
$imageRef = Get-ImageRefForService -Service $service -Plan $plan -Tag $AppTag
|
||||
Write-Host "==> Build frontend image $imageRef"
|
||||
Invoke-Docker -Arguments @(
|
||||
"build", "--platform", "linux/amd64",
|
||||
"-f", (Join-Path $repoRoot "frontend\Dockerfile"),
|
||||
"-t", $imageRef,
|
||||
(Join-Path $repoRoot "frontend")
|
||||
)
|
||||
$appImages += $imageRef
|
||||
continue
|
||||
}
|
||||
|
||||
if ($SkipBackend) {
|
||||
continue
|
||||
}
|
||||
if (-not (Test-SmartFlowBackendService -Service $service)) {
|
||||
throw ("unknown backend release service: {0}" -f $service)
|
||||
}
|
||||
|
||||
$imageRef = Get-ImageRefForService -Service $service -Plan $plan -Tag $AppTag
|
||||
Write-Host "==> Build backend service image $imageRef"
|
||||
Invoke-Docker -Arguments @(
|
||||
"build", "--platform", "linux/amd64",
|
||||
"--target", "runtime-service",
|
||||
"--build-arg", ("SERVICE={0}" -f $service),
|
||||
"-f", (Join-Path $repoRoot "backend\Dockerfile"),
|
||||
"-t", $imageRef,
|
||||
(Join-Path $repoRoot "backend")
|
||||
)
|
||||
$appImages += $imageRef
|
||||
}
|
||||
|
||||
if ($appImages.Count -gt 0) {
|
||||
Write-Host "==> Export app bundle to $appBundlePath"
|
||||
Invoke-Docker -Arguments (@("save", "-o", $appBundlePath) + $appImages)
|
||||
} else {
|
||||
Write-Host "==> Skip app bundle export because no application image is selected"
|
||||
}
|
||||
|
||||
if (-not $IncludeInfra) {
|
||||
Write-Host "==> Done."
|
||||
return
|
||||
}
|
||||
|
||||
$infraImages = @()
|
||||
if ([string]::IsNullOrWhiteSpace($env:SMARTFLOW_MYSQL_IMAGE)) { $infraImages += "mysql:8.0" } else { $infraImages += $env:SMARTFLOW_MYSQL_IMAGE }
|
||||
if ([string]::IsNullOrWhiteSpace($env:SMARTFLOW_REDIS_IMAGE)) { $infraImages += "redis:7" } else { $infraImages += $env:SMARTFLOW_REDIS_IMAGE }
|
||||
if ([string]::IsNullOrWhiteSpace($env:SMARTFLOW_KAFKA_IMAGE)) { $infraImages += "apache/kafka:3.7.2" } else { $infraImages += $env:SMARTFLOW_KAFKA_IMAGE }
|
||||
if ([string]::IsNullOrWhiteSpace($env:SMARTFLOW_ETCD_IMAGE)) { $infraImages += "quay.io/coreos/etcd:v3.5.5" } else { $infraImages += $env:SMARTFLOW_ETCD_IMAGE }
|
||||
if ([string]::IsNullOrWhiteSpace($env:SMARTFLOW_MINIO_IMAGE)) { $infraImages += "minio/minio:RELEASE.2023-03-20T20-16-18Z" } else { $infraImages += $env:SMARTFLOW_MINIO_IMAGE }
|
||||
if ([string]::IsNullOrWhiteSpace($env:SMARTFLOW_MILVUS_IMAGE)) { $infraImages += "milvusdb/milvus:v2.4.4" } else { $infraImages += $env:SMARTFLOW_MILVUS_IMAGE }
|
||||
if ([string]::IsNullOrWhiteSpace($env:SMARTFLOW_ATTU_IMAGE)) { $infraImages += "zilliz/attu:v2.4.3" } else { $infraImages += $env:SMARTFLOW_ATTU_IMAGE }
|
||||
|
||||
foreach ($imageRef in $infraImages) {
|
||||
& docker image inspect $imageRef | Out-Null
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "==> Reuse local infra image $imageRef"
|
||||
continue
|
||||
}
|
||||
|
||||
Write-Host "==> Pull infra image $imageRef"
|
||||
Invoke-Docker -Arguments @("pull", $imageRef)
|
||||
}
|
||||
|
||||
if (Test-Path -LiteralPath $infraBundlePath) {
|
||||
Remove-Item -LiteralPath $infraBundlePath -Force
|
||||
}
|
||||
|
||||
Write-Host "==> Export infra bundle to $infraBundlePath"
|
||||
docker save -o $infraBundlePath @infraImages
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Infra bundle export failed."
|
||||
}
|
||||
Invoke-Docker -Arguments (@("save", "-o", $infraBundlePath) + $infraImages)
|
||||
|
||||
Write-Host "==> Done. App bundle and infra bundle exported."
|
||||
Write-Host "==> Done."
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
set -euo pipefail
|
||||
|
||||
APP_TAG="latest"
|
||||
BACKEND_IMAGE="smartflow/backend-suite"
|
||||
FRONTEND_IMAGE="smartflow/frontend"
|
||||
OUTPUT_DIR=".docker-bundles"
|
||||
INCLUDE_INFRA=0
|
||||
PLAN_FILE=""
|
||||
SERVICES_CSV=""
|
||||
SKIP_BACKEND=0
|
||||
SKIP_FRONTEND=0
|
||||
|
||||
@@ -15,14 +15,6 @@ while [[ $# -gt 0 ]]; do
|
||||
APP_TAG="$2"
|
||||
shift 2
|
||||
;;
|
||||
--backend-image)
|
||||
BACKEND_IMAGE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--frontend-image)
|
||||
FRONTEND_IMAGE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--output-dir)
|
||||
OUTPUT_DIR="$2"
|
||||
shift 2
|
||||
@@ -31,6 +23,14 @@ while [[ $# -gt 0 ]]; do
|
||||
INCLUDE_INFRA=1
|
||||
shift
|
||||
;;
|
||||
--plan-file)
|
||||
PLAN_FILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--services)
|
||||
SERVICES_CSV="$2"
|
||||
shift 2
|
||||
;;
|
||||
--skip-backend)
|
||||
SKIP_BACKEND=1
|
||||
shift
|
||||
@@ -39,6 +39,10 @@ while [[ $# -gt 0 ]]; do
|
||||
SKIP_FRONTEND=1
|
||||
shift
|
||||
;;
|
||||
--backend-image|--frontend-image)
|
||||
# 兼容旧调用参数。服务级发布后镜像引用来自 release-plan.env,不再由统一 backend/frontend 参数决定。
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
echo "unknown argument: $1" >&2
|
||||
exit 64
|
||||
@@ -47,38 +51,100 @@ while [[ $# -gt 0 ]]; do
|
||||
done
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
source "${repo_root}/deploy/service-catalog.sh"
|
||||
|
||||
bundle_dir="${repo_root}/${OUTPUT_DIR}"
|
||||
backend_ref="${BACKEND_IMAGE}:${APP_TAG}"
|
||||
frontend_ref="${FRONTEND_IMAGE}:${APP_TAG}"
|
||||
app_bundle_path="${bundle_dir}/smartflow-app-${APP_TAG}.tar"
|
||||
infra_bundle_path="${bundle_dir}/smartflow-infra-${APP_TAG}.tar"
|
||||
|
||||
mkdir -p "${bundle_dir}"
|
||||
rm -f "${app_bundle_path}"
|
||||
|
||||
if [[ "${SKIP_BACKEND}" -eq 0 ]]; then
|
||||
echo "==> Build backend image ${backend_ref}"
|
||||
docker build --platform linux/amd64 -f "${repo_root}/backend/Dockerfile" -t "${backend_ref}" "${repo_root}/backend"
|
||||
if [[ -n "${PLAN_FILE}" ]]; then
|
||||
# 1. 构建机只信任影响分析生成的计划文件,避免 workflow 和脚本重复计算影响范围。
|
||||
# 2. plan 文件缺失时直接失败,防止误把默认全量构建当成精准发布。
|
||||
# 3. SMARTFLOW_APP_TAG 优先级高于命令行参数,保证镜像 tag 与 release id 一致。
|
||||
source "${PLAN_FILE}"
|
||||
APP_TAG="${SMARTFLOW_APP_TAG:-${APP_TAG}}"
|
||||
SERVICES_CSV="${SMARTFLOW_RESTART_SERVICES:-${SERVICES_CSV}}"
|
||||
app_bundle_path="${bundle_dir}/smartflow-app-${APP_TAG}.tar"
|
||||
infra_bundle_path="${bundle_dir}/smartflow-infra-${APP_TAG}.tar"
|
||||
rm -f "${app_bundle_path}"
|
||||
fi
|
||||
|
||||
if [[ "${SKIP_FRONTEND}" -eq 0 ]]; then
|
||||
echo "==> Build frontend image ${frontend_ref}"
|
||||
docker build --platform linux/amd64 -f "${repo_root}/frontend/Dockerfile" -t "${frontend_ref}" "${repo_root}/frontend"
|
||||
declare -a services=()
|
||||
if [[ -n "${SERVICES_CSV}" ]]; then
|
||||
IFS=',' read -r -a services <<< "${SERVICES_CSV}"
|
||||
elif [[ -z "${PLAN_FILE}" ]]; then
|
||||
# 1. 手工执行且没有传 plan 时,默认构建所有应用服务,保持旧脚本“一键全量打包”的可用性。
|
||||
# 2. 这里改为服务级镜像全量,而不是 backend-suite,便于后续逐步淘汰单体后端镜像。
|
||||
if [[ "${SKIP_BACKEND}" -eq 0 ]]; then
|
||||
services+=("${SMARTFLOW_BACKEND_SERVICES[@]}")
|
||||
fi
|
||||
if [[ "${SKIP_FRONTEND}" -eq 0 ]]; then
|
||||
services+=("frontend")
|
||||
fi
|
||||
fi
|
||||
|
||||
image_ref_for_service() {
|
||||
local service="$1"
|
||||
local image_env
|
||||
local image_ref
|
||||
|
||||
image_env="$(smartflow_image_env_for_service "${service}")"
|
||||
local -n image_value="${image_env}"
|
||||
image_ref="${image_value:-}"
|
||||
if [[ -z "${image_ref}" ]]; then
|
||||
image_ref="$(smartflow_default_image_for_service "${service}" "${APP_TAG}")"
|
||||
fi
|
||||
|
||||
printf '%s\n' "${image_ref}"
|
||||
}
|
||||
|
||||
declare -a app_images=()
|
||||
if [[ "${SKIP_BACKEND}" -eq 0 ]]; then
|
||||
app_images+=("${backend_ref}")
|
||||
fi
|
||||
if [[ "${SKIP_FRONTEND}" -eq 0 ]]; then
|
||||
app_images+=("${frontend_ref}")
|
||||
fi
|
||||
for service in "${services[@]}"; do
|
||||
if [[ -z "${service}" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "${service}" == "frontend" ]]; then
|
||||
if [[ "${SKIP_FRONTEND}" -eq 1 ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
image_ref="$(image_ref_for_service "${service}")"
|
||||
echo "==> Build frontend image ${image_ref}"
|
||||
docker build --platform linux/amd64 -f "${repo_root}/frontend/Dockerfile" -t "${image_ref}" "${repo_root}/frontend"
|
||||
app_images+=("${image_ref}")
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "${SKIP_BACKEND}" -eq 1 ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if ! smartflow_is_backend_service "${service}"; then
|
||||
echo "unknown release service: ${service}" >&2
|
||||
exit 65
|
||||
fi
|
||||
|
||||
image_ref="$(image_ref_for_service "${service}")"
|
||||
echo "==> Build backend service image ${image_ref}"
|
||||
docker build \
|
||||
--platform linux/amd64 \
|
||||
--target runtime-service \
|
||||
--build-arg "SERVICE=${service}" \
|
||||
-f "${repo_root}/backend/Dockerfile" \
|
||||
-t "${image_ref}" \
|
||||
"${repo_root}/backend"
|
||||
app_images+=("${image_ref}")
|
||||
done
|
||||
|
||||
if [[ "${#app_images[@]}" -gt 0 ]]; then
|
||||
rm -f "${app_bundle_path}"
|
||||
echo "==> Export app bundle to ${app_bundle_path}"
|
||||
docker save -o "${app_bundle_path}" "${app_images[@]}"
|
||||
else
|
||||
echo "==> Skip app bundle export because backend/frontend are both skipped"
|
||||
echo "==> Skip app bundle export because no application image is selected"
|
||||
fi
|
||||
|
||||
if [[ "${INCLUDE_INFRA}" -eq 0 ]]; then
|
||||
|
||||
151
deploy/impact-rules.ps1
Normal file
151
deploy/impact-rules.ps1
Normal file
@@ -0,0 +1,151 @@
|
||||
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
|
||||
}
|
||||
@@ -8,7 +8,8 @@ output_file="${3:-}"
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "${repo_root}"
|
||||
|
||||
backend_services=(userauth notification active-scheduler schedule task task-class course memory agent taskclassforum tokenstore llm api)
|
||||
source "${repo_root}/deploy/service-catalog.sh"
|
||||
|
||||
selected_services=()
|
||||
frontend_changed=0
|
||||
full_backend=0
|
||||
@@ -50,7 +51,7 @@ for file in "${changed_files[@]}"; do
|
||||
frontend/*|deploy/nginx/*)
|
||||
frontend_changed=1
|
||||
;;
|
||||
deploy/docker-pack.*|deploy/docker-load.sh|deploy/stage-release.sh|deploy/project-release.sh|deploy/project-rollback.sh|deploy/impact-rules.sh)
|
||||
deploy/docker-pack.*|deploy/docker-load.sh|deploy/stage-release.*|deploy/project-release.sh|deploy/project-rollback.sh|deploy/impact-rules.*|deploy/service-catalog.*)
|
||||
frontend_changed=1
|
||||
full_backend=1
|
||||
;;
|
||||
@@ -107,7 +108,7 @@ for file in "${changed_files[@]}"; do
|
||||
done
|
||||
|
||||
if [[ "${full_backend}" -eq 1 ]]; then
|
||||
selected_services=("${backend_services[@]}")
|
||||
selected_services=("${SMARTFLOW_BACKEND_SERVICES[@]}")
|
||||
fi
|
||||
|
||||
if [[ "${frontend_changed}" -eq 1 ]]; then
|
||||
@@ -140,12 +141,16 @@ SMARTFLOW_APP_TAG=${app_tag}
|
||||
SMARTFLOW_NOOP=${noop}
|
||||
SMARTFLOW_BUILD_BACKEND=${build_backend}
|
||||
SMARTFLOW_BUILD_FRONTEND=${build_frontend}
|
||||
SMARTFLOW_BACKEND_IMAGE=smartflow/backend-suite:${app_tag}
|
||||
SMARTFLOW_FRONTEND_IMAGE=smartflow/frontend:${app_tag}
|
||||
SMARTFLOW_RESTART_SERVICES=${restart_csv}
|
||||
EOF
|
||||
)
|
||||
|
||||
for service in "${selected_services[@]}"; do
|
||||
image_env="$(smartflow_image_env_for_service "${service}")"
|
||||
image_ref="$(smartflow_default_image_for_service "${service}" "${app_tag}")"
|
||||
content+=$'\n'"${image_env}=${image_ref}"
|
||||
done
|
||||
|
||||
if [[ -n "${output_file}" ]]; then
|
||||
printf '%s\n' "${content}" > "${output_file}"
|
||||
else
|
||||
|
||||
@@ -11,6 +11,8 @@ release_id="${SMARTFLOW_RELEASE_ID:?SMARTFLOW_RELEASE_ID is required}"
|
||||
plan_file="${release_dir}/deploy/release-plan.env"
|
||||
runtime_env="${runtime_dir}/.env"
|
||||
|
||||
source "${release_dir}/deploy/service-catalog.sh"
|
||||
|
||||
if [[ ! -f "${plan_file}" ]]; then
|
||||
echo "release plan not found: ${plan_file}" >&2
|
||||
exit 66
|
||||
@@ -61,14 +63,6 @@ if compgen -G "${release_dir}/.docker-bundles/*.tar" >/dev/null 2>&1; then
|
||||
bash "${release_dir}/deploy/docker-load.sh" "${release_dir}/.docker-bundles"
|
||||
fi
|
||||
|
||||
if [[ "${SMARTFLOW_BUILD_BACKEND:-0}" == "1" ]]; then
|
||||
set_env_var "SMARTFLOW_BACKEND_IMAGE" "${SMARTFLOW_BACKEND_IMAGE}" "${runtime_env}"
|
||||
fi
|
||||
|
||||
if [[ "${SMARTFLOW_BUILD_FRONTEND:-0}" == "1" ]]; then
|
||||
set_env_var "SMARTFLOW_FRONTEND_IMAGE" "${SMARTFLOW_FRONTEND_IMAGE}" "${runtime_env}"
|
||||
fi
|
||||
|
||||
services=()
|
||||
IFS=',' read -r -a raw_services <<< "${SMARTFLOW_RESTART_SERVICES:-}"
|
||||
for service in "${raw_services[@]}"; do
|
||||
@@ -82,6 +76,19 @@ if [[ "${#services[@]}" -eq 0 ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 1. release-plan.env 是构建机生成的单一事实源,部署机只按服务名读取对应镜像变量。
|
||||
# 2. 某个服务缺少镜像变量时直接失败,避免 compose 沿用旧镜像造成“发布成功但代码未更新”。
|
||||
# 3. .env 更新发生在 docker load 之后;如果镜像包无法加载,不会提前切换运行时镜像引用。
|
||||
for service in "${services[@]}"; do
|
||||
image_env="$(smartflow_image_env_for_service "${service}")"
|
||||
local_image_ref="${!image_env:-}"
|
||||
if [[ -z "${local_image_ref}" ]]; then
|
||||
echo "image ref not found in release plan: ${image_env}" >&2
|
||||
exit 68
|
||||
fi
|
||||
set_env_var "${image_env}" "${local_image_ref}" "${runtime_env}"
|
||||
done
|
||||
|
||||
# 1. 使用 --no-deps 只重建命中的服务,避免后端小改动把整套依赖链一起拉起来。
|
||||
# 2. 如果后续服务新增或删减,只要 release-plan.env 给出的服务名同步更新,这里无需改脚本。
|
||||
# 3. 失败时直接退出,由上层薄封装决定是否切回旧 release。
|
||||
|
||||
85
deploy/service-catalog.ps1
Normal file
85
deploy/service-catalog.ps1
Normal file
@@ -0,0 +1,85 @@
|
||||
$ErrorActionPreference = "Stop"
|
||||
Set-StrictMode -Version Latest
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($env:SMARTFLOW_SERVICE_CATALOG_FILE)) {
|
||||
$script:SmartFlowCatalogFile = Join-Path $PSScriptRoot "service-catalog.txt"
|
||||
}
|
||||
if (-not [string]::IsNullOrWhiteSpace($env:SMARTFLOW_SERVICE_CATALOG_FILE)) {
|
||||
$script:SmartFlowCatalogFile = $env:SMARTFLOW_SERVICE_CATALOG_FILE
|
||||
}
|
||||
|
||||
function Get-SmartFlowServiceCatalog {
|
||||
if (-not (Test-Path -LiteralPath $script:SmartFlowCatalogFile)) {
|
||||
throw ("service catalog not found: {0}" -f $script:SmartFlowCatalogFile)
|
||||
}
|
||||
|
||||
$items = @()
|
||||
foreach ($line in Get-Content -LiteralPath $script:SmartFlowCatalogFile -Encoding UTF8) {
|
||||
if ([string]::IsNullOrWhiteSpace($line) -or $line.TrimStart().StartsWith("#")) {
|
||||
continue
|
||||
}
|
||||
|
||||
$parts = $line.Split("|")
|
||||
if ($parts.Count -ne 4) {
|
||||
throw ("invalid service catalog line: {0}" -f $line)
|
||||
}
|
||||
|
||||
$items += [pscustomobject]@{
|
||||
Service = $parts[0].Trim()
|
||||
ImageEnv = $parts[1].Trim()
|
||||
ImageRepo = $parts[2].Trim()
|
||||
Kind = $parts[3].Trim()
|
||||
}
|
||||
}
|
||||
|
||||
return $items
|
||||
}
|
||||
|
||||
function Get-SmartFlowBackendServices {
|
||||
return @(Get-SmartFlowServiceCatalog | Where-Object { $_.Kind -eq "backend" } | ForEach-Object { $_.Service })
|
||||
}
|
||||
|
||||
function Get-SmartFlowServiceCatalogItem {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Service
|
||||
)
|
||||
|
||||
$item = Get-SmartFlowServiceCatalog | Where-Object { $_.Service -eq $Service } | Select-Object -First 1
|
||||
if ($null -eq $item) {
|
||||
throw ("unknown release service: {0}" -f $Service)
|
||||
}
|
||||
|
||||
return $item
|
||||
}
|
||||
|
||||
function Test-SmartFlowBackendService {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Service
|
||||
)
|
||||
|
||||
return ((Get-SmartFlowServiceCatalogItem -Service $Service).Kind -eq "backend")
|
||||
}
|
||||
|
||||
function Get-SmartFlowImageEnvForService {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Service
|
||||
)
|
||||
|
||||
return (Get-SmartFlowServiceCatalogItem -Service $Service).ImageEnv
|
||||
}
|
||||
|
||||
function Get-SmartFlowDefaultImageForService {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Service,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$AppTag
|
||||
)
|
||||
|
||||
$item = Get-SmartFlowServiceCatalogItem -Service $Service
|
||||
return ("{0}:{1}" -f $item.ImageRepo, $AppTag)
|
||||
}
|
||||
71
deploy/service-catalog.sh
Normal file
71
deploy/service-catalog.sh
Normal file
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# 1. 发布脚本共享同一份服务清单,避免影响计算、镜像构建、部署更新三处各自维护服务名。
|
||||
# 2. 这里只把文本清单加载成 Bash 可用的数据结构;不负责判断某次发布要构建哪些服务。
|
||||
# 3. 新增或删除后端服务时,优先改 service-catalog.txt,再同步 compose 服务定义,避免脚本之间出现漂移。
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
catalog_file="${SMARTFLOW_SERVICE_CATALOG_FILE:-${script_dir}/service-catalog.txt}"
|
||||
|
||||
if [[ ! -f "${catalog_file}" ]]; then
|
||||
echo "service catalog not found: ${catalog_file}" >&2
|
||||
exit 66
|
||||
fi
|
||||
|
||||
SMARTFLOW_BACKEND_SERVICES=()
|
||||
declare -Ag SMARTFLOW_SERVICE_IMAGE_ENVS=()
|
||||
declare -Ag SMARTFLOW_SERVICE_IMAGE_REPOS=()
|
||||
declare -Ag SMARTFLOW_SERVICE_KINDS=()
|
||||
|
||||
while IFS='|' read -r service image_env image_repo kind; do
|
||||
if [[ -z "${service}" || "${service}" == \#* ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
SMARTFLOW_SERVICE_IMAGE_ENVS["${service}"]="${image_env}"
|
||||
SMARTFLOW_SERVICE_IMAGE_REPOS["${service}"]="${image_repo}"
|
||||
SMARTFLOW_SERVICE_KINDS["${service}"]="${kind}"
|
||||
|
||||
if [[ "${kind}" == "backend" ]]; then
|
||||
SMARTFLOW_BACKEND_SERVICES+=("${service}")
|
||||
fi
|
||||
done < "${catalog_file}"
|
||||
|
||||
# smartflow_is_backend_service 负责判断服务是否属于后端发布粒度。
|
||||
# 输入:compose 服务名。
|
||||
# 输出:命中返回 0,未命中返回 1;不负责校验 frontend 这类非后端服务。
|
||||
smartflow_is_backend_service() {
|
||||
local service="$1"
|
||||
[[ "${SMARTFLOW_SERVICE_KINDS[${service}]-}" == "backend" ]]
|
||||
}
|
||||
|
||||
# smartflow_image_env_for_service 负责把 compose 服务名映射成运行时 .env 里的镜像变量。
|
||||
# 输入:compose 服务名,例如 task-class。
|
||||
# 输出:变量名,例如 SMARTFLOW_IMAGE_TASK_CLASS;未知服务直接失败,避免发布脚本静默写错键。
|
||||
smartflow_image_env_for_service() {
|
||||
local service="$1"
|
||||
local image_env="${SMARTFLOW_SERVICE_IMAGE_ENVS[${service}]-}"
|
||||
|
||||
if [[ -z "${image_env}" ]]; then
|
||||
echo "unknown service: ${service}" >&2
|
||||
return 65
|
||||
fi
|
||||
|
||||
echo "${image_env}"
|
||||
}
|
||||
|
||||
# smartflow_default_image_for_service 负责生成服务级镜像的默认引用。
|
||||
# 输入:compose 服务名、应用 tag。
|
||||
# 输出:smartflow/<service>:<tag>,frontend 保持 smartflow/frontend:<tag>。
|
||||
smartflow_default_image_for_service() {
|
||||
local service="$1"
|
||||
local app_tag="$2"
|
||||
local image_repo="${SMARTFLOW_SERVICE_IMAGE_REPOS[${service}]-}"
|
||||
|
||||
if [[ -z "${image_repo}" ]]; then
|
||||
echo "unknown service: ${service}" >&2
|
||||
return 65
|
||||
fi
|
||||
|
||||
echo "${image_repo}:${app_tag}"
|
||||
}
|
||||
15
deploy/service-catalog.txt
Normal file
15
deploy/service-catalog.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
# service|image_env|image_repo|kind
|
||||
userauth|SMARTFLOW_IMAGE_USERAUTH|smartflow/userauth|backend
|
||||
notification|SMARTFLOW_IMAGE_NOTIFICATION|smartflow/notification|backend
|
||||
active-scheduler|SMARTFLOW_IMAGE_ACTIVE_SCHEDULER|smartflow/active-scheduler|backend
|
||||
schedule|SMARTFLOW_IMAGE_SCHEDULE|smartflow/schedule|backend
|
||||
task|SMARTFLOW_IMAGE_TASK|smartflow/task|backend
|
||||
task-class|SMARTFLOW_IMAGE_TASK_CLASS|smartflow/task-class|backend
|
||||
course|SMARTFLOW_IMAGE_COURSE|smartflow/course|backend
|
||||
memory|SMARTFLOW_IMAGE_MEMORY|smartflow/memory|backend
|
||||
agent|SMARTFLOW_IMAGE_AGENT|smartflow/agent|backend
|
||||
taskclassforum|SMARTFLOW_IMAGE_TASKCLASSFORUM|smartflow/taskclassforum|backend
|
||||
tokenstore|SMARTFLOW_IMAGE_TOKENSTORE|smartflow/tokenstore|backend
|
||||
llm|SMARTFLOW_IMAGE_LLM|smartflow/llm|backend
|
||||
api|SMARTFLOW_IMAGE_API|smartflow/api|backend
|
||||
frontend|SMARTFLOW_IMAGE_FRONTEND|smartflow/frontend|frontend
|
||||
46
deploy/stage-release.ps1
Normal file
46
deploy/stage-release.ps1
Normal file
@@ -0,0 +1,46 @@
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$ReleaseDir,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$PlanFile,
|
||||
|
||||
[string]$BundleDir = ".docker-bundles"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
Set-StrictMode -Version Latest
|
||||
|
||||
$repoRoot = Split-Path -Parent $PSScriptRoot
|
||||
$releaseAbs = Join-Path $repoRoot $ReleaseDir
|
||||
$bundleAbs = Join-Path $repoRoot $BundleDir
|
||||
|
||||
if (-not (Test-Path -LiteralPath $PlanFile)) {
|
||||
throw ("release plan not found: {0}" -f $PlanFile)
|
||||
}
|
||||
|
||||
if (Test-Path -LiteralPath $releaseAbs) {
|
||||
Remove-Item -LiteralPath $releaseAbs -Recurse -Force
|
||||
}
|
||||
|
||||
New-Item -ItemType Directory -Force -Path (Join-Path $releaseAbs "deploy\nginx") | Out-Null
|
||||
New-Item -ItemType Directory -Force -Path (Join-Path $releaseAbs "deploy\certs") | Out-Null
|
||||
New-Item -ItemType Directory -Force -Path (Join-Path $releaseAbs ".docker-bundles") | Out-Null
|
||||
|
||||
Copy-Item -LiteralPath (Join-Path $repoRoot "docker-compose.full.yml") -Destination (Join-Path $releaseAbs "docker-compose.full.yml")
|
||||
Copy-Item -LiteralPath (Join-Path $repoRoot "deploy\docker-load.sh") -Destination (Join-Path $releaseAbs "deploy\docker-load.sh")
|
||||
Copy-Item -LiteralPath (Join-Path $repoRoot "deploy\project-release.sh") -Destination (Join-Path $releaseAbs "deploy\project-release.sh")
|
||||
Copy-Item -LiteralPath (Join-Path $repoRoot "deploy\project-rollback.sh") -Destination (Join-Path $releaseAbs "deploy\project-rollback.sh")
|
||||
Copy-Item -LiteralPath (Join-Path $repoRoot "deploy\impact-rules.sh") -Destination (Join-Path $releaseAbs "deploy\impact-rules.sh")
|
||||
Copy-Item -LiteralPath (Join-Path $repoRoot "deploy\service-catalog.sh") -Destination (Join-Path $releaseAbs "deploy\service-catalog.sh")
|
||||
Copy-Item -LiteralPath (Join-Path $repoRoot "deploy\service-catalog.txt") -Destination (Join-Path $releaseAbs "deploy\service-catalog.txt")
|
||||
Copy-Item -LiteralPath (Join-Path $repoRoot "deploy\nginx\default.conf") -Destination (Join-Path $releaseAbs "deploy\nginx\default.conf")
|
||||
Copy-Item -LiteralPath (Join-Path $repoRoot "deploy\certs\README.md") -Destination (Join-Path $releaseAbs "deploy\certs\README.md")
|
||||
Copy-Item -LiteralPath $PlanFile -Destination (Join-Path $releaseAbs "deploy\release-plan.env")
|
||||
|
||||
if (Test-Path -LiteralPath $bundleAbs) {
|
||||
$bundles = Get-ChildItem -LiteralPath $bundleAbs -Filter "*.tar" -File
|
||||
foreach ($bundle in $bundles) {
|
||||
Copy-Item -LiteralPath $bundle.FullName -Destination (Join-Path $releaseAbs ".docker-bundles")
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,8 @@ cp "${repo_root}/deploy/docker-load.sh" "${release_abs}/deploy/docker-load.sh"
|
||||
cp "${repo_root}/deploy/project-release.sh" "${release_abs}/deploy/project-release.sh"
|
||||
cp "${repo_root}/deploy/project-rollback.sh" "${release_abs}/deploy/project-rollback.sh"
|
||||
cp "${repo_root}/deploy/impact-rules.sh" "${release_abs}/deploy/impact-rules.sh"
|
||||
cp "${repo_root}/deploy/service-catalog.sh" "${release_abs}/deploy/service-catalog.sh"
|
||||
cp "${repo_root}/deploy/service-catalog.txt" "${release_abs}/deploy/service-catalog.txt"
|
||||
cp "${repo_root}/deploy/nginx/default.conf" "${release_abs}/deploy/nginx/default.conf"
|
||||
cp "${repo_root}/deploy/certs/README.md" "${release_abs}/deploy/certs/README.md"
|
||||
cp "${plan_file}" "${release_abs}/deploy/release-plan.env"
|
||||
|
||||
Reference in New Issue
Block a user