Tools live under tools/<role>/<domain> (checks, generate, release, ci, dev), every tool is a workspace named @open-pencil/<domain>-tools, a shared tools/tsconfig.json backs the new check:tools gate that fixed 55 latent type errors, test:tools runs through bun --filter, the placement check is its own checks/test-homes package, and every tool resolves the repository through resolveWorkspaceRoot. Bun, Node, and mdast types live in a tools-root workspace so they never reach the app program.
53 lines
1.7 KiB
TypeScript
53 lines
1.7 KiB
TypeScript
import { expect, test } from 'bun:test'
|
|
|
|
import type { ReleaseIdentity } from '#release/native/context'
|
|
import { assertDraftReplacement } from '#release/native/draft'
|
|
|
|
const identity: ReleaseIdentity = {
|
|
tag: 'v0.15.0',
|
|
sourceCommit: 'a'.repeat(40),
|
|
workflowCommit: 'b'.repeat(40),
|
|
runId: '123',
|
|
runAttempt: '1',
|
|
frontendSha256: 'c'.repeat(64)
|
|
}
|
|
const names = ['release-manifest.json', 'SHA256SUMS', 'installer.exe']
|
|
const draft = { id: 123, tag_name: identity.tag, draft: true, assets: [{ name: 'installer.exe' }] }
|
|
|
|
test('permits creating a draft or replacing its known assets', () => {
|
|
expect(() =>
|
|
assertDraftReplacement(undefined, names, identity.sourceCommit, identity)
|
|
).not.toThrow()
|
|
expect(() => assertDraftReplacement(draft, names, identity.sourceCommit, identity)).not.toThrow()
|
|
})
|
|
|
|
test('refuses to modify a published release', () => {
|
|
expect(() =>
|
|
assertDraftReplacement({ ...draft, draft: false }, names, identity.sourceCommit, identity)
|
|
).toThrow('published release')
|
|
})
|
|
|
|
test('refuses a tag moved after artifact construction', () => {
|
|
expect(() => assertDraftReplacement(draft, names, 'd'.repeat(40), identity)).toThrow(
|
|
'tag changed'
|
|
)
|
|
})
|
|
|
|
test('refuses to silently delete unexpected draft assets', () => {
|
|
const unexpected = { ...draft, assets: [{ name: 'unrelated.zip' }] }
|
|
expect(() => assertDraftReplacement(unexpected, names, identity.sourceCommit, identity)).toThrow(
|
|
'unexpected draft assets'
|
|
)
|
|
})
|
|
|
|
test.each(['release-manifest.json', 'SHA256SUMS'])('requires %s before publication', (missing) => {
|
|
expect(() =>
|
|
assertDraftReplacement(
|
|
draft,
|
|
names.filter((name) => name !== missing),
|
|
identity.sourceCommit,
|
|
identity
|
|
)
|
|
).toThrow('Missing release manifest')
|
|
})
|