From 21db3220d681628581a91ca23ea0fe595f73d482 Mon Sep 17 00:00:00 2001 From: imccyu <276526105+imccyu@users.noreply.github.com> Date: Tue, 11 Aug 2026 01:39:01 +0800 Subject: [PATCH] fix(release): omit optional dependencies from the packed install The Landlock platform packages sit behind optionalDependencies, and npm fails the install on their 404 rather than skipping them: they belong to the native sequence, whose pack needs a musl toolchain and one build per architecture, so this job cannot produce them and holds no credentials to fetch them. A consumer that cannot install them must still start, which is what optional means here. The release spec also gains block bodies where the lint rule rejects returning a void expression from an arrow shorthand. --- .../2026-08-10-npm-release-sequences.i18n.yaml | 4 ++-- .../2026-08-10-npm-release-sequences.md | 2 ++ .../2026-08-10-npm-release-sequences.zh.md | 2 ++ scripts/release/families.spec.ts | 18 +++++++++--------- scripts/release/verify-packed-install.ts | 7 ++++++- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/.agents/notes/implemented/process/2026-08-10-npm-release-sequences.i18n.yaml b/.agents/notes/implemented/process/2026-08-10-npm-release-sequences.i18n.yaml index 4246b4c62a..632b8b3d0d 100644 --- a/.agents/notes/implemented/process/2026-08-10-npm-release-sequences.i18n.yaml +++ b/.agents/notes/implemented/process/2026-08-10-npm-release-sequences.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-10-npm-release-sequences.md -2026-08-10-npm-release-sequences.md: 23c5f26c7be2b87d1ef2edffdd3f79a87cf1f9a1 -2026-08-10-npm-release-sequences.zh.md: 77b772460d0bf6b66ae6924c7bab1dfe0860b401 +2026-08-10-npm-release-sequences.md: 7efe5c9a1c3aa30d4c0a52aa5983b61a01f514cd +2026-08-10-npm-release-sequences.zh.md: cca853bae3f0b19dbf50aca0f2cf32aa573293ef diff --git a/.agents/notes/implemented/process/2026-08-10-npm-release-sequences.md b/.agents/notes/implemented/process/2026-08-10-npm-release-sequences.md index 23c5f26c7b..7efe5c9a1c 100644 --- a/.agents/notes/implemented/process/2026-08-10-npm-release-sequences.md +++ b/.agents/notes/implemented/process/2026-08-10-npm-release-sequences.md @@ -101,6 +101,8 @@ The `pack` job walks the whole release set once, packing each member into one di A dsh verification installs the vendored family's pack output too. The harness packages declare the vendored framework as a peer, those packages live in another sequence, and the credential-free job cannot fetch them from a private registry — so `release.yml` packs the vendored family for verification while publishing only its own set. +The verification omits optional dependencies. The Landlock platform packages behind them belong to the native sequence, whose pack needs a musl toolchain and one build per architecture, so a job on one runner cannot produce them; a consumer that cannot install them must still start, which is what optional means here. + ### Repository changes this carried | Item | Content | diff --git a/.agents/notes/implemented/process/2026-08-10-npm-release-sequences.zh.md b/.agents/notes/implemented/process/2026-08-10-npm-release-sequences.zh.md index 77b772460d..cca853bae3 100644 --- a/.agents/notes/implemented/process/2026-08-10-npm-release-sequences.zh.md +++ b/.agents/notes/implemented/process/2026-08-10-npm-release-sequences.zh.md @@ -101,6 +101,8 @@ dsh 族套用仓库的发布 payload 策略(拒绝源码与声明映射)。v dsh 的验证会一并安装 vendored 族的 pack 产物。harness 的包把 vendored 框架声明成 peer,而那些包属于另一条序列,无凭据的 job 无法从私有 registry 取到——所以 `release.yml` 为验证而打包 vendored 族,发布的仍只有自己那一份。 +验证会略去可选依赖。它们背后的 Landlock 平台包属于 native 序列,那条序列的 pack 需要 musl 工具链且每个架构各构建一次,单台 runner 产不出来;而装不到它们的消费方也必须能起——这正是「可选」在这里的含义。 + ### 本次带出的仓库改动 | 项 | 内容 | diff --git a/scripts/release/families.spec.ts b/scripts/release/families.spec.ts index 34faf36ddc..054fd900ac 100644 --- a/scripts/release/families.spec.ts +++ b/scripts/release/families.spec.ts @@ -34,8 +34,8 @@ describe('release families', () => { const dsh = releaseFamily('dsh') const members = [member('apps/cli', '@deepseek-ai/dsh'), { ...member('apps/web', '@deepseek-ai/dsh-frontend'), version: '0.0.2' }] - expect(() => dsh.verifyVersions(members)).toThrow(/must share one version/) - expect(() => dsh.verifyVersions([members[0]!])).not.toThrow() + expect(() => { dsh.verifyVersions(members) }).toThrow(/must share one version/) + expect(() => { dsh.verifyVersions([members[0]!]) }).not.toThrow() }) it('accepts independent vendored versions and rejects an unpublishable one', () => { @@ -45,8 +45,8 @@ describe('release families', () => { { ...member('vendor/cosmokit', '@deepseek-ai/cosmokit'), version: '1.8.2' }, ] - expect(() => vendor.verifyVersions(members)).not.toThrow() - expect(() => vendor.verifyVersions([{ ...members[0]!, version: 'latest' }])).toThrow(/unpublishable version/) + expect(() => { vendor.verifyVersions(members) }).not.toThrow() + expect(() => { vendor.verifyVersions([{ ...members[0]!, version: 'latest' }]) }).toThrow(/unpublishable version/) }) it('publishes a dependency before its consumer, and orders ties by name', () => { @@ -71,7 +71,7 @@ describe('release families', () => { member('packages/a/right', '@deepseek-ai/dsh-right', { dependencies: { '@deepseek-ai/dsh-left': 'workspace:^' } }), ] - expect(() => dsh.publishOrder(members)).toThrow(/dependency cycle/) + expect(() => { dsh.publishOrder(members) }).toThrow(/dependency cycle/) }) it('applies the harness payload policy to dsh and keeps upstream payloads for vendored packages', () => { @@ -80,10 +80,10 @@ describe('release families', () => { const harness = member('packages/a/library', '@deepseek-ai/dsh-library') const vendored = member('vendor/cordis', '@deepseek-ai/cordis') - expect(() => dsh.validatePayload(harness, ['package/lib/index.js', 'package/src/index.ts'])) + expect(() => { dsh.validatePayload(harness, ['package/lib/index.js', 'package/src/index.ts']) }) .toThrow(/publishes source file/) - expect(() => vendor.validatePayload(vendored, ['package/lib/index.js', 'package/src/index.ts'])).not.toThrow() - expect(() => vendor.validatePayload(vendored, [])).toThrow(/empty tarball/) + expect(() => { vendor.validatePayload(vendored, ['package/lib/index.js', 'package/src/index.ts']) }).not.toThrow() + expect(() => { vendor.validatePayload(vendored, []) }).toThrow(/empty tarball/) }) it('drives the installed entry only for the family that publishes one', () => { @@ -92,7 +92,7 @@ describe('release families', () => { }) it('rejects an unknown family identifier', () => { - expect(() => releaseFamily('native')).toThrow(/unknown release family/) + expect(() => { releaseFamily('native') }).toThrow(/unknown release family/) }) }) diff --git a/scripts/release/verify-packed-install.ts b/scripts/release/verify-packed-install.ts index 10fb824147..f4e5c4b07f 100644 --- a/scripts/release/verify-packed-install.ts +++ b/scripts/release/verify-packed-install.ts @@ -92,7 +92,12 @@ function main(): void { const environment = consumerEnvironment(consumerRoot) console.log(`release verify-packed-install: installing ${String(packed.size)} tarball(s) into ${consumerRoot}`) - capture('npm', ['install', '--no-audit', '--no-fund', '--package-lock=false'], { cwd: consumerRoot, env: environment }) + // Optional dependencies are omitted: the platform packages behind them + // belong to the native release sequence, this job holds no credentials for + // the private scope, and a consumer that cannot install them must still + // start — which is what optional means here. + capture('npm', ['install', '--no-audit', '--no-fund', '--package-lock=false', '--omit=optional'], + { cwd: consumerRoot, env: environment }) const bin = join(consumerRoot, 'node_modules', ...entry.packageName.split('/'), entry.binPath) const version = capture(process.execPath, [bin, '--version'], { cwd: consumerRoot, env: environment })