Skip to content

Commit 176fcc1

Browse files
committed
feat(installer): use GitHub API digests for checksum verification
Replace separate .sha256 checksum files with GitHub's built-in SHA256 digests from the release API. This simplifies the release process and leverages GitHub's native asset digest feature. Changes: - install.sh: Fetch release info and extract digest from API response - install.ps1: Use Invoke-RestMethod to get release data with digests - release.yml: Remove .sha256 file generation and upload steps Closes #103
1 parent 0a13088 commit 176fcc1

3 files changed

Lines changed: 160 additions & 111 deletions

File tree

.github/workflows/release.yml

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -209,38 +209,11 @@ jobs:
209209
cd ..
210210
shell: bash
211211

212-
- name: Generate SHA256 checksum (Unix)
213-
if: matrix.goos != 'windows'
214-
run: |
215-
cd dist
216-
ARCHIVE_NAME="dtvem-${{ github.event.inputs.version }}-${{ matrix.asset_name_suffix }}.${{ matrix.archive_ext }}"
217-
if command -v sha256sum &> /dev/null; then
218-
sha256sum "$ARCHIVE_NAME" > "$ARCHIVE_NAME.sha256"
219-
else
220-
shasum -a 256 "$ARCHIVE_NAME" > "$ARCHIVE_NAME.sha256"
221-
fi
222-
echo "Generated checksum:"
223-
cat "$ARCHIVE_NAME.sha256"
224-
shell: bash
225-
226-
- name: Generate SHA256 checksum (Windows)
227-
if: matrix.goos == 'windows'
228-
run: |
229-
$archiveName = "dtvem-${{ github.event.inputs.version }}-${{ matrix.asset_name_suffix }}.${{ matrix.archive_ext }}"
230-
$archivePath = "dist/$archiveName"
231-
$hash = (Get-FileHash -Path $archivePath -Algorithm SHA256).Hash.ToLower()
232-
"$hash $archiveName" | Out-File -FilePath "dist/$archiveName.sha256" -Encoding ASCII -NoNewline
233-
Write-Host "Generated checksum:"
234-
Get-Content "dist/$archiveName.sha256"
235-
shell: pwsh
236-
237212
- name: Upload build artifacts
238213
uses: actions/upload-artifact@v4
239214
with:
240215
name: build-${{ matrix.asset_name_suffix }}
241-
path: |
242-
dist/dtvem-${{ github.event.inputs.version }}-${{ matrix.asset_name_suffix }}.${{ matrix.archive_ext }}
243-
dist/dtvem-${{ github.event.inputs.version }}-${{ matrix.asset_name_suffix }}.${{ matrix.archive_ext }}.sha256
216+
path: dist/dtvem-${{ github.event.inputs.version }}-${{ matrix.asset_name_suffix }}.${{ matrix.archive_ext }}
244217
retention-days: 1
245218

246219
- name: Upload install scripts (linux-amd64 only)
@@ -301,15 +274,10 @@ jobs:
301274
tag_name: v${{ github.event.inputs.version }}
302275
files: |
303276
artifacts/build-linux-amd64/dtvem-${{ github.event.inputs.version }}-linux-amd64.tar.gz
304-
artifacts/build-linux-amd64/dtvem-${{ github.event.inputs.version }}-linux-amd64.tar.gz.sha256
305277
artifacts/build-macos-amd64/dtvem-${{ github.event.inputs.version }}-macos-amd64.tar.gz
306-
artifacts/build-macos-amd64/dtvem-${{ github.event.inputs.version }}-macos-amd64.tar.gz.sha256
307278
artifacts/build-macos-arm64/dtvem-${{ github.event.inputs.version }}-macos-arm64.tar.gz
308-
artifacts/build-macos-arm64/dtvem-${{ github.event.inputs.version }}-macos-arm64.tar.gz.sha256
309279
artifacts/build-windows-amd64/dtvem-${{ github.event.inputs.version }}-windows-amd64.zip
310-
artifacts/build-windows-amd64/dtvem-${{ github.event.inputs.version }}-windows-amd64.zip.sha256
311280
artifacts/build-windows-arm64/dtvem-${{ github.event.inputs.version }}-windows-arm64.zip
312-
artifacts/build-windows-arm64/dtvem-${{ github.event.inputs.version }}-windows-arm64.zip.sha256
313281
install.sh
314282
install.ps1
315283
body: |
@@ -343,11 +311,6 @@ jobs:
343311
- ✅ Windows (amd64, arm64)
344312
- ✅ macOS (amd64, arm64/Apple Silicon)
345313
- ✅ Linux (amd64)
346-
347-
## Checksums
348-
349-
SHA256 checksums are provided for each archive (`.sha256` files).
350-
The installers automatically verify checksums before extraction.
351314
draft: false
352315
prerelease: false
353316
generate_release_notes: false

install.ps1

Lines changed: 74 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -35,38 +35,68 @@ function Write-Warning-Custom {
3535
Write-Host $Message
3636
}
3737

38-
function Get-LatestVersion {
38+
# Global variable to store release data
39+
$script:ReleaseData = $null
40+
41+
function Get-ReleaseInfo {
42+
param([string]$Version)
43+
3944
try {
40-
$response = Invoke-RestMethod -Uri "https://api.github.com/repos/$REPO/releases/latest"
41-
return $response.tag_name
45+
if ($Version) {
46+
$apiUrl = "https://api.github.com/repos/$REPO/releases/tags/$Version"
47+
}
48+
else {
49+
$apiUrl = "https://api.github.com/repos/$REPO/releases/latest"
50+
}
51+
52+
$script:ReleaseData = Invoke-RestMethod -Uri $apiUrl
53+
return $script:ReleaseData.tag_name
4254
}
4355
catch {
44-
Write-Error-Custom "Failed to fetch latest version: $_"
56+
Write-Error-Custom "Failed to fetch release information: $_"
4557
exit 1
4658
}
4759
}
4860

61+
function Get-AssetDigest {
62+
param([string]$AssetName)
63+
64+
if (-not $script:ReleaseData) {
65+
return $null
66+
}
67+
68+
# Find the asset with matching name
69+
$asset = $script:ReleaseData.assets | Where-Object { $_.name -eq $AssetName }
70+
71+
if (-not $asset) {
72+
return $null
73+
}
74+
75+
# GitHub returns digest in format "sha256:hash"
76+
if ($asset.digest -and $asset.digest.StartsWith("sha256:")) {
77+
return $asset.digest.Substring(7)
78+
}
79+
80+
return $null
81+
}
82+
4983
function Test-Checksum {
5084
param(
5185
[string]$FilePath,
52-
[string]$ChecksumPath
86+
[string]$ExpectedHash
5387
)
5488

55-
if (-not (Test-Path $ChecksumPath)) {
56-
Write-Error-Custom "Checksum file not found: $ChecksumPath"
57-
return $false
89+
if (-not $ExpectedHash) {
90+
Write-Warning-Custom "No checksum available from GitHub API - skipping verification"
91+
return $true
5892
}
5993

60-
# Read expected hash from checksum file (format: "hash filename")
61-
$checksumContent = Get-Content $ChecksumPath -Raw
62-
$expectedHash = ($checksumContent -split '\s+')[0].ToLower()
63-
6494
# Calculate actual hash
6595
$actualHash = (Get-FileHash -Path $FilePath -Algorithm SHA256).Hash.ToLower()
6696

67-
if ($expectedHash -ne $actualHash) {
97+
if ($ExpectedHash.ToLower() -ne $actualHash) {
6898
Write-Error-Custom "Checksum verification failed!"
69-
Write-Error-Custom "Expected: $expectedHash"
99+
Write-Error-Custom "Expected: $ExpectedHash"
70100
Write-Error-Custom "Actual: $actualHash"
71101
return $false
72102
}
@@ -90,22 +120,33 @@ function Main {
90120
}
91121
Write-Info "Detected platform: windows-$ARCH"
92122

93-
# Get version (priority: DTVEM_VERSION env var > hardcoded > fetch latest)
123+
# Determine version to install
124+
$requestedVersion = $null
94125
if ($env:DTVEM_VERSION) {
95-
$VERSION = $env:DTVEM_VERSION
96-
Write-Info "Installing user-specified version: $VERSION"
126+
$requestedVersion = $env:DTVEM_VERSION
127+
Write-Info "Installing user-specified version: $requestedVersion"
97128
}
98129
elseif ($DTVEM_RELEASE_VERSION) {
99-
$VERSION = $DTVEM_RELEASE_VERSION
100-
Write-Info "Installing release version: $VERSION"
130+
$requestedVersion = $DTVEM_RELEASE_VERSION
131+
Write-Info "Installing release version: $requestedVersion"
101132
}
102133
else {
103134
Write-Info "Fetching latest release..."
104-
$VERSION = Get-LatestVersion
135+
}
136+
137+
# Get release info from GitHub API
138+
$VERSION = Get-ReleaseInfo -Version $requestedVersion
139+
140+
if (-not $VERSION) {
141+
Write-Error-Custom "Failed to determine version"
142+
exit 1
143+
}
144+
145+
if (-not $requestedVersion) {
105146
Write-Success "Latest version: $VERSION"
106147
}
107148

108-
# Strip "v" prefix from version for archive name (GitHub releases use v1.0.0 in paths, but archives are named 1.0.0)
149+
# Strip "v" prefix from version for archive name
109150
$VERSION_NO_V = $VERSION.TrimStart('v')
110151

111152
# Construct download URL
@@ -114,6 +155,16 @@ function Main {
114155

115156
Write-Info "Download URL: $DOWNLOAD_URL"
116157

158+
# Get expected checksum from GitHub API
159+
Write-Info "Fetching checksum from GitHub API..."
160+
$EXPECTED_HASH = Get-AssetDigest -AssetName $ARCHIVE_NAME
161+
if ($EXPECTED_HASH) {
162+
Write-Success "Got checksum: $($EXPECTED_HASH.Substring(0, 16))..."
163+
}
164+
else {
165+
Write-Warning-Custom "Checksum not available from API (may be an older release)"
166+
}
167+
117168
# Create temporary directory
118169
$TMP_DIR = Join-Path $env:TEMP "dtvem-install-$(Get-Random)"
119170
New-Item -ItemType Directory -Path $TMP_DIR -Force | Out-Null
@@ -133,22 +184,9 @@ function Main {
133184
exit 1
134185
}
135186

136-
# Download and verify checksum
137-
$CHECKSUM_URL = "$DOWNLOAD_URL.sha256"
138-
$CHECKSUM_PATH = Join-Path $TMP_DIR "$ARCHIVE_NAME.sha256"
139-
140-
Write-Info "Downloading checksum..."
141-
try {
142-
Invoke-WebRequest -Uri $CHECKSUM_URL -OutFile $CHECKSUM_PATH -UseBasicParsing
143-
}
144-
catch {
145-
Write-Error-Custom "Failed to download checksum file: $_"
146-
Write-Error-Custom "URL: $CHECKSUM_URL"
147-
exit 1
148-
}
149-
187+
# Verify checksum
150188
Write-Info "Verifying checksum..."
151-
if (-not (Test-Checksum -FilePath $ARCHIVE_PATH -ChecksumPath $CHECKSUM_PATH)) {
189+
if (-not (Test-Checksum -FilePath $ARCHIVE_PATH -ExpectedHash $EXPECTED_HASH)) {
152190
Write-Error-Custom "Archive integrity check failed - aborting installation"
153191
exit 1
154192
}

0 commit comments

Comments
 (0)