155 lines
4.3 KiB
PowerShell
155 lines
4.3 KiB
PowerShell
# Upload myoffice-publish.tar.gz to a Gitea Release on the public repo.
|
|
# Usage:
|
|
# $env:GITEA_TOKEN = '<token>'
|
|
# .\proxmox\publish.ps1 -Tar
|
|
# .\proxmox\release.ps1 -GiteaUrl https://gitea.example.com -Owner org -Repo myoffice-public -Tag v1.2.3
|
|
#
|
|
# Token needs write:repository on the public repo.
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$GiteaUrl,
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Owner,
|
|
|
|
[string]$Repo = 'myoffice-public',
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Tag,
|
|
|
|
[string]$Token = $env:GITEA_TOKEN,
|
|
|
|
[string]$AssetPath = '',
|
|
|
|
[string]$Title = '',
|
|
|
|
[string]$Body = 'MyOffice published API + SPA (Proxmox CT artifact).',
|
|
|
|
[string]$Target = 'main'
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
if (-not $Token) {
|
|
throw 'GITEA_TOKEN (or -Token) is required.'
|
|
}
|
|
|
|
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
$repoRoot = Resolve-Path (Join-Path $scriptDir '..')
|
|
|
|
if (-not $AssetPath) {
|
|
$AssetPath = Join-Path $repoRoot 'myoffice-publish.tar.gz'
|
|
}
|
|
if (-not (Test-Path $AssetPath)) {
|
|
throw "Asset not found: $AssetPath — run .\proxmox\publish.ps1 -Tar first."
|
|
}
|
|
|
|
$GiteaUrl = $GiteaUrl.TrimEnd('/')
|
|
$api = "$GiteaUrl/api/v1"
|
|
$assetName = 'myoffice-publish.tar.gz'
|
|
if (-not $Title) { $Title = $Tag }
|
|
|
|
$headers = @{
|
|
Authorization = "token $Token"
|
|
Accept = 'application/json'
|
|
}
|
|
|
|
function Invoke-GiteaJson {
|
|
param(
|
|
[string]$Method,
|
|
[string]$Uri,
|
|
[object]$BodyObject = $null
|
|
)
|
|
$params = @{
|
|
Method = $Method
|
|
Uri = $Uri
|
|
Headers = $headers
|
|
}
|
|
if ($null -ne $BodyObject) {
|
|
$params.ContentType = 'application/json'
|
|
$params.Body = ($BodyObject | ConvertTo-Json -Depth 6)
|
|
}
|
|
return Invoke-RestMethod @params
|
|
}
|
|
|
|
Write-Host "-----------------------------------------------"
|
|
Write-Host "Gitea release $Owner/$Repo tag $Tag"
|
|
Write-Host "-----------------------------------------------"
|
|
|
|
$release = $null
|
|
try {
|
|
$release = Invoke-GiteaJson -Method GET -Uri "$api/repos/$Owner/$Repo/releases/tags/$Tag"
|
|
Write-Host "Release $Tag already exists (id $($release.id))."
|
|
}
|
|
catch {
|
|
Write-Host "Creating release $Tag..."
|
|
$release = Invoke-GiteaJson -Method POST -Uri "$api/repos/$Owner/$Repo/releases" -BodyObject @{
|
|
tag_name = $Tag
|
|
target_commitish = $Target
|
|
name = $Title
|
|
body = $Body
|
|
draft = $false
|
|
prerelease = $false
|
|
}
|
|
Write-Host "Created release id $($release.id)."
|
|
}
|
|
|
|
# Remove existing asset with the same name so re-upload works
|
|
$existing = @($release.assets) | Where-Object { $_.name -eq $assetName }
|
|
foreach ($a in $existing) {
|
|
Write-Host "Deleting existing asset id $($a.id) ($($a.name))..."
|
|
Invoke-GiteaJson -Method DELETE -Uri "$api/repos/$Owner/$Repo/releases/$($release.id)/assets/$($a.id)" | Out-Null
|
|
}
|
|
|
|
$uploadUrl = "$api/repos/$Owner/$Repo/releases/$($release.id)/assets?name=$assetName"
|
|
Write-Host "Uploading $AssetPath ..."
|
|
|
|
# Prefer curl multipart (reliable on Windows PowerShell 5 + 7)
|
|
$curl = Get-Command curl.exe -ErrorAction SilentlyContinue
|
|
if ($curl) {
|
|
$args = @(
|
|
'-fsS', '-X', 'POST',
|
|
'-H', "Authorization: token $Token",
|
|
'-F', "attachment=@$AssetPath",
|
|
$uploadUrl
|
|
)
|
|
& curl.exe @args
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "curl upload failed with exit code $LASTEXITCODE"
|
|
}
|
|
}
|
|
else {
|
|
# Fallback: .NET multipart
|
|
Add-Type -AssemblyName System.Net.Http
|
|
$handler = [System.Net.Http.HttpClientHandler]::new()
|
|
$client = [System.Net.Http.HttpClient]::new($handler)
|
|
$client.DefaultRequestHeaders.Add('Authorization', "token $Token")
|
|
$content = [System.Net.Http.MultipartFormDataContent]::new()
|
|
$fs = [System.IO.File]::OpenRead($AssetPath)
|
|
try {
|
|
$streamContent = [System.Net.Http.StreamContent]::new($fs)
|
|
$streamContent.Headers.ContentType = [System.Net.Http.Headers.MediaTypeHeaderValue]::Parse('application/octet-stream')
|
|
$content.Add($streamContent, 'attachment', $assetName)
|
|
$resp = $client.PostAsync($uploadUrl, $content).Result
|
|
if (-not $resp.IsSuccessStatusCode) {
|
|
$err = $resp.Content.ReadAsStringAsync().Result
|
|
throw "Upload failed: $($resp.StatusCode) $err"
|
|
}
|
|
}
|
|
finally {
|
|
$fs.Dispose()
|
|
$content.Dispose()
|
|
$client.Dispose()
|
|
}
|
|
}
|
|
|
|
$downloadUrl = "$GiteaUrl/$Owner/$Repo/releases/download/$Tag/$assetName"
|
|
Write-Host ""
|
|
Write-Host "Uploaded. Download URL:"
|
|
Write-Host " $downloadUrl"
|
|
Write-Host "Latest API:"
|
|
Write-Host " $api/repos/$Owner/$Repo/releases/latest"
|
|
Write-Host ""
|