Initial commit: RGB LED Strip Controller v0.3.0
- 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
This commit is contained in:
40 files changed
+5411
No files matched your search
@@ -0,0 +1,141 @@
|
||||
[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' })"
|
||||
Reference in new issue
Block a user