130 lines
3.7 KiB
PowerShell
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"
|