pre-release

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

pre-release — Release Readiness & Changeset Generation

预发布 — 发布就绪检查与变更集生成

A structured pre-release workflow that runs automated checks, generates user-facing changesets from git history, and optionally spawns fresh-eyes README reviewers.
这是一个结构化的预发布工作流,可运行自动化检查、从Git历史生成面向用户的变更集,还可选择性地发起全新视角的README审查。

When to Use

适用场景

  • Before any
    npm publish
    or version bump
  • When you need to generate CHANGELOG entries from recent work
  • Before merging a release PR
  • Any time you want a release-readiness report
  • 在执行任何
    npm publish
    或版本升级之前
  • 当你需要从近期工作中生成CHANGELOG条目时
  • 在合并发布PR之前
  • 任何需要获取发布就绪报告的时刻

Prerequisites

前置条件

The target project must have
@changesets/cli
initialized:
bash
npm install --save-dev @changesets/cli @changesets/changelog-github
npx changeset init
See Changesets Setup for first-time configuration.
目标项目必须已初始化
@changesets/cli
bash
npm install --save-dev @changesets/cli @changesets/changelog-github
npx changeset init
首次配置请查看Changesets 配置

The Workflow

工作流

Step 1: Pre-Flight Checks

步骤1:预发布预检

Run these checks against the project root. Report each as ✅ / ❌ / ⚠️:
#CheckHow
1README.md exists with: purpose, install, usage, prerequisites, licenseRead and verify sections
2LICENSE file present and matches
package.json
license field
Compare files
3No hardcoded credentials, API keys, or personal paths in tracked files
git grep -iE '(api.key|secret|password|token|/Users/|/home/|C:\\\\Users)' -- ':!*.lock' ':!node_modules'
4No TODO/FIXME/HACK in shipped code
git grep -iE '(TODO|FIXME|HACK)' -- '*.ts' '*.js' '*.mjs' ':!node_modules' ':!*.test.*' ':!*.spec.*'
5Tests pass
npm test
(or project's test command)
6Lint passes
npm run lint
(if script exists)
7Build succeeds
npm run build
(if script exists)
8Git working tree clean
git status --porcelain
9On correct branch
git branch --show-current
(should be
main
or release branch)
10.gitignore covers:
node_modules
,
dist
,
.env
, editor config
Read
.gitignore
11
package.json
has required fields: name, version, description, license, repository
Read and verify
12
.changeset/config.json
exists and is configured
Read and verify
13GitHub Actions release workflow uses Trusted Publishers (OIDC), not
NPM_TOKEN
Read
.github/workflows/release.yml
; verify
id-token: write
permission present and no
NPM_TOKEN
/
NODE_AUTH_TOKEN
secrets used
14Trusted Publisher configured on npmjs.com for this packageAsk user to confirm (cannot be checked programmatically)
15History scan clean (gitleaks + trufflehog)
gitleaks detect --source . --verbose
AND
trufflehog git file://. --since-commit=HEAD~0 --fail
— both must pass with zero findings
16Workflow security auditRead all
.github/workflows/*.yml
— verify: least-privilege
permissions:
(job-level, not
write-all
), actions pinned by SHA (not tag), no
pull_request_target
with PR head checkout, no secret interpolation in
echo
/
$GITHUB_OUTPUT
/
$GITHUB_ENV
, no broad
GITHUB_TOKEN
perms, no
env
dumping in debug steps
17Template-only values in examples
git grep -rE '(ghp_[A-Za-z0-9]{36}|npm_[A-Za-z0-9]{36}|sk-[A-Za-z0-9]{48}|AKIA[A-Z0-9]{16}|xox[bprs]-)' -- ':!node_modules' ':!*.lock'
— must be zero; all example configs must use
<REPLACE_ME>
placeholders
18No
.local
files tracked
git ls-files '*.local' '*.local.*' '.env.local'
— must return empty
19Redaction review for docs & screenshotsScan README, docs/, and any images for: internal domains (
*.internal
,
*.corp
), tenant/account IDs, internal route patterns, environment naming conventions, unredacted screenshots
20Skills discovery (if project ships skills)Only if
SKILL.md
files exist: (a)
.well-known/skills/index.json
exists and lists every skill found by
find . -name SKILL.md
, (b) README lists every skill in a discoverable table, (c)
package.json
files
includes
.well-known/
. Run
npx skills add . --list
and verify output matches expectations.
Blockers (must fix before release): checks 1-5, 8, 11-18, 20 (if applicable). Warnings (should fix): checks 6-7, 9-10, 19. Info: anything else notable.
针对项目根目录运行以下检查,每项结果标记为✅ / ❌ / ⚠️:
序号检查项检查方式
1README.md包含:用途、安装、使用方法、前置条件、许可证读取并验证各章节
2存在LICENSE文件且与
package.json
中的许可证字段匹配
对比文件内容
3已跟踪文件中无硬编码凭证、API密钥或个人路径
git grep -iE '(api.key|secret|password|token|/Users/|/home/|C:\\\\Users)' -- ':!*.lock' ':!node_modules'
4发布代码中无TODO/FIXME/HACK标记
git grep -iE '(TODO|FIXME|HACK)' -- '*.ts' '*.js' '*.mjs' ':!node_modules' ':!*.test.*' ':!*.spec.*'
5测试通过
npm test
(或项目的测试命令)
6代码检查通过
npm run lint
(若存在该脚本)
7构建成功
npm run build
(若存在该脚本)
8Git工作区干净
git status --porcelain
9当前处于正确分支
git branch --show-current
(应为
main
或发布分支)
10.gitignore已覆盖:
node_modules
dist
.env
、编辑器配置
读取
.gitignore
11
package.json
包含必填字段:name、version、description、license、repository
读取并验证
12
.changeset/config.json
已存在且配置正确
读取并验证
13GitHub Actions发布工作流使用可信发布者(OIDC),而非
NPM_TOKEN
读取
.github/workflows/release.yml
;验证存在
id-token: write
权限,且未使用
NPM_TOKEN
/
NODE_AUTH_TOKEN
密钥
14npmjs.com上已为该包配置可信发布者请用户确认(无法通过编程方式检查)
15历史记录扫描干净(gitleaks + trufflehog)
gitleaks detect --source . --verbose
trufflehog git file://. --since-commit=HEAD~0 --fail
—— 两者必须零结果通过
16工作流安全审计读取所有
.github/workflows/*.yml
—— 验证:最小权限
permissions:
(作业级别,而非
write-all
)、操作通过SHA固定(而非标签)、无
pull_request_target
配合PR头部检出、无在
echo
/
$GITHUB_OUTPUT
/
$GITHUB_ENV
中插入密钥、无宽泛的
GITHUB_TOKEN
权限、无在调试步骤中打印环境变量
17示例中仅使用模板值
git grep -rE '(ghp_[A-Za-z0-9]{36}|npm_[A-Za-z0-9]{36}|sk-[A-Za-z0-9]{48}|AKIA[A-Z0-9]{16}|xox[bprs]-)' -- ':!node_modules' ':!*.lock'
—— 结果必须为零;所有示例配置必须使用
<REPLACE_ME>
占位符
18
.local
文件被跟踪
git ls-files '*.local' '*.local.*' '.env.local'
—— 必须返回空
19文档与截图的脱敏审查扫描README、docs/及所有图片,检查是否包含:内部域名(
*.internal
*.corp
)、租户/账户ID、内部路由模式、环境命名规范、未脱敏截图
20技能发现(若项目发布技能)仅当存在
SKILL.md
文件时:(a)
.well-known/skills/index.json
已存在且列出所有通过
find . -name SKILL.md
找到的技能,(b) README在可发现的表格中列出所有技能,(c)
package.json
files
字段包含
.well-known/
。运行
npx skills add . --list
并验证输出符合预期。
阻塞项(发布前必须修复):检查项1-5、8、11-18、20(若适用)。 警告项(建议修复):检查项6-7、9-10、19。 信息项:其他值得注意的内容。

Step 2: Generate Changesets

步骤2:生成变更集

This is the core value — AI-written, user-facing release notes instead of mechanical commit scraping.
这是核心价值所在 —— 由AI编写的、面向用户的发布说明,而非机械的提交记录抓取。

2a. Find the range

2a. 确定范围

bash
undefined
bash
undefined

Last release tag

上一个发布标签

LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")

If no tags, use first commit

若无标签,使用首次提交

if [ -z "$LAST_TAG" ]; then RANGE="$(git rev-list --max-parents=0 HEAD)..HEAD" echo "No previous tags found — covering entire history" else RANGE="${LAST_TAG}..HEAD" echo "Changes since $LAST_TAG" fi
undefined
if [ -z "$LAST_TAG" ]; then RANGE="$(git rev-list --max-parents=0 HEAD)..HEAD" echo "未找到之前的标签 —— 覆盖全部历史" else RANGE="${LAST_TAG}..HEAD" echo "自$LAST_TAG以来的变更" fi
undefined

2b. Gather the raw material

2b. 收集原始素材

bash
undefined
bash
undefined

Commits with files changed

包含文件变更的提交

git log $RANGE --pretty=format:'%h %s' --no-merges
git log $RANGE --pretty=format:'%h %s' --no-merges

For more context on what changed

查看变更的更多上下文

git log $RANGE --pretty=format:'### %h %s%n%b' --no-merges
git log $RANGE --pretty=format:'### %h %s%n%b' --no-merges

Files changed (to understand scope)

变更的文件(了解范围)

git diff --stat $LAST_TAG..HEAD 2>/dev/null || git diff --stat $(git rev-list --max-parents=0 HEAD)..HEAD

Also check for **existing pending changesets** — don't duplicate:

```bash
ls .changeset/*.md 2>/dev/null | grep -v README.md
If there are already changeset files, read them and account for what's already covered.
git diff --stat $LAST_TAG..HEAD 2>/dev/null || git diff --stat $(git rev-list --max-parents=0 HEAD)..HEAD

同时检查**已存在的待处理变更集** —— 避免重复:

```bash
ls .changeset/*.md 2>/dev/null | grep -v README.md
若已存在变更集文件,请读取并确认已覆盖的内容。

2c. Classify and write changesets

2c. 分类并编写变更集

Group commits by impact and write changeset files. Each changeset is a markdown file in
.changeset/
:
File format (
.changeset/<descriptive-name>.md
):
markdown
---
"package-name": patch
---

Brief, user-facing description of what changed.
Semver classification:
TypeBumpExamples
Breaking API changes
major
Removed function, changed signature, dropped Node version
New features, capabilities
minor
New command, new option, new API
Bug fixes, docs, internal
patch
Fix crash, update README, refactor internals
Writing guidelines:
  • Write for users, not developers. "Added
    --verbose
    flag" not "refactored logger module"
  • Group related commits into a single changeset when they're part of one logical change
  • Use present tense: "Add", "Fix", "Remove", not "Added", "Fixed", "Removed"
  • If a commit is purely internal (CI, refactor with no behavior change), it can be omitted or grouped under a generic "Internal improvements" patch
  • One changeset per logical change, not per commit
Name the files descriptively using kebab-case:
add-verbose-flag.md
,
fix-auth-crash.md
,
initial-release.md
.
按影响程度分组提交,并编写变更集文件。每个变更集是
.changeset/
目录下的一个markdown文件:
文件格式
.changeset/<描述性名称>.md
):
markdown
---
"package-name": patch
---

简短的、面向用户的变更描述。
语义化版本分类:
类型版本升级幅度示例
破坏性API变更
major
移除函数、修改签名、放弃对旧Node版本的支持
新功能、新能力
minor
新增命令、新增选项、新增API
Bug修复、文档更新、内部优化
patch
修复崩溃、更新README、内部重构
编写指南:
  • 用户编写,而非开发者。例如写“新增
    --verbose
    标志”而非“重构日志模块”
  • 当多个提交属于同一逻辑变更时,将它们分组到一个变更集中
  • 使用现在时态:“Add”、“Fix”、“Remove”,而非“Added”、“Fixed”、“Removed”
  • 若提交纯为内部变更(CI、无行为变化的重构),可省略或归类到通用的“内部改进”patch变更集中
  • 每个逻辑变更对应一个变更集,而非每个提交对应一个
使用短横线命名法为文件命名
add-verbose-flag.md
fix-auth-crash.md
initial-release.md

2d. For initial releases (no previous tags)

2d. 首次发布(无之前的标签)

Write a single changeset covering the initial release:
markdown
---
"package-name": minor
---

Initial release.

- Feature 1: brief description
- Feature 2: brief description
- Feature 3: brief description
Use
minor
(0.1.0) for initial releases unless the project is already at 1.x.
编写一个覆盖首次发布的变更集:
markdown
---
"package-name": minor
---

首次发布。

- 功能1:简要描述
- 功能2:简要描述
- 功能3:简要描述
首次发布使用
minor
版本(0.1.0),除非项目已处于1.x版本。

Step 3: Fresh-Eyes README Review (Optional)

步骤3:全新视角的README审查(可选)

Load the
run-agents
skill. Use pi-subagents to spawn 2 parallel agents on different models to review the README as first-time users:
json
{ "tasks": [
    { "agent": "_arch-reviewer", "task": "Read the README.md in <project-path>. You are a developer who has NEVER seen this project. Can you answer: (1) What does it do? (2) How to install? (3) How to use? (4) Prerequisites? (5) Where to get help? For each: quote relevant text or say MISSING. Then list anything confusing or that assumes prior knowledge.", "model": "google/gemini-3-pro" },
    { "agent": "_arch-reviewer", "task": "Read the README.md in <project-path>. You are a developer who has NEVER seen this project. Can you answer: (1) What does it do? (2) How to install? (3) How to use? (4) Prerequisites? (5) Where to get help? For each: quote relevant text or say MISSING. Then list anything confusing or that assumes prior knowledge.", "model": "github-copilot/gpt-5.3" }
]}
Read both outputs and note any gaps.
加载
run-agents
技能。使用pi-subagents并行启动2个不同模型的代理,以首次接触项目的用户身份审查README:
json
{ "tasks": [
    { "agent": "_arch-reviewer", "task": "Read the README.md in <project-path>. You are a developer who has NEVER seen this project. Can you answer: (1) What does it do? (2) How to install? (3) How to use? (4) Prerequisites? (5) Where to get help? For each: quote relevant text or say MISSING. Then list anything confusing or that assumes prior knowledge.", "model": "google/gemini-3-pro" },
    { "agent": "_arch-reviewer", "task": "Read the README.md in <project-path>. You are a developer who has NEVER seen this project. Can you answer: (1) What does it do? (2) How to install? (3) How to use? (4) Prerequisites? (5) Where to get help? For each: quote relevant text or say MISSING. Then list anything confusing or that assumes prior knowledge.", "model": "github-copilot/gpt-5.3" }
]}
读取两个输出并记录任何遗漏点。

Step 4: Report

步骤4:生成报告

Present the final report in this structure:
markdown
undefined
按照以下结构呈现最终报告:
markdown
undefined

Pre-Release Report: <package-name>

预发布报告:<package-name>

Version: <current><proposed>

版本:<当前版本> → <提议版本>

Date: <today>

日期:<今日日期>

Checklist

检查清单

#CheckStatusNotes
1README✅/❌...
...
序号检查项状态备注
1README✅/❌...
...

Changesets Generated

生成的变更集

FileBumpSummary
add-feature-x.md
minorAdd feature X
...
文件版本升级幅度摘要
add-feature-x.md
minor新增功能X
...

README Review

README审查

(If Step 3 was run)
  • Gaps: ...
  • Confusing: ...
(若执行了步骤3)
  • 遗漏点:...
  • 易混淆点:...

Blockers (must fix)

阻塞项(必须修复)

  1. ...
  1. ...

Suggestions (can wait)

建议项(可延后)

  1. ...
  1. ...

Ready to Release?

是否准备好发布?

YES / NO — N blockers remain
undefined
/ 否 —— 仍有N个阻塞项
undefined

Step 5: Commit (if approved)

步骤5:提交(若获得批准)

If the user approves, commit the changeset files:
bash
git add .changeset/*.md
git commit -m "chore: add changesets for next release" -m "Co-Authored-By: Pi <noreply@pi.dev>"

若用户批准,提交变更集文件:
bash
git add .changeset/*.md
git commit -m "chore: add changesets for next release" -m "Co-Authored-By: Pi <noreply@pi.dev>"

Changesets Setup

Changesets配置

For projects that don't have changesets yet. Run once:
针对尚未配置changesets的项目,仅需运行一次:

1. Install

1. 安装

bash
npm install --save-dev @changesets/cli @changesets/changelog-github
npx changeset init
bash
npm install --save-dev @changesets/cli @changesets/changelog-github
npx changeset init

2. Configure
.changeset/config.json

2. 配置
.changeset/config.json

json
{
  "$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json",
  "changelog": "@changesets/changelog-github",
  "commit": false,
  "fixed": [],
  "linked": [],
  "access": "public",
  "baseBranch": "main",
  "updateInternalDependencies": "patch",
  "ignore": []
}
Set
"access": "public"
for scoped packages (
@scope/name
). Set
"baseBranch"
to your default branch.
json
{
  "$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json",
  "changelog": "@changesets/changelog-github",
  "commit": false,
  "fixed": [],
  "linked": [],
  "access": "public",
  "baseBranch": "main",
  "updateInternalDependencies": "patch",
  "ignore": []
}
对于作用域包(
@scope/name
),设置
"access": "public"
。 将
"baseBranch"
设置为你的默认分支。

3. Add npm scripts to
package.json

3. 向
package.json
添加npm脚本

json
{
  "scripts": {
    "changeset": "changeset",
    "version-packages": "changeset version",
    "release": "changeset publish"
  }
}
json
{
  "scripts": {
    "changeset": "changeset",
    "version-packages": "changeset version",
    "release": "changeset publish"
  }
}

4. GitHub Actions workflow (
.github/workflows/release.yml
)

4. GitHub Actions工作流(
.github/workflows/release.yml

yaml
name: Release

on:
  push:
    branches: [main]

concurrency: ${{ github.workflow }}-${{ github.ref }}

permissions:
  contents: write
  pull-requests: write
  id-token: write  # Required for npm Trusted Publishing (OIDC)

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 24  # npm >= 11.5.1 required for Trusted Publishing
          cache: npm
          registry-url: https://registry.npmjs.org

      - run: npm ci
      - run: npm run build
      - run: npm test

      - name: Create Release PR or Publish
        id: changesets
        uses: changesets/action@v1
        with:
          publish: npx changeset publish
          title: "chore: version packages"
          commit: "chore: version packages"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
yaml
name: Release

on:
  push:
    branches: [main]

concurrency: ${{ github.workflow }}-${{ github.ref }}

permissions:
  contents: write
  pull-requests: write
  id-token: write  # 用于npm可信发布(OIDC)的必填项

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 24  # npm >= 11.5.1 是可信发布的要求
          cache: npm
          registry-url: https://registry.npmjs.org

      - run: npm ci
      - run: npm run build
      - run: npm test

      - name: Create Release PR or Publish
        id: changesets
        uses: changesets/action@v1
        with:
          publish: npx changeset publish
          title: "chore: version packages"
          commit: "chore: version packages"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

5. Configure Trusted Publishing (recommended — no tokens needed)

5. 配置可信发布(推荐 —— 无需令牌)

npm's Trusted Publishing uses OIDC to authenticate GitHub Actions with the npm registry. No
NPM_TOKEN
secret required.
  1. Go to your package on npmjs.com → Settings → Trusted Publisher
  2. Select GitHub Actions and configure:
    • Organization or user: your GitHub username
    • Repository: your repo name
    • Workflow filename:
      release.yml
  3. That's it. The
    id-token: write
    permission in the workflow enables OIDC. Provenance attestations are generated automatically.
After verifying Trusted Publishing works, go to package Settings → Publishing access → "Require two-factor authentication and disallow tokens" for maximum security.
⚠️ NPM_TOKEN is deprecated: Do not use
NPM_TOKEN
secrets for publishing from GitHub Actions. Trusted Publishers (OIDC) is the only supported method. If you encounter an existing workflow using
NPM_TOKEN
, migrate it to Trusted Publishers. See: https://docs.npmjs.com/trusted-publishers

npm的可信发布使用OIDC验证GitHub Actions与npm注册表的身份,无需
NPM_TOKEN
密钥。
  1. 访问npmjs.com上你的包 → 设置 → 可信发布者
  2. 选择GitHub Actions并配置:
    • 组织或用户:你的GitHub用户名
    • 仓库:你的仓库名称
    • 工作流文件名
      release.yml
  3. 完成配置。工作流中的
    id-token: write
    权限启用了OIDC,溯源证明会自动生成。
验证可信发布正常工作后,进入包设置 → 发布权限 → **"要求双因素认证并禁用令牌"**以获得最高安全性。
⚠️ NPM_TOKEN已弃用:请勿在GitHub Actions的发布工作流中使用
NPM_TOKEN
密钥。可信发布者(OIDC)是唯一受支持的方式。若遇到使用
NPM_TOKEN
的现有工作流,请将其迁移到可信发布者。参考: https://docs.npmjs.com/trusted-publishers

Tips

小贴士

  • Run this skill early and often, not just before release. The checklist catches issues faster when run during development.
  • Edit generated changesets freely. They're just markdown files — tweak wording, merge entries, split large ones.
  • One changeset per PR is a good rhythm. The pre-release skill can also be run to generate changesets for a single PR's worth of work.
  • For monorepos, changesets handles multi-package versioning natively. List multiple packages in the frontmatter.
  • 尽早且频繁地运行此技能,不要只在发布前才用。在开发过程中运行检查清单能更快发现问题。
  • 自由编辑生成的变更集。它们只是markdown文件 —— 调整措辞、合并条目、拆分大条目均可。
  • 每个PR对应一个变更集是良好的节奏。预发布技能也可用于为单个PR的工作生成变更集。
  • 对于单仓库多包项目,changesets原生支持多包版本管理。在前置内容中列出多个包即可。