221 lines
9.7 KiB
PowerShell
221 lines
9.7 KiB
PowerShell
param([string]$ApkDir = "")
|
|
|
|
# Load .env.local
|
|
$envFile = Join-Path $PSScriptRoot ".env.local"
|
|
if (-not (Test-Path $envFile)) { Write-Error ".env.local not found"; exit 1 }
|
|
Get-Content $envFile | ForEach-Object {
|
|
$line = $_.Trim()
|
|
if ($line -and -not $line.StartsWith('#') -and $line.Contains('=')) {
|
|
$idx = $line.IndexOf('=')
|
|
$key = $line.Substring(0, $idx).Trim()
|
|
$val = $line.Substring($idx + 1).Trim()
|
|
[System.Environment]::SetEnvironmentVariable($key, $val)
|
|
}
|
|
}
|
|
|
|
$GITEA_TOKEN = $env:GITEA_TOKEN
|
|
$GITEA_BASE_URL = $env:GITEA_BASE_URL
|
|
$GITEA_OWNER = $env:GITEA_OWNER
|
|
$GITEA_REPO = $env:GITEA_REPO
|
|
|
|
if (-not $GITEA_TOKEN) { Write-Error "GITEA_TOKEN not set in .env.local"; exit 1 }
|
|
|
|
# Find latest APK build folder
|
|
if (-not $ApkDir) {
|
|
$root = Join-Path $PSScriptRoot "build\apk_releases"
|
|
if (-not (Test-Path $root)) { Write-Error "build\apk_releases not found"; exit 1 }
|
|
$ApkDir = Get-ChildItem $root -Directory |
|
|
Sort-Object Name -Descending |
|
|
Select-Object -First 1 -ExpandProperty FullName
|
|
}
|
|
if (-not (Test-Path $ApkDir)) { Write-Error "APK folder not found: $ApkDir"; exit 1 }
|
|
|
|
$apkFiles = Get-ChildItem $ApkDir -Filter "*.apk"
|
|
if ($apkFiles.Count -eq 0) { Write-Error "No APK files in: $ApkDir"; exit 1 }
|
|
|
|
# Read version from pubspec.yaml
|
|
$publine = Get-Content (Join-Path $PSScriptRoot "pubspec.yaml") | Where-Object { $_ -match "^version:" } | Select-Object -First 1
|
|
$version = if ($publine -match "version:\s*(\S+)") { $Matches[1].Split("+")[0] } else { "1.0.0" }
|
|
$buildNum = if ($publine -match "version:\s*[^+]+\+(\S+)") { $Matches[1] } else { "0" }
|
|
$dateStr = Get-Date -Format "yyyy-MM-dd"
|
|
$tagName = "v$version"
|
|
$relName = "Ponshu Room $version ($dateStr)"
|
|
|
|
# APKの埋め込みバージョンと pubspec.yaml が一致するか確認
|
|
Write-Host " Checking APK version matches pubspec ($version+$buildNum)..." -ForegroundColor Gray
|
|
$firstApk = $apkFiles | Select-Object -First 1
|
|
# aapt2 でバージョン確認(利用可能な場合)
|
|
$aapt2 = Get-ChildItem "$env:LOCALAPPDATA\Android\Sdk\build-tools" -Recurse -Filter "aapt2.exe" -ErrorAction SilentlyContinue | Sort-Object FullName -Descending | Select-Object -First 1 -ExpandProperty FullName
|
|
if ($aapt2) {
|
|
$apkDump = & $aapt2 dump badging $firstApk.FullName 2>$null | Select-String "versionName|versionCode"
|
|
$apkVersion = if ($apkDump -match "versionName='([^']+)'") { $Matches[1] } else { $null }
|
|
$apkBuild = if ($apkDump -match "versionCode='([^']+)'") { $Matches[1] } else { $null }
|
|
if ($apkVersion -and $apkVersion -ne $version) {
|
|
Write-Host ""
|
|
Write-Host " [ERROR] APK version mismatch!" -ForegroundColor Red
|
|
Write-Host " APK contains : $apkVersion (build $apkBuild)" -ForegroundColor Red
|
|
Write-Host " pubspec.yaml : $version+$buildNum" -ForegroundColor Red
|
|
Write-Host " -> Rebuild APKs after version bump, then retry." -ForegroundColor Yellow
|
|
exit 1
|
|
}
|
|
Write-Host " OK: APK version = $apkVersion (build $apkBuild)" -ForegroundColor Green
|
|
} else {
|
|
Write-Host " (aapt2 not found, skipping version check)" -ForegroundColor DarkGray
|
|
}
|
|
|
|
Write-Host "================================================" -ForegroundColor Cyan
|
|
Write-Host " Ponshu Room - Gitea Auto Release" -ForegroundColor Cyan
|
|
Write-Host "================================================" -ForegroundColor Cyan
|
|
Write-Host " Server : $GITEA_BASE_URL" -ForegroundColor Gray
|
|
Write-Host " Repo : $GITEA_OWNER/$GITEA_REPO" -ForegroundColor Gray
|
|
Write-Host " Tag : $tagName" -ForegroundColor Gray
|
|
Write-Host " APKs : $($apkFiles.Count) files" -ForegroundColor Gray
|
|
Write-Host ""
|
|
|
|
$authHeader = @{ "Authorization" = "token $GITEA_TOKEN" }
|
|
|
|
# Step 1: Delete existing release if found
|
|
Write-Host "[1/3] Checking existing release..." -ForegroundColor Yellow
|
|
try {
|
|
$existing = Invoke-RestMethod `
|
|
-Uri "$GITEA_BASE_URL/api/v1/repos/$GITEA_OWNER/$GITEA_REPO/releases/tags/$tagName" `
|
|
-Headers $authHeader -Method Get -ErrorAction Stop
|
|
Write-Host " Found existing (ID: $($existing.id)). Deleting..." -ForegroundColor Yellow
|
|
Invoke-RestMethod `
|
|
-Uri "$GITEA_BASE_URL/api/v1/repos/$GITEA_OWNER/$GITEA_REPO/releases/$($existing.id)" `
|
|
-Headers $authHeader -Method Delete | Out-Null
|
|
} catch {
|
|
Write-Host " No existing release. Creating new." -ForegroundColor Gray
|
|
}
|
|
|
|
# Step 2: Create release
|
|
Write-Host "[2/3] Creating release..." -ForegroundColor Yellow
|
|
|
|
$releaseNotes = @(
|
|
"## Ponshu Room $version ($dateStr)",
|
|
"",
|
|
"### APK Files",
|
|
"- ponshu_room_consumer_maita.apk : Maita",
|
|
"- ponshu_room_consumer_eiji.apk : Eiji",
|
|
"",
|
|
"### Install",
|
|
"1. Download the APK for your name",
|
|
"2. On Android: Settings > Security > Allow unknown sources",
|
|
"3. Tap the downloaded APK to install",
|
|
"",
|
|
"Requires Android 8.0+ (API 26+)"
|
|
) -join "`n"
|
|
|
|
$body = @{
|
|
tag_name = $tagName
|
|
name = $relName
|
|
body = $releaseNotes
|
|
draft = $false
|
|
prerelease = $false
|
|
} | ConvertTo-Json -Depth 3
|
|
|
|
$release = Invoke-RestMethod `
|
|
-Uri "$GITEA_BASE_URL/api/v1/repos/$GITEA_OWNER/$GITEA_REPO/releases" `
|
|
-Headers $authHeader `
|
|
-Method Post `
|
|
-ContentType "application/json" `
|
|
-Body $body
|
|
|
|
Write-Host " OK - Release ID: $($release.id)" -ForegroundColor Green
|
|
|
|
# Step 3: Upload APKs with multipart/form-data
|
|
Write-Host "[3/3] Uploading APK files..." -ForegroundColor Yellow
|
|
$downloadUrls = @{}
|
|
foreach ($apk in $apkFiles) {
|
|
$mb = [math]::Round($apk.Length / 1MB, 1)
|
|
Write-Host " Uploading: $($apk.Name) ($mb MB)..." -ForegroundColor Gray
|
|
|
|
$uploadUrl = "$GITEA_BASE_URL/api/v1/repos/$GITEA_OWNER/$GITEA_REPO/releases/$($release.id)/assets?name=$($apk.Name)"
|
|
|
|
# curl.exe (Windows 10+ 内蔵) を使用: WebClient より大容量ファイルに強く、
|
|
# --max-time で明示的なタイムアウト設定が可能
|
|
$curlOutput = curl.exe -s --max-time 900 `
|
|
-X POST $uploadUrl `
|
|
-H "Authorization: token $GITEA_TOKEN" `
|
|
-F "attachment=@$($apk.FullName);type=application/octet-stream"
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "curl upload failed (exit code $LASTEXITCODE)"
|
|
}
|
|
|
|
$json = $curlOutput | ConvertFrom-Json
|
|
$downloadUrls[$apk.BaseName] = $json.browser_download_url
|
|
Write-Host " OK: $($json.browser_download_url)" -ForegroundColor Green
|
|
}
|
|
|
|
# Step 4: Update releases.json for Vercel
|
|
Write-Host ""
|
|
Write-Host "[4/4] Updating releases.json..." -ForegroundColor Yellow
|
|
$tailscaleBase = "$GITEA_BASE_URL".Replace("http://100.76.7.3:3000", "https://posimai-lab.tail72e846.ts.net")
|
|
$maitaApk = $apkFiles | Where-Object { $_.Name -eq "ponshu_room_consumer_maita.apk" }
|
|
$eijiApk = $apkFiles | Where-Object { $_.Name -eq "ponshu_room_consumer_eiji.apk" }
|
|
$relJson = @{
|
|
version = $tagName
|
|
name = $relName
|
|
date = $dateStr
|
|
apks = @{
|
|
maita = @{
|
|
lite = @{ filename = "ponshu_room_consumer_maita.apk"; url = "$tailscaleBase/mai/ponshu-room-lite/releases/download/$tagName/ponshu_room_consumer_maita.apk"; size_mb = [math]::Round($maitaApk.Length / 1MB, 1) }
|
|
}
|
|
eiji = @{
|
|
lite = @{ filename = "ponshu_room_consumer_eiji.apk"; url = "$tailscaleBase/mai/ponshu-room-lite/releases/download/$tagName/ponshu_room_consumer_eiji.apk"; size_mb = [math]::Round($eijiApk.Length / 1MB, 1) }
|
|
}
|
|
}
|
|
} | ConvertTo-Json -Depth 5
|
|
|
|
$relJsonPath = Join-Path $PSScriptRoot "web\download\releases.json"
|
|
[System.IO.File]::WriteAllText($relJsonPath, $relJson, [System.Text.Encoding]::UTF8)
|
|
Write-Host " OK: releases.json updated" -ForegroundColor Green
|
|
|
|
# Step 5: Vercel redeploy
|
|
Write-Host ""
|
|
Write-Host "[5/5] Deploying to Vercel..." -ForegroundColor Yellow
|
|
$vercelDir = Join-Path $PSScriptRoot "web\download"
|
|
Push-Location $vercelDir
|
|
try {
|
|
# Vercel CLI が stderr に "Vercel CLI x.x.x" を書くため、ErrorRecord を文字列に変換して収集する
|
|
$prevEap = $ErrorActionPreference
|
|
$ErrorActionPreference = 'Continue'
|
|
$deployLines = vercel --prod --yes --no-color 2>&1 | ForEach-Object { $_.ToString() }
|
|
$ErrorActionPreference = $prevEap
|
|
|
|
$deployLines | ForEach-Object { Write-Host " $_" }
|
|
|
|
# ANSI エスケープコード(カーソル移動等)を除去してから Production: 行を抽出
|
|
$cleanLines = $deployLines | ForEach-Object { $_ -replace '\x1B\[[0-9;]*[A-Za-z]', '' -replace '\x1B\[[\?][0-9;]*[A-Za-z]', '' }
|
|
$prodLine = $cleanLines | Where-Object { $_ -match "(?i)Production:\s+https://" } | Select-Object -First 1
|
|
$prodUrl = $null
|
|
if ($prodLine -match 'https://\S+') {
|
|
$prodUrl = ($Matches[0] -replace '\s.*$', '').Trim()
|
|
}
|
|
|
|
if ($prodUrl) {
|
|
Write-Host " Setting alias ponshu-room.vercel.app -> $prodUrl ..." -ForegroundColor Gray
|
|
$prevEap2 = $ErrorActionPreference
|
|
$ErrorActionPreference = 'Continue'
|
|
vercel alias set $prodUrl ponshu-room.vercel.app 2>&1 | ForEach-Object { Write-Host " $_" }
|
|
$ErrorActionPreference = $prevEap2
|
|
Write-Host " OK: Alias set" -ForegroundColor Green
|
|
} else {
|
|
Write-Host " [WARN] Could not extract deployment URL. Run manually:" -ForegroundColor Yellow
|
|
Write-Host " vercel alias set <deployment-url> ponshu-room.vercel.app" -ForegroundColor Yellow
|
|
}
|
|
} catch {
|
|
Write-Host " Warning: Vercel deploy or alias failed: $_" -ForegroundColor Yellow
|
|
} finally {
|
|
Pop-Location
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host "================================================" -ForegroundColor Green
|
|
Write-Host " All done!" -ForegroundColor Green
|
|
Write-Host "================================================" -ForegroundColor Green
|
|
Write-Host " Gitea : $GITEA_BASE_URL/$GITEA_OWNER/$GITEA_REPO/releases/tag/$tagName"
|
|
Write-Host " Download : https://ponshu-room.vercel.app"
|
|
Write-Host ""
|