123 lines
4.7 KiB
PowerShell
123 lines
4.7 KiB
PowerShell
# ============================================================
|
||
# 本机一键打包脚本(Windows PowerShell)
|
||
# 流程: go build(linux/amd64) -> web/frontend 两个 vite build
|
||
# -> 渲染 web/nginx.k8s.conf(去 BOM) -> docker build -> push Harbor
|
||
#
|
||
# 用法:
|
||
# .\deploy\build.ps1 # 打包当前代码并推送 (tag = commit sha + latest)
|
||
# .\deploy\build.ps1 -Tag v1.0.2 # 使用指定 tag
|
||
# .\deploy\build.ps1 -NoPush # 只构建不推送
|
||
#
|
||
# 依赖: go / node(corepack pnpm) / docker(Harbor 登录态已存于 Docker Desktop 凭据库)
|
||
# ============================================================
|
||
param(
|
||
[string]$Tag = "",
|
||
[switch]$NoPush
|
||
)
|
||
|
||
$ErrorActionPreference = 'Stop'
|
||
|
||
# 脚本所在目录的上一级即项目根目录,任何 cwd 下运行都正确
|
||
$Root = Split-Path -Parent $PSScriptRoot
|
||
$Registry = 'harbor.fuhua91.com'
|
||
$Project = 'live'
|
||
|
||
function Invoke-Step {
|
||
param([string]$Name, [scriptblock]$Block)
|
||
Write-Host "==> $Name" -ForegroundColor Cyan
|
||
& $Block
|
||
if ($LASTEXITCODE -and $LASTEXITCODE -ne 0) {
|
||
Write-Host "错误: $Name 失败 (exit $LASTEXITCODE)" -ForegroundColor Red
|
||
exit $LASTEXITCODE
|
||
}
|
||
}
|
||
|
||
# 前端包管理器: 本机 pnpm 通常不在 PATH,回退 corepack pnpm
|
||
function Invoke-Pnpm {
|
||
param([string]$Dir, [string[]]$PnpmArgs)
|
||
Push-Location (Join-Path $Root $Dir)
|
||
try {
|
||
if (Get-Command pnpm -ErrorAction SilentlyContinue) {
|
||
& pnpm @PnpmArgs
|
||
} else {
|
||
& corepack pnpm @PnpmArgs
|
||
}
|
||
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||
} finally {
|
||
Pop-Location
|
||
}
|
||
}
|
||
|
||
function Build-Frontend {
|
||
param([string]$Dir)
|
||
if (-not (Test-Path (Join-Path $Root "$Dir\node_modules"))) {
|
||
Invoke-Step "[$Dir] pnpm install" { Invoke-Pnpm -Dir $Dir -PnpmArgs @('install', '--frozen-lockfile') }
|
||
}
|
||
Invoke-Step "[$Dir] vite build" { Invoke-Pnpm -Dir $Dir -PnpmArgs @('build') }
|
||
}
|
||
|
||
Set-Location $Root
|
||
|
||
# ---------- 0. 版本号 ----------
|
||
if (-not $Tag) {
|
||
$Tag = (& git rev-parse --short=12 HEAD).Trim()
|
||
if ($LASTEXITCODE -ne 0) { Write-Host '错误: 无法获取 git commit sha' -ForegroundColor Red; exit 1 }
|
||
}
|
||
$BackendImage = "$Registry/$Project/backend:$Tag"
|
||
$FrontendImage = "$Registry/$Project/frontend:$Tag"
|
||
$LivewebImage = "$Registry/$Project/live-web:$Tag"
|
||
Write-Host "==> 打包版本: $Tag"
|
||
|
||
# ---------- 1. 后端二进制 (必须 linux/amd64,否则容器内 Exec format error) ----------
|
||
Invoke-Step 'go build (GOOS=linux GOARCH=amd64)' {
|
||
$env:GOOS = 'linux'; $env:GOARCH = 'amd64'; $env:CGO_ENABLED = '0'
|
||
go build -ldflags "-X main.Version=$Tag" -o ./bin/kratos-admin ./cmd
|
||
}
|
||
|
||
# ---------- 2. 两个前端 ----------
|
||
Build-Frontend 'web' # admin 管理后台
|
||
Build-Frontend 'frontend' # live 用户端(PC 直播页)
|
||
|
||
# ---------- 3. 渲染 nginx.k8s.conf ----------
|
||
# PowerShell Set-Content 会写 UTF-8 BOM,导致 nginx 报 unknown directive;
|
||
# 必须用 WriteAllBytes 写无 BOM 内容。KRA_APP=live -> proxy_pass http://live-backend:8000
|
||
Invoke-Step '渲染 web/nginx.k8s.conf (KRA_APP=live, 去 BOM)' {
|
||
$src = Get-Content -Raw (Join-Path $Root 'web\.docker-compose\nginx\conf.d\my.conf')
|
||
$rendered = $src -replace '\$\{KRA_APP\}', $Project
|
||
$dst = Join-Path $Root 'web\nginx.k8s.conf'
|
||
[System.IO.File]::WriteAllBytes($dst, [System.Text.Encoding]::UTF8.GetBytes($rendered))
|
||
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||
# 校验文件头非 EF BB BF
|
||
$head = [System.IO.File]::ReadAllBytes($dst)[0..1]
|
||
if ($head[0] -eq 0xEF -and $head[1] -eq 0xBB) {
|
||
Write-Host '错误: nginx.k8s.conf 仍含 BOM' -ForegroundColor Red
|
||
exit 1
|
||
}
|
||
}
|
||
|
||
# ---------- 4. docker build ----------
|
||
Invoke-Step "docker build $BackendImage" {
|
||
docker build -t $BackendImage -t "$Registry/$Project/backend:latest" $Root
|
||
}
|
||
Invoke-Step "docker build $FrontendImage" {
|
||
docker build -t $FrontendImage -t "$Registry/$Project/frontend:latest" (Join-Path $Root 'web')
|
||
}
|
||
Invoke-Step "docker build $LivewebImage" {
|
||
docker build -t $LivewebImage -t "$Registry/$Project/live-web:latest" (Join-Path $Root 'frontend')
|
||
}
|
||
|
||
# ---------- 5. docker push ----------
|
||
if (-not $NoPush) {
|
||
foreach ($img in @($BackendImage, $FrontendImage, $LivewebImage)) {
|
||
Invoke-Step "docker push ${img}:$Tag + latest" {
|
||
docker push $img
|
||
docker push ($img -replace ":[^:]+$", ':latest')
|
||
}
|
||
}
|
||
Write-Host ""
|
||
Write-Host "完成。服务器上执行: ./deploy.sh $Tag (或不带参数拉 latest)" -ForegroundColor Green
|
||
} else {
|
||
Write-Host ""
|
||
Write-Host "构建完成 (-NoPush 未推送)。镜像: $BackendImage / $FrontendImage / $LivewebImage" -ForegroundColor Green
|
||
}
|