@longzai-intelligence-release/core 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/dist/index.d.ts +14 -17
- package/dist/index.js +9 -9
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# @longzai-intelligence-release/core
|
|
2
|
+
|
|
3
|
+
`@longzai-intelligence-release/core` 是 Longzai Intelligence 发布工具的核心实现包:承载发布业务从配置到结果的全流程执行。
|
|
4
|
+
|
|
5
|
+
## 简介
|
|
6
|
+
|
|
7
|
+
治理多包发布的执行过程:发布目标按公网轨与本地私有轨归一,依赖按拓扑分层,逐层构建、发布并在层间更新依赖版本,最终以摘要汇总结果——保证发布顺序正确、目标明确、结果可核。
|
|
8
|
+
|
|
9
|
+
## 能力
|
|
10
|
+
|
|
11
|
+
- 发布目标归一化:双轨包清单统一为带目标 registry 的发布清单
|
|
12
|
+
- 依赖拓扑分层:跨轨统一推导依赖顺序,按层组织发布
|
|
13
|
+
- 构建与发布执行:发布前产物清理、依赖安装、逐包构建与发布
|
|
14
|
+
- 本地私有 registry 就绪保障:发布前确保本地 registry 可用
|
|
15
|
+
- 发布结果汇总:逐包结果统计与发布摘要输出
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "./rolldown-runtime-BqT_7tdF.js";
|
|
2
|
-
import { PackageManifest, scanAllPackages } from "@longzai-intelligence-dev-tools/dependency-graph";
|
|
3
2
|
import "zod";
|
|
3
|
+
import { PackageManifest, scanAllPackages } from "@longzai-intelligence-dev-tools/dependency-graph";
|
|
4
4
|
//#region src/commands/publish.command.d.ts
|
|
5
5
|
/**
|
|
6
6
|
* publish 命令实现
|
|
@@ -105,10 +105,9 @@ type PublishResult = 'success' | 'skip' | 'fail';
|
|
|
105
105
|
/**
|
|
106
106
|
* 发布目标轨道(ADR 0082:包级自治的双轨发布)
|
|
107
107
|
*
|
|
108
|
-
* - `npm`:公网 npm 轨(bun publish --registry 显式指定 npm 官方源。注意旗标不具
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
* 失败——发布前的 scope 映射预检见 registry-resolution.utils,apps/cli issue 0004)
|
|
108
|
+
* - `npm`:公网 npm 轨(bun publish --registry 显式指定 npm 官方源。注意旗标不具 终局性:bun 的 registry 解析优先级为 scope 映射 >
|
|
109
|
+
* `--registry` 旗标,scope 被 映射到镜像源或本仓 scope 未注册时发布仍会被改写目标并以 missing authentication 失败——发布前的 scope
|
|
110
|
+
* 映射预检见 registry-resolution.utils,apps/cli issue 0004)
|
|
112
111
|
* - `local`:本地私有轨(bun publish --registry <url>;发布前 ensure 本地 registry 在线, 地址来自 env
|
|
113
112
|
* `LZI_NPM_REGISTRY_URL`,凭据经 `NPM_CONFIG_TOKEN` env 继承)
|
|
114
113
|
*/
|
|
@@ -238,16 +237,18 @@ declare const topologicalSort: (manifests: PackageManifest[]) => PackageManifest
|
|
|
238
237
|
* 安装依赖
|
|
239
238
|
*
|
|
240
239
|
* @param basePath - 项目根目录路径
|
|
240
|
+
* @param env - 子进程环境变量(本地私有轨非空时传入注入后的 env,见 buildDependencyInstallEnv;缺省完整继承父进程)
|
|
241
241
|
* @returns 安装是否成功
|
|
242
242
|
*/
|
|
243
|
-
declare const installDependencies: (basePath: string) => Promise<boolean>;
|
|
243
|
+
declare const installDependencies: (basePath: string, env?: Record<string, string>) => Promise<boolean>;
|
|
244
244
|
/**
|
|
245
245
|
* 更新依赖
|
|
246
246
|
*
|
|
247
247
|
* @param basePath - 项目根目录路径
|
|
248
|
+
* @param env - 子进程环境变量(本地私有轨非空时传入注入后的 env,见 buildDependencyInstallEnv;缺省完整继承父进程)
|
|
248
249
|
* @returns 更新是否成功
|
|
249
250
|
*/
|
|
250
|
-
declare const updateDependencies: (basePath: string) => Promise<boolean>;
|
|
251
|
+
declare const updateDependencies: (basePath: string, env?: Record<string, string>) => Promise<boolean>;
|
|
251
252
|
/**
|
|
252
253
|
* 构建包
|
|
253
254
|
*
|
|
@@ -294,13 +295,10 @@ declare const printSummary: (stats: PublishStats) => void;
|
|
|
294
295
|
* lzi-release 两轨均以 `--registry` 显式指定目标,但旗标不具终局性——scope 映射
|
|
295
296
|
* 优先于旗标(bun 文档 Custom Registry 节),发布目标可能被静默改写:
|
|
296
297
|
*
|
|
297
|
-
* 1. npm 轨包的 scope 被映射到镜像源(bunfig 或 .npmrc):发布写入只读镜像,
|
|
298
|
-
*
|
|
299
|
-
* 2. npm 轨包的 scope 未注册(映射缺位):bun 1.3.x 实测旗标路径凭据解析不可靠
|
|
300
|
-
* (github-trending-markdown 仓公网轨发布失败实录),同样以 missing
|
|
298
|
+
* 1. npm 轨包的 scope 被映射到镜像源(bunfig 或 .npmrc):发布写入只读镜像, 以 missing authentication 失败;
|
|
299
|
+
* 2. npm 轨包的 scope 未注册(映射缺位):bun 1.3.x 实测旗标路径凭据解析不可靠 (github-trending-markdown 仓公网轨发布失败实录),同样以 missing
|
|
301
300
|
* authentication 失败;
|
|
302
|
-
* 3. local 轨包的 scope 被映射到非本轨源(如 globals 预设统一映射 npmjs):
|
|
303
|
-
* 发布偏离本地私有 registry。
|
|
301
|
+
* 3. local 轨包的 scope 被映射到非本轨源(如 globals 预设统一映射 npmjs): 发布偏离本地私有 registry。
|
|
304
302
|
*
|
|
305
303
|
* 发布前按上述优先级实际解析每个待发包的 registry 并与轨道声明比对,不符即
|
|
306
304
|
* fail fast,把 bun 侧误导性的 missing authentication 翻译成根因清晰的指引。
|
|
@@ -395,11 +393,10 @@ declare const loadScopeRegistrySources: (rootDir: string) => Promise<ScopeRegist
|
|
|
395
393
|
*
|
|
396
394
|
* 判定规则(按轨道,ADR 0082 + bun scope 映射优先级事实):
|
|
397
395
|
*
|
|
398
|
-
* - npm 轨:scope 映射存在则必须等于官方源(映射劫持即违规);scoped 包的映射
|
|
399
|
-
* 缺位同样违规(bun 1.3.x 旗标路径凭据解析不可靠的实录,且本仓 scope 兜底
|
|
396
|
+
* - npm 轨:scope 映射存在则必须等于官方源(映射劫持即违规);scoped 包的映射 缺位同样违规(bun 1.3.x 旗标路径凭据解析不可靠的实录,且本仓 scope 兜底
|
|
400
397
|
* 注入后缺位即漂移信号);非 scoped 包无映射可命中,放行。
|
|
401
|
-
* - local 轨:scope 映射存在则必须等于本轨私有源(偏离即违规);映射缺位放行
|
|
402
|
-
*
|
|
398
|
+
* - local 轨:scope 映射存在则必须等于本轨私有源(偏离即违规);映射缺位放行 (ADR 0082 privateScopes 的设计形态即缺位 + 旗标 +
|
|
399
|
+
* NPM_CONFIG_TOKEN env 凭据)。
|
|
403
400
|
*
|
|
404
401
|
* @param input - 单包预检入参(包名、轨道、期望源、映射来源清单)
|
|
405
402
|
* @returns 违规明细列表(空数组即通过)
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import"./rolldown-runtime-BqT_7tdF.js";import{loadReleaseConfig as e}from"@longzai-intelligence-release/config";import{spawnSync as t}from"node:child_process";import{join as n,resolve as r}from"node:path";import{createGraph as
|
|
2
|
-
`),!1)},
|
|
3
|
-
`),
|
|
1
|
+
import"./rolldown-runtime-BqT_7tdF.js";import{loadReleaseConfig as e}from"@longzai-intelligence-release/config";import{spawnSync as t}from"node:child_process";import{join as n,resolve as r}from"node:path";import*as i from"zod";import{createGraph as a,extractWorkspaceDeps as o,scanAllPackages as s,topologicalSort as c}from"@longzai-intelligence-dev-tools/dependency-graph";import{existsSync as l,readFileSync as u}from"node:fs";import{homedir as d}from"node:os";function f(e){return e.map(e=>{if(typeof e==`string`)return e;if(e instanceof Error)return e.message;try{return JSON.stringify(e)}catch{return String(e)}}).join(` `)}function p(...e){process.stdout.write(`${f(e)}\n`)}const m={RED:`\x1B[0;31m`,GREEN:`\x1B[0;32m`,YELLOW:`\x1B[1;33m`,BLUE:`\x1B[0;34m`,RESET:`\x1B[0m`},h=`https://registry.npmjs.org/`,g=[`NPM_CONFIG_REGISTRY`,`npm_config_registry`],_=[`cannot publish over the previously published versions`,`409 Conflict`],v=e=>_.some(t=>e.includes(t)),y=(e,t)=>[`publish`,`--access`,t,`--registry`,e.kind===`npm`?h:e.registryUrl],b=e=>{let t={};for(let[n,r]of Object.entries(e))r===void 0||g.includes(n)||(t[n]=r);return t},x=e=>e.kind===`npm`?`registry.npmjs.org(公网 npm 轨)`:`${e.registryUrl}(本地私有轨)`,S=async e=>{let t=await O(`lzi-npm-registry`,[`ensure`],e);return t.code===0||(D(`本地私有 registry 未在线且自动拉起失败`),process.stderr.write(`${t.stderr}\n`),process.stderr.write(`指引:发布仓 devDependency 添加 @longzai-intelligence-npm-registry/cli,并在仓库 .env 配置 LZI_NPM_REGISTRY_URL 与 NPM_CONFIG_TOKEN(ADR 0082)
|
|
2
|
+
`),!1)},C=i.object({version:i.string().optional()}),w=e=>{process.stdout.write(`${m.BLUE}[INFO]${m.RESET} ${e}\n`)},T=e=>{process.stdout.write(`${m.GREEN}[SUCCESS]${m.RESET} ${e}\n`)},E=e=>{process.stdout.write(`${m.YELLOW}[WARN]${m.RESET} ${e}\n`)},D=e=>{process.stderr.write(`${m.RED}[ERROR]${m.RESET} ${e}\n`)},O=async(e,t,n,r)=>{let i=Bun.spawn([e,...t],{cwd:n,stdout:`pipe`,stderr:`pipe`,env:r}),a=await Bun.readableStreamToText(i.stdout),o=await Bun.readableStreamToText(i.stderr);return{code:await i.exited,stdout:a,stderr:o}},k=e=>{let t=a();for(let n of e)t.addNode(n.name,n);for(let n of e)for(let e of n.workspaceDeps)t.hasNode(e)&&t.addEdge(e,n.name);return c(t).map(e=>e.map(e=>e.data))},ee=(e,t)=>{let n={};for(let[t,r]of Object.entries(e))r===void 0||g.includes(t)||(n[t]=r);return n.BUN_CONFIG_REGISTRY=t,n},A=async(e,t)=>{w(`安装依赖...`);let n=await O(`bun`,[`install`],e,t);return n.code===0?(T(`依赖安装完成`),!0):(D(`安装依赖失败`),process.stdout.write(`${n.stdout}\n`),process.stderr.write(`${n.stderr}\n`),!1)},j=async(e,t)=>(w(`更新依赖...`),(await O(`bun`,[`update`],e,t)).code===0?(T(`依赖更新完成`),!0):(E(`更新依赖失败,继续发布`),!1)),M=async(e,t)=>{w(`构建 ${t}...`);let n=await O(`bun`,[`run`,`build:prod`],e);return n.code===0?(T(`${t} 构建成功`),!0):(D(`${t} 构建失败`),process.stdout.write(`${n.stdout}\n`),process.stderr.write(`${n.stderr}\n`),!1)},N=async(e,t,n=`public`,r={kind:`npm`})=>{if(r.kind===`local`&&!await S(e))return{result:`fail`,error:`本地私有 registry 未在线`};w(`发布 ${t} 到 ${x(r)}...`);let i=await O(`bun`,y(r,n),e,b(process.env)),a=i.stdout+i.stderr;return i.code===0?(T(`${t} 发布成功!`),{result:`success`}):v(a)?(E(`${t} 版本已存在,跳过`),{result:`skip`}):(D(`${t} 发布失败`),process.stderr.write(`${a}\n`),a.includes(`missing authentication`)&&D(`${t} 命中 bun 侧 missing authentication:该文案与真因常脱节——优先排查包 scope 的 registry 映射(bunfig.toml [install.scopes] / .npmrc @scope:registry=,bun 优先级 scope 映射 > --registry 旗标)与本仓 scope 是否已注册,运行 bun run bun-config:generate 重新生成后再试;仍失败再核查目标 registry 凭据`),{result:`fail`,error:`发布失败`})},P=async e=>{try{let t=await Bun.file(n(e,`package.json`)).json(),r=C.safeParse(t);return r.success?r.data.version??`unknown`:`unknown`}catch{return`unknown`}},F=e=>{process.stdout.write(`========================================
|
|
3
|
+
`),w(`发布摘要`),process.stdout.write(`========================================
|
|
4
4
|
`),process.stdout.write(`
|
|
5
|
-
`),process.stdout.write(`总包数: ${e.total}\n`),process.stdout.write(`${
|
|
6
|
-
`);let t=e.results.filter(e=>e.result===`skip`);if(t.length>0){
|
|
7
|
-
`)}let n=e.results.filter(e=>e.result===`fail`);if(n.length>0){
|
|
8
|
-
`)}let r=e.
|
|
9
|
-
`)){let e=r.trim(),i=t.exec(e);i?.[1]!==void 0&&i[2]!==void 0&&!i[2].includes("${")&&(n[i[1]]=i[2])}return n},
|
|
5
|
+
`),process.stdout.write(`总包数: ${e.total}\n`),process.stdout.write(`${m.GREEN}成功: ${e.success}${m.RESET}\n`),process.stdout.write(`${m.YELLOW}跳过: ${e.skip}${m.RESET}\n`),process.stdout.write(`${m.RED}失败: ${e.fail}${m.RESET}\n`),process.stdout.write(`
|
|
6
|
+
`);let t=e.results.filter(e=>e.result===`skip`);if(t.length>0){E(`跳过的包:`);for(let e of t)process.stdout.write(` - ${e.name}\n`);process.stdout.write(`
|
|
7
|
+
`)}let n=e.results.filter(e=>e.result===`fail`);if(n.length>0){D(`失败的包:`);for(let e of n)process.stderr.write(` - ${e.name}${e.error?`: ${e.error}`:``}\n`);process.stderr.write(`
|
|
8
|
+
`)}},I=i.object({workspaces:i.record(i.string(),i.unknown())}),L=i.object({name:i.string(),version:i.string().optional()});var R=class extends Error{constructor(e){super(e),this.name=`LockfileParseError`}};const z=async e=>{let t=n(e,`bun.lock`),r=Bun.file(t);if(!await r.exists())return null;let i=(await r.text()).replace(/,(\s*[}\]])/g,`$1`),a;try{a=JSON.parse(i)}catch(e){throw new R(`bun.lock 解析失败(${t}): ${e instanceof Error?e.message:String(e)}`)}let o=I.safeParse(a);if(!o.success)throw new R(`bun.lock 缺少 workspaces 段或结构不合法(${t})`);let s=/* @__PURE__ */ new Map;for(let e of Object.values(o.data.workspaces)){let t=L.safeParse(e);t.success&&t.data.version!==void 0&&s.set(t.data.name,t.data.version)}return s},B=(e,t)=>{let n=[];for(let r of e){let e=t.get(r.dependency)??null;e!==r.manifestVersion&&n.push({dependent:r.dependent,dependency:r.dependency,manifestVersion:r.manifestVersion,lockVersion:e})}return n},te=async e=>{let t;try{t=await z(e.rootDir)}catch(e){return D(e instanceof Error?e.message:String(e)),!1}if(t===null)return w(`未找到 bun.lock,跳过 workspace 快照一致性闸门(无 lockfile 即无过期快照面)`),!0;let n=[];for(let t of e.manifests)for(let r of t.workspaceDeps){let i=e.allPackages.get(r);if(i===void 0)return D(`workspace 依赖 ${r}(被 ${t.name} 声明)未能在仓内解析到包目录,终止发布`),!1;n.push({dependent:t.name,dependency:r,manifestVersion:await P(i)})}let r=B(n,t);if(r.length>0){D(`bun.lock workspace 版本快照与 package.json 不一致,共 ${r.length} 处,终止发布`);for(let e of r)D(` - 依赖方 ${e.dependent} 依赖 ${e.dependency},package.json 为 ${e.manifestVersion},bun.lock 快照为 ${e.lockVersion??`未记录`}`);return D(`修复指引:在仓根重新执行 version sync 刷新快照后重试。`),D(`手工改版本号的场景,将 bun.lock workspaces 段内的版本字段对齐 package.json。`),!1}return w(`bun.lock workspace 版本快照一致性校验通过`),!0},ne=i.record(i.string(),i.unknown());i.record(i.string(),i.string());const V=i.object({name:i.string()}),H=async e=>{let t=Bun.file(`${e}/package.json`),n=ne.safeParse(await t.json());if(!n.success)throw Error(`package.json 格式不合法: ${e}`);return n.data},U=async(e,t,n)=>{let i=`${t}/${e}/package.json`;if(await Bun.file(i).exists()){let n=await H(`${t}/${e}`),i=V.safeParse(n);return i.success?{name:i.data.name,path:r(`${t}/${e}`),workspaceDeps:o(n)}:null}let a=n.get(e);if(a){let e=await H(a),t=V.safeParse(e);return t.success?{name:t.data.name,path:r(a),workspaceDeps:o(e)}:null}return null},W=e=>{let t=e.indexOf(`/`);if(!(!e.startsWith(`@`)||t<=1))return e.slice(1,t)},G=e=>e.replace(/\/+$/,``),K=e=>typeof e==`object`&&!!e&&!Array.isArray(e),q=e=>{let t;try{t=Bun.TOML.parse(e)}catch{return{}}if(!K(t))return{};let n=`install`in t?t.install:void 0;if(!K(n))return{};let r=`scopes`in n?n.scopes:void 0;if(!K(r))return{};let i={};for(let[e,t]of Object.entries(r))typeof t==`string`&&(i[e.replace(/^@+/,``)]=t);return i},J=e=>{let t=/^@([^:\s]+):registry\s*=\s*(\S+)$/,n={};for(let r of e.split(`
|
|
9
|
+
`)){let e=r.trim(),i=t.exec(e);i?.[1]!==void 0&&i[2]!==void 0&&!i[2].includes("${")&&(n[i[1]]=i[2])}return n},Y=async e=>{let t=[{label:`bunfig.toml`,path:n(e,`bunfig.toml`)},{label:`项目 .npmrc`,path:n(e,`.npmrc`)},{label:`用户 ~/.npmrc`,path:n(d(),`.npmrc`)}],r=[];for(let e of t){if(!l(e.path))continue;let t=u(e.path,`utf8`);if(e.label===`bunfig.toml`){let n=q(t);Object.keys(n).length===0&&t.trim()!==``&&E(`bunfig.toml 解析不出 [install.scopes](可能无该段或格式异常),预检按空映射处理`),r.push({label:e.label,scopes:n})}else r.push({label:e.label,scopes:J(t)})}return r},X=e=>{let t=W(e.packageName);if(t===void 0)return[];let n=[];for(let r of e.sources){let e=r.scopes[t];e!==void 0&&n.push({label:r.label,url:e})}let r=G(e.expectedRegistryUrl),i=[];if(e.track===`npm`){if(n.length===0)return i.push(`${e.packageName} 的 scope @${t} 未注册进任何 [install.scopes] / @scope:registry 映射——bun 1.3.x 实测 scope 缺位时 --registry 旗标路径凭据解析不可靠,公网轨发布会以 missing authentication 失败;请运行 bun run bun-config:generate 重新生成(lzi-bun-cli 会兜底注入本仓 scope)`),i;for(let a of n)G(a.url)!==r&&i.push(`${e.packageName} 的 scope @${t} 在 ${a.label} 中映射到 ${a.url},按 bun 优先级(scope 映射 > --registry 旗标)发布将写入该源而非轨道目标 ${e.expectedRegistryUrl},并以 missing authentication 失败;请运行 bun run bun-config:generate 重新生成或修正 ${a.label} 的该条映射`);return i}for(let a of n)G(a.url)!==r&&i.push(`${e.packageName} 的 scope @${t} 在 ${a.label} 中映射到 ${a.url},按 bun 优先级(scope 映射 > --registry 旗标)发布将偏离本地私有轨目标 ${e.expectedRegistryUrl};请在 lzi-bun.config.ts 的 install.privateScopes 排除该 scope(ADR 0082)后运行 bun run bun-config:generate 重新生成`);return i},Z=async e=>{w(`发布 registry 预检(scope 映射优先级防线)...`);let t=await Y(e.rootDir),n=[];for(let r of e.manifests){let i=e.trackByName.get(r.name)??`npm`;n.push(...X({packageName:r.name,track:i,expectedRegistryUrl:i===`local`?e.localRegistryUrl:h,sources:t}))}if(n.length>0){D(`发布 registry 预检失败(${n.length} 项违规,均为发布目标被静默改写或 scope 缺位的风险):`);for(let e of n)D(` - ${e}`);return!1}return w(`发布 registry 预检通过(scope 映射与轨道声明一致)`),!0},Q=`LZI_NPM_REGISTRY_URL`;function $(e){if(e===void 0)return{npm:[],local:[]};if(Array.isArray(e))return{npm:e,local:[]};if(typeof e!=`object`||!e)throw Error(`publish.packages 必须是字符串数组或 { npm, local } 对象(ADR 0082)`);let t=Object.keys(e),n=t.includes(`npm`),r=t.includes(`local`);if(!n||!r||t.length>2)throw Error(`publish.packages 对象形态必须且只能含 npm/local 两键(实际键:${t.join(`, `)||`空`};ADR 0082)`);let i=e.npm,a=e.local,o=e=>Array.isArray(e)&&e.every(e=>typeof e==`string`);if(!o(i)||!o(a))throw Error(`publish.packages 的 npm/local 键值必须是字符串数组(包名或相对路径)`);return{npm:i,local:a}}const re=e=>{let t;try{t=$(e)}catch(e){D(e instanceof Error?e.message:String(e)),process.exit(1)}t.npm.length===0&&t.local.length===0&&(D(`配置文件中没有定义要发布的包`),process.exit(1));let n=process.env[Q]??``;return t.local.length>0&&n===``&&(D(`本地私有轨非空但未设置 ${Q}(发布仓 .env 配置,ADR 0082)`),process.exit(1)),{tracks:t,localRegistryUrl:n}},ie=async(e,t,n)=>{if(n||t.fail!==0||t.success===0)return;let r=t.results.find(e=>e.result===`success`),i=e.find(e=>e.name===r?.name);if(!i)return;let a=i.name.indexOf(`/`),o=a>=0?i.name.slice(0,a):i.name,s=await P(i.path),c=s.startsWith(`^`)||s.startsWith(`~`)?s:`^${s}`;p(``),p(`下一步:提交版本变更`),p(` release: 更新版本至 v${s}`),p(``),p(`然后:升级所有消费者并推送`),p(` bun version:upgrade-across --scope ${o} --target ${c} --dry-run`),p(` bun version:upgrade-across --scope ${o} --target ${c}`),p(` bun push-all`)},ae=async e=>{await Z(e)||process.exit(1)},oe=async e=>{let t=/* @__PURE__ */ new Map,n=[];for(let[r,i]of[[`npm`,e.tracks.npm],[`local`,e.tracks.local]])for(let a of i){let i=await U(a,e.rootDir,e.allPackages);i||(D(`未找到包: ${a}`),process.exit(1)),t.has(i.name)&&(D(`包 ${i.name} 在 publish.packages 中重复声明`),process.exit(1)),t.set(i.name,r),n.push(i)}return{manifests:n,trackByName:t}},se=async e=>{await Bun.spawn([`lzi-dev-cli`,`clean`],{cwd:e,stdout:`inherit`,stderr:`inherit`}).exited!==0&&E(`lzi-dev-cli clean 执行失败(继续发布,请核查清理产物是否完整)`)},ce=async n=>{let i;try{i=await e()}catch(e){D(`加载配置文件失败: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}i||(D(`未找到配置文件 lzi-release.config.ts 或 lzi-dev.config.ts`),p(``),p(`请创建配置文件,示例:`),p(`
|
|
10
10
|
import { defineConfig } from '@longzai-intelligence-release/config';
|
|
11
11
|
|
|
12
12
|
export default defineConfig({
|
|
@@ -14,4 +14,4 @@ export default defineConfig({
|
|
|
14
14
|
packages: ['apps/cli'],
|
|
15
15
|
},
|
|
16
16
|
});
|
|
17
|
-
`),process.exit(1)),i.source===`legacy-dev-tools`&&
|
|
17
|
+
`),process.exit(1)),i.source===`legacy-dev-tools`&&E(`发布配置读取自 lzi-dev.config.ts 的 publish 字段(发布命令的兼容回退;该字段仍被 release log/version 域消费,请勿删除)。如需发布域专属清单可另建 lzi-release.config.ts,两处声明需保持一致(ADR 0087)`);let{tracks:a,localRegistryUrl:o}=re(i.config.publish?.packages),c=r(i.configPath,`..`),l=i.config.publish;l===void 0&&(D(`配置文件中没有定义要发布的包`),process.exit(1));let u=l.access??`public`,d=l.installDeps??!0,f=l.buildBeforePublish??!0,m=l.cleanBeforePublish??!0,h=n?.dryRun??!1,g=await s(c),{manifests:_,trackByName:v}=await oe({tracks:a,rootDir:c,allPackages:g}),y=e=>v.get(e)===`local`?{kind:`local`,registryUrl:o}:{kind:`npm`},b=e=>x(y(e));await ae({manifests:_,trackByName:v,localRegistryUrl:o,rootDir:c});let S=a.local.length>0?ee(process.env,o):void 0,C=k(_);if(h){w(`[dry-run] 预览模式,不会实际安装、构建或发布`),w(`[dry-run] 发布顺序(含目标 registry,发布前核对轨道,ADR 0082):`);for(let e=0;e<C.length;e++){let t=C[e]??[];for(let n of t)w(`[dry-run] 第 ${e+1} 层: ${n.name} → ${b(n.name)}`)}p(``)}let T={total:_.length,success:0,skip:0,fail:0,results:[]};w(`开始发布流程`),w(`基础路径: ${c}`),p(``);let O=n?.cleanRunner??(async()=>se(c));m&&!h?(w(`发布前清理构建产物`),p(``),await O({dryRun:!1}),p(``)):m&&h&&(w(`[dry-run] 跳过发布前清理`),p(``)),d&&!h?(await A(c,S)||(D(`安装依赖失败,终止发布`),process.exit(1)),p(``)):d&&h&&(w(`[dry-run] 跳过安装依赖`),p(``)),await te({rootDir:c,manifests:_,allPackages:g})||process.exit(1),p(``),l.preBuildHook&&!h?(w(`执行 preBuildHook`),t(l.preBuildHook,{cwd:c,stdio:`inherit`,shell:!0}).status!==0&&(D(`preBuildHook 执行失败,终止发布`),process.exit(1)),p(``)):l.preBuildHook&&h&&(w(`[dry-run] 跳过 preBuildHook`),p(``)),p(`========================================`),p(``);for(let e=0;e<C.length;e++){let t=C[e]??[];if(t.length!==0){w(`【第 ${e+1} 层】发布 ${t.length} 个包...`),p(``);for(let e of t){let t=y(e.name);w(`开始发布: ${e.name}`),w(`路径: ${e.path}`),w(`目标: ${x(t)}`);let n=await P(e.path);if(w(`版本: ${n}`),f&&!h){if(!await M(e.path,e.name)){T.fail++,T.results.push({name:e.name,result:`fail`,error:`构建失败`}),p(``);continue}}else f&&h&&w(`[dry-run] 跳过构建 ${e.name}`);if(h)w(`[dry-run] 将发布 ${e.name}@${n} → ${x(t)}`),T.results.push({name:e.name,result:`success`}),T.success++;else{let n=await N(e.path,e.name,u,t);switch(T.results.push({name:e.name,result:n.result,error:n.error}),n.result){case`success`:T.success++;break;case`skip`:T.skip++;break;case`fail`:T.fail++}}p(``)}e<C.length-1&&(h?w(`[dry-run] 跳过更新依赖`):!await j(c,S)&&a.local.length>0&&(D(`更新依赖失败,终止发布(本地私有轨仓:快照刷新失败,继续发布将产出 workspace 依赖版本错位制品)`),process.exit(1)),p(``))}}F(T),await ie(_,T,h),T.fail>0&&process.exit(1)};export{h as NPM_OFFICIAL_REGISTRY_URL,M as buildPackage,y as buildPublishArgs,b as buildPublishEnv,X as checkScopeRegistryForPublish,x as describePublishTarget,S as ensureLocalRegistry,W as extractPackageScope,P as getPackageVersion,A as installDependencies,Y as loadScopeRegistrySources,D as logError,w as logInfo,T as logSuccess,E as logWarn,$ as normalizePublishTracks,G as normalizeRegistryUrl,q as parseBunfigScopeRegistries,J as parseNpmrcScopeRegistries,F as printSummary,ce as publishCommand,N as publishPackage,H as readPackageJson,U as resolvePackageManifest,Z as runPublishRegistryPreflight,s as scanAllPackages,k as topologicalSort,j as updateDependencies};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@longzai-intelligence-release/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Longzai Intelligence 发布业务核心实现(双轨归一化、依赖拓扑分层、构建与发布管线)",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"files": [
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@longzai-intelligence-dev-tools/dependency-graph": "^0.2.29",
|
|
35
|
-
"@longzai-intelligence-release/config": "0.0.
|
|
35
|
+
"@longzai-intelligence-release/config": "0.0.4",
|
|
36
36
|
"zod": "^4.4.3"
|
|
37
37
|
}
|
|
38
38
|
}
|