From b225f38188ca5fe0a1ca5fab2627360214f20655 Mon Sep 17 00:00:00 2001 From: huanld Date: Thu, 25 Jun 2026 02:32:13 +0700 Subject: [PATCH] Add Gitea Windows release workflow --- .gitea/workflows/windows-release.yml | 198 +++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 .gitea/workflows/windows-release.yml diff --git a/.gitea/workflows/windows-release.yml b/.gitea/workflows/windows-release.yml new file mode 100644 index 0000000..b24d2cf --- /dev/null +++ b/.gitea/workflows/windows-release.yml @@ -0,0 +1,198 @@ +name: Windows Release + +on: + workflow_dispatch: + push: + tags: + - "v*" + +permissions: + contents: write + +jobs: + build-and-publish: + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install dependencies + run: npm ci + + - name: Build Windows setup + run: npm run build:win + + - name: Normalize release artifacts + id: artifacts + shell: pwsh + run: | + $version = node -p "require('./package.json').version" + $releaseDir = "release/$version" + $setupName = "Openscreen-Setup-$version.exe" + $blockmapName = "$setupName.blockmap" + $setupPath = Join-Path $releaseDir "Openscreen Setup $version.exe" + $blockmapPath = Join-Path $releaseDir "Openscreen Setup $version.exe.blockmap" + $normalizedSetupPath = Join-Path $releaseDir $setupName + $normalizedBlockmapPath = Join-Path $releaseDir $blockmapName + $latestPath = Join-Path $releaseDir "latest.yml" + + if (!(Test-Path -LiteralPath $setupPath)) { + throw "Missing Windows setup file: $setupPath" + } + if (!(Test-Path -LiteralPath $blockmapPath)) { + throw "Missing Windows setup blockmap: $blockmapPath" + } + if (!(Test-Path -LiteralPath $latestPath)) { + throw "Missing electron-builder metadata: $latestPath" + } + + Copy-Item -LiteralPath $setupPath -Destination $normalizedSetupPath -Force + Copy-Item -LiteralPath $blockmapPath -Destination $normalizedBlockmapPath -Force + + (Get-Content -LiteralPath $latestPath -Raw) ` + -replace "Openscreen Setup $version\.exe", $setupName | + Set-Content -LiteralPath $latestPath -Encoding utf8 + + $hash = Get-FileHash -LiteralPath $normalizedSetupPath -Algorithm SHA256 + $sha256Path = "$normalizedSetupPath.sha256" + "$($hash.Hash.ToLowerInvariant()) $setupName" | + Set-Content -LiteralPath $sha256Path -Encoding ascii + + "version=$version" >> $env:GITHUB_OUTPUT + "tag=v$version" >> $env:GITHUB_OUTPUT + "release_dir=$releaseDir" >> $env:GITHUB_OUTPUT + "setup_name=$setupName" >> $env:GITHUB_OUTPUT + "setup_path=$normalizedSetupPath" >> $env:GITHUB_OUTPUT + "blockmap_path=$normalizedBlockmapPath" >> $env:GITHUB_OUTPUT + "sha256_path=$sha256Path" >> $env:GITHUB_OUTPUT + "latest_path=$latestPath" >> $env:GITHUB_OUTPUT + + - name: Upload workflow artifact + uses: actions/upload-artifact@v4 + with: + name: openscreen-windows-${{ steps.artifacts.outputs.version }} + path: | + ${{ steps.artifacts.outputs.setup_path }} + ${{ steps.artifacts.outputs.blockmap_path }} + ${{ steps.artifacts.outputs.sha256_path }} + ${{ steps.artifacts.outputs.latest_path }} + retention-days: 30 + + - name: Ensure release tag exists + shell: pwsh + run: | + $tag = "${{ steps.artifacts.outputs.tag }}" + git config user.name "gitea-actions" + git config user.email "actions@gitea.local" + git fetch --tags + if (!(git tag --list $tag)) { + git tag -a $tag -m "Release $tag" + git push origin $tag + } + + - name: Publish Gitea release assets + shell: pwsh + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + run: | + if (!$env:GITEA_TOKEN) { + throw "Missing secrets.GITEA_TOKEN. Gitea Actions should provide this built-in token." + } + + $apiBase = "${{ github.server_url }}/api/v1" + $repo = "${{ github.repository }}" + $tag = "${{ steps.artifacts.outputs.tag }}" + $headers = @{ + Authorization = "token $env:GITEA_TOKEN" + Accept = "application/json" + } + + try { + $release = Invoke-RestMethod ` + -Method Get ` + -Uri "$apiBase/repos/$repo/releases/tags/$tag" ` + -Headers $headers + } catch { + $body = @{ + tag_name = $tag + target_commitish = "${{ github.sha }}" + name = $tag + body = "OpenScreen Windows setup $tag" + draft = $false + prerelease = $false + } | ConvertTo-Json + + $release = Invoke-RestMethod ` + -Method Post ` + -Uri "$apiBase/repos/$repo/releases" ` + -Headers $headers ` + -ContentType "application/json" ` + -Body $body + } + + $assets = @( + "${{ steps.artifacts.outputs.setup_path }}", + "${{ steps.artifacts.outputs.blockmap_path }}", + "${{ steps.artifacts.outputs.sha256_path }}", + "${{ steps.artifacts.outputs.latest_path }}" + ) + + foreach ($assetPath in $assets) { + $assetName = Split-Path -Leaf $assetPath + $existing = @($release.assets | Where-Object { $_.name -eq $assetName }) + foreach ($asset in $existing) { + Invoke-RestMethod ` + -Method Delete ` + -Uri "$apiBase/repos/$repo/releases/$($release.id)/assets/$($asset.id)" ` + -Headers $headers | Out-Null + } + + $uploadUri = "$apiBase/repos/$repo/releases/$($release.id)/assets?name=$([uri]::EscapeDataString($assetName))" + Invoke-RestMethod ` + -Method Post ` + -Uri $uploadUri ` + -Headers $headers ` + -Form @{ attachment = Get-Item -LiteralPath $assetPath } | Out-Null + } + + - name: Publish generic updater branch + shell: pwsh + run: | + $version = "${{ steps.artifacts.outputs.version }}" + $tag = "${{ steps.artifacts.outputs.tag }}" + $branch = "release-assets/$tag" + $releaseDir = "${{ steps.artifacts.outputs.release_dir }}" + $setupName = "${{ steps.artifacts.outputs.setup_name }}" + $blockmapName = "$setupName.blockmap" + $sha256Name = "$setupName.sha256" + + git config user.name "gitea-actions" + git config user.email "actions@gitea.local" + git checkout -B $branch + + Copy-Item -LiteralPath (Join-Path $releaseDir $setupName) -Destination $setupName -Force + Copy-Item -LiteralPath (Join-Path $releaseDir $blockmapName) -Destination $blockmapName -Force + Copy-Item -LiteralPath (Join-Path $releaseDir $sha256Name) -Destination $sha256Name -Force + Copy-Item -LiteralPath (Join-Path $releaseDir "latest.yml") -Destination "latest.yml" -Force + + git add latest.yml $setupName $blockmapName $sha256Name + if (git status --short) { + git commit -m "Publish $tag Windows release assets" + } else { + Write-Host "Release asset branch is already up to date." + } + git push origin $branch --force + git push origin "${branch}:release-assets/latest" --force