287 lines
9.0 KiB
PowerShell
287 lines
9.0 KiB
PowerShell
# 四套主题 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
|
||
$env:PLAYER_IMAGE_TAG = $Tag
|
||
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
|