The root manifest carries the dsh family version. bump writes it with the members, because the workspace constraint requires them to match, and that constraint now accepts a prerelease segment: without both, release:dsh 0.0.2 left the root behind and 0.0.1-rc.1 could satisfy neither check. The Landlock workflow no longer passes --access public, which overrode the restricted publishConfig this repository just adopted for those packages. Vendored change detection reads build inputs when a package publishes build output, and vendor/cordis publishes the src its export map already pointed at: its lib/ is untracked, so a real source edit read as 'nothing changed' and the next publish would fail on a version whose bytes moved. The next version also takes the last published version as its baseline, so a re-sync that restores a lower upstream version cannot recompute a version already on the registry, and bump confirms the registry carries what the newest tag names. Tag prefixes are constructed rather than recovered from a full tag, which a hyphenated version defeated. Pack runs group per ref so concurrent pull requests stop displacing each other, the publish job carries the global group, and the unused id-token permission is gone. Every release script sits behind an entry guard, which is what lets the pure judgements carry tests: tag naming, publish order and cycle reporting, version arithmetic, payload policy, and the change judgement. The Agent Note moves to implemented and states what shipped: one probe command, the registry confirmation that now exists, and byte reproducibility recorded as assumed rather than measured.
62 lines
2.5 KiB
TypeScript
62 lines
2.5 KiB
TypeScript
/**
|
|
* Pack one release family's whole publish set into a single directory, in
|
|
* publish order, and record that order for the publish step.
|
|
*
|
|
* The pack step is the release boundary: it runs without credentials, produces
|
|
* every tarball from one commit, and hands the publish step exactly those bytes
|
|
* ([rationale](../../.agents/notes/implemented/process/2026-08-10-npm-release-sequences.md)).
|
|
*/
|
|
|
|
import { existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs'
|
|
import { join, resolve } from 'node:path'
|
|
import { parseArgs } from 'node:util'
|
|
import { releaseFamily, tarballName, type ReleaseFamily, type ReleaseMember } from './families.ts'
|
|
import { isEntry, run } from './process.ts'
|
|
import { PUBLISH_ORDER_FILE, tarballFiles } from './tarball.ts'
|
|
|
|
/** Where pack output lands when `--out` is omitted. */
|
|
const DEFAULT_OUTPUT = 'dist/npm'
|
|
|
|
/**
|
|
* Pack one member and check what its tarball carries.
|
|
* @param family - the release family being packed.
|
|
* @param member - the member to pack.
|
|
* @param destination - absolute output directory.
|
|
* @returns The tarball filename.
|
|
*/
|
|
function packMember(family: ReleaseFamily, member: ReleaseMember, destination: string): string {
|
|
run('pnpm', ['--dir', member.directory, 'pack', '--pack-destination', destination])
|
|
|
|
const filename = tarballName(member)
|
|
const tarball = join(destination, filename)
|
|
if (!existsSync(tarball)) throw new Error(`${member.name} produced no tarball at ${tarball}`)
|
|
family.validatePayload(member, tarballFiles(tarball))
|
|
return filename
|
|
}
|
|
|
|
/** Pack the family named by `--family` into `--out`. */
|
|
function main(): void {
|
|
const { values } = parseArgs({
|
|
options: { family: { type: 'string' }, out: { type: 'string' } },
|
|
allowPositionals: false,
|
|
})
|
|
if (values.family === undefined) throw new Error('usage: pack.ts --family <dsh|vendor> [--out dist/npm]')
|
|
|
|
const family = releaseFamily(values.family)
|
|
const root = process.cwd()
|
|
const destination = resolve(root, values.out ?? DEFAULT_OUTPUT)
|
|
const members = family.publishOrder(family.members(root))
|
|
family.verifyVersions(members)
|
|
|
|
rmSync(destination, { recursive: true, force: true })
|
|
mkdirSync(destination, { recursive: true })
|
|
|
|
const order: string[] = []
|
|
for (const member of members) order.push(packMember(family, member, destination))
|
|
writeFileSync(join(destination, PUBLISH_ORDER_FILE), `${order.join('\n')}\n`)
|
|
|
|
console.log(`release pack: family ${family.id}, ${String(order.length)} tarball(s) in ${values.out ?? DEFAULT_OUTPUT}`)
|
|
}
|
|
|
|
if (isEntry(import.meta.url)) main()
|