Files
chengnan/.gitea/workflows/build-windows-release.yml
luochen570 ce5918e4c0
Some checks failed
Build Windows Release / Build Windows x64 Release (push) Failing after -3s
ci: make Windows workflow PowerShell 5 compatible
2026-05-30 21:01:21 +08:00

198 lines
9.3 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: Build Windows Release
on:
push:
branches:
- main
tags:
- 'v*'
workflow_dispatch:
permissions:
contents: write
jobs:
build-windows-release:
name: Build Windows x64 Release
# Windows runner 已注册标签windows-latest、windows-2022、self-hosted均为 host 模式。
runs-on: windows-2022
env:
BUILD_TYPE: Release
MSYS2_ROOT: C:\msys64
MSYSTEM: UCRT64
CHERE_INVOKING: 1
PACKAGE_BASENAME: chengnan-windows-x64
PACKAGE_NAME: chengnan-windows-x64
steps:
- name: Prepare source
shell: powershell
run: |
$ErrorActionPreference = 'Stop'
$work = Join-Path $env:RUNNER_TEMP 'chengnan-src'
$zip = Join-Path $env:RUNNER_TEMP 'chengnan-src.zip'
if (Test-Path $work) { Remove-Item -Recurse -Force $work }
if (Test-Path $zip) { Remove-Item -Force $zip }
New-Item -ItemType Directory -Force -Path $work | Out-Null
$serverUrl = if ($env:GITHUB_SERVER_URL) { $env:GITHUB_SERVER_URL.TrimEnd('/') } else { 'https://git.luochen570.cn' }
$archiveUrl = "$serverUrl/$env:GITHUB_REPOSITORY/archive/$env:GITHUB_SHA.zip"
Write-Host "Downloading source archive from $archiveUrl"
Invoke-WebRequest -Uri $archiveUrl -OutFile $zip
Expand-Archive -Path $zip -DestinationPath $work -Force
$src = Get-ChildItem -Path $work -Directory | Select-Object -First 1
if (-not $src) { throw '源码压缩包解压后没有目录' }
"SOURCE_DIR=$($src.FullName)" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
Write-Host "Source dir: $($src.FullName)"
- name: Install MSYS2 and build dependencies
shell: powershell
run: |
$ErrorActionPreference = 'Stop'
$msysRoot = $env:MSYS2_ROOT
if (-not (Test-Path "$msysRoot\usr\bin\bash.exe")) {
$installer = Join-Path $env:RUNNER_TEMP 'msys2-installer.exe'
$installerUrl = 'https://github.com/msys2/msys2-installer/releases/latest/download/msys2-x86_64-latest.exe'
Write-Host "Downloading MSYS2 installer from $installerUrl"
Invoke-WebRequest -Uri $installerUrl -OutFile $installer
& $installer in --confirm-command --accept-messages --root $msysRoot
}
$bash = "$msysRoot\usr\bin\bash.exe"
& $bash -lc "pacman --noconfirm -Syuu"
if ($LASTEXITCODE -ne 0) { Write-Host '第一次 pacman 系统更新返回非零,继续执行第二次更新。' }
& $bash -lc "pacman --noconfirm -Syuu"
if ($LASTEXITCODE -ne 0) { throw "pacman 系统更新失败,退出码:$LASTEXITCODE" }
& $bash -lc "pacman --noconfirm -S --needed git zip unzip p7zip mingw-w64-ucrt-x86_64-toolchain mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-ninja mingw-w64-ucrt-x86_64-qt6-base mingw-w64-ucrt-x86_64-qt6-imageformats"
if ($LASTEXITCODE -ne 0) { throw "pacman 安装依赖失败,退出码:$LASTEXITCODE" }
- name: Configure and build
shell: powershell
run: |
$ErrorActionPreference = 'Stop'
$bash = "$env:MSYS2_ROOT\usr\bin\bash.exe"
$src = $env:SOURCE_DIR -replace '\\','/'
$src = $src -replace '^([A-Za-z]):','/$1'
$src = $src.ToLower()
$script = @"
set -euo pipefail
cd '$src'
export PATH=/ucrt64/bin:/usr/bin:`$PATH
cmake -S . -B build-windows -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build-windows --parallel `$(nproc)
rm -rf dist-windows
mkdir -p dist-windows/chengnan
cp build-windows/chengnan.exe dist-windows/chengnan/
/ucrt64/bin/windeployqt6.exe --release --no-translations dist-windows/chengnan/chengnan.exe || /ucrt64/bin/windeployqt.exe --release --no-translations dist-windows/chengnan/chengnan.exe
cat > dist-windows/chengnan/README.txt <<'EOF'
chengnan Windows x64 发布包
运行方式:
1. 解压整个目录。
2. 双击 chengnan.exe 运行。
说明:
- 本目录由 Windows Runner 使用 MSYS2 UCRT64 + Qt 构建生成。
- 请不要只复制 chengnan.exe需保留同目录 DLL 和 Qt 插件目录。
EOF
"@
& $bash -lc $script
- name: Package
shell: powershell
run: |
$ErrorActionPreference = 'Stop'
$shortSha = $env:GITHUB_SHA.Substring(0, 10)
$version = if ($env:GITHUB_REF_TYPE -eq 'tag') { $env:GITHUB_REF_NAME } else { "build-$shortSha" }
$zipName = "$env:PACKAGE_BASENAME-$version.zip"
$dist = Join-Path $env:SOURCE_DIR 'dist-windows\chengnan'
if (-not (Test-Path "$dist\chengnan.exe")) { throw "缺少构建产物:$dist\chengnan.exe" }
Push-Location (Split-Path $dist -Parent)
if (Test-Path (Join-Path $env:SOURCE_DIR $zipName)) { Remove-Item -Force (Join-Path $env:SOURCE_DIR $zipName) }
Compress-Archive -Path 'chengnan\*' -DestinationPath (Join-Path $env:SOURCE_DIR $zipName) -Force
Pop-Location
$zipPath = Join-Path $env:SOURCE_DIR $zipName
$hash = (Get-FileHash $zipPath -Algorithm SHA256).Hash.ToLowerInvariant()
"$hash $zipName" | Out-File -FilePath "$zipPath.sha256" -Encoding ascii
"PACKAGE_ZIP=$zipPath" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
"PACKAGE_SHA256=$zipPath.sha256" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
"RELEASE_TAG=$version" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
Write-Host "Package: $zipPath"
Write-Host "SHA256: $hash"
- name: Verify package
shell: powershell
run: |
$ErrorActionPreference = 'Stop'
if (-not (Test-Path $env:PACKAGE_ZIP)) { throw "zip 不存在:$env:PACKAGE_ZIP" }
if (-not (Test-Path $env:PACKAGE_SHA256)) { throw "sha256 不存在:$env:PACKAGE_SHA256" }
if ((Get-Item $env:PACKAGE_ZIP).Length -le 0) { throw "zip 文件为空:$env:PACKAGE_ZIP" }
- name: Upload package to repository release
shell: powershell
env:
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
run: |
$ErrorActionPreference = 'Stop'
$token = $env:RELEASE_TOKEN
if ([string]::IsNullOrWhiteSpace($token)) { $token = $env:GITHUB_TOKEN }
if ([string]::IsNullOrWhiteSpace($token)) { throw '缺少发布 Token请在仓库 Secrets 中配置 RELEASE_TOKEN或确保 Gitea Actions 提供 GITHUB_TOKEN。' }
$serverUrl = if ($env:GITHUB_SERVER_URL) { $env:GITHUB_SERVER_URL.TrimEnd('/') } else { 'https://git.luochen570.cn' }
$repo = $env:GITHUB_REPOSITORY
$apiBase = "$serverUrl/api/v1/repos/$repo"
$tagName = $env:RELEASE_TAG
$releaseName = if ($env:GITHUB_REF_TYPE -eq 'tag') { $env:GITHUB_REF_NAME } else { "chengnan $($env:GITHUB_SHA.Substring(0, 10))" }
$isPrerelease = if ($env:GITHUB_REF_TYPE -eq 'tag') { $false } else { $true }
$headers = @{ Authorization = "token $token"; Accept = 'application/json' }
$releasePayload = @{
tag_name = $tagName
target_commitish = $env:GITHUB_SHA
name = $releaseName
body = "Automated Windows x64 build from Gitea Actions.`n"
draft = $false
prerelease = $isPrerelease
} | ConvertTo-Json -Depth 5
try {
$release = Invoke-RestMethod -Method Post -Uri "$apiBase/releases" -Headers $headers -ContentType 'application/json' -Body $releasePayload
} catch {
$release = Invoke-RestMethod -Method Get -Uri "$apiBase/releases/tags/$tagName" -Headers $headers
}
function Remove-ExistingAsset([string]$assetName) {
$assets = Invoke-RestMethod -Method Get -Uri "$apiBase/releases/$($release.id)/assets" -Headers $headers
foreach ($asset in @($assets)) {
if ($asset.name -eq $assetName) {
Invoke-RestMethod -Method Delete -Uri "$apiBase/releases/assets/$($asset.id)" -Headers $headers | Out-Null
}
}
}
function Upload-Asset([string]$path) {
$name = Split-Path $path -Leaf
Remove-ExistingAsset $name
$uploadUrl = "$apiBase/releases/$($release.id)/assets?name=$([uri]::EscapeDataString($name))"
$responseFile = Join-Path $env:RUNNER_TEMP "gitea-upload-response.json"
$curl = Join-Path $env:SystemRoot 'System32\curl.exe'
$status = & $curl --silent --show-error --location `
--header "Authorization: token $token" `
--form "attachment=@$path;filename=$name" `
--write-out '%{http_code}' `
--output $responseFile `
$uploadUrl
if ($status -ne '200' -and $status -ne '201') {
Write-Error "上传 Release 附件失败HTTP $status$name"
if (Test-Path $responseFile) { Get-Content $responseFile }
exit 1
}
Write-Host "Uploaded release asset: $name"
}
Upload-Asset $env:PACKAGE_ZIP
Upload-Asset $env:PACKAGE_SHA256
Write-Host "Release assets uploaded to $serverUrl/$repo/releases/tag/$tagName"