param( [Parameter(Mandatory=$true)][string]$Server, [Parameter(Mandatory=$true)][string]$Owner, [Parameter(Mandatory=$true)][string]$Repo, [Parameter(Mandatory=$true)][string]$Token ) $ErrorActionPreference = 'Stop' $headers = @{ Authorization = "token $Token" } # Get latest release $latest = Invoke-RestMethod -Headers $headers -Method GET -Uri "$Server/api/v1/repos/$Owner/$Repo/releases/latest" if (-not $latest -or -not $latest.id) { throw "Failed to get latest release" } $rid = [string]$latest.id Write-Host "Operating on release id: $rid" # Load full release including attachments/assets list $release = Invoke-RestMethod -Headers $headers -Method GET -Uri "$Server/api/v1/repos/$Owner/$Repo/releases/$rid" $assets = $release.assets if (-not $assets) { $assets = $release.attachments } if ($assets) { $groups = $assets | Group-Object -Property name foreach ($g in $groups) { $sorted = $g.Group | Sort-Object -Property id -Descending if ($sorted.Count -gt 1) { $keep = $sorted[0] foreach ($extra in $sorted[1..($sorted.Count-1)]) { if ($null -ne $extra -and $extra.id -ne $keep.id) { $delUrl = "$Server/api/v1/repos/$Owner/$Repo/releases/assets/$($extra.id)" try { Invoke-RestMethod -Headers $headers -Method DELETE -Uri $delUrl | Out-Null Write-Host ("Deleted duplicate asset: " + $extra.name + " (id=" + $extra.id + ")") } catch { Write-Host ("Failed to delete asset id=" + $extra.id + ": " + $_.Exception.Message) -ForegroundColor Red } } } } } } else { Write-Host 'No assets found on release.' } # Compose release notes with known checksums if they exist locally $zipShaPath = (Resolve-Path 'dist\lib-privatebin-v0.1.1.3-windows-x64.zip.sha256' -ErrorAction SilentlyContinue) $dllShaPath = (Resolve-Path 'dist\windows_bin\privatebinapi.dll.sha256' -ErrorAction SilentlyContinue) $libShaPath = (Resolve-Path 'dist\windows_bin\privatebinapi.lib.sha256' -ErrorAction SilentlyContinue) $exeShaPath = (Resolve-Path 'dist\windows_bin\example.exe.sha256' -ErrorAction SilentlyContinue) $lines = @('# Downloadable artifacts', '') $lines += ("- [lib-privatebin-v0.1.1.3-windows-x64.zip]($Server/$Owner/$Repo/releases/download/$tag/lib-privatebin-v0.1.1.3-windows-x64.zip)") $lines += ("- [privatebinapi.dll]($Server/$Owner/$Repo/releases/download/$tag/privatebinapi.dll)") $lines += ("- [privatebinapi.lib]($Server/$Owner/$Repo/releases/download/$tag/privatebinapi.lib)") $lines += ("- [example.exe]($Server/$Owner/$Repo/releases/download/$tag/example.exe)") $lines += '' $lines += '# SHA256 checksums' if ($zipShaPath) { $lines += ("- [lib-privatebin-v0.1.1.3-windows-x64.zip.sha256]($Server/$Owner/$Repo/releases/download/$tag/lib-privatebin-v0.1.1.3-windows-x64.zip.sha256)") } if ($dllShaPath) { $lines += ("- [privatebinapi.dll.sha256]($Server/$Owner/$Repo/releases/download/$tag/privatebinapi.dll.sha256)") } if ($libShaPath) { $lines += ("- [privatebinapi.lib.sha256]($Server/$Owner/$Repo/releases/download/$tag/privatebinapi.lib.sha256)") } if ($exeShaPath) { $lines += ("- [example.exe.sha256]($Server/$Owner/$Repo/releases/download/$tag/example.exe.sha256)") } $lines += '' $lines += '# Changes' try { $changelog = Get-Content -Raw -LiteralPath 'CHANGELOG.md' $sections = $changelog -split "\r?\n## " $section = $sections | Where-Object { $_ -like 'v0.1.1.3*' } | Select-Object -First 1 if ($section) { $secLines = $section -split "\r?\n" if ($secLines[0] -like 'v0.1.1.3*') { $secLines[0] = 'v0.1.1.3' } $lines += $secLines } else { $lines += 'See CHANGELOG.md' } } catch { $lines += 'See CHANGELOG.md' } $bodyText = ($lines -join "`n") $payload = @{ body = $bodyText } | ConvertTo-Json -Depth 3 Invoke-RestMethod -Headers (@{ Authorization = ("token " + $Token); 'Content-Type' = 'application/json' }) -Method PATCH -Uri "$Server/api/v1/repos/$Owner/$Repo/releases/$rid" -Body $payload | Out-Null Write-Host 'Release notes updated.'