diff --git a/.gitea/workflows/build-windows-release.yml b/.gitea/workflows/build-windows-release.yml new file mode 100644 index 0000000..dd739e2 --- /dev/null +++ b/.gitea/workflows/build-windows-release.yml @@ -0,0 +1,129 @@ +name: Build Windows Release + +on: + push: + branches: + - main + tags: + - 'v*' + workflow_dispatch: + +permissions: + contents: write + +jobs: + build-windows-release: + name: Build Windows x64 Release + runs-on: + - windows + + env: + BUILD_TYPE: Release + QT_VERSION: '6.7.3' + QT_ARCH: win64_msvc2019_64 + QT_MODULES: qtimageformats + DIST_DIR: dist-windows\chengnan + + 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 with aqtinstall + 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 win64_msvc2019_64 --outputdir C:\Qt --modules $env:QT_MODULES + $qtPrefix = "C:\Qt\$env:QT_VERSION\msvc2019_64" + if (-not (Test-Path "$qtPrefix\bin\windeployqt.exe")) { + throw "Qt 安装不完整,找不到 windeployqt:$qtPrefix\bin\windeployqt.exe" + } + "QT_PREFIX=$qtPrefix" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 + + - name: Configure and build + shell: powershell + run: | + $ErrorActionPreference = 'Stop' + powershell -ExecutionPolicy Bypass -File .\build-windows.ps1 -QtPrefix "$env:QT_PREFIX" -Config $env:BUILD_TYPE + + - 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 = "chengnan-windows-x64-$version.zip" + if (-not (Test-Path $env:DIST_DIR)) { + throw "发布目录不存在:$env:DIST_DIR" + } + 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 + "RELEASE_TAG=$version" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 + Write-Host "Package: $zipName" + Write-Host "SHA256: $hash" + + - name: Upload build artifact + uses: actions/upload-artifact@v3 + with: + name: chengnan-windows-x64 + path: | + ${{ env.PACKAGE_ZIP }} + ${{ env.PACKAGE_ZIP }}.sha256 + + - name: Publish to Gitea Release + if: ${{ github.event_name != 'pull_request' }} + shell: powershell + env: + GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN || secrets.GITHUB_TOKEN }} + run: | + $ErrorActionPreference = 'Stop' + if ([string]::IsNullOrWhiteSpace($env:GITEA_TOKEN)) { + throw '缺少发布 Token。请在仓库 Secrets 中配置 RELEASE_TOKEN,或确保 Gitea 提供 GITHUB_TOKEN。' + } + + $api = $env:GITHUB_API_URL.TrimEnd('/') + $repo = $env:GITHUB_REPOSITORY + $tag = $env:RELEASE_TAG + $zip = $env:PACKAGE_ZIP + $headers = @{ + Authorization = "token $env:GITEA_TOKEN" + Accept = 'application/json' + } + + $releaseUrl = "$api/repos/$repo/releases/tags/$tag" + try { + $release = Invoke-RestMethod -Method Get -Uri $releaseUrl -Headers $headers + } catch { + $body = @{ + tag_name = $tag + target_commitish = $env:GITHUB_SHA + name = "chengnan $tag" + body = "Windows x64 Release 自动构建产物。`n`n提交:$env:GITHUB_SHA" + draft = $false + prerelease = ($env:GITHUB_REF_TYPE -ne 'tag') + } | ConvertTo-Json -Depth 5 + $release = Invoke-RestMethod -Method Post -Uri "$api/repos/$repo/releases" -Headers $headers -ContentType 'application/json' -Body $body + } + + foreach ($asset in @($zip, "$zip.sha256")) { + $existing = @($release.assets | Where-Object { $_.name -eq $asset }) + foreach ($item in $existing) { + Invoke-RestMethod -Method Delete -Uri "$api/repos/$repo/releases/assets/$($item.id)" -Headers $headers | Out-Null + } + $uploadUrl = "$api/repos/$repo/releases/$($release.id)/assets?name=$([uri]::EscapeDataString($asset))" + Invoke-RestMethod -Method Post -Uri $uploadUrl -Headers $headers -ContentType 'multipart/form-data' -Form @{ attachment = Get-Item $asset } | Out-Null + Write-Host "Uploaded release asset: $asset" + }