portless 发布流程全解从 CHANGELOG 标记到 CI 自动 npm 发布的完整链路【免费下载链接】portlessReplace port numbers with stable, named local URLs. For humans and agents.项目地址: https://gitcode.com/GitHub_Trending/por/portlessportless 是一款用「稳定、可命名的 .localhost 域名 URL」替代端口号的本地开发代理工具它的发布流程堪称自动化范本维护者只需手动写好 CHANGELOG.md 中的标记块并升级版本号合并到main后CI 就会自动比对 npm 上的版本、构建并npm publish最后从 changelog 标记里提取 Release Notes 创建 GitHub Release。本文带你完整走一遍这条「手动 5 分钟、机器全自动」的发布链路。一图看懂portless 自动发布链路整条链路由两个工作流协作完成.github/workflows/ci.yml每次合并前的质量门禁.github/workflows/release.yml真正的发布流水线3 个 Job发布前准备4 步打好版本标记portless 的发布是「手动单 PR」模式见 AGENTS.md 的 Releasing 章节维护者在合入前完成 4 件事建分支例如prepare-v1.2.0升级版本号修改packages/portless/package.json中的version字段写 changelog 条目并打上标记在 CHANGELOG.md 的最新版条目中用!-- release:start --和!-- release:end --两个 HTML 注释包裹本次更新内容收尾移除上一版条目里的标记保证任何时刻只有最新版带标记并在文档站 changelog 页面 apps/docs/src/app/changelog/page.mdx 添加对应条目 为什么是「注释标记」而不是直接按标题切分因为 Release Notes 的提取逻辑很简单粗暴——awk只打印两个标记之间的内容不需要解析 Markdown 层级既可靠又零依赖。Job 1check-release版本对比就是发布开关release.yml的第一个 Job 只做一件事比较「仓库里的版本」和「npm 上的版本」。读取本地packages/portless/package.json的version执行npm view portless version查询 npm 上已发布的版本版本不同→ 输出should_releasetrue触发后续发布版本相同→ 跳过 npm 发布但如果对应的v版本号标签缺失仍会补建 GitHub Release这个设计有两个巧妙的幂等保障️ 重复推送同一版本不会重复发布npm 版本是「唯一事实源」 万一某次发布中断比如 npm 成功但建标签失败下次触发流水线会自动补上缺失的 Release另外 concurrency 配置 保证了同一分支同时只跑一条发布流水线避免并发冲突。Job 2publish一次带「出处证明」的 npm 发布publishJob 只在版本确实变化时执行流程为pnpm install --frozen-lockfile # 锁定依赖 pnpm build # 通过 Turborepo 构建各包 npm publish --provenance # 在 packages/portless 目录发布这里有 3 个值得新手关注的细节①--provenance发布来源证明发布包会携带一个由 CI 签名生成的provenance元数据用户可以用npm view portless验证「这个包确实来自这个仓库的这次构建」防投毒能力拉满。它依赖 Job 上的id-token: write权限 通过 OIDC 临时令牌完成签名仓库里不需要存放任何 npm token。②environment: Release部署环境闸门publish Job 声明了environment: Release维护者可以为此环境配置审批规则给发布加一道人工确认。③ 构建细节有讲究pnpm build由 turbo.json 调度portless包用 tsup 打包tsup.config.ts 会把package.json里的版本号注入到编译产物中__VERSION__常量保证 CLI 运行时能报出正确版本。同时files: [dist]确保发布包里只包含构建产物不含源码。Job 3github-release从标记块提取 Release Notes最后一个 Job 负责把 changelog 内容变成用户可见的 GitHub Release用awk提取CHANGELOG.md中!-- release:start --与!-- release:end --之间的内容写入release-notes.md防呆校验提取结果不足 2 行就报错退出——防止标记块被误删或写空导致用户看到一个空壳 Release若v版本号标签不存在执行gh release create创建 Release标题即版本号执行条件if 表达式也值得品味always()且npm 发布成功或被跳过这样无论是完整发布还是纯补标签场景Release 都能正确落地。发布之前的质量门禁CI 与本地钩子自动发布的底气来自合并前的多层拦截GitHub Actions CI.github/workflows/ci.yml在推送到main或 PR 时依次执行步骤命令作用格式化检查pnpm format:checkPrettier 风格一致性静态检查pnpm lintESLint 代码规范类型检查pnpm type-checkTypeScript 类型安全构建pnpm build验证可构建单元测试pnpm test核心逻辑正确性端到端测试pnpm test:e2e真实启动代理验证此外还有ci-windowsJob在 Windows 上真实安装「开机自启服务」校验计划任务配置并确认代理在 18080 端口监听最后上传任务 XML 作为证据存档——跨平台行为不会只靠「看起来没问题」。本地提交钩子Husky 的pre-commit触发 lint-staged配合根 package.json 的lint-staged配置只对本次改动的文件跑 ESLint Prettier保证进入仓库的代码都是干净的。环境一致性仓库用.node-versionNode 24统一本地与 CI 的 Node 版本pnpm 版本由 package.json 的packageManager字段锁定任何人 clone 后克隆环境都一致git clone https://gitcode.com/GitHub_Trending/por/portless新手常见疑问 FAQQ1忘了打release:start标记会怎样npm 发布照常完成但创建 GitHub Release 的 Job 会因「提取内容不足 2 行」而失败。npm 版本已发布后续重新触发流水线即可补建 Release。Q2会重复发布吗不会。发布开关是「本地版本 ≠ npm 版本」同一版本号无论推送多少次最多发布一次且缺标签会自动补。Q3为什么选 pnpm Turborepo 而不是单包项目portless 是 monorepopnpm workspace Turboreponpm 包、文档站Next.js、示例和 e2e 测试共存。turbo.json 定义了任务依赖图test依赖build、test:e2e依赖portless#build保证测试永远跑在最新构建产物上。Q4我想发一个紧急小修版本流程有捷径吗没有捷径也没有必要建分支 → 升版本 → 写 changelog 标记 → 合入全程不超过 5 分钟剩下的都交给 CI。小结portless 的发布链路把「人的判断力」和「机器的可靠性」分工得很清楚人负责决定「发什么、怎么写 changelog」机器负责「比对版本、可信构建、签名发布、生成 Release」且全程幂等可重试。对想给自己的项目搭发布流水线的同学来说这套「changelog 标记 版本对比开关 --provenance发布」的组合非常值得直接抄作业。【免费下载链接】portlessReplace port numbers with stable, named local URLs. For humans and agents.项目地址: https://gitcode.com/GitHub_Trending/por/portless创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考