Review found that `apps/desktop/README.md#release-versions` and the 2026-09-16 version-derivation note already specify this convention, and that three of their requirements were reversed without saying so. The rules themselves are right; what was wrong was leaving them undocumented and rejecting one of the forms they prescribe. A stable base takes `-test.YYYYMMDD.index`, which validation refused because such a version ranks below its base. That ordering is the point: the form belongs to a test feed that never serves the production release. Both READMEs, the older note, and a new note now record which requirements this change reverses and why. Three defects the review found, each reproducible: - `afterPack` compared the bundled runtime against the product version, which broke installed-update qualification: that flow passes a runtime whose version was deliberately rewritten. The expected version is now a parameter the preparer supplies, and `verifyDesktopRuntime` says "bundled X is not the expected Y" rather than naming Electron. - Upload could only learn the published version from a shell variable, conflicting with "release fields come only from the target file". It reads the completion record packaging wrote, and a mismatch now prints the version that record holds. - Automatic numbering read one listing page and one fixed directory. It now follows every page, discards a listing it could not finish rather than reusing an index that would overwrite a published installer, bounds the request through the client's own timeout, and reads the directory an unsigned build actually writes. Also: `npm run` and `yarn run` set `npm_execpath` too, so the pnpm resolution checks the path names pnpm; the argument separator can arrive after a run script's preset arguments, not only first; and the toolchain probe, parser, build commit, and tarball readers now have specs.
74 lines
3.2 KiB
TypeScript
74 lines
3.2 KiB
TypeScript
import { mkdtemp, rm, writeFile } from 'node:fs/promises'
|
|
import { tmpdir } from 'node:os'
|
|
import { join } from 'node:path'
|
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
import {
|
|
desktopBuildDateSegment,
|
|
suggestDesktopBuildVersion,
|
|
} from '../scripts/desktop-build-version-discovery.ts'
|
|
|
|
const PRERELEASE = '0.1.6-alpha.2'
|
|
const STABLE = '0.1.6'
|
|
const DATE = '20260921'
|
|
const directories: string[] = []
|
|
|
|
async function artifactsWith(names: readonly string[]): Promise<string> {
|
|
const directory = await mkdtemp(join(tmpdir(), 'dsh-discovery-'))
|
|
directories.push(directory)
|
|
for (const name of names) await writeFile(join(directory, name), '')
|
|
return directory
|
|
}
|
|
|
|
afterEach(async () => {
|
|
for (const directory of directories.splice(0)) await rm(directory, { recursive: true, force: true })
|
|
})
|
|
|
|
describe('desktop build version discovery', () => {
|
|
it('formats the date segment in the build host time zone', () => {
|
|
expect(desktopBuildDateSegment(new Date(2026, 8, 21))).toBe('20260921')
|
|
expect(desktopBuildDateSegment(new Date(2026, 0, 5))).toBe('20260105')
|
|
})
|
|
|
|
it('starts at one when nothing is taken', async () => {
|
|
const artifactsRoot = await artifactsWith([])
|
|
await expect(suggestDesktopBuildVersion({ productVersion: PRERELEASE, target: 'win-x64', environment: {}, date: DATE, artifactsRoot }))
|
|
.resolves.toBe(`${PRERELEASE}.${DATE}.1`)
|
|
})
|
|
|
|
it('numbers a stable product version under the documented test prerelease', async () => {
|
|
const artifactsRoot = await artifactsWith([`deepseek-harness-${STABLE}-test.${DATE}.4-win-x64.exe`])
|
|
await expect(suggestDesktopBuildVersion({ productVersion: STABLE, target: 'win-x64', environment: {}, date: DATE, artifactsRoot }))
|
|
.resolves.toBe(`${STABLE}-test.${DATE}.5`)
|
|
})
|
|
|
|
it('numbers after the highest local artifact for the same date', async () => {
|
|
const artifactsRoot = await artifactsWith([
|
|
`deepseek-harness-${PRERELEASE}.${DATE}.1-win-x64.exe`,
|
|
`deepseek-harness-${PRERELEASE}.${DATE}.2-win-x64.exe`,
|
|
`deepseek-harness-${PRERELEASE}.${DATE}.10-win-x64.exe`,
|
|
])
|
|
await expect(suggestDesktopBuildVersion({ productVersion: PRERELEASE, target: 'win-x64', environment: {}, date: DATE, artifactsRoot }))
|
|
.resolves.toBe(`${PRERELEASE}.${DATE}.11`)
|
|
})
|
|
|
|
it('ignores artifacts from another date or product version', async () => {
|
|
const artifactsRoot = await artifactsWith([
|
|
`deepseek-harness-${PRERELEASE}.20260920.7-win-x64.exe`,
|
|
`deepseek-harness-0.1.5-alpha.1.${DATE}.9-win-x64.exe`,
|
|
`deepseek-harness-${PRERELEASE}-win-x64.exe`,
|
|
'unrelated.exe',
|
|
])
|
|
await expect(suggestDesktopBuildVersion({ productVersion: PRERELEASE, target: 'win-x64', environment: {}, date: DATE, artifactsRoot }))
|
|
.resolves.toBe(`${PRERELEASE}.${DATE}.1`)
|
|
})
|
|
|
|
it('reads macOS artifact names too', async () => {
|
|
const artifactsRoot = await artifactsWith([
|
|
`deepseek-harness-${PRERELEASE}.${DATE}.3-mac-arm64.dmg`,
|
|
`deepseek-harness-${PRERELEASE}.${DATE}.3-mac-arm64.zip`,
|
|
])
|
|
await expect(suggestDesktopBuildVersion({ productVersion: PRERELEASE, target: 'mac-arm64', environment: {}, date: DATE, artifactsRoot }))
|
|
.resolves.toBe(`${PRERELEASE}.${DATE}.4`)
|
|
})
|
|
})
|