diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cbd8fd..30f3a46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,10 @@ - 테스트 서버를 normal 난이도로 실행하고 빈 서버 자동 일시정지를 비활성화 - GoReleaser가 직접 관리하는 installer 파일을 각 릴리스 자산에 첨부 +### Fixed + +- Windows PowerShell 5.1의 UTF-8 해석 및 `Get-FileHash` 가용성 차이로 installer가 실패하던 문제 + ## [0.1.0] - TBD - 첫 공개 프리릴리스 예정 diff --git a/scripts/install.ps1 b/scripts/install.ps1 index f2714b1..431d7e7 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -1,4 +1,4 @@ -[CmdletBinding()] +[CmdletBinding()] param( [string]$Version = $(if ($env:DPT_VERSION) { $env:DPT_VERSION } else { "latest" }), [string]$InstallDir = $(if ($env:DPT_INSTALL_DIR) { $env:DPT_INSTALL_DIR } else { Join-Path $env:LOCALAPPDATA "Programs\DPT\bin" }), @@ -56,6 +56,26 @@ function Get-DptFile { } @WebRequestCompatibility } +function Get-DptSHA256 { + param([string]$Path) + + $Stream = $null + $Hash = $null + $Hasher = [System.Security.Cryptography.SHA256]::Create() + try { + $Stream = [System.IO.File]::OpenRead($Path) + $Hash = $Hasher.ComputeHash($Stream) + } + finally { + if ($Stream) { + $Stream.Dispose() + } + $Hasher.Dispose() + } + + return ([System.BitConverter]::ToString($Hash).Replace("-", "").ToLowerInvariant()) +} + switch ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString()) { "X64" { $Architecture = "amd64" } "Arm64" { $Architecture = "arm64" } @@ -108,7 +128,7 @@ try { throw "checksums.txt에서 $Asset 항목을 찾을 수 없습니다" } - $ActualChecksum = (Get-FileHash -LiteralPath $ArchivePath -Algorithm SHA256).Hash.ToLowerInvariant() + $ActualChecksum = Get-DptSHA256 -Path $ArchivePath if ($ExpectedChecksum.ToLowerInvariant() -ne $ActualChecksum) { throw "SHA-256 체크섬이 일치하지 않습니다" } diff --git a/scripts/install_test.go b/scripts/install_test.go index 36f1055..ff2a70d 100644 --- a/scripts/install_test.go +++ b/scripts/install_test.go @@ -53,6 +53,16 @@ func TestInstallPowerShellSyntax(t *testing.T) { } } +func TestInstallPowerShellHasUTF8BOM(t *testing.T) { + content, err := os.ReadFile(filepath.Join(scriptDir(t), "install.ps1")) + if err != nil { + t.Fatal(err) + } + if !bytes.HasPrefix(content, []byte{0xEF, 0xBB, 0xBF}) { + t.Fatal("install.ps1에는 Windows PowerShell 5.1용 UTF-8 BOM이 필요합니다") + } +} + func TestInstallPowerShellFromReleaseFixture(t *testing.T) { if runtime.GOOS != "windows" { t.Skip("install.ps1 통합 테스트는 Windows에서 실행합니다")