用于单仓库的黑客式语义发布
这是一个概念验证项目,它包装了semantic-release以适用于单仓库。
这个包应该能够正常工作,但可能不够稳定,不适合用于重要的生产环境,因为它高度依赖于semantic-release的工作方式(所以在semantic-release的未来版本中可能会出现问题或过时)。
semantic-release最好的特点之一是可以忘记版本号。但在单仓库中,对于本地依赖(在同一个单仓库中被引用为dependencies、devDependencies或peerDependencies的包)仍然需要大量的版本号管理。然而,在multi-semantic-release中,本地依赖的版本号会在发布时被写入package.json。这意味着不再需要硬编码版本号(我们建议在您的仓库代码中直接使用*星号)。
yarn add multi-semantic-release --dev npm i multi-semantic-release -D
multi-semantic-release [选项] npx multi-semantic-release [选项]
发布的配置与semantic-release配置相同,即在package.json的release键下或任何类型的.releaserc文件中设置,如.yaml、.json。
但在multi-semantic-release中,这种配置可以在全局(在您的顶级目录中)或每个包(在该单独包的目录中)中完成。如果您同时设置了两者,则每个包的设置将覆盖全局设置。
multi-semantic-release不支持任何命令行参数(这是不可能的,除非复制semantic-release的文件,而我一直在尽量避免这样做)。
multi-semantic-release自动检测以下包管理器的工作空间中的包:
确保在您的package.json项目文件中有一个workspaces属性。在那里,您可以设置一个包列表,这些包可能会在msr过程中被处理,也可以忽略其他包。例如,假设您的项目有4个包(即a、b、c和d),您只想处理a和d(忽略b和c)。您可以在package.json文件中设置以下结构:
{ "name": "msr-test-yarn", "author": "Dave Houlbrooke <dave@shax.com", "version": "0.0.0-semantically-released", "private": true, "license": "0BSD", "engines": { "node": ">=8.3" }, "workspaces": [ "packages/*", "!packages/b/**", "!packages/c/**" ], "release": { "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator" ], "noCi": true } }
确保在项目根目录的pnpm-workspace.yaml中有一个packages属性。在那里,您可以设置一个包列表,这些包可能会在msr过程中被处理,也可以忽略其他包。例如,假设您的项目有4个包(即a、b、c和d),您只想处理a和d(忽略b和c)。您可以在pnpm-workspace.yaml文件中设置以下结构:
packages: - 'packages/**' - '!packages/b/**' - '!packages/c/**'
注意,包版本中的workspace:前缀目前还不支持。issues/85
确保在您的package.json项目文件中有一个bolt.workspaces属性。在那里,您可以设置一个包列表,这些包可能会在msr过程中被处理,也可以忽略其他包。例如,假设您的项目有4个包(即a、b、c和d),您只想处理a和d(忽略b和c)。您可以在package.json文件中设置以下结构:
{ "name": "msr-test-bolt", "author": "Dave Houlbrooke <dave@shax.com", "version": "0.0.0-semantically-released", "private": true, "license": "0BSD", "engines": { "node": ">=8.3" }, "bolt": { "workspaces": [ "packages/*", "!packages/b/**", "!packages/c/**" ] }, "release": { "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator" ], "noCi": true } }
有几个调整可以使msr适应一些特殊情况:
| 标志 | 类型 | 描述 | 默认值 |
|---|---|---|---|
--sequential-init | 布尔值 | 避免假设的并发初始化冲突 | false |
--debug | 布尔值 | 输出调试信息 | false |
--first-parent | 布尔值 | 仅对当前分支应用提交过滤 | false |
--deps.bump | 字符串 | 定义依赖版本更新规则。<ul><li>override — 用下一个版本替换任何先前版本</li><li>satisfy — 检查下一个包版本是否符合其当前引用。如果匹配(*匹配任何版本,1.1.0匹配1.1.x,1.5.0匹配^1.0.0等),则不会触发发布;如果不匹配,则应用override策略;inherit将尝试遵循当前声明的版本/范围。~1.0.0 + minor变为~1.1.0,1.x + major变为2.x,但1.x + minor仍为1.x,因此不会发布,等等。</li><li>ignore 阻止MSR更新依赖</li></ul> 实验性功能 | override |
--deps.release | 字符串 | 如果任何依赖项发生更改,定义依赖包的发布类型。<ul><li>patch、minor、major — 严格声明更新任何依赖时发生的发布类型;</li><li>inherit — 将更新的依赖中"最高"的发布类型应用于包。<br/>例如,如果任何依赖有破坏性变更,major发布将应用于链上的所有依赖项。</li></ul> 实验性功能 | patch |
--deps.prefix | 字符串 | 如果--deps.bump设置为override,可选择附加到下一个版本的前缀。支持的值:^ | ~ | ''(空字符串) | ''(空字符串) |
--dry-run | 布尔值 | 演练模式 | false |
--ignore-packages | 字符串 | 在升级过程中要忽略的包列表(附加到package.json工作区中已存在的包) | null |
--ignore-private-packages | 布尔值 | 忽略私有包 | false |
示例:
$ multi-semantic-release --debug
$ multi-semantic-release --deps.bump=satisfy --deps.release=patch
$ multi-semantic-release --ignore-packages=packages/a/**,packages/b/**
你还可以将CLI的--ignore-packages选项与package.json的workspaces属性中每个包内的!操作符结合使用。尽管你可以使用CLI忽略选项,但不能使用它来设置要发布的包 - 也就是说,你仍需要在package.json中设置workspaces属性。
⚠️ 请注意,allowUnknownFlags已启用,因此其余标志将作为options参数传递给所有包的内部semrel调用。
multi-semantic-release默认导出一个multirelease()方法,该方法接受以下参数:
packages 包含package.json文件字符串路径的数组options 包含默认semantic-release配置选项的对象multirelease()返回一个描述多重发布结果的对象数组( 对应传入的packages数组)。
const multirelease = require("multi-semantic-release"); multirelease([ `${__dirname}/packages/my-pkg-1/package.json`, `${__dirname}/packages/my-pkg-2/package.json`, ]);
Multi-semantic release似乎与许多CI/CD系统兼容。至少我们确定了三个,以下是配置示例:
发布monorepo时,你可能会遇到npm ERR! code ETARGET错误。这是因为npm version在MSR尚未更新的未来依赖版本上创建了重新验证更新。
最简单的解决方法是在.npmrc中设置workspaces-update为false,或手动运行npm config set workspaces-update false
发布monorepo时,你可能会遇到EINVALIDNPMTOKEN错误。包越多,出错的机会就越大,很遗憾。
INVALIDNPMTOKEN 无效的npm令牌。 在NPM_TOKEN环境变量中配置的npm令牌(https://github.com/semantic-release/npm/blob/master/README.md#npm-registry-authentication)必须是有效的令牌(https://docs.npmjs.com/getting-started/working_with_tokens),允许发布到注册表https://registry.npmjs.org/。
不要急于更改你的令牌。_也许_这与你的注册表上的npm whoami请求限流有关(仅是假设:https://github.com/semantic-release/npm/pull/416)。此时你可以:
这个错误似乎与并发的git调用有关(issues/24)。或者可能不是。
无论如何,我们添加了一个特殊的--sequental-init标志来对这些调用进行排队。
只要按照支持的包管理器之一的工作区功能配置工作区,就会自动查找包。
我知道Lerna现在是最知名的工具,但未来似乎很明显它将被Yarn和NPM的功能直接替代。如果你现在(2019年1月)使用Yarn工作区,那么发布是Lerna_真正_需要的唯一剩余功能(尽管如果Yarn添加并行脚本执行会很好)。因此,使用multi-semantic-release意味着你可能可以完全从项目中移除Lerna。
其他支持monorepo的semantic-release包通过迭代进入每个包并运行semantic-release命令来工作。这在概念上很简单,但不幸的是不可行,因为:
一个关键要求是优雅地处理本地依赖版本号。multi-semantic-release执行以下操作:
patch升级package.json文件(覆盖任何现有值)上述意味着,可能如果有人在多重发布_期间_(在所有依赖都以其下一个版本发布之前)升级依赖并从NPM拉取包,那么他们的npm install将失败(如果他们几分钟后再次尝试,就会成功)。权衡之下,我认为保持原子正确性更重要(假设项目提交了它们的锁文件,这种情况应该相当罕见)。
这是multi-semantic-release最棘手的部分,也是最可能破坏依赖的部分。我预计这将在未来引起维护问题。在理想情况下,semantic-release将内置对monorepo的支持(使得这个包变得不必要)。
我最终集成的方式是为semantic-release创建一个自定义的"内联插件",并将其作为唯一的插件传递给semanticRelease()。然后,这个插件调用任何其他配置的插件来检索并可能修改响应。
该插件同时启动所有发布,然后在不同点暂停它们(使用 Promises),以允许多发布中的其他包赶上进度。这主要是为了在发布任何包之前确定所有包的版本号。这使我们能够对本地依赖项已升级的发布进行"补丁"升级,并在每个 package.json 中准确写入本地依赖项的版本。
内联插件执行以下操作:
context.commits 替换为仅限于该文件夹的提交列表plugins.analyzeCommits() 获取下一个发布类型(例如来自 @semantic-release/commit-analyzer)patchplugins.generateNotes() 获取发布说明(例如来自 @semantic-release/release-notes-generator)package.json 的 dependencies、devDependencies、peerDependencies 中为本地依赖项写入正确的版本git push,多个同时发布会失败,因为 Git 引用未锁定 — semantic-release 应该使用 execa.sync() 使 Git 操作具有原子性)与 semantic release 的集成相当不完善 — 以下是这个包难以维护的原因简要总结:
@semantic-release/commit-analyzer 使用前过滤 context.commits 对象(使其只列出相应目录的提交)。context.commits 非常困难!我最终通过创建一个内联插件并通过 options.plugins 将其传递给 semanticRelease() 来实现plugins.analyzeCommits() 并覆盖 context.commits — 参见 createInlinePluginCreator.jsdependencies 指向内部包),这一步还会在它们中任何一个升级时进行 patch 升级。.releaserc 和每个目录的单个包覆盖)。git tag 异步执行而陷入奇怪的状态execa() 的调用应该替换为 execa.sync() 以确保 Git 的内部状态是原子的。Synchronizer 是其中的精髓。它对于使 标签和提交发布阶段严格按顺序进行至关重要。事件发射器允许:
发布始终使用 my-pkg-1@1.0.1 格式的 tagFormat 作为 Git 标签,并始终覆盖 semantic-release 配置中设置的任何 gitTag。
我个人可以看到这个选项在协调 semantic-release 方面的潜力(例如,使两个具有相同标签的包始终同时升级和发布)。不幸的是,由于 semantic-release 中可用的集成点,在发布时阻止第二个包创建重复标签(导致错误)实际上是不可能的。
要使 tagFormat 选项按预期工作,需要进行以下操作:
v1.0.0 将具有与 Lerna 的固定模式相同的效果(所有更改的 monorepo 包同时发布)欢迎提出任何类型的问题:错误、功能请求或问题。 你随时可以提出 PR。只需 fork 这个仓库,编写一些代码,添加一些测试,然后推送你的更改。 欢迎任何反馈。


AI一键生成PPT,就用博思AIPPT!
博思AIPPT,新一代的AI生成PPT平台,支持智能生成PPT、AI美化PPT、文本&链接生成PPT、导入Word/PDF/Markdown文档生成PPT等,内置海量精美PPT模板,涵盖商务、教育、科技等不同风格,同时针对每个页面提供多种版式,一键自适应切换,完美适配各种办公场景。


AI赋能电商视觉革命,一站式智能商拍平台
潮际好麦深耕服装行业,是国内AI试 衣效果最好的软件。使用先进AIGC能力为电商卖家批量提供优质的、低成本的商拍图。合作品牌有Shein、Lazada、安踏、百丽等65个国内外头部品牌,以及国内10万+淘宝、天猫、京东等主流平台的品牌商家,为卖家节省将近85%的出图成本,提升约3倍出图效率,让品牌能够快速上架。


企业专属的AI法律顾问
iTerms是法大大集团旗下法律子品牌,基于最先进的大语言模型(LLM)、专业的法律知识库和强大的智能体架构,帮助企业扫清合规障碍,筑牢风控防线,成为您企业专属的AI法律顾问。


稳定高效的流量提升解决方案,助力品牌曝光
稳定高效的流量提升解决方案,助力品牌曝光


最新版Sora2模型免费使用,一键生成无水印视频
最新版Sora2模型免费使用,一键生成无水印视频


实时语音翻译/同声传译工具
Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。


选题、配图、成文,一站式创作,让内容运营更高效
讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。


AI辅助编程,代码自动修复
Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。


最强AI数据分析助手
小浣熊家族Raccoon,您的AI智能助手,致力于通过先进的人工智能技术,为用户提供高效、便捷的智能服务。无论是日常咨询还是专业问题解答,小浣熊都能以快速、准确的响应满足您的需求,让您的生活更加智能便捷。


像人一样思考的AI智能体
imini 是一款超级AI智能体,能根据人类指令,自主思考、自主完成、并且交付结果的AI智能体。
最新AI工具、AI资讯
独家AI资源、AI项目落地

微信扫一扫关注公众号