@exadev/释放门
标记并推出一个语义-放出发行,然后在以后完成出版——从一个单独的过程,在外部的大门之后——没有语义-放出核心在本土上支持这一点.
为什么
语义 - 释放自己的 run() 标记并按下发布,然后立即调用每个配置 publish 插件(npm,GitHub Releases等)在同一过程中,在同一CI任务中. 在标签存在之后,没有支持的停止方法,在以后恢复出版,一旦语义本身以外的东西 -- -- 中转部署、烟雾测试、人工签注 -- -- 已经确认发行实际上应该出去. 语义-释出/语义-释出#2411 并不止一次地被提起(并因超出核心范围而被拒绝)。 此套件是设计评论中承诺的独立参考执行: 一小副添加剂的一对功能 - detachRelease 财务报告和审定财务报表 resumeRelease ——完全建立在语义释放本身的内部上,表明分裂是一个真实的,有用的事物,而不是抽象的建议.
它通过重新使用语义释放的内在 run() 函数上到(并包括)标记和推出步骤,然后停止——在语义-放出内部没有输出接合物来钩入这个中点,因为其唯一的公共输出是运行一个放出开始完成的单个函数. 状态需要稍后完成释放(哪个分支,哪个版本,哪个版本,哪个版本) 被捕获成平地,JSON-序列可 ReleaseGateState,哪个 resumeRelease 在同一或完全不同的进程中,开始重建和运行真实的 publish编号 :success 插件管道 .
开始
pnpm add @exadev/release-gate
// Job 1: tag and push, but stop short of publishing.
import { detachRelease } from '@exadev/release-gate';
import { writeFile } from 'node:fs/promises';
const state = await detachRelease();
if (state) {
await writeFile('release-gate-state.json', JSON.stringify(state));
}
// Job 2, later -- once whatever external gate needs to pass has passed.
import { resumeRelease } from '@exadev/release-gate';
import { readFile } from 'node:fs/promises';
const state: unknown = JSON.parse(await readFile('release-gate-state.json', 'utf8'));
const releases = await resumeRelease(state);
detachRelease(cliOptions?, execEnv?)
function detachRelease(cliOptions?: Options, execEnv?: DetachReleaseEnv): Promise<ReleaseGateState | null>;
interface DetachReleaseEnv {
cwd?: string;
env?: NodeJS.ProcessEnv;
stdout?: NodeJS.WritableStream;
stderr?: NodeJS.WritableStream;
}
签名刻意反射语义放出自己默认的导出 -- cliOptions 是真正的语义释放 Options 类型,且呼叫者可以互换 semanticRelease(cliOptions, execEnv) 页:1 detachRelease(cliOptions, execEnv) 没有其他改动。 运行验证配置,分支分辨率,推-自动验证, verifyConditions,承诺分析, verifyRelease, (中文(简体) ), generateNotes,以及 prepare,然后创建和推出释放标记——正是语义释放本身在真正运行的此时所做的事情.
回返 null 在每一个情况下,语义释放自己的 run() 将会在发布前停止:没有检测到 CI 环境,拉-请求-触发运行,分支语义释放没有配置以释放,本地分支在它的远程后方,自上次发布后没有可放出的承诺,或者干跑模式(干跑从不创建标记,所以没有恢复). 否则返回 ReleaseGateState 日后 resumeRelease 电话需要.
resumeRelease(state, execEnv?)
function resumeRelease(state: unknown, execEnv?: ResumeReleaseEnv): Promise<readonly Release[]>;
interface ResumeReleaseEnv {
cwd?: string;
env?: NodeJS.ProcessEnv;
stdout?: NodeJS.WritableStream;
stderr?: NodeJS.WritableStream;
}
state 被接受为 unknown 运行时验证(通过 isReleaseGateState),未输入为 ReleaseGateState 直接——它通常从当前进程(一个文件,一个CI文物)之外运出,因此在它到达此功能时,它不带编译时间保证. 这个软件包没有产生,或者来自一个不兼容的状态 schemaVersion掷出 ReleaseGateStateError。 。 。 .
cwd编号 :env编号 :stdout编号 :stderr 总是为这个电话而新造 从来没有读出来 state: 简历可以在一个完全不同的进程中运行, 退出, 或 CI 任务, 而不是运行该任务 detachRelease,具有不同的证书和不同的日志目的地。 特别是,认证的推力URL是从此调用本身的再出自 env,没有坚持 -- -- 见 ReleaseGateState 见下文.
重建真实 publish编号 :success 插件管道从 state.options编号 :state.pluginsPath 以它对抗顽固者 branch编号 :lastRelease编号 :commits编号 :nextRelease完全照搬语义 -释放的 真实的呼叫站点(publish 接下来 success,与 fail 引用错误,如果 publish 或者说 success - 扔下来). 返回已配置的发布插件返回的任意内容 .
释放状态
| 外地 | 这是什么 |
|---|---|
schemaVersion | 永远 1 在此版本中. resumeRelease 拒绝具有不同价值的国家,而不是误解它. |
options | 解决的语义释放选项 detachRelease 跟着跑. |
pluginsPath | 可共享配置插件分辨率映射 。 永远 {} - 见下文“这个软件包没有做什么”. |
branches | 每个分支语义释放都为寄存器解决了. |
branch | 这个发行的分支运行. |
lastRelease | 这之前在树枝上发现的释放物,或者 {} 第一次发布. |
commits | 自此以后的每一项承诺 lastRelease 分析过了. |
nextRelease | 被标记和推开的释放.. resumeRelease 发表准确的这个. |
故意不坚持: cwd, (中文(简体) ), env, (中文(简体) ), stdout, (中文(简体) ), stderr,且记录器全部由进程输入并重建由 resumeRelease (见上文); releases 总是空的 detachRelease 返回,因为唯一可以容纳它的东西 -- -- 维修处后港路径 -- -- 被彻底拒绝,而不是默默处理.
options.repositoryUrl 总是没有证书的原始 URL, 从来没有证书 嵌入 一种语义释放 用于推进. 语义 - 释放自己的 run() 覆盖 options.repositoryUrl 带有嵌入式 CI 符号的 URL( 例如) . https://x-access-token:[email protected]/...这样 git push 可进行非交互认证. ReleaseGateState 被设计成被写到文件或CI 文物,并读回其他地方, 所以它决不能携带证书.. detachRelease 在返回前将其换回原版. resumeRelease 重新定义它自己认证的按键 URL env 这是给的.
此软件包没有做什么
- 维修处后港/没有支持
addChannel路径. 语义放行可以在维护分支从下行合并时将已经发布的放行添加到额外的放行通道 -- -- 从标记新放行中结构上截然不同的流出,并有它自己的标记和推出步骤发生 在此之前publish甚至跑,没有之后.detachRelease掷出ReleaseGateConfigurationError而不是悄悄地处理它. - 无支持
extends(共享配置). 语义 - 释放自己的getConfig决定extends改为 apluginsPath用于装入相对于可共享配置所在位置的插件的地图, 但从未在返回值中曝光该地图—— 以后没有重运行, 无法重建它extends从零开始解析,其中resumeRelease没有配置文件可做.detachRelease掷出ReleaseGateConfigurationError若为cliOptions.extends已经设定. - 没有 Stdout/stder 秘密编辑 . 语义- 释放自己默认的导出包装进程 stdout/ stderr 从任何插件日志中去除敏感值( 磁盘、 证书), 通过
hook-std。 。 。 .detachRelease编号 :resumeRelease不要这样做,这是一个二级控制台的博客安全网, 不是一个标记的一部分,在打印之前的机械师 这个软件包是用来演示的, 并且增加了一个真正的依赖性来复制它, 它被评为不值得一个参考执行。 拥有可能记录机密的插件的呼叫者应该通过他们的CI提供者已经为此提供的任何机制来清除CI日志.
与 @ exadev/ building- 身份对齐
@exadev/build-identity 回答“这是一个真实的,标记的释放” 从活的git状态。 结合这个软件包,一个建筑可以报告一个真正的三态身份,而不只是两个:
import { resolveBuildIdentity } from '@exadev/build-identity';
import { readFile } from 'node:fs/promises';
const identity = resolveBuildIdentity(process.cwd(), 'exadev/example');
if (identity.kind === 'commit') {
// Not yet a release at all.
} else {
// A tag exists -- but was it actually published, or is it still sitting behind the gate?
const gateState: unknown = await readFile('release-gate-state.json', 'utf8')
.then(JSON.parse)
.catch(() => null);
const stillGated = gateState !== null;
}
这两个软件包之间没有代码依赖性——这是只使用文档的配对,因为 build-identity标记确认的事实和 release-gate出版确认的事实是两个独立有用的,可以独立核查的东西.
为什么一个精确的语义式发售版本针
这个包裹 深进口语义 释放自己的内部 lib/*.js 模块getConfig, (中文(简体) ), verify, (中文(简体) ), getBranches, (中文(简体) ), getCommits,插件管道建造器,以及更多) run()'所生之躯. semantic-release属于自己的 package.json 没有 exports 字段,所以没有什么能阻挡这些深层的导入 来解决 - 但只有它的单个默认导出 带有一个精密的保证。 轻微或补丁会改变这些内部的签名或行为,而不发出警告. package.json 针头 semantic-release 以及真实的端到端集成测试(一个可支配的git寄存器,一个真实的标签,一个真实的推动) 专门存在以捕捉未来的版本 默默地突破了其中的深层进口。 升级是一个经过人工审查的刻意步骤,而不是一个自动依赖的起伏.
公约
整个英国英语。 由承诺方实施的commitlint.config.ts)并自动由 semantic-release (单位:千美元)release.config.ts在每次推动 main。严格类型脚本,否 any,没有不合理的类型断言 -- -- 见 eslint.config.ts,该软件包用哪一种 @exadev/eslint-config。 。 。 .
出版
释放完全由 .github/workflows/ci.yml是因为 release 任务 : semantic-release 自上一个标签以来, 分析会通过 OIDC 信任的出版( 没有存储) 发布到 npmjs.org NPM_TOKEN),并创建标签和 GitHub Release。 具体步骤请参见该工作流程 CONTRIBUTING.md 一个全新的可信任的软件包 需要用手做一次 才能实现自动化.