- WPF + WinRT BLE controller for ELK-BLEDOM compatible LED strips - Multi-device control, effects, grayscale and temperature modes - Velopack updates via Gitea Releases, Gitea Actions CI
142 lines
4.8 KiB
PowerShell
142 lines
4.8 KiB
PowerShell
[CmdletBinding(SupportsShouldProcess = $true)]
|
|
param(
|
|
[string]$Channel = "win-x64-stable",
|
|
[string]$GiteaRepoUrl = "https://git.fristy.net/fristy/rgb-led-strip-controller",
|
|
[string]$Tag = "",
|
|
[string]$Token = $env:VPK_TOKEN,
|
|
[string]$ExpectedTag = "",
|
|
[switch]$Prerelease,
|
|
[switch]$Merge
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
Set-StrictMode -Version Latest
|
|
|
|
$repoRoot = [System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot "..\.."))
|
|
|
|
if ([string]::IsNullOrWhiteSpace($Token)) {
|
|
throw "Gitea token is required. Pass -Token or set the VPK_TOKEN environment variable."
|
|
}
|
|
|
|
function Assert-WorkspacePath {
|
|
param([string]$Path)
|
|
|
|
$fullPath = [System.IO.Path]::GetFullPath($Path)
|
|
if (-not $fullPath.StartsWith($repoRoot, [System.StringComparison]::OrdinalIgnoreCase)) {
|
|
throw "Refusing to use path outside workspace: $fullPath"
|
|
}
|
|
|
|
return $fullPath
|
|
}
|
|
|
|
function Get-GiteaReleaseTagNames {
|
|
param(
|
|
[string]$RepoUrl,
|
|
[string]$AccessToken
|
|
)
|
|
|
|
$uri = [Uri]$RepoUrl
|
|
$segments = $uri.AbsolutePath.Trim("/").Split("/") | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }
|
|
if ($segments.Count -lt 2) {
|
|
throw "Could not parse owner/repo from GiteaRepoUrl: $RepoUrl"
|
|
}
|
|
|
|
$owner = $segments[-2]
|
|
$repo = $segments[-1]
|
|
$apiUrl = "{0}://{1}/api/v1/repos/{2}/{3}/releases?draft=false&limit=50" -f $uri.Scheme, $uri.Authority, $owner, $repo
|
|
|
|
try {
|
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
|
$headers = @{ Authorization = "token $AccessToken" }
|
|
$releases = Invoke-RestMethod -Uri $apiUrl -Method Get -Headers $headers -ErrorAction Stop
|
|
}
|
|
catch {
|
|
throw "Gitea releases could not be read: $apiUrl`n$($_.Exception.Message)"
|
|
}
|
|
|
|
return @($releases | ForEach-Object { $_.tag_name } | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })
|
|
}
|
|
|
|
$releaseDir = Assert-WorkspacePath (Join-Path $repoRoot "artifacts\velopack\$Channel")
|
|
$manifestPath = Join-Path $releaseDir "releases.$Channel.json"
|
|
|
|
if (-not (Test-Path -LiteralPath $releaseDir)) {
|
|
throw "Release directory not found: $releaseDir"
|
|
}
|
|
|
|
if (-not (Test-Path -LiteralPath $manifestPath)) {
|
|
throw "Release manifest not found: $manifestPath"
|
|
}
|
|
|
|
$localManifest = Get-Content -Raw -LiteralPath $manifestPath | ConvertFrom-Json
|
|
if ($null -eq $localManifest.Assets -or $localManifest.Assets.Count -eq 0) {
|
|
throw "Release manifest does not contain any assets: $manifestPath"
|
|
}
|
|
|
|
$packageId = $localManifest.Assets[0].PackageId
|
|
$localVersions = @(
|
|
$localManifest.Assets |
|
|
Where-Object { $_.PackageId -eq $packageId -and -not [string]::IsNullOrWhiteSpace($_.Version) } |
|
|
ForEach-Object { [Version]$_.Version }
|
|
)
|
|
if ($localVersions.Count -eq 0) {
|
|
throw "Could not determine local package version from: $manifestPath"
|
|
}
|
|
|
|
$localVersion = ($localVersions | Sort-Object -Descending | Select-Object -First 1)
|
|
$tag = if ([string]::IsNullOrWhiteSpace($Tag)) { "v$($localVersion.ToString())" } else { $Tag }
|
|
|
|
if (-not [string]::IsNullOrWhiteSpace($ExpectedTag) -and -not [string]::Equals($tag, $ExpectedTag, [System.StringComparison]::OrdinalIgnoreCase)) {
|
|
throw "Derived tag $tag does not match expected tag $ExpectedTag. Check the pushed tag against the project version."
|
|
}
|
|
|
|
$setupFiles = @(Get-ChildItem -LiteralPath $releaseDir -Filter "*-Setup.exe" -File)
|
|
$portableFiles = @(Get-ChildItem -LiteralPath $releaseDir -Filter "*-Portable.zip" -File)
|
|
if ($setupFiles.Count -eq 0) {
|
|
throw "No Setup.exe file found in release directory: $releaseDir"
|
|
}
|
|
|
|
if ($portableFiles.Count -eq 0) {
|
|
throw "No Portable.zip file found in release directory: $releaseDir"
|
|
}
|
|
|
|
$existingTags = Get-GiteaReleaseTagNames -RepoUrl $GiteaRepoUrl -AccessToken $Token
|
|
if ($existingTags -contains $tag -and -not $Merge.IsPresent) {
|
|
throw "Gitea already contains tag $tag. Upload is blocked (pass -Merge to merge into the existing release)."
|
|
}
|
|
|
|
$releaseUrl = $GiteaRepoUrl.TrimEnd("/") + "/releases/tag/" + $tag
|
|
$vpkArgs = @(
|
|
"tool", "run", "vpk", "--",
|
|
"upload", "gitea",
|
|
"--outputDir", $releaseDir,
|
|
"--channel", $Channel,
|
|
"--repoUrl", $GiteaRepoUrl,
|
|
"--token", $Token,
|
|
"--tag", $tag,
|
|
"--publish"
|
|
)
|
|
if ($Prerelease.IsPresent) {
|
|
$vpkArgs += "--pre"
|
|
}
|
|
|
|
if ($Merge.IsPresent) {
|
|
$vpkArgs += "--merge"
|
|
}
|
|
|
|
if ($PSCmdlet.ShouldProcess("$GiteaRepoUrl@$tag", "Upload Velopack release")) {
|
|
& "dotnet" @vpkArgs
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "vpk upload failed with exit code $LASTEXITCODE"
|
|
}
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host "Velopack feed upload complete." -ForegroundColor Green
|
|
Write-Host "Version: $($localVersion.ToString())"
|
|
Write-Host "Tag: $tag"
|
|
Write-Host "Channel: $Channel"
|
|
Write-Host "ReleaseDir: $releaseDir"
|
|
Write-Host "Release: $releaseUrl"
|
|
Write-Host "Prerelease: $(if ($Prerelease.IsPresent) { 'yes' } else { 'no' })"
|