Files
2026-03-18 11:07:16 +09:00

130 lines
3.7 KiB
PowerShell

<# ci\package.ps1
목적:
- PyInstaller 결과물을 out\ 폴더에 “릴리즈 업로드용” 파일로 패키징
- onefile: dist\<App>.exe -> out\<App>-<Tag>-windows.exe
- onedir : dist\<App>\... -> out\<App>-<Tag>-windows.zip
사용:
powershell -NoProfile -ExecutionPolicy Bypass -File .\ci\package.ps1 -App "myapp" -Tag "v0.1.11"
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$App,
[Parameter(Mandatory = $true)]
[string]$Tag,
# 작업 루트(기본: 현재 워크스페이스)
[string]$Root = ".",
# 결과물을 넣을 폴더
[string]$OutDir = "out",
# PyInstaller 기본 출력 폴더
[string]$DistDir = "dist",
# zip 생성 시 include 루트 폴더 자체를 포함할지 여부(기본: 포함)
[switch]$IncludeRootFolder,
# 기존 out\ 파일 삭제 여부(기본: true)
[switch]$CleanOut = $true,
# sha256 체크섬 파일 생성 여부
[switch]$WriteChecksum = $true
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
function Resolve-FullPath([string]$p) {
return (Resolve-Path -LiteralPath $p).Path
}
function Ensure-Dir([string]$p) {
if (-not (Test-Path -LiteralPath $p)) {
New-Item -ItemType Directory -Path $p | Out-Null
}
}
function Write-Sha256([string]$filePath, [string]$outPath) {
$h = Get-FileHash -Algorithm SHA256 -LiteralPath $filePath
# "SHA256 filename" 형태
"$($h.Hash) $([IO.Path]::GetFileName($filePath))" | Out-File -LiteralPath $outPath -Encoding ascii
}
# ---- paths ----
$rootPath = Resolve-FullPath $Root
$distPath = Join-Path $rootPath $DistDir
$outPath = Join-Path $rootPath $OutDir
Ensure-Dir $outPath
if ($CleanOut) {
Get-ChildItem -LiteralPath $outPath -File -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue
}
if (-not (Test-Path -LiteralPath $distPath)) {
throw "Dist folder not found: $distPath (PyInstaller output missing?)"
}
# ---- decide output type ----
$exePath = Join-Path $distPath "$App.exe"
$onedirPath = Join-Path $distPath $App
# 파일명 규칙(윈도우 릴리즈 자산명)
# 예: parameter_editor-v0.1.11-windows.exe / .zip
$baseName = "$App-$Tag-windows"
Write-Host "[PACKAGE] App=$App Tag=$Tag"
Write-Host "[PACKAGE] dist=$distPath"
Write-Host "[PACKAGE] out =$outPath"
# ---- onefile ----
if (Test-Path -LiteralPath $exePath) {
$destExe = Join-Path $outPath "$baseName.exe"
Copy-Item -LiteralPath $exePath -Destination $destExe -Force
Write-Host "[PACKAGE] Copied onefile exe -> $destExe"
if ($WriteChecksum) {
$shaPath = Join-Path $outPath "$baseName.exe.sha256"
Write-Sha256 $destExe $shaPath
Write-Host "[PACKAGE] Wrote checksum -> $shaPath"
}
exit 0
}
# ---- onedir ----
if (Test-Path -LiteralPath $onedirPath) {
$zipPath = Join-Path $outPath "$baseName.zip"
if (Test-Path -LiteralPath $zipPath) {
Remove-Item -LiteralPath $zipPath -Force
}
if ($IncludeRootFolder) {
# dist\<App>\... 를 zip에 <App>\... 형태로 포함
Compress-Archive -LiteralPath $onedirPath -DestinationPath $zipPath -Force
} else {
# dist\<App>\ 내부만 zip에 담기 (루트 폴더 없이)
$items = Get-ChildItem -LiteralPath $onedirPath
if (-not $items -or $items.Count -eq 0) {
throw "Onedir folder is empty: $onedirPath"
}
Compress-Archive -LiteralPath $items.FullName -DestinationPath $zipPath -Force
}
Write-Host "[PACKAGE] Created onedir zip -> $zipPath"
if ($WriteChecksum) {
$shaPath = Join-Path $outPath "$baseName.zip.sha256"
Write-Sha256 $zipPath $shaPath
Write-Host "[PACKAGE] Wrote checksum -> $shaPath"
}
exit 0
}
throw "No PyInstaller output found. Expected one of:`n- $exePath`n- $onedirPath"