Skip to content

TidyWindow

TidyWindow #38

name: Refresh release manifest
on:
release:
types: [published]
permissions:
contents: write
jobs:
update-manifest:
name: Update latest-release.json
runs-on: windows-latest
steps:
- name: Check out repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Update manifest with release metadata
shell: pwsh
env:
RELEASE_JSON: ${{ toJson(github.event.release) }}
INSTALLER_PATTERN: TidyWindow-Setup-*.exe
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
if (-not $env:RELEASE_JSON) {
throw "Release payload not available."
}
$release = $env:RELEASE_JSON | ConvertFrom-Json
if (-not $release) {
throw "Unable to parse release payload."
}
function Get-ReleaseFromApi {
param(
[Parameter(Mandatory = $true)]
[long] $Id,
[Parameter(Mandatory = $true)]
[string] $Repository
)
if (-not $env:GITHUB_TOKEN) {
return $null
}
$headers = @{
Authorization = "Bearer $env:GITHUB_TOKEN";
Accept = "application/vnd.github+json";
"User-Agent" = "github-actions"
}
$uri = "https://api.github.com/repos/$Repository/releases/$Id"
try {
return Invoke-RestMethod -Method Get -Uri $uri -Headers $headers -ErrorAction Stop
}
catch {
Write-Warning "Failed to refresh release metadata: $($_.Exception.Message)"
return $null
}
}
$repo = $env:GITHUB_REPOSITORY
if ([string]::IsNullOrWhiteSpace($repo)) {
throw "GITHUB_REPOSITORY was not provided."
}
$releaseId = $release.id
$maxAttempts = 40
$delaySeconds = 15
$asset = $null
for ($attempt = 1; $attempt -le $maxAttempts; $attempt++) {
$asset = $release.assets | Where-Object { $_.name -like $env:INSTALLER_PATTERN } | Select-Object -First 1
if ($asset) {
break
}
if ($attempt -lt $maxAttempts) {
Write-Host "Installer asset not yet available (attempt $attempt/$maxAttempts). Waiting $delaySeconds seconds before retrying..."
Start-Sleep -Seconds $delaySeconds
if ($attempt % 2 -eq 0) {
$refreshed = Get-ReleaseFromApi -Id $releaseId -Repository $repo
if ($refreshed) {
$release = $refreshed
}
}
}
}
if (-not $asset) {
$waited = $maxAttempts * $delaySeconds
throw "No asset matching pattern '$env:INSTALLER_PATTERN' was found after waiting $waited seconds."
}
$downloadPath = Join-Path $PWD $asset.name
Write-Host "Downloading release asset $($asset.name) ..."
try {
$response = Invoke-WebRequest -Uri $asset.browser_download_url -OutFile $downloadPath -PassThru -ErrorAction Stop
}
catch {
throw "Failed to download release asset: $($_.Exception.Message)"
}
if (-not $response.StatusCode -or $response.StatusCode -lt 200 -or $response.StatusCode -ge 300) {
throw "Asset download returned non-success status code: $($response.StatusCode)"
}
$installerFile = Get-Item $downloadPath
$hash = Get-FileHash $downloadPath -Algorithm SHA256
$summary = if ([string]::IsNullOrWhiteSpace($release.body)) {
"See release notes for details."
} else {
# Preserve the full body so clients can render complete notes; normalize newlines only.
($release.body.Trim() -replace "`r`n", "`n" -replace "`r", "`n")
}
function Get-NormalizedVersion([string]$tagName) {
if ([string]::IsNullOrWhiteSpace($tagName)) {
return "0.0.0"
}
$candidate = $tagName.Split('/')[-1]
$candidate = $candidate.TrimStart('v', 'V')
if ($candidate -match '(?<version>\d+(?:\.\d+){1,3})') {
return $Matches.version
}
return $candidate
}
$manifestPath = "data/catalog/latest-release.json"
$manifestDirectory = Split-Path $manifestPath -Parent
if (-not (Test-Path $manifestDirectory)) {
New-Item -ItemType Directory -Path $manifestDirectory -Force | Out-Null
}
$manifest = [ordered]@{
version = (Get-NormalizedVersion -tagName $release.tag_name)
channel = "stable"
summary = $summary
downloadUrl = $asset.browser_download_url
releaseNotesUrl = $release.html_url
publishedAt = $release.published_at
installerSizeBytes = $installerFile.Length
sha256 = $hash.Hash.ToLowerInvariant()
}
$manifestJson = $manifest | ConvertTo-Json -Depth 4
$manifestJson | Out-File -FilePath $manifestPath -Encoding utf8
Write-Host "Updated $manifestPath with:"
Write-Host $manifestJson
- name: Commit manifest update
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "chore: refresh release manifest"
file_pattern: data/catalog/latest-release.json
branch: ${{ github.event.release.target_commitish }}