fix(docker): multi-theme packaging with PS1 orchestration and full bundle export

Replace all-themes bat logic with PowerShell to survive branch checkout; add api-admin and full-themes service modes; fix bat findstr path check and cmd exit codes; document six-in-one tar and update gitignore for player/full-themes artifacts.
This commit is contained in:
2026-06-24 14:18:31 +08:00
parent 25dd0cf514
commit 9c5e8d6f5c
8 changed files with 425 additions and 298 deletions

View File

@@ -0,0 +1,285 @@
# 四套主题 player 一键打包(自动切换 Git 分支)
# PowerShell 会在启动时将整份脚本载入内存git checkout 后仍可继续执行。
# 用法(项目根目录或本目录均可):
# .\docs\docker\build-and-export-all-themes.ps1
# .\docs\docker\build-and-export-all-themes.ps1 -UseCache
# .\docs\docker\build-and-export-all-themes.ps1 -ExportOnly
# .\docs\docker\build-and-export-all-themes.ps1 -SkipApiAdmin
# 或通过 bat 启动(参数支持 --use-cache 等 CMD 风格):
# docs\docker\build-and-export-all-themes.bat --use-cache
param(
[switch]$UseCache,
[switch]$ExportOnly,
[switch]$SkipApiAdmin,
[switch]$SkipBundle,
[switch]$Help
)
$ErrorActionPreference = "Stop"
foreach ($arg in $args) {
switch ($arg.ToLowerInvariant()) {
"--use-cache" { $UseCache = $true; continue }
"--export-only" { $ExportOnly = $true; continue }
"--skip-api-admin" { $SkipApiAdmin = $true; continue }
"--skip-bundle" { $SkipBundle = $true; continue }
"-h" { $Help = $true; continue }
"--help" { $Help = $true; continue }
"/?" { $Help = $true; continue }
default { throw "Unknown argument: $arg" }
}
}
function Show-Help {
Write-Host @"
Usage: docs\docker\build-and-export-all-themes.ps1 [options]
-UseCache, --use-cache Use Docker build cache (default: --no-cache)
-ExportOnly, --export-only Skip build, export existing images only
-SkipApiAdmin, --skip-api-admin
Only build 4 player themes, skip api/admin
-SkipBundle, --skip-bundle Skip thebet365-full-themes-latest.tar (6-in-1 bundle)
-Help, -h, --help Show this help
Output (project root):
thebet365-player-main.tar
thebet365-player-theme-2.tar
thebet365-player-theme-3.tar
thebet365-player-theme-4.tar
thebet365-images-latest.tar (api + admin, unless -SkipApiAdmin)
thebet365-full-themes-latest.tar (api + admin + 4 player themes, unless -SkipBundle)
"@
}
if ($Help) {
Show-Help
exit 0
}
$Root = (Resolve-Path (Join-Path $PSScriptRoot "../..")).Path
$Themes = @(
@{ Branch = "main"; Tag = "main" },
@{ Branch = "theme-2"; Tag = "theme-2" },
@{ Branch = "theme-3"; Tag = "theme-3" },
@{ Branch = "theme-4"; Tag = "theme-4" }
)
if (-not (Get-Command docker -ErrorAction SilentlyContinue)) {
throw "docker not found. Please start Docker Desktop first."
}
if (-not (Test-Path (Join-Path $Root "docs\docker\build-and-export-images.bat"))) {
throw "Missing build script: docs\docker\build-and-export-images.bat"
}
function Invoke-Git {
param([Parameter(ValueFromRemainingArguments = $true)][string[]]$GitArgs)
$prevErrorAction = $ErrorActionPreference
$ErrorActionPreference = "SilentlyContinue"
try {
& git @GitArgs 2>$null | Out-Null
return $LASTEXITCODE
} finally {
$ErrorActionPreference = $prevErrorAction
}
}
function Get-GitOutput {
param([Parameter(ValueFromRemainingArguments = $true)][string[]]$GitArgs)
$prevErrorAction = $ErrorActionPreference
$ErrorActionPreference = "SilentlyContinue"
try {
return ((& git @GitArgs 2>$null | Out-String).Trim())
} finally {
$ErrorActionPreference = $prevErrorAction
}
}
Set-Location $Root
$OriginalBranch = Get-GitOutput rev-parse --abbrev-ref HEAD
if ([string]::IsNullOrWhiteSpace($OriginalBranch)) {
throw "Cannot determine current Git branch. Run this script from the repo root."
}
Write-Host "[INFO] Current branch: $OriginalBranch"
$DidStash = $false
$diffExit = Invoke-Git diff --quiet
$cachedExit = Invoke-Git diff --cached --quiet
if ($diffExit -ne 0 -or $cachedExit -ne 0) {
Write-Host "[INFO] Stashing local changes before branch switching..."
$stashExit = Invoke-Git stash push -m "build-all-themes auto-stash"
if ($stashExit -eq 0) {
$DidStash = $true
Write-Host "[INFO] Changes stashed."
} else {
Write-Warning "git stash failed. Branch switching may fail if there are conflicts."
}
}
$FailedThemes = [System.Collections.Generic.List[string]]::new()
$SuccessCount = 0
function Invoke-BuildExport {
param(
[string]$Service = "",
[string]$Tag
)
$argList = @()
if (-not [string]::IsNullOrWhiteSpace($Service)) {
$argList += "--service"
$argList += $Service
}
$argList += "--tag"
$argList += $Tag
if ($UseCache) { $argList += "--use-cache" }
if ($ExportOnly) { $argList += "--export-only" }
Set-Location $Root
$batPath = Join-Path $Root "docs\docker\build-and-export-images.bat"
$argText = ($argList | ForEach-Object {
if ($_ -match '\s') { "`"$_`"" } else { $_ }
}) -join ' '
& cmd.exe /c "`"$batPath`" $argText"
return $LASTEXITCODE
}
function Invoke-PlayerThemeBuild {
param(
[string]$Branch,
[string]$Tag
)
Write-Host ""
Write-Host "----------------------------------------------------------------"
Write-Host "[INFO] Theme: $Branch (image tag: $Tag)"
Write-Host "----------------------------------------------------------------"
Set-Location $Root
$checkoutExit = Invoke-Git checkout $Branch
if ($checkoutExit -ne 0) {
Write-Host "[ERROR] Cannot switch to branch $Branch -- skipping"
$script:FailedThemes.Add($Branch) | Out-Null
return
}
Write-Host "[INFO] Switched to $Branch"
Set-Location $Root
if ((Invoke-BuildExport -Service "player" -Tag $Tag) -ne 0) {
Write-Host "[ERROR] Player build failed for $Branch"
$script:FailedThemes.Add($Branch) | Out-Null
return
}
Write-Host "[OK] thebet365-player:$Tag exported successfully"
$script:SuccessCount++
}
foreach ($theme in $Themes) {
Invoke-PlayerThemeBuild -Branch $theme.Branch -Tag $theme.Tag
}
Write-Host ""
Write-Host "[INFO] Restoring original branch: $OriginalBranch"
Set-Location $Root
if ((Invoke-Git checkout $OriginalBranch) -eq 0) {
Write-Host "[INFO] Restored to $OriginalBranch"
} else {
Write-Warning "Could not restore branch $OriginalBranch. Run: git checkout $OriginalBranch"
}
if ($DidStash) {
Write-Host "[INFO] Restoring stashed changes..."
if ((Invoke-Git stash pop) -eq 0) {
Write-Host "[INFO] Stash restored."
} else {
Write-Warning "git stash pop failed. Run: git stash pop"
}
}
if (-not $SkipApiAdmin) {
Write-Host ""
Write-Host "[INFO] Building api + admin (tag: latest) on branch main..."
Set-Location $Root
if ((Invoke-Git checkout main) -ne 0) {
Write-Host "[ERROR] Cannot switch to branch main for api/admin build"
$FailedThemes.Add("api/admin") | Out-Null
} else {
Set-Location $Root
if ((Invoke-BuildExport -Service "api-admin" -Tag "latest") -ne 0) {
Write-Host "[ERROR] api/admin build failed"
$FailedThemes.Add("api/admin") | Out-Null
} else {
$SuccessCount++
}
}
Write-Host ""
Write-Host "[INFO] Restoring original branch: $OriginalBranch"
Set-Location $Root
Invoke-Git checkout $OriginalBranch | Out-Null
}
if (-not $SkipBundle -and -not $SkipApiAdmin -and $FailedThemes.Count -eq 0) {
Write-Host ""
Write-Host "[INFO] Exporting full bundle (api + admin + 4 player themes)..."
Set-Location $Root
if ((Invoke-BuildExport -Service "full-themes" -Tag "latest") -ne 0) {
Write-Host "[ERROR] Full bundle export failed"
$FailedThemes.Add("full-bundle") | Out-Null
} else {
Write-Host "[OK] thebet365-full-themes-latest.tar exported successfully"
$SuccessCount++
}
}
Write-Host ""
Write-Host "================================================================"
Write-Host " BUILD SUMMARY"
Write-Host "================================================================"
Write-Host " Succeeded: $SuccessCount task(s)"
if ($FailedThemes.Count -gt 0) {
Write-Host " Failed: $($FailedThemes -join ' ')"
Write-Host ""
Write-Host " Tip: Retry failed themes manually:"
Write-Host " git checkout <branch>"
Write-Host " docs\docker\build-and-export-images.bat --service player --tag <tag>"
Write-Host "================================================================"
exit 1
}
Write-Host ""
Write-Host " All done! Output files in project root:"
Write-Host " thebet365-player-main.tar"
Write-Host " thebet365-player-theme-2.tar"
Write-Host " thebet365-player-theme-3.tar"
Write-Host " thebet365-player-theme-4.tar"
if (-not $SkipApiAdmin) {
Write-Host " thebet365-images-latest.tar (api + admin)"
}
if (-not $SkipBundle -and -not $SkipApiAdmin) {
Write-Host " thebet365-full-themes-latest.tar (api + admin + 4 themes, upload this only)"
}
Write-Host ""
Write-Host " Server import (single bundle):"
Write-Host " docker load -i thebet365-full-themes-latest.tar"
Write-Host " docker compose -f docker-compose.prod.yml -f docker-compose.themes.yml --env-file .env.docker up -d"
Write-Host ""
Write-Host " Or import separate tars:"
if (-not $SkipApiAdmin) {
Write-Host " docker load -i thebet365-images-latest.tar"
}
Write-Host " docker load -i thebet365-player-main.tar"
Write-Host " docker load -i thebet365-player-theme-2.tar"
Write-Host " docker load -i thebet365-player-theme-3.tar"
Write-Host " docker load -i thebet365-player-theme-4.tar"
Write-Host "================================================================"
exit 0