The harness packages declare the vendored framework as a peer, so installing only the dsh tarballs left npm resolving @deepseek-ai/cordis from a private registry the credential-free pack job cannot reach. The verification now takes several pack directories and installs every tarball in them, and the dsh workflow packs the vendored family for that purpose while still publishing only its own set. The verification also reads what each tarball declares instead of what the checkout says, which is what let the process and tarball helpers become one home each - the three copies of a spawn wrapper were a duplication finding.
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/proposed/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 { 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}`)
|
|
}
|
|
|
|
main()
|