feat: migrate all artifacts to SeaweedFS — single source of truth
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 3m59s

All build artifacts now upload to files.command.vigilcyber.com/wraith/:
- Installer: /wraith/{ver}/Wraith_{ver}_x64-setup.exe + /wraith/latest/
- MCP bridge: /wraith/{ver}/wraith-mcp-bridge.exe + /wraith/latest/
- Update bundle: /wraith/{ver}/*.nsis.zip
- Update manifest: /wraith/update.json (Tauri updater endpoint)
- Version metadata: /wraith/{ver}/version.json + /wraith/latest/

Removed: Gitea package uploads, Gitea release creation/attachment.
Updated: tauri.conf.json updater endpoint, bridge auto-download URL,
manual update checker download URL.

CI is now: build -> sign -> upload to SeaweedFS. Done.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Vantz Stockwell 2026-03-26 15:52:10 -04:00
parent 5d472a6e53
commit 037c76384b
4 changed files with 38 additions and 65 deletions

View File

@ -115,54 +115,60 @@ jobs:
} }
Remove-Item "$env:TEMP\aztoken.txt" -ErrorAction SilentlyContinue Remove-Item "$env:TEMP\aztoken.txt" -ErrorAction SilentlyContinue
- name: Upload to Gitea - name: Upload all artifacts to SeaweedFS
shell: powershell shell: powershell
run: | run: |
$ver = ("${{ github.ref_name }}" -replace '^v','') $ver = ("${{ github.ref_name }}" -replace '^v','')
$giteaUrl = "https://git.command.vigilcyber.com" $s3 = "https://files.command.vigilcyber.com/wraith"
$headers = @{ Authorization = "token ${{ secrets.GIT_TOKEN }}" }
# Upload installer
$installers = Get-ChildItem -Recurse src-tauri\target\release\bundle\nsis\*.exe
foreach ($file in $installers) {
Write-Host "Uploading: $($file.Name)"
Invoke-RestMethod -Uri "$s3/$ver/$($file.Name)" -Method PUT -ContentType "application/octet-stream" -InFile $file.FullName
# Also upload as 'latest' for direct download links
Invoke-RestMethod -Uri "$s3/latest/$($file.Name)" -Method PUT -ContentType "application/octet-stream" -InFile $file.FullName
}
# Upload MCP bridge binary # Upload MCP bridge binary
$bridge = "src-tauri\target\release\wraith-mcp-bridge.exe" $bridge = "src-tauri\target\release\wraith-mcp-bridge.exe"
if (Test-Path $bridge) { if (Test-Path $bridge) {
Write-Host "Uploading: wraith-mcp-bridge.exe" Write-Host "Uploading: wraith-mcp-bridge.exe"
Invoke-RestMethod -Uri "$giteaUrl/api/packages/vstockwell/generic/wraith/$ver/wraith-mcp-bridge.exe" -Method PUT -Headers $headers -ContentType "application/octet-stream" -InFile $bridge Invoke-RestMethod -Uri "$s3/$ver/wraith-mcp-bridge.exe" -Method PUT -ContentType "application/octet-stream" -InFile $bridge
Invoke-RestMethod -Uri "$s3/latest/wraith-mcp-bridge.exe" -Method PUT -ContentType "application/octet-stream" -InFile $bridge
} }
$installers = Get-ChildItem -Recurse src-tauri\target\release\bundle\nsis\*.exe # Upload .nsis.zip for Tauri auto-updater
foreach ($file in $installers) { $zipFile = Get-ChildItem -Recurse src-tauri\target\release\bundle\nsis\*.nsis.zip | Select-Object -First 1
$hash = (Get-FileHash $file.FullName -Algorithm SHA256).Hash.ToLower() if ($zipFile) {
@{ version = $ver; filename = $file.Name; sha256 = $hash; platform = "windows"; architecture = "amd64"; released = (Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ"); signed = $true } | ConvertTo-Json | Out-File version.json -Encoding utf8 Write-Host "Uploading: $($zipFile.Name)"
Invoke-RestMethod -Uri "$s3/$ver/$($zipFile.Name)" -Method PUT -ContentType "application/octet-stream" -InFile $zipFile.FullName
Write-Host "Uploading: $($file.Name)"
Invoke-RestMethod -Uri "$giteaUrl/api/packages/vstockwell/generic/wraith/$ver/$($file.Name)" -Method PUT -Headers $headers -ContentType "application/octet-stream" -InFile $file.FullName
Write-Host "Uploading: version.json"
Invoke-RestMethod -Uri "$giteaUrl/api/packages/vstockwell/generic/wraith/$ver/version.json" -Method PUT -Headers $headers -ContentType "application/octet-stream" -InFile version.json
} }
Write-Host "=== Upload complete ===" # Upload version.json metadata
$installer = $installers | Select-Object -First 1
if ($installer) {
$hash = (Get-FileHash $installer.FullName -Algorithm SHA256).Hash.ToLower()
@{ version = $ver; filename = $installer.Name; sha256 = $hash; platform = "windows"; architecture = "amd64"; released = (Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ"); signed = $true } | ConvertTo-Json | Out-File version.json -Encoding utf8
Invoke-RestMethod -Uri "$s3/$ver/version.json" -Method PUT -ContentType "application/json" -InFile version.json
Invoke-RestMethod -Uri "$s3/latest/version.json" -Method PUT -ContentType "application/json" -InFile version.json
}
Write-Host "=== SeaweedFS upload complete ==="
- name: Generate and upload update.json for Tauri updater - name: Generate and upload update.json for Tauri updater
shell: powershell shell: powershell
run: | run: |
$ver = ("${{ github.ref_name }}" -replace '^v','') $ver = ("${{ github.ref_name }}" -replace '^v','')
$giteaUrl = "https://git.command.vigilcyber.com" $s3 = "https://files.command.vigilcyber.com/wraith"
$headers = @{ Authorization = "token ${{ secrets.GIT_TOKEN }}" }
# Find the .sig file produced by Tauri signing
$sigFile = Get-ChildItem -Recurse src-tauri\target\release\bundle\nsis\*.nsis.zip.sig | Select-Object -First 1 $sigFile = Get-ChildItem -Recurse src-tauri\target\release\bundle\nsis\*.nsis.zip.sig | Select-Object -First 1
$zipFile = Get-ChildItem -Recurse src-tauri\target\release\bundle\nsis\*.nsis.zip | Select-Object -First 1 $zipFile = Get-ChildItem -Recurse src-tauri\target\release\bundle\nsis\*.nsis.zip | Select-Object -First 1
if ($sigFile -and $zipFile) { if ($sigFile -and $zipFile) {
$signature = Get-Content $sigFile.FullName -Raw $signature = Get-Content $sigFile.FullName -Raw
$downloadUrl = "$giteaUrl/api/packages/vstockwell/generic/wraith/$ver/$($zipFile.Name)" $downloadUrl = "$s3/$ver/$($zipFile.Name)"
# Upload the .nsis.zip to packages
Write-Host "Uploading: $($zipFile.Name)"
Invoke-RestMethod -Uri "$giteaUrl/api/packages/vstockwell/generic/wraith/$ver/$($zipFile.Name)" -Method PUT -Headers $headers -ContentType "application/octet-stream" -InFile $zipFile.FullName
# Build update.json
$updateJson = @{ $updateJson = @{
version = "v$ver" version = "v$ver"
notes = "Wraith Desktop v$ver" notes = "Wraith Desktop v$ver"
@ -179,44 +185,13 @@ jobs:
Write-Host "update.json content:" Write-Host "update.json content:"
Get-Content update.json Get-Content update.json
# Upload to latest/ so the updater endpoint always points to the newest # Upload to root (Tauri updater endpoint)
Invoke-RestMethod -Uri "$giteaUrl/api/packages/vstockwell/generic/wraith/latest/update.json" -Method PUT -Headers $headers -ContentType "application/octet-stream" -InFile update.json Invoke-RestMethod -Uri "$s3/update.json" -Method PUT -ContentType "application/json" -InFile update.json
# Also versioned copy
# Also upload to versioned path Invoke-RestMethod -Uri "$s3/$ver/update.json" -Method PUT -ContentType "application/json" -InFile update.json
Invoke-RestMethod -Uri "$giteaUrl/api/packages/vstockwell/generic/wraith/$ver/update.json" -Method PUT -Headers $headers -ContentType "application/octet-stream" -InFile update.json
Write-Host "=== Update manifest uploaded ===" Write-Host "=== Update manifest uploaded ==="
} else { } else {
Write-Host 'WARNING - No .sig file found, update signing may have failed' Write-Host 'WARNING - No .sig file found, update signing may have failed'
Write-Host 'Sig files found'
Get-ChildItem -Recurse src-tauri\target\release\bundle\nsis\*.sig
} }
- name: Create Release and attach installers
shell: powershell
run: |
$ver = ("${{ github.ref_name }}" -replace '^v','')
$giteaUrl = "https://git.command.vigilcyber.com"
$headers = @{ Authorization = "token ${{ secrets.GIT_TOKEN }}"; "Content-Type" = "application/json" }
$body = @{ tag_name = "v$ver"; name = "Wraith v$ver"; body = "Wraith Desktop v$ver - Tauri v2 / Rust build." } | ConvertTo-Json
$release = Invoke-RestMethod -Uri "$giteaUrl/api/v1/repos/vstockwell/wraith/releases" -Method POST -Headers $headers -Body $body
$releaseId = $release.id
Write-Host "Release v$ver created (id: $releaseId)"
$uploadHeaders = @{ Authorization = "token ${{ secrets.GIT_TOKEN }}" }
# Attach installer(s)
$installers = Get-ChildItem -Recurse src-tauri\target\release\bundle\nsis\*.exe
foreach ($file in $installers) {
Write-Host "Attaching $($file.Name) to release..."
Invoke-RestMethod -Uri "$giteaUrl/api/v1/repos/vstockwell/wraith/releases/$releaseId/assets?name=$($file.Name)" -Method POST -Headers $uploadHeaders -ContentType "application/octet-stream" -InFile $file.FullName
Write-Host "Attached: $($file.Name)"
}
# Attach MCP bridge binary
$bridge = "src-tauri\target\release\wraith-mcp-bridge.exe"
if (Test-Path $bridge) {
Write-Host "Attaching wraith-mcp-bridge.exe to release..."
Invoke-RestMethod -Uri "$giteaUrl/api/v1/repos/vstockwell/wraith/releases/$releaseId/assets?name=wraith-mcp-bridge.exe" -Method POST -Headers $uploadHeaders -ContentType "application/octet-stream" -InFile $bridge
Write-Host "Attached: wraith-mcp-bridge.exe"
}

View File

@ -48,10 +48,8 @@ pub async fn check_for_updates(app_handle: tauri::AppHandle) -> Result<UpdateInf
.unwrap_or("") .unwrap_or("")
.to_string(); .to_string();
let html_url = latest.get("html_url") // Direct download from SeaweedFS
.and_then(|v| v.as_str()) let html_url = format!("https://files.command.vigilcyber.com/wraith/{}/", tag);
.unwrap_or("https://git.command.vigilcyber.com/vstockwell/wraith/releases")
.to_string();
let update_available = version_is_newer(&tag, &current); let update_available = version_is_newer(&tag, &current);

View File

@ -40,7 +40,7 @@ pub async fn ensure_bridge(app_version: &str) -> Result<(), String> {
}; };
let url = format!( let url = format!(
"https://git.command.vigilcyber.com/api/packages/vstockwell/generic/wraith/{}/{}", "https://files.command.vigilcyber.com/wraith/{}/{}",
app_version, binary_name app_version, binary_name
); );

View File

@ -52,7 +52,7 @@
"updater": { "updater": {
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDNCRkQ2OUY2OEY0Q0ZFQkYKUldTLy9reVA5bW45T3dUQ1R5OFNCenVhL2srTXlLcHR4cFNaeCtJSmJUSTZKSUNHVTRIbWZwanEK", "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDNCRkQ2OUY2OEY0Q0ZFQkYKUldTLy9reVA5bW45T3dUQ1R5OFNCenVhL2srTXlLcHR4cFNaeCtJSmJUSTZKSUNHVTRIbWZwanEK",
"endpoints": [ "endpoints": [
"https://git.command.vigilcyber.com/api/packages/vstockwell/generic/wraith/latest/update.json" "https://files.command.vigilcyber.com/wraith/update.json"
] ]
} }
} }