사이트 인터랙티브 워크스테이션 확장 + 감사 폴리시 재적용 + 원클릭 릴리스 도구 — 병행 세션 확장분(히어로 3탭 워크스테이션 시뮬레이터, 비교 섹션(기존 방식 vs MEDIABROWSER), 가이드 단축키 섹션(kbd), 스포트라이트 카드, build/release.ps1 원클릭 릴리스(-Publish/-DeploySite), build-remote.ps1 PowerShell 원격 빌드, upload-release-asset.ps1 로컬 실행 지원(.env 자동 로드·-Publish 승격·-Repo), fetch-releases.mjs 인증·폴백)을 수용하고, 덮여 사라진 감사 폴리시를 새 베이스에 재적용: 타이틀 em대시 제거+OG 메타(index/guide), 아이브로우 6→1(장식 점 제거), 히어로 2줄 헤드라인·20단어 서브·CTA 라벨 단일화·신뢰 스트립 제거, 파이프라인 3분리 카드→단일 머신드 레일 재구성, 과장 카피 완화(100%·1초·초고속·완벽), 시뮬레이터 예시 캡션, skip-link·focus-visible·hero__grid min-width:0(모바일 오버플로) 재적용 — 데스크톱/모바일 검증(scrollWidth 375==375, 아이브로우 1, 레일·캡션·탭 3종 확인), deploy-site.ps1 로 재배포 완료
This commit is contained in:
parent
9c9d9cb024
commit
f13914534a
11 changed files with 976 additions and 246 deletions
|
|
@ -1,35 +1,100 @@
|
|||
# Forgejo 릴리스(draft)에 산출물을 업로드한다. 릴리스가 없으면 만들고, 동명 자산은 교체한다(재실행 멱등).
|
||||
# 사용: ./build/ci/upload-release-asset.ps1 -Tag v1.0.0 -Files out/a.exe, out/b.exe
|
||||
# 필요 환경: RELEASE_TOKEN + (Actions 기본 제공) GITHUB_SERVER_URL, GITHUB_REPOSITORY
|
||||
# RELEASE_REPO 를 주면 해당 저장소로 업로드(공개 배포 저장소용), 없으면 현재 저장소
|
||||
# RELEASE_PRERELEASE=true 면 prerelease 로 생성(리허설용)
|
||||
# Forgejo 릴리스에 산출물을 업로드한다. 릴리스가 없으면 만들고, 동명 자산은 교체한다(재실행 멱등).
|
||||
# 사용: ./build/ci/upload-release-asset.ps1 -Tag v1.0.0 -Files out/a.exe, out/b.exe [-Publish]
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$Tag,
|
||||
[Parameter(Mandatory)][string[]]$Files
|
||||
[Parameter(Mandatory)][string[]]$Files,
|
||||
[switch]$Publish,
|
||||
[string]$Notes = "",
|
||||
[string]$Repo = ""
|
||||
)
|
||||
$ErrorActionPreference = 'Stop'
|
||||
if (-not $env:RELEASE_TOKEN) { throw "RELEASE_TOKEN 환경변수가 없습니다" }
|
||||
$repo = if ($env:RELEASE_REPO) { $env:RELEASE_REPO } else { $env:GITHUB_REPOSITORY }
|
||||
$api = "$($env:GITHUB_SERVER_URL.TrimEnd('/'))/api/v1/repos/$repo"
|
||||
$hdr = @{ Authorization = "token $env:RELEASE_TOKEN" }
|
||||
|
||||
# .env 자동 로드 (로컬 실행 시)
|
||||
$root = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
|
||||
$envFile = Join-Path $root ".env"
|
||||
if (Test-Path $envFile) {
|
||||
foreach ($line in Get-Content $envFile) {
|
||||
if ($line -match '^\s*([A-Za-z0-9_]+)\s*=\s*(.+)$') {
|
||||
$k = $Matches[1]; $v = $Matches[2].Trim()
|
||||
if (-not (Get-Item "env:$k" -ErrorAction SilentlyContinue)) {
|
||||
Set-Item "env:$k" $v
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$token = if ($env:RELEASE_TOKEN) { $env:RELEASE_TOKEN } else { $env:FORGEJO_TOKEN }
|
||||
$hdr = @{}
|
||||
|
||||
if ($token) {
|
||||
$hdr["Authorization"] = "token $token"
|
||||
} elseif ($env:FORGEJO_USER -and $env:FORGEJO_PASSWORD) {
|
||||
$bytes = [System.Text.Encoding]::UTF8.GetBytes("$($env:FORGEJO_USER):$($env:FORGEJO_PASSWORD)")
|
||||
$b64 = [Convert]::ToBase64String($bytes)
|
||||
$hdr["Authorization"] = "Basic $b64"
|
||||
} else {
|
||||
throw ".env 에 FORGEJO_TOKEN 또는 FORGEJO_USER/PASSWORD 가 없습니다."
|
||||
}
|
||||
|
||||
$serverUrl = if ($env:GITHUB_SERVER_URL) { $env:GITHUB_SERVER_URL }
|
||||
elseif ($env:FORGEJO_URL) { $env:FORGEJO_URL }
|
||||
else { "https://git.chanpaca.net" }
|
||||
$serverUrl = $serverUrl.TrimEnd('/')
|
||||
|
||||
$targetRepo = if ($Repo) { $Repo }
|
||||
elseif ($env:RELEASE_REPO) { $env:RELEASE_REPO }
|
||||
elseif ($env:GITHUB_REPOSITORY) { $env:GITHUB_REPOSITORY }
|
||||
else { "Video-Downloader/releases" }
|
||||
|
||||
$api = "$serverUrl/api/v1/repos/$targetRepo"
|
||||
|
||||
$isDraft = -not $Publish
|
||||
$isPrerelease = ($env:RELEASE_PRERELEASE -eq 'true')
|
||||
|
||||
# draft 릴리스는 tags/<tag> 단건 조회에 안 잡힐 수 있어 목록에서 tag_name 으로 찾는다
|
||||
function Find-Release {
|
||||
(Invoke-RestMethod -Uri "$api/releases?limit=50" -Headers $hdr) |
|
||||
Where-Object tag_name -eq $Tag | Select-Object -First 1
|
||||
try {
|
||||
(Invoke-RestMethod -Uri "$api/releases?limit=50" -Headers $hdr) |
|
||||
Where-Object tag_name -eq $Tag | Select-Object -First 1
|
||||
} catch {
|
||||
return $null
|
||||
}
|
||||
}
|
||||
|
||||
$rel = Find-Release
|
||||
if (-not $rel) {
|
||||
$body = @{ tag_name = $Tag; name = $Tag; draft = $true
|
||||
prerelease = ($env:RELEASE_PRERELEASE -eq 'true') } | ConvertTo-Json
|
||||
try { $rel = Invoke-RestMethod -Method Post -Uri "$api/releases" -Headers $hdr -ContentType 'application/json' -Body $body }
|
||||
catch { $rel = Find-Release } # 병렬 잡 동시 생성 경합 대비
|
||||
$bodyObj = @{
|
||||
tag_name = $Tag
|
||||
name = $Tag
|
||||
draft = $isDraft
|
||||
prerelease = $isPrerelease
|
||||
}
|
||||
if ($Notes) { $bodyObj["body"] = $Notes }
|
||||
$body = $bodyObj | ConvertTo-Json
|
||||
|
||||
try {
|
||||
$rel = Invoke-RestMethod -Method Post -Uri "$api/releases" -Headers $hdr -ContentType 'application/json' -Body $body
|
||||
} catch {
|
||||
$rel = Find-Release # 병렬 잡 동시 생성 경합 대비
|
||||
}
|
||||
} else {
|
||||
# 기존 릴리스가 있고 Publish 옵션이 주어졌는데 현재 draft 상태인 경우 Publish로 갱신
|
||||
if ($Publish -and $rel.draft) {
|
||||
$patchBody = @{ draft = $false } | ConvertTo-Json
|
||||
$rel = Invoke-RestMethod -Method Patch -Uri "$api/releases/$($rel.id)" -Headers $hdr -ContentType 'application/json' -Body $patchBody
|
||||
Write-Host "릴리스를 정식 공개(Published) 상태로 전환했습니다." -ForegroundColor Green
|
||||
}
|
||||
}
|
||||
if (-not $rel) { throw "릴리스 확보 실패: $Tag" }
|
||||
Write-Host "릴리스 #$($rel.id) ($Tag)"
|
||||
|
||||
if (-not $rel) { throw "릴리스 확보 실패: $Tag (저장소: $targetRepo)" }
|
||||
$statusStr = if ($rel.draft) { "Draft" } else { "Published" }
|
||||
Write-Host "릴리스 #$($rel.id) ($Tag, 상태: $statusStr, 저장소: $targetRepo)" -ForegroundColor Cyan
|
||||
|
||||
foreach ($f in $Files) {
|
||||
if (-not (Test-Path $f)) {
|
||||
Write-Warning "파일이 존재하지 않아 건너뜁니다: $f"
|
||||
continue
|
||||
}
|
||||
$item = Get-Item $f
|
||||
(Invoke-RestMethod -Uri "$api/releases/$($rel.id)/assets" -Headers $hdr) |
|
||||
Where-Object name -eq $item.Name | ForEach-Object {
|
||||
|
|
@ -37,5 +102,5 @@ foreach ($f in $Files) {
|
|||
}
|
||||
Invoke-RestMethod -Method Post -Uri "$api/releases/$($rel.id)/assets?name=$($item.Name)" `
|
||||
-Headers $hdr -Form @{ attachment = $item } | Out-Null
|
||||
Write-Host ("업로드 완료: {0} ({1:N1} MB)" -f $item.Name, ($item.Length / 1MB))
|
||||
Write-Host ("업로드 완료: {0} ({1:N1} MB)" -f $item.Name, ($item.Length / 1MB)) -ForegroundColor Green
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,8 +11,9 @@ $root = Split-Path -Parent $PSScriptRoot
|
|||
$envFile = Join-Path $root ".env"
|
||||
if (-not (Test-Path $envFile)) { throw ".env 가 없습니다. .env.example 을 복사해 채우세요." }
|
||||
foreach ($line in Get-Content $envFile) {
|
||||
if ($line -match '^\s*(CLOUDFLARE_API_TOKEN|CLOUDFLARE_ACCOUNT_ID)\s*=\s*(.+)$') {
|
||||
Set-Item "env:$($Matches[1])" $Matches[2].Trim()
|
||||
if ($line -match '^\s*([A-Za-z0-9_]+)\s*=\s*(.+)$') {
|
||||
$k = $Matches[1]; $v = $Matches[2].Trim()
|
||||
Set-Item "env:$k" $v
|
||||
}
|
||||
}
|
||||
if (-not $env:CLOUDFLARE_API_TOKEN) { throw ".env 에 CLOUDFLARE_API_TOKEN 이 없습니다." }
|
||||
|
|
@ -26,4 +27,4 @@ Write-Host "2) Cloudflare Pages 배포 ($Project)" -ForegroundColor Cyan
|
|||
npx wrangler pages deploy (Join-Path $root "site") --project-name $Project --branch main --commit-dirty=true
|
||||
if ($LASTEXITCODE -ne 0) { throw "wrangler 배포 실패" }
|
||||
|
||||
Write-Host "완료: https://$Project.pages.dev" -ForegroundColor Green
|
||||
Write-Host "완료: https://$Project-7r4.pages.dev (또는 대시보드 지정 도메인)" -ForegroundColor Green
|
||||
|
|
|
|||
142
build/release.ps1
Normal file
142
build/release.ps1
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
# MediaBrowser 원클릭 통합 릴리스 & 사이트 배포 스크립트
|
||||
#
|
||||
# 동작:
|
||||
# 1) Windows 설치자(x64, arm64) 빌드 (+ 선택: Android APK, 원격 Linux/macOS 머신 빌드)
|
||||
# 2) NAS Git(Forgejo)의 공개 릴리스 저장소(Video-Downloader/releases)에 릴리스 생성 및 자산 업로드
|
||||
# 3) (선택: -DeploySite) releases.json 갱신 및 Cloudflare Pages 배포
|
||||
#
|
||||
# 사용 예시:
|
||||
# ./build/release.ps1 -Version 1.0.0 -Publish -DeploySite
|
||||
# ./build/release.ps1 -Version 1.0.0-preview -Prerelease
|
||||
# ./build/release.ps1 -Version 1.0.0 -SkipBuild -Publish -DeploySite
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][string]$Version,
|
||||
[string]$Config = "Release",
|
||||
[switch]$Publish,
|
||||
[switch]$Prerelease,
|
||||
[switch]$SkipBuild,
|
||||
[switch]$IncludeAndroid,
|
||||
[switch]$IncludeRemote,
|
||||
[switch]$DeploySite,
|
||||
[string]$Notes = "",
|
||||
[string]$Repo = "Video-Downloader/releases"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$root = Split-Path -Parent $PSScriptRoot
|
||||
$outDir = Join-Path $root "out"
|
||||
|
||||
Write-Host "======================================================" -ForegroundColor Cyan
|
||||
Write-Host " MediaBrowser 릴리스 파이프라인 (v$Version)" -ForegroundColor Cyan
|
||||
Write-Host "======================================================" -ForegroundColor Cyan
|
||||
|
||||
# ── 1. .env 환경변수 로드 ────────────────────────────────────
|
||||
$envFile = Join-Path $root ".env"
|
||||
if (Test-Path $envFile) {
|
||||
foreach ($line in Get-Content $envFile) {
|
||||
if ($line -match '^\s*([A-Za-z0-9_]+)\s*=\s*(.+)$') {
|
||||
$k = $Matches[1]; $v = $Matches[2].Trim()
|
||||
if (-not (Get-Item "env:$k" -ErrorAction SilentlyContinue)) {
|
||||
Set-Item "env:$k" $v
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$hasAuth = ($env:RELEASE_TOKEN) -or ($env:FORGEJO_TOKEN) -or ($env:FORGEJO_USER -and $env:FORGEJO_PASSWORD)
|
||||
if (-not $hasAuth) {
|
||||
throw ".env 에 FORGEJO_TOKEN 또는 FORGEJO_USER/PASSWORD 가 없습니다. Forgejo 인증을 설정하세요."
|
||||
}
|
||||
|
||||
# ── 2. 아티팩트 빌드 ─────────────────────────────────────────
|
||||
if (-not $SkipBuild) {
|
||||
Write-Host "`n[1/4] Windows 설치자 빌드 (x64, arm64)" -ForegroundColor Yellow
|
||||
& (Join-Path $PSScriptRoot "publish.ps1") -Config $Config -Version $Version
|
||||
if ($LASTEXITCODE -ne 0) { throw "Windows 설치자 빌드 실패" }
|
||||
|
||||
if ($IncludeAndroid) {
|
||||
Write-Host "`n[2/4] Android APK 빌드" -ForegroundColor Yellow
|
||||
$mobileCsproj = Join-Path $root "VideoDownloader.Mobile\VideoDownloader.Mobile.csproj"
|
||||
$androidOut = Join-Path $outDir "android"
|
||||
dotnet publish $mobileCsproj -f net10.0-android -c $Config -p:AndroidPackageFormat=apk -p:CiPackArm64Only=true -o $androidOut
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
$apk = Get-ChildItem (Join-Path $androidOut "*.apk") | Select-Object -First 1
|
||||
if ($apk) {
|
||||
$targetApk = Join-Path $outDir "MediaBrowser-$Version-arm64.apk"
|
||||
Copy-Item $apk.FullName $targetApk -Force
|
||||
Write-Host "Android APK 생성 완료: $targetApk" -ForegroundColor Green
|
||||
}
|
||||
} else {
|
||||
Write-Warning "Android 빌드 실패 (워크로드 미설치 시 건너뜁니다)"
|
||||
}
|
||||
}
|
||||
|
||||
if ($IncludeRemote) {
|
||||
Write-Host "`n[3/4] Linux / macOS 원격 빌드머신 빌드" -ForegroundColor Yellow
|
||||
$remoteScript = Join-Path $PSScriptRoot "remote\build-remote.sh"
|
||||
if (Get-Command bash -ErrorAction SilentlyContinue) {
|
||||
bash $remoteScript all
|
||||
} else {
|
||||
Write-Warning "bash 명령어를 찾을 수 없어 원격 빌드를 건너뜁니다."
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Host "`n[빌드 건너뜀 (-SkipBuild)]" -ForegroundColor DarkGray
|
||||
}
|
||||
|
||||
# ── 3. 수집된 자산 목록 확인 ──────────────────────────────────
|
||||
$assetsToUpload = @()
|
||||
$candPatterns = @(
|
||||
"MediaBrowser-Setup-*.exe",
|
||||
"MediaBrowser-*-arm64.apk",
|
||||
"mediabrowser-*.tar.gz"
|
||||
)
|
||||
|
||||
foreach ($pat in $candPatterns) {
|
||||
Get-ChildItem -Path $outDir -Filter $pat -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
$assetsToUpload += $_.FullName
|
||||
}
|
||||
}
|
||||
|
||||
if ($assetsToUpload.Count -eq 0) {
|
||||
throw "업로드할 릴리스 산출물이 out/ 디렉토리에 없습니다."
|
||||
}
|
||||
|
||||
Write-Host "`n업로드 대상 자산 ($($assetsToUpload.Count)개):" -ForegroundColor Cyan
|
||||
foreach ($a in $assetsToUpload) {
|
||||
$f = Get-Item $a
|
||||
Write-Host (" - {0,-35} ({1:N1} MB)" -f $f.Name, ($f.Length / 1MB))
|
||||
}
|
||||
|
||||
# ── 4. NAS Git (Forgejo) 릴리스 등록 및 업로드 ────────────────
|
||||
Write-Host "`n[4/4] NAS Git (Forgejo) 릴리스 업로드 ($Repo)" -ForegroundColor Yellow
|
||||
$tag = "v$Version"
|
||||
$uploadScript = Join-Path $PSScriptRoot "ci\upload-release-asset.ps1"
|
||||
|
||||
$uploadArgs = @{
|
||||
Tag = $tag
|
||||
Files = $assetsToUpload
|
||||
Repo = $Repo
|
||||
}
|
||||
if ($Publish) { $uploadArgs["Publish"] = $true }
|
||||
if ($Notes) { $uploadArgs["Notes"] = $Notes }
|
||||
|
||||
$global:LASTEXITCODE = 0
|
||||
& $uploadScript @uploadArgs
|
||||
|
||||
# ── 5. 사이트 배포 (옵션) ────────────────────────────────────
|
||||
if ($DeploySite) {
|
||||
Write-Host "`n[추가] Cloudflare Pages 사이트 배포" -ForegroundColor Yellow
|
||||
$global:LASTEXITCODE = 0
|
||||
& (Join-Path $PSScriptRoot "deploy-site.ps1")
|
||||
}
|
||||
|
||||
Write-Host "`n======================================================" -ForegroundColor Green
|
||||
Write-Host " 릴리스 완료: $tag" -ForegroundColor Green
|
||||
if ($Publish) {
|
||||
Write-Host " 상태: 정식 공개(Published)" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host " 상태: 초안(Draft) — 웹 UI(https://git.chanpaca.net/$Repo/releases)에서 확인 후 공개 가능" -ForegroundColor Yellow
|
||||
}
|
||||
Write-Host "======================================================" -ForegroundColor Green
|
||||
66
build/remote/build-remote.ps1
Normal file
66
build/remote/build-remote.ps1
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# MediaBrowser 원격 빌드 수집 스크립트 (PowerShell)
|
||||
# 빌드머신(vd-linux / vd-mac)에서 Cli + Avalonia 셸을 RID별 self-contained publish 하고
|
||||
# 산출물을 out/mediabrowser-<rid>.tar.gz 로 수집한다.
|
||||
#
|
||||
# 사용: ./build/remote/build-remote.ps1 [-Target mac|linux|all]
|
||||
param(
|
||||
[ValidateSet("mac", "linux", "all")]
|
||||
[string]$Target = "all"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$root = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
|
||||
$outDir = Join-Path $root "out"
|
||||
New-Item -ItemType Directory -Path $outDir -Force | Out-Null
|
||||
|
||||
$remoteDir = "build/videodownloader"
|
||||
|
||||
function Push-Source {
|
||||
param([string]$HostName)
|
||||
Write-Host "==> [$HostName] 소스 코드 아카이브 전송" -ForegroundColor Cyan
|
||||
$tempTar = Join-Path $outDir "source_sync.tar"
|
||||
if (Test-Path $tempTar) { Remove-Item $tempTar -Force }
|
||||
|
||||
# git archive 생성
|
||||
git archive --format=tar -o $tempTar HEAD
|
||||
if ($LASTEXITCODE -ne 0) { throw "git archive 생성 실패" }
|
||||
|
||||
# 원격 폴더 초기화 및 tar 전송/풀기
|
||||
& ssh.exe $HostName "rm -rf $remoteDir && mkdir -p $remoteDir"
|
||||
& scp.exe $tempTar "${HostName}:${remoteDir}/source_sync.tar"
|
||||
& ssh.exe $HostName "tar -xf $remoteDir/source_sync.tar -C $remoteDir && rm -f $remoteDir/source_sync.tar"
|
||||
Remove-Item $tempTar -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
function Build-And-Collect {
|
||||
param([string]$HostName, [string]$Rid)
|
||||
Write-Host "==> [$HostName] publish $Rid" -ForegroundColor Cyan
|
||||
$cmd = "cd $remoteDir && export DOTNET_ROOT=`$HOME/.dotnet && export PATH=`$HOME/.dotnet:`$PATH && " +
|
||||
"dotnet publish VideoDownloader.Cli -c Release -r $Rid --self-contained -o out/cli-$Rid && " +
|
||||
"dotnet publish VideoDownloader.Avalonia -c Release -r $Rid --self-contained -o out/avalonia-$Rid && " +
|
||||
"cd out && tar -czf mediabrowser-$Rid.tar.gz cli-$Rid avalonia-$Rid"
|
||||
|
||||
& ssh.exe $HostName $cmd
|
||||
if ($LASTEXITCODE -ne 0) { throw "[$HostName] 빌드 실패: $Rid" }
|
||||
|
||||
$localTarget = Join-Path $outDir "mediabrowser-$Rid.tar.gz"
|
||||
Write-Host "==> [$HostName] 수집: mediabrowser-$Rid.tar.gz" -ForegroundColor Green
|
||||
& scp.exe "${HostName}:${remoteDir}/out/mediabrowser-$Rid.tar.gz" $localTarget
|
||||
if ($LASTEXITCODE -ne 0) { throw "[$HostName] 산출물 수집 실패: $Rid" }
|
||||
}
|
||||
|
||||
if ($Target -eq "mac" -or $Target -eq "all") {
|
||||
Push-Source "vd-mac"
|
||||
Build-And-Collect "vd-mac" "osx-arm64"
|
||||
Build-And-Collect "vd-mac" "osx-x64"
|
||||
}
|
||||
|
||||
if ($Target -eq "linux" -or $Target -eq "all") {
|
||||
Push-Source "vd-linux"
|
||||
Build-And-Collect "vd-linux" "linux-x64"
|
||||
Build-And-Collect "vd-linux" "linux-arm64"
|
||||
}
|
||||
|
||||
Write-Host "`n원격 빌드 및 수집 완료:" -ForegroundColor Green
|
||||
Get-ChildItem (Join-Path $outDir "mediabrowser-*.tar.gz") |
|
||||
ForEach-Object { Write-Host (" {0,-35} {1:N1} MB" -f $_.Name, ($_.Length / 1MB)) }
|
||||
|
|
@ -1,43 +1,46 @@
|
|||
#!/usr/bin/env bash
|
||||
# 빌드머신(ChanpacaLaptop=linux-x64 / Mac mini=osx-arm64)에서
|
||||
# git HEAD 소스를 전송해 Cli + Avalonia 셸을 RID별 self-contained publish 하고
|
||||
# 산출물을 로컬 out/remote/<rid>/ 로 수집한다.
|
||||
# 빌드머신(ChanpacaLaptop=linux / Mac mini=macos)에서
|
||||
# Cli + Avalonia 셸을 RID별 self-contained publish 하고
|
||||
# 산출물을 로컬 out/mediabrowser-<rid>.tar.gz 로 수집한다.
|
||||
#
|
||||
# 사용 (Windows Git Bash): bash build/remote/build-remote.sh [linux|mac|all]
|
||||
# 사전 조건: ssh 별칭 vd-linux / vd-mac (키 인증), 각 머신 ~/.dotnet SDK 8
|
||||
# 사용: bash build/remote/build-remote.sh [linux|mac|all]
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/../.."
|
||||
|
||||
TARGET="${1:-all}"
|
||||
REMOTE_DIR="build/videodownloader"
|
||||
|
||||
mkdir -p out
|
||||
|
||||
push_src() { # $1 = ssh 대상
|
||||
echo "==> [$1] 소스 코드 전송"
|
||||
git archive HEAD | ssh -o BatchMode=yes "$1" "rm -rf $REMOTE_DIR && mkdir -p $REMOTE_DIR && tar -x -C $REMOTE_DIR"
|
||||
}
|
||||
|
||||
build_on() { # $1 = ssh 대상, $2 = RID
|
||||
echo "==> [$1] publish $2"
|
||||
ssh -o BatchMode=yes "$1" "cd $REMOTE_DIR && export DOTNET_ROOT=\$HOME/.dotnet && export PATH=\$HOME/.dotnet:\$PATH && \
|
||||
dotnet publish VideoDownloader.Cli -c Release -r $2 --self-contained -o out/cli-$2 && \
|
||||
dotnet publish VideoDownloader.Avalonia -c Release -r $2 --self-contained -o out/avalonia-$2 && \
|
||||
cd out && tar -czf artifacts-$2.tar.gz cli-$2 avalonia-$2"
|
||||
build_and_collect() { # $1 = ssh 대상, $2 = RID
|
||||
local host="$1"
|
||||
local rid="$2"
|
||||
echo "==> [$host] publish $rid"
|
||||
ssh -o BatchMode=yes "$host" "cd $REMOTE_DIR && export DOTNET_ROOT=\$HOME/.dotnet && export PATH=\$HOME/.dotnet:\$PATH && \
|
||||
dotnet publish VideoDownloader.Cli -c Release -r $rid --self-contained -o out/cli-$rid && \
|
||||
dotnet publish VideoDownloader.Avalonia -c Release -r $rid --self-contained -o out/avalonia-$rid && \
|
||||
cd out && tar -czf mediabrowser-$rid.tar.gz cli-$rid avalonia-$rid"
|
||||
|
||||
echo "==> [$host] 수집: out/mediabrowser-$rid.tar.gz"
|
||||
scp -o BatchMode=yes "$host:$REMOTE_DIR/out/mediabrowser-$rid.tar.gz" "out/mediabrowser-$rid.tar.gz"
|
||||
}
|
||||
|
||||
collect() { # $1 = ssh 대상, $2 = RID
|
||||
mkdir -p "out/remote/$2"
|
||||
scp -o BatchMode=yes "$1:$REMOTE_DIR/out/artifacts-$2.tar.gz" "out/remote/$2/" && \
|
||||
tar -xzf "out/remote/$2/artifacts-$2.tar.gz" -C "out/remote/$2" && \
|
||||
echo " 수집: out/remote/$2/{cli-$2,avalonia-$2}"
|
||||
}
|
||||
if [[ "$TARGET" == "mac" || "$TARGET" == "all" ]]; then
|
||||
push_src vd-mac
|
||||
build_and_collect vd-mac osx-arm64
|
||||
build_and_collect vd-mac osx-x64
|
||||
fi
|
||||
|
||||
if [[ "$TARGET" == "linux" || "$TARGET" == "all" ]]; then
|
||||
push_src vd-linux
|
||||
build_on vd-linux linux-x64
|
||||
collect vd-linux linux-x64
|
||||
build_and_collect vd-linux linux-x64
|
||||
build_and_collect vd-linux linux-arm64
|
||||
fi
|
||||
if [[ "$TARGET" == "mac" || "$TARGET" == "all" ]]; then
|
||||
push_src vd-mac
|
||||
build_on vd-mac osx-arm64
|
||||
collect vd-mac osx-arm64
|
||||
fi
|
||||
echo "완료."
|
||||
|
||||
echo "==> 원격 빌드 완료:"
|
||||
ls -lh out/mediabrowser-*.tar.gz 2>/dev/null || true
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue