diff --git a/.gitea/workflows/build-windows-release.yml b/.gitea/workflows/build-windows-release.yml index cf72549..25bd998 100644 --- a/.gitea/workflows/build-windows-release.yml +++ b/.gitea/workflows/build-windows-release.yml @@ -19,52 +19,84 @@ jobs: env: BUILD_TYPE: Release - QT_VERSION: '6.7.3' - QT_ARCH: win64_msvc2019_64 - QT_DIR_NAME: msvc2019_64 - DIST_DIR: dist-windows\chengnan + MSYS2_ROOT: C:\msys64 + MSYSTEM: UCRT64 + CHERE_INVOKING: 1 PACKAGE_BASENAME: chengnan-windows-x64 + PACKAGE_NAME: chengnan-windows-x64 steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup MSVC developer command prompt - uses: ilammy/msvc-dev-cmd@v1 - with: - arch: x64 - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Install Qt + - name: Prepare source shell: powershell run: | $ErrorActionPreference = 'Stop' - python -m pip install --upgrade pip - python -m pip install aqtinstall - python -m aqt install-qt windows desktop $env:QT_VERSION $env:QT_ARCH --outputdir C:\Qt --modules qtimageformats - $qtPrefix = "C:\Qt\$env:QT_VERSION\$env:QT_DIR_NAME" - $windeployqt = Join-Path $qtPrefix 'bin\windeployqt.exe' - if (-not (Test-Path $windeployqt)) { - throw "Qt 安装不完整,找不到 windeployqt:$windeployqt" - } - "QT_PREFIX=$qtPrefix" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 + $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 - - name: Build and deploy Qt runtime + $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' - powershell -ExecutionPolicy Bypass -File .\build-windows.ps1 -QtPrefix "$env:QT_PREFIX" -Config $env:BUILD_TYPE - if (-not (Test-Path $env:DIST_DIR)) { - throw "发布目录不存在:$env:DIST_DIR" - } - if (-not (Test-Path "$env:DIST_DIR\chengnan.exe")) { - throw "构建产物不存在:$env:DIST_DIR\chengnan.exe" + $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" || $true + & $bash -lc "pacman --noconfirm -Syuu" + & $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" + + - 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: | @@ -72,53 +104,28 @@ jobs: $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" - - @" - chengnan Windows x64 发布包 - - 运行方式: - 1. 解压整个目录。 - 2. 双击 chengnan.exe 运行。 - - 说明: - - 本目录由 Windows Runner 使用 MSVC + Qt 构建生成。 - - 请不要只复制 chengnan.exe,需保留同目录 DLL 和 Qt 插件目录。 - "@ | Out-File -FilePath "$env:DIST_DIR\README.txt" -Encoding utf8 - - if (Test-Path $zipName) { - Remove-Item -Force $zipName - } - Compress-Archive -Path "$env:DIST_DIR\*" -DestinationPath $zipName -Force - $hash = (Get-FileHash $zipName -Algorithm SHA256).Hash.ToLowerInvariant() - "$hash $zipName" | Out-File -FilePath "$zipName.sha256" -Encoding ascii - "PACKAGE_ZIP=$zipName" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 + $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: $zipName" + 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_ZIP.sha256")) { - throw "sha256 不存在:$env:PACKAGE_ZIP.sha256" - } - $items = Get-ChildItem -Path $env:PACKAGE_ZIP | Select-Object -ExpandProperty FullName - if (-not $items) { - throw "zip 文件为空或不可读:$env:PACKAGE_ZIP" - } - - - name: Upload build artifact - uses: actions/upload-artifact@v3 - with: - name: chengnan-windows-x64 - path: | - ${{ env.PACKAGE_ZIP }} - ${{ env.PACKAGE_ZIP }}.sha256 - if-no-files-found: error + 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 @@ -127,12 +134,8 @@ jobs: 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。' - } + 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 @@ -171,7 +174,8 @@ jobs: Remove-ExistingAsset $name $uploadUrl = "$apiBase/releases/$($release.id)/assets?name=$([uri]::EscapeDataString($name))" $responseFile = Join-Path $env:RUNNER_TEMP "gitea-upload-response.json" - $status = & curl.exe --silent --show-error --location ` + $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}' ` @@ -186,5 +190,5 @@ jobs: } Upload-Asset $env:PACKAGE_ZIP - Upload-Asset "$env:PACKAGE_ZIP.sha256" + Upload-Asset $env:PACKAGE_SHA256 Write-Host "Release assets uploaded to $serverUrl/$repo/releases/tag/$tagName"