fix(release): verify all desktop assets

This commit is contained in:
Aditya Vikram Singh 2026-08-13 20:01:00 +05:30
parent fe6d183573
commit 864991fe3f
4 changed files with 36 additions and 5 deletions

View file

@ -4,7 +4,7 @@ This document describes the actual steps a maintainer takes to cut a CLI or macO
The Electron desktop app (`app/`) is released manually under `desktop-v<version>` tags. Build macOS and Linux artifacts as described in `app/DISTRIBUTION.md`; the tag also runs the read-only `Build Windows installer` workflow on `windows-latest`. Download its `CodeBurn-Windows-Installer` artifact and upload both the `.exe` and `.exe.blockmap` with the other platform assets. The workflow never publishes release assets.
Before announcing a desktop release, the release owner must confirm the live GitHub Release contains all four macOS `.dmg`/`.zip` files, the Linux `.AppImage`, and both Windows installer files. Publishing the Release runs the workflow's read-only live-asset verification job. If assets are uploaded after publication, rerun `Build Windows installer` with the `release_tag` input and require that verification job to pass. A failed or missing verification is a release blocker.
Before announcing a desktop release, the release owner must confirm the live GitHub Release contains all four macOS `.dmg`/`.zip` files, the Linux `.AppImage`, `.deb`, and `.rpm`, and both Windows installer files. Publishing the Release runs the workflow's read-only live-asset verification job. If assets are uploaded after publication, rerun `Build Windows installer` with the `release_tag` input and require that verification job to pass. A failed or missing verification is a release blocker.
## Versioning

View file

@ -256,8 +256,10 @@ Actions artifact. The workflow has read-only repository permissions and does
Before publishing the GitHub Release, the release owner must download that
workflow artifact and manually upload both Windows files along with the four
macOS `.dmg`/`.zip` files and `CodeBurn-<version>.AppImage`. Confirm the live
release contains every required platform asset before announcing it. The
macOS `.dmg`/`.zip` files, `CodeBurn-<version>.AppImage`,
`codeburn-desktop_<version>_amd64.deb`, and
`codeburn-desktop-<version>.x86_64.rpm`. Confirm the live release contains
every required platform asset before announcing it. The
website's download links **pin that tag** in their URLs, so a release with a
missing installer is broken even when another Windows distribution channel is
available. The Windows installer uses an explicit `nsis.artifactName` of

View file

@ -44,6 +44,8 @@ function verifyLiveRelease(tag, assetPath) {
`CodeBurn-${version}-arm64-mac.zip`,
`CodeBurn-${version}-mac.zip`,
`CodeBurn-${version}.AppImage`,
`codeburn-desktop_${version}_amd64.deb`,
`codeburn-desktop-${version}.x86_64.rpm`,
`CodeBurn-Setup-${version}.exe`,
`CodeBurn-Setup-${version}.exe.blockmap`,
]

View file

@ -2,10 +2,12 @@ import { mkdtempSync, mkdirSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { spawnSync } from 'node:child_process'
import { fileURLToPath } from 'node:url'
import { describe, expect, it } from 'vitest'
import { rootFromModuleUrl } from './windows-installer-paths.mjs'
const verifier = new URL('./verify-windows-installer.mjs', import.meta.url)
const verifierPath = fileURLToPath(verifier)
function fixture(options: {
appVersion?: string
@ -30,7 +32,7 @@ function fixture(options: {
writeFileSync(path, 'fixture')
}
const args = [verifier.pathname, '--root', root, '--artifacts', releaseDir]
const args = [verifierPath, '--root', root, '--artifacts', releaseDir]
if (options.tag) args.push('--tag', options.tag)
return spawnSync(process.execPath, args, { encoding: 'utf8' })
}
@ -40,7 +42,7 @@ function releaseFixture(files: string[]) {
const assets = join(root, 'assets.json')
writeFileSync(assets, JSON.stringify(files))
return spawnSync(process.execPath, [
verifier.pathname,
verifierPath,
'--tag',
'desktop-v1.2.3',
'--release-assets',
@ -117,6 +119,8 @@ describe('Windows installer release manifest verifier', () => {
'CodeBurn-1.2.3-arm64-mac.zip',
'CodeBurn-1.2.3-mac.zip',
'CodeBurn-1.2.3.AppImage',
'codeburn-desktop_1.2.3_amd64.deb',
'codeburn-desktop-1.2.3.x86_64.rpm',
'CodeBurn-Setup-1.2.3.exe',
'CodeBurn-Setup-1.2.3.exe.blockmap',
])
@ -132,10 +136,33 @@ describe('Windows installer release manifest verifier', () => {
'CodeBurn-1.2.3-arm64-mac.zip',
'CodeBurn-1.2.3-mac.zip',
'CodeBurn-1.2.3.AppImage',
'codeburn-desktop_1.2.3_amd64.deb',
'codeburn-desktop-1.2.3.x86_64.rpm',
'CodeBurn-Setup-1.2.3.exe.blockmap',
])
expect(result.status).toBe(1)
expect(result.stderr).toContain('live release is missing CodeBurn-Setup-1.2.3.exe')
})
it.each([
'codeburn-desktop_1.2.3_amd64.deb',
'codeburn-desktop-1.2.3.x86_64.rpm',
])('rejects a live desktop release missing %s', missing => {
const required = [
'CodeBurn-1.2.3-arm64.dmg',
'CodeBurn-1.2.3.dmg',
'CodeBurn-1.2.3-arm64-mac.zip',
'CodeBurn-1.2.3-mac.zip',
'CodeBurn-1.2.3.AppImage',
'codeburn-desktop_1.2.3_amd64.deb',
'codeburn-desktop-1.2.3.x86_64.rpm',
'CodeBurn-Setup-1.2.3.exe',
'CodeBurn-Setup-1.2.3.exe.blockmap',
]
const result = releaseFixture(required.filter(asset => asset !== missing))
expect(result.status).toBe(1)
expect(result.stderr).toContain(`live release is missing ${missing}`)
})
})