@icebreakers/monorepo-templates 1.0.15 → 1.1.0

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.
@@ -0,0 +1,26 @@
1
+ "@icebreakers/monorepo-templates@1.1.0":
2
+ dir: packages/monorepo-templates
3
+ intents:
4
+ - pnpm-native-versioning
5
+ - release-ci-token
6
+ - repoctl-release-orchestration
7
+ - vitest-native-config
8
+ "@icebreakers/monorepo@5.1.0":
9
+ dir: packages/monorepo
10
+ intents:
11
+ - close-legacy-release-pr
12
+ - human-readable-release-notes
13
+ - pnpm-native-versioning
14
+ - publish-versioned-packages
15
+ - release-ci-token
16
+ - release-links
17
+ - release-npm-links
18
+ - release-npm-links-prepublish
19
+ - release-pr-body
20
+ - release-pr-layout
21
+ - release-test-isolation
22
+ - repoctl-release-orchestration
23
+ create-icebreaker@1.1.0:
24
+ dir: packages/create-icebreaker
25
+ intents:
26
+ - pnpm-native-versioning
@@ -1,3 +1,4 @@
1
+ # repoctl-managed: release/v2
1
2
  name: Release
2
3
 
3
4
  on:
@@ -13,33 +14,37 @@ on:
13
14
  mode:
14
15
  description: Release operation
15
16
  required: true
16
- default: changesets
17
+ default: auto
17
18
  type: choice
18
19
  options:
19
- - changesets
20
+ - auto
21
+ - prepare
22
+ - publish
20
23
  - publish-unpublished
21
24
  package:
22
- description: Package used to verify an unpublished-version recovery
25
+ description: Package used for unpublished-version recovery
23
26
  required: false
24
27
  type: string
25
28
  version:
26
- description: Version used to verify an unpublished-version recovery
29
+ description: Version used for unpublished-version recovery
27
30
  required: false
28
31
  type: string
29
32
 
30
33
  concurrency: ${{ github.workflow }}-${{ github.ref }}
34
+
31
35
  env:
32
36
  HUSKY: 0
37
+ NPM_CONFIG_PROVENANCE: true
38
+ npm_config_registry: https://registry.npmjs.org
33
39
 
34
40
  permissions:
35
- contents: write # to create release (changesets/action)
36
- issues: write # to post issue comments (changesets/action)
37
- pull-requests: write # to create pull request (changesets/action)
38
- id-token: write # to use OpenID Connect token for provenance (changesets/action)
41
+ contents: write
42
+ pull-requests: write
43
+ id-token: write
39
44
 
40
45
  jobs:
41
46
  release:
42
- if: github.ref_name == 'main'
47
+ if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
43
48
  name: Release
44
49
  runs-on: ubuntu-latest
45
50
  steps:
@@ -53,95 +58,15 @@ jobs:
53
58
  with:
54
59
  node-version: 24
55
60
  cache: pnpm
61
+ registry-url: https://registry.npmjs.org
56
62
 
57
63
  - name: Install Dependencies
58
- run: pnpm i
59
-
60
- - name: Create Release Pull Request or Publish to npm
61
- if: github.event_name != 'workflow_dispatch' || inputs.mode == 'changesets'
62
- id: changesets
63
- uses: changesets/action@v2.0.0
64
- with:
65
- github-token: ${{ secrets.GITHUB_TOKEN }}
66
- publish-script: pnpm exec repo release stable
67
- env:
68
- # this doesn't work but semantic-release works
69
- # see https://github.com/sonofmagic/npm-lib-rollup-template/blob/main/.github/workflows/release.yml#L46
70
- # NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
71
- # NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
72
- npm_config_registry: https://registry.npmjs.org
73
- # https://github.com/changesets/changesets/pull/1659
74
- NPM_CONFIG_PROVENANCE: true
75
-
76
- - name: Validate unpublished-version recovery
77
- if: github.event_name == 'workflow_dispatch' && inputs.mode == 'publish-unpublished'
78
- shell: bash
79
- env:
80
- RECOVERY_PACKAGE: ${{ inputs.package }}
81
- RECOVERY_VERSION: ${{ inputs.version }}
82
- run: |
83
- if [[ -z "$RECOVERY_PACKAGE" || -z "$RECOVERY_VERSION" ]]; then
84
- echo "package and version are required for publish-unpublished" >&2
85
- exit 1
86
- fi
87
- actual_version="$(pnpm --filter "$RECOVERY_PACKAGE" exec node -p "require('./package.json').version")"
88
- if [[ "$actual_version" != "$RECOVERY_VERSION" ]]; then
89
- echo "Expected $RECOVERY_PACKAGE@$RECOVERY_VERSION on main, found $actual_version" >&2
90
- exit 1
91
- fi
92
-
93
- - name: Publish unpublished versions to npm
94
- if: github.event_name == 'workflow_dispatch' && inputs.mode == 'publish-unpublished'
95
- run: pnpm exec repo release stable
96
- env:
97
- npm_config_registry: https://registry.npmjs.org
98
- NPM_CONFIG_PROVENANCE: true
99
-
100
- - name: Verify recovered npm version
101
- if: github.event_name == 'workflow_dispatch' && inputs.mode == 'publish-unpublished'
102
- shell: bash
103
- env:
104
- RECOVERY_PACKAGE: ${{ inputs.package }}
105
- RECOVERY_VERSION: ${{ inputs.version }}
106
- run: |
107
- published_version="$(npm view "$RECOVERY_PACKAGE@$RECOVERY_VERSION" version)"
108
- test "$published_version" = "$RECOVERY_VERSION"
109
-
110
- - name: Push recovered release tags
111
- if: github.event_name == 'workflow_dispatch' && inputs.mode == 'publish-unpublished'
112
- run: git push origin --follow-tags
113
-
114
- - name: Upload coverage reports to Codecov
115
- uses: codecov/codecov-action@v7
116
- env:
117
- CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
118
-
119
- prerelease:
120
- if: github.event_name == 'push' && github.ref_name != 'main'
121
- name: Prerelease
122
- runs-on: ubuntu-latest
123
- steps:
124
- - name: Checkout Repo
125
- uses: actions/checkout@v7
126
-
127
- - uses: pnpm/action-setup@v6
128
-
129
- - name: Setup Node.js environment
130
- uses: actions/setup-node@v7
131
- with:
132
- node-version: 24
133
- cache: pnpm
134
-
135
- - name: Install Dependencies
136
- run: pnpm i
137
-
138
- - name: Configure Git
139
- run: |
140
- git config user.name "github-actions[bot]"
141
- git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
64
+ run: pnpm install --frozen-lockfile
142
65
 
143
- - name: Publish Prerelease
144
- run: pnpm exec repo release pre publish
66
+ - name: Run repo release CI
145
67
  env:
146
- npm_config_registry: https://registry.npmjs.org
147
- NPM_CONFIG_PROVENANCE: true
68
+ GITHUB_TOKEN: ${{ github.token }}
69
+ REPO_RELEASE_MODE: ${{ inputs.mode || 'auto' }}
70
+ REPO_RELEASE_PACKAGE: ${{ inputs.package }}
71
+ REPO_RELEASE_VERSION: ${{ inputs.version }}
72
+ run: pnpm exec repo release ci
package/assets/AGENTS.md CHANGED
@@ -40,7 +40,7 @@ When building TypeScript libraries (type-focused APIs or public type definitions
40
40
 
41
41
  ## Commit & Pull Request Guidelines
42
42
 
43
- Commits must conform to Conventional Commit syntax; recent history uses prefixes like `feat`, `fix`, and `chore`. Example: `feat(server): add auth router`. Use `pnpm commit` (commitlint prompt) or ensure your manual message passes `pnpm commitlint --edit`. Before opening a PR, make sure `pnpm lint` and `pnpm test` succeed, link related issues, and provide screenshots or logs for user-facing changes. Touching publishable packages requires a changeset (`pnpm changeset`) so releases stay traceable.
43
+ Commits must conform to Conventional Commit syntax; recent history uses prefixes like `feat`, `fix`, and `chore`. Example: `feat(server): add auth router`. Use `pnpm commit` (commitlint prompt) or ensure your manual message passes `pnpm commitlint --edit`. Before opening a PR, make sure `pnpm lint` and `pnpm test` succeed, link related issues, and provide screenshots or logs for user-facing changes. Touching publishable packages requires a pnpm change intent (`pnpm change`) so releases stay traceable.
44
44
 
45
45
  For AI-generated or AI-assisted changes, use this verification order before commit or PR:
46
46
 
@@ -30,8 +30,9 @@
30
30
  "typecheck": "turbo run typecheck",
31
31
  "format": "eslint . --fix",
32
32
  "validate": "pnpm run build && pnpm run lint && pnpm run typecheck && pnpm run tsd && pnpm run test",
33
- "release": "changeset",
34
- "publish-packages": "repo release stable",
33
+ "release": "pnpm change",
34
+ "version-packages": "pnpm version -r",
35
+ "publish-packages": "repo release stable publish",
35
36
  "release:pre": "repo release pre publish",
36
37
  "------": "--------------",
37
38
  "preinstall": "npx only-allow pnpm",
@@ -52,9 +53,7 @@
52
53
  "--------": "----------------"
53
54
  },
54
55
  "devDependencies": {
55
- "@changesets/cli": "^3.0.0",
56
- "@commitlint/cli": "^21.2.1",
57
- "@icebreakers/changelog-github": "^2.0.0",
56
+ "@commitlint/cli": "^21.2.2",
58
57
  "@icebreakers/monorepo": "workspace:*",
59
58
  "@types/node": "^26.2.0",
60
59
  "@types/semver": "^7.8.0",
@@ -76,7 +75,7 @@
76
75
  "tsdown": "0.22.14",
77
76
  "tslib": "^2.8.1",
78
77
  "tsx": "^4.23.12",
79
- "turbo": "^2.10.9",
78
+ "turbo": "^2.10.10",
80
79
  "type-fest": "^5.8.0",
81
80
  "typescript": "^6.0.3",
82
81
  "vitest": "~4.1.10",
@@ -6,6 +6,14 @@ packages:
6
6
 
7
7
  minimumReleaseAge: 0
8
8
 
9
+ versioning:
10
+ fixed:
11
+ - ['@icebreakers/monorepo', repoctl]
12
+ ignore:
13
+ - '@icebreakers/client'
14
+ changelog:
15
+ storage: repository
16
+
9
17
  allowBuilds:
10
18
  '@tailwindcss/oxide': true
11
19
  esbuild: true
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@icebreakers/monorepo-templates",
3
3
  "type": "module",
4
- "version": "1.0.15",
4
+ "version": "1.1.0",
5
5
  "description": "Template assets for icebreaker monorepo scaffolding",
6
6
  "author": "ice breaker <hi@sonofmagic.top>",
7
7
  "license": "MIT",
@@ -15,7 +15,7 @@
15
15
  "typecheck": "pnpm cf-typegen:check && vue-tsc -b"
16
16
  },
17
17
  "dependencies": {
18
- "@faker-js/faker": "^10.5.0",
18
+ "@faker-js/faker": "^10.6.0",
19
19
  "@tanstack/vue-query": "^5.101.4",
20
20
  "@tanstack/vue-query-devtools": "^6.1.38",
21
21
  "@tanstack/vue-table": "^9.1.2",
@@ -30,8 +30,8 @@
30
30
  "vue-router": "^5.2.0"
31
31
  },
32
32
  "devDependencies": {
33
- "@cloudflare/vite-plugin": "^1.52.0",
34
- "@hono/node-server": "^2.1.0",
33
+ "@cloudflare/vite-plugin": "^1.52.1",
34
+ "@hono/node-server": "^2.1.1",
35
35
  "@hono/trpc-server": "^0.4.2",
36
36
  "@tailwindcss/vite": "^4.3.3",
37
37
  "@trpc/server": "^11.18.0",
@@ -39,14 +39,14 @@
39
39
  "@vitejs/plugin-vue-jsx": "^5.1.6",
40
40
  "@vue/tsconfig": "^0.9.1",
41
41
  "consola": "^3.4.2",
42
- "hono": "^4.13.1",
42
+ "hono": "^4.13.2",
43
43
  "tailwindcss": "^4.3.3",
44
44
  "typescript": "~6.0.3",
45
45
  "vite": "^8.2.1",
46
46
  "vite-plugin-vue-devtools": "^8.2.1",
47
47
  "vite-tsconfig-paths": "^6.1.1",
48
48
  "vue-tsc": "3.3.9",
49
- "wrangler": "^4.122.0",
49
+ "wrangler": "^4.123.0",
50
50
  "zod": "^4.4.3"
51
51
  }
52
52
  }
@@ -54,11 +54,11 @@
54
54
  "types": "./dist/index.d.ts"
55
55
  },
56
56
  "devDependencies": {
57
- "@hono/node-server": "^2.1.0",
57
+ "@hono/node-server": "^2.1.1",
58
58
  "consola": "^3.4.2",
59
- "hono": "^4.13.1",
59
+ "hono": "^4.13.2",
60
60
  "tsdown": "0.22.14",
61
- "wrangler": "^4.122.0",
61
+ "wrangler": "^4.123.0",
62
62
  "zod": "^4.4.3"
63
63
  }
64
64
  }
@@ -1,16 +1,13 @@
1
1
  import path from 'node:path'
2
- import { fileURLToPath } from 'node:url'
3
2
  import { defineVitestProjectConfig } from 'repoctl/tooling'
4
3
  import { defineProject } from 'vitest/config'
5
4
 
6
- const __dirname = path.dirname(fileURLToPath(import.meta.url))
7
-
8
5
  export default defineProject(await defineVitestProjectConfig({
9
6
  options: {
10
7
  alias: [
11
8
  {
12
9
  find: '@',
13
- replacement: path.resolve(__dirname, './src'),
10
+ replacement: path.resolve(import.meta.dirname, './src'),
14
11
  },
15
12
  ],
16
13
  },
@@ -1,16 +1,13 @@
1
1
  import path from 'node:path'
2
- import { fileURLToPath } from 'node:url'
3
2
  import { defineVitestProjectConfig } from 'repoctl/tooling'
4
3
  import { defineProject } from 'vitest/config'
5
4
 
6
- const __dirname = path.dirname(fileURLToPath(import.meta.url))
7
-
8
5
  export default defineProject(await defineVitestProjectConfig({
9
6
  options: {
10
7
  alias: [
11
8
  {
12
9
  find: '@',
13
- replacement: path.resolve(__dirname, './src'),
10
+ replacement: path.resolve(import.meta.dirname, './src'),
14
11
  },
15
12
  ],
16
13
  },
@@ -34,9 +34,9 @@ description: 说明这个页面解决的问题和适用场景。
34
34
 
35
35
  AI 入口应该保持显眼,但不要替代正常文档结构:
36
36
 
37
- | 页面类型 | 推荐位置 |
38
- | ------------------------------------- | ------------------------------------ |
39
- | repoctl 命令、校验、诊断、报告 | `/repoctl/` |
40
- | monorepo 和 npm 包基础知识 | `/knowledge/`、`/monorepo/`、`/why/` |
41
- | pnpm、Turborepo、changeset 等工具专题 | `/tools/` |
42
- | llms.txt 和 AI 工具读取约定 | `/ai/` |
37
+ | 页面类型 | 推荐位置 |
38
+ | -------------------------------------- | ------------------------------------ |
39
+ | repoctl 命令、校验、诊断、报告 | `/repoctl/` |
40
+ | monorepo 和 npm 包基础知识 | `/knowledge/`、`/monorepo/`、`/why/` |
41
+ | pnpm、Turborepo、versioning 等工具专题 | `/tools/` |
42
+ | llms.txt 和 AI 工具读取约定 | `/ai/` |
@@ -2,7 +2,7 @@
2
2
 
3
3
  `repoctl` is the user-facing package name for this monorepo toolkit. Its recommended command is `repo`.
4
4
 
5
- The CLI does not replace pnpm, Turborepo, or changesets. It gives teams a stable layer for common monorepo actions: setup, diagnostics, scaffolding, local verification, and template asset upgrades.
5
+ The CLI does not replace pnpm, Turborepo, or pnpm versioning. It gives teams a stable layer for common monorepo actions: setup, diagnostics, scaffolding, local verification, and template asset upgrades.
6
6
 
7
7
  ## When To Use It
8
8
 
@@ -12,7 +12,7 @@ description: repoctl 文档站的知识库入口,汇总 monorepo 管理、现
12
12
  | -------------------------------------------------- | ---------------------------------- |
13
13
  | [为什么往 monorepo 方向演进](../monorepo/index.md) | 判断多包仓库是否值得合并管理 |
14
14
  | [如何管理 monorepo](../monorepo/manage.md) | 理解 workspace、任务编排和依赖边界 |
15
- | [发包与变更日志](../monorepo/publish.md) | 设计 changeset、版本和发布链路 |
15
+ | [发包与变更日志](../monorepo/publish.md) | 设计 pnpm intent、版本和发布链路 |
16
16
  | [monorepo 命令参考](../monorepo/commands.md) | 查看通用 monorepo 操作命令 |
17
17
  | [monorepo 模板体系](../monorepo/templates.md) | 理解模板如何减少重复初始化 |
18
18
  | [monorepo 排障](../monorepo/troubleshooting.md) | 排查依赖、构建、类型和发布问题 |
@@ -47,7 +47,7 @@
47
47
  | 语言 | TypeScript 优先 |
48
48
  | 校验链路 | ESLint + Stylelint + typecheck + Vitest |
49
49
  | 提交规范 | Husky + lint-staged + commitlint |
50
- | 发包 | changesets |
50
+ | 发包 | pnpm versioning |
51
51
  | 命令入口 | `repo` 为主,`repoctl` 为完整包名入口 |
52
52
 
53
53
  这些选择的目的只有一个:减少“每个项目重新想一遍”的成本。
@@ -1,47 +1,10 @@
1
1
  # monorepo 发包与变更日志
2
2
 
3
- 这套模板默认推荐用 `changesets` 管理版本和 changelog。原因不是“它很流行”,而是它对 monorepo 的工作方式最顺手:
3
+ 这套模板默认使用 pnpm 原生 versioning。它保留 Changesets 格式的变更意图,同时把版本计算、依赖传播、changelog 和发布收进 pnpm 本身。
4
4
 
5
- - 变更是按包记录的
6
- - 版本升级能自动联动内部依赖
7
- - changelog 可以稳定产出
8
- - 很容易接到 CI 里
5
+ ## 日常流程
9
6
 
10
- repoctl 在发布流程里的位置很明确:它不替代 `changesets` 发布版本,而是在发布前帮你确认仓库状态、模板资产和校验计划。
11
-
12
- ## repoctl 在发布前做什么
13
-
14
- ```bash
15
- pnpm exec repo doctor --strict
16
- pnpm exec repo check --full
17
- pnpm exec repo env support --markdown --redact --out reports/support.md
18
- ```
19
-
20
- | 命令 | 发布前价值 |
21
- | ---------------------- | -------------------------------------------------------- |
22
- | `repo doctor --strict` | 确认仓库结构、Node、脚本、配置和提交链路没有漂移 |
23
- | `repo check --full` | 跑根脚本里的 lint/typecheck/test/build 计划 |
24
- | `repo env support` | 保存环境、配置、doctor 和 check plan,方便发布失败后回溯 |
25
-
26
- 发布本身仍交给 `changesets`:
27
-
28
- ```bash
29
- pnpm changeset
30
- pnpm exec repo release stable
31
- ```
32
-
33
- 正式发布只走 `main`;`alpha`、`beta`、`rc`、`next` 只做 Changesets 的 prerelease,并发布对应 tag 包。
34
-
35
- ## 一条务实的发布流程
36
-
37
- 先把顺序记住:
38
-
39
- 1. 写代码
40
- 2. 跑校验
41
- 3. 生成 changeset
42
- 4. 合并后 version / publish
43
-
44
- 对应到命令,一般是:
7
+ 先完成质量校验,再记录变更:
45
8
 
46
9
  ```bash
47
10
  pnpm build
@@ -49,212 +12,76 @@ pnpm lint
49
12
  pnpm typecheck
50
13
  pnpm tsd
51
14
  pnpm test
52
- pnpm changeset
15
+ pnpm change
16
+ pnpm change status
53
17
  ```
54
18
 
55
- 如果你改的是公开类型或类库 API,`tsd` 不要省。
56
-
57
- ## 为什么推荐 `changesets`
58
-
59
- | 需求 | `changesets` 的做法 |
60
- | -------------- | ----------------------------------------- |
61
- | 记录哪些包变了 | 每次变更生成单独的 `.changeset/*.md` 文件 |
62
- | 控制版本类型 | 明确选择 `patch` / `minor` / `major` |
63
- | 自动生成日志 | `changeset version` 统一产出 changelog |
64
- | 联动内部包版本 | 自动改内部依赖引用 |
65
- | CI 自动发布 | 可接 `changesets/action` |
19
+ 变更意图文件放在 `.changeset/*.md`,描述受影响包和 patch/minor/major。不要手动修改包版本。
66
20
 
67
- ## 日常开发阶段怎么做
21
+ ## Release PR
68
22
 
69
- ### 1. 本地先把质量门过掉
23
+ main push 会运行:
70
24
 
71
25
  ```bash
72
- pnpm build
73
- pnpm lint
74
- pnpm typecheck
75
- pnpm tsd
76
- pnpm test
26
+ pnpm version -r --dry-run
27
+ pnpm version -r
77
28
  ```
78
29
 
79
- 这一点和仓库的提交要求是一致的。
80
-
81
- ### 2. 记录 changeset
30
+ CI 将版本号、各包 `CHANGELOG.md` 和 `.changeset/ledger.yaml` 提交到 Release PR。合并 Release PR 后,下一次 main push 执行:
82
31
 
83
32
  ```bash
84
- pnpm changeset
33
+ pnpm publish -r --report-summary --provenance --no-git-checks
85
34
  ```
86
35
 
87
- 按提示选择:
36
+ pnpm 根据 registry 中已有的版本自动跳过已发布包。CI 读取 `pnpm-publish-summary.json` 创建 `package@version` tag 和 GitHub Release,发布操作可以安全重试。
88
37
 
89
- 1. 哪些包受影响
90
- 2. 这些包分别是 `patch` / `minor` / `major`
91
- 3. 这次改动怎么写进 changelog
38
+ ## Workspace versioning 配置
92
39
 
93
- 示例:
94
-
95
- ```md
96
- ---
97
- "@my/utils": minor
98
- "@my/ui": patch
99
- ---
100
-
101
- - feat(utils): 新增时间格式化工具
102
- - fix(ui): 修复按钮禁用态样式
103
- ```
104
-
105
- ### 3. 合并前看一眼影响面
106
-
107
- changeset 文件本身就是最便宜的“发布预告”。代码评审时顺手看一下,通常就能避免:
108
-
109
- - 漏记某个包
110
- - 版本类型选错
111
- - changelog 写得太含糊
112
-
113
- ## 发布阶段怎么做
114
-
115
- ### 手动流程
116
-
117
- ```bash
118
- pnpm exec repo release stable
119
- ```
120
-
121
- `repo release stable` 会先执行构建、lint 和测试,再调用 `changeset version` 与 `changeset publish`。其中 `changeset version` 会做这些事:
122
-
123
- - 更新受影响包的版本号
124
- - 调整内部依赖版本
125
- - 生成或更新每个包的 `CHANGELOG.md`
126
-
127
- ### CI 自动流程
128
-
129
- 模板推荐结合 `changesets/action`。
130
-
131
- 一个常见的工作流结构如下:
40
+ 根 `pnpm-workspace.yaml` 中的关键配置:
132
41
 
133
42
  ```yaml
134
- name: Release
135
-
136
- on:
137
- push:
138
- branches:
139
- - main
140
- - alpha
141
- - beta
142
- - rc
143
- - next
144
- workflow_dispatch:
145
-
146
- permissions:
147
- contents: write
148
- pull-requests: write
149
- issues: write
150
- id-token: write
151
-
152
- env:
153
- HUSKY: 0
154
-
155
- jobs:
156
- release:
157
- if: github.ref_name == 'main'
158
- runs-on: ubuntu-latest
159
- steps:
160
- - uses: actions/checkout@v7
161
- - uses: pnpm/action-setup@v6
162
- - uses: actions/setup-node@v7
163
- with:
164
- node-version: 24
165
- cache: pnpm
166
- registry-url: https://registry.npmjs.org
167
- - run: pnpm install
168
- - name: Create Release Pull Request or Publish to npm
169
- uses: changesets/action@v2.0.0
170
- with:
171
- github-token: ${{ secrets.GITHUB_TOKEN }}
172
- publish-script: pnpm exec repo release stable
173
- env:
174
- NPM_CONFIG_PROVENANCE: true
175
-
176
- prerelease:
177
- if: github.ref_name != 'main'
178
- runs-on: ubuntu-latest
179
- steps:
180
- - uses: actions/checkout@v7
181
- - uses: pnpm/action-setup@v6
182
- - uses: actions/setup-node@v7
183
- with:
184
- node-version: 24
185
- cache: pnpm
186
- - run: pnpm install
187
- - run: git config user.name "github-actions[bot]"
188
- - run: git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
189
- - name: Publish Prerelease
190
- run: pnpm exec repo release pre publish
43
+ versioning:
44
+ fixed:
45
+ - ['@icebreakers/monorepo', repoctl]
46
+ ignore:
47
+ - '@icebreakers/client'
48
+ changelog:
49
+ storage: repository
191
50
  ```
192
51
 
193
- ## 关于 npm 鉴权
52
+ `fixed` 保证组内包同版本;`ignore` 排除 private 包;`repository` 让 changelog 作为源代码提交。
194
53
 
195
- 现在更推荐在 CI 里使用 OIDC,而不是长期保存一个会过期的 `NPM_TOKEN`。
54
+ ## Prerelease lanes
196
55
 
197
- 原因很现实:
56
+ 预发布使用 pnpm lanes:
198
57
 
199
- - token 会过期
200
- - token 泄漏风险更高
201
- - OIDC 更适合自动化发布
202
-
203
- 所以工作流里建议保留:
204
-
205
- ```yaml
206
- permissions:
207
- id-token: write
58
+ ```bash
59
+ pnpm exec repo release pre enter beta
60
+ git add pnpm-workspace.yaml && git commit -m "chore(release): enter beta lane"
61
+ git push
62
+ pnpm exec repo release pre publish
208
63
  ```
209
64
 
210
- ## 常见发布约束
211
-
212
- ### 私有包不会被发布
65
+ 预发布版本为 `X.Y.Z-beta.N`,并使用 npm `beta` dist-tag。退出时运行:
213
66
 
214
- 如果一个包是:
215
-
216
- ```json
217
- {
218
- "private": true
219
- }
67
+ ```bash
68
+ pnpm exec repo release pre exit
69
+ git add pnpm-workspace.yaml && git commit -m "chore(release): exit prerelease lane"
220
70
  ```
221
71
 
222
- 那么它通常不会进入 npm 发布流程。
223
-
224
- ### 没有 changeset 就不会有版本 PR
225
-
226
- 如果你改了公开包,却没有提交 `.changeset/*.md`,那么后续版本流转通常会断掉。
227
-
228
- ### 先 build 再发
229
-
230
- 这个仓库的约定很明确:先 build,再 lint / typecheck / tsd / test,再谈发布。不要跳步。
231
-
232
- ## 常见问题
233
-
234
- ### 为什么没有生成 changelog?
235
-
236
- 通常是下面几种原因:
237
-
238
- - 没有执行 `pnpm changeset version`
239
- - `.changeset/*.md` 没有提交
240
- - 受影响包实际没有进入版本计算
241
-
242
- ### 如何跳过某个包的发布?
243
-
244
- - 在 changeset 里不要勾选它
245
- - 或者把它标记为 `private: true`
246
-
247
- ### 为什么要在 PR 阶段就看 changeset?
72
+ fixed group 必须整体切换 lane,不能只移动其中一个包。
248
73
 
249
- 因为它本质上是在回答一个非常具体的问题:
74
+ ## 恢复未发布版本
250
75
 
251
- “这次改动准备怎么影响发布面?”
76
+ 如果版本提交已合并但 npm 发布失败,在 Release workflow 手动选择 `publish-unpublished`,填入 package 和 version。CI 会校验 main 上的 manifest 版本,使用 pnpm 发布并重新生成 tag 和 GitHub Release 元数据。
252
77
 
253
- 这个问题越早看,越不容易在合并后补救。
78
+ ## repoctl 的边界
254
79
 
255
- ## 继续阅读
80
+ 生成的 GitHub Actions 只保留环境准备和一个 `pnpm exec repo release ci` 调用。
81
+ repoctl 负责发布前 build/lint/test、lane 一致性检查、Release PR、npm
82
+ 发布、package tag 与 GitHub Release;pnpm 负责变更意图、版本计算、changelog、
83
+ ledger 和 registry 发布细节。
256
84
 
257
- - [如何管理 monorepo](./manage.md)
258
- - [repoctl 工作流与 CI](../repoctl/workflows.md)
259
- - [repoctl 排障与报告](../repoctl/troubleshooting.md)
260
- - [命令别名](../repoctl/aliases.md)
85
+ 存量项目首次迁移运行 `pnpm dlx repoctl@latest upgrade --yes`,后续使用
86
+ `pnpm exec repo upgrade --yes` 即可跟随 repoctl 升级。未标记的自定义 release
87
+ workflow 默认不会被覆盖,确认后可使用 `repo upgrade --overwrite-release`。
@@ -35,7 +35,7 @@
35
35
  "mermaid": "^11.16.1",
36
36
  "tailwindcss": "^4.3.3",
37
37
  "vitepress": "^1.6.4",
38
- "vitepress-plugin-llms": "^1.13.4",
38
+ "vitepress-plugin-llms": "^1.13.5",
39
39
  "vitepress-plugin-mermaid": "^2.0.17"
40
40
  }
41
41
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  `repoctl` 是这套模板推荐给使用者的包名。默认命令是 `repo`,目标是把 pnpm workspace、Turborepo、模板创建、诊断报告和提交前校验收敛到一组稳定入口里。
4
4
 
5
- 它不替代 pnpm、Turbo 或 changesets,而是把这些工具在 monorepo 里的常见动作串起来。
5
+ 它不替代 pnpm、Turbo 或 pnpm versioning,而是把这些工具在 monorepo 里的常见动作串起来。
6
6
 
7
7
  ## 什么时候使用 repoctl
8
8
 
@@ -61,7 +61,7 @@
61
61
 
62
62
  ### 发包流程
63
63
 
64
- 我采用了 `changesets`,它在 `monorepo` 环境下发布非常方便。功能非常的多,具体可以查看官方文档。
64
+ 现在使用 pnpm 原生 versioning:用 `pnpm change` 记录意图,用 `pnpm version -r` 生成版本和 changelog,再用 `pnpm publish -r` 发布。版本计划保留在 `.changeset/ledger.yaml`,预发布则由 pnpm lanes 管理。
65
65
 
66
66
  ### Github 相关配置
67
67
 
@@ -1,98 +1,75 @@
1
- # Changesets
1
+ # pnpm Versioning
2
2
 
3
- [Changesets](https://github.com/changesets/changesets)。它帮助你在 **monorepo** 或多包项目中更有条理地维护变更日志(changelog)、版本号升级策略以及自动化发布流程。
3
+ 本模板使用 pnpm 11 原生 versioning 管理 monorepo 的变更意图、版本号、changelog 和发布。变更意图仍然使用 `.changeset/*.md` 格式,因此每次改动可以独立提交,不会直接修改包版本。
4
4
 
5
- 在 repoctl 体系里,Changesets 负责“版本和发布”,repoctl 负责“发布前仓库是否健康”。
5
+ ## 日常开发
6
6
 
7
7
  ```bash
8
- pnpm exec repo doctor --strict
9
- pnpm exec repo check --full
10
- pnpm changeset
11
- pnpm exec repo release stable
8
+ pnpm change
9
+ pnpm change status
12
10
  ```
13
11
 
14
- 继续看:[monorepo 发包与变更日志](../monorepo/publish.md)。
15
-
16
- ## 1. 什么是 Changeset?
17
-
18
- - **核心思想**:每一次改动,不直接修改 `package.json` 里的版本号,而是通过写一个 `changeset` 文件(通常放在 `.changeset` 文件夹下)。
19
- - **作用**:
20
- - 记录每次改动影响了哪些包(哪些需要 bump 版本)。
21
- - 指定改动类型(`patch`、`minor`、`major`)。
22
- - 自动生成 **Changelog**。
23
- - 自动修改 `package.json` 的版本号。
24
- - 与 CI/CD 集成后,可以实现一键自动发版。
25
-
26
- ## 2. 如何使用 Changesets?
27
-
28
- ### 安装
12
+ `pnpm change` 会询问受影响的包、patch/minor/major 类型和 changelog 摘要。脚本或自动化场景可以直接指定:
29
13
 
30
14
  ```bash
31
- npm install --save-dev @changesets/cli
15
+ pnpm change --bump patch --summary "修复空输入崩溃" repoctl
32
16
  ```
33
17
 
34
- ### 初始化
35
-
36
- ```bash
37
- npx changeset init
38
- ```
18
+ 变更意图会写入 `.changeset/`,与代码一起提交。`pnpm change status` 只预览计划,不会修改文件。
39
19
 
40
- 会生成一个 `.changeset` 文件夹,里面包含配置文件。
20
+ ## 版本与 changelog
41
21
 
42
- ### 添加变更
43
-
44
- 当你完成某个功能或修复后,运行:
22
+ 在 Release PR 中由 CI 消费变更意图:
45
23
 
46
24
  ```bash
47
- npx changeset
25
+ pnpm version -r --dry-run
26
+ pnpm version -r
48
27
  ```
49
28
 
50
- 它会问:
29
+ `pnpm version -r` 会更新受影响包、传播 workspace 依赖、生成 `CHANGELOG.md`,并把消费记录追加到 `.changeset/ledger.yaml`。仓库配置使用 `versioning.changelog.storage: repository`,所以 changelog 会和版本提交一起审查。
51
30
 
52
- 1. 哪些包受影响?
53
- 2. 这是 **patch**(补丁)、**minor**(新功能)、还是 **major**(重大变更)?
54
- 3. 变更的描述是什么?
31
+ `@icebreakers/monorepo` 与 `repoctl` 属于 pnpm fixed group,任一包需要发布时两者始终使用同一个版本。
55
32
 
56
- 这会生成一个类似这样的文件:
33
+ ## 发布
57
34
 
58
- ```yaml
59
- # .changeset/sweet-pandas-sing.md
60
- ---
61
- my-package: patch
62
- ---
35
+ 正式发布由 Release PR 合并后的 main workflow 完成:
63
36
 
64
- 修复了登录时的 bug
37
+ ```bash
38
+ pnpm publish -r --report-summary --provenance --no-git-checks
65
39
  ```
66
40
 
67
- ### 应用版本更新
41
+ pnpm 会跳过 registry 中已经存在的版本,并把新发布包写入 `pnpm-publish-summary.json`。CI 根据 summary 创建 `package@version` Git tag 和 GitHub Release,因此重复执行不会重新发布已存在版本。
68
42
 
69
- 当积累了多个 changeset 后,可以执行:
43
+ 本地推荐使用 repoctl 包装命令:
70
44
 
71
45
  ```bash
72
- npx changeset version
46
+ pnpm exec repo release stable prepare
47
+ pnpm exec repo release stable publish
73
48
  ```
74
49
 
75
- 它会根据 changeset 文件:
76
-
77
- - 更新对应包的版本号。
78
- - 生成/更新 `CHANGELOG.md`。
50
+ ## Prerelease lanes
79
51
 
80
- ### 发布
81
-
82
- 最后可以发布:
52
+ alpha、beta、rc、next 是 pnpm lanes,而不是 Changesets pre 状态:
83
53
 
84
54
  ```bash
85
- npx changeset publish
86
- ```
55
+ pnpm exec repo release pre enter alpha
56
+ git add pnpm-workspace.yaml && git commit -m "chore(release): enter alpha lane"
57
+ git push
87
58
 
88
- 会自动调用 `npm publish`,把包发到 npm registry。
59
+ pnpm exec repo release pre publish
60
+ ```
89
61
 
90
- ## 3. 在 Monorepo 中的优势
62
+ 退出预发布轨道时执行 `pnpm exec repo release pre exit`,提交 `pnpm-workspace.yaml` 后合并回 main。lane 切换必须覆盖 fixed group 的全部包。
91
63
 
92
- - 避免多人协作时冲突:大家都往 `.changeset` 添加文件,不会直接改 `package.json`。
93
- - 统一生成 changelog:自动保证每个版本的改动都被记录。
94
- - 自动化发布:和 GitHub Actions 等 CI 工具结合,可在合并到主分支后自动发版。
64
+ ## CI 约定
95
65
 
96
- ## 总结
66
+ - 生成的 release workflow 只负责 checkout、安装依赖和权限声明,全部业务统一由 `pnpm exec repo release ci` 执行。
67
+ - main push 先生成或更新 Release PR;Release PR 合并后才发布 npm。
68
+ - alpha、beta、rc、next 分支要求所有可发布包位于对应 lane。
69
+ - npm 发布使用 GitHub OIDC provenance,不需要长期保存 `NPM_TOKEN`。
70
+ - 未发布版本恢复使用 workflow dispatch 的 `publish-unpublished` 模式,并按 package/version 校验后发布。
71
+ - repoctl 通过 GitHub REST API 幂等创建或更新 Release PR、package tag 和 GitHub Release,重复执行不会重复创建元数据。
97
72
 
98
- **Changeset 就是一个版本管理与发版工具**,它通过“先记录再统一处理”的方式,帮助 npm 包(尤其是 monorepo)保持版本升级和 changelog 的一致性与可追溯性。
73
+ 存量项目首次迁移运行 `pnpm dlx repoctl@latest upgrade --yes`。带有
74
+ `repoctl-managed: release/v2` 的 workflow 会自动升级;未标记的自定义
75
+ workflow 默认保留,可在确认后使用 `repo upgrade --overwrite-release`。
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: repoctl 文档站的工具专题入口,汇总 pnpm、Turborepo、changeset、Husky、lint-staged 和 Renovate。
2
+ description: repoctl 文档站的工具专题入口,汇总 pnpm、Turborepo、版本管理、Husky、lint-staged 和 Renovate。
3
3
  ---
4
4
 
5
5
  # 工具专题
@@ -8,14 +8,14 @@ description: repoctl 文档站的工具专题入口,汇总 pnpm、Turborepo、
8
8
 
9
9
  ## 1. 工具地图
10
10
 
11
- | 工具 | 在 repoctl 工作流里的位置 | 详细页面 |
12
- | ----------- | ----------------------------------------------- | ------------------------------- |
13
- | pnpm | workspace、依赖安装、根脚本和包内脚本执行 | [pnpm](./pnpm.md) |
14
- | Turborepo | build、lint、typecheck、test 等任务编排 | [turborepo](./turborepo.md) |
15
- | changeset | 多包版本、变更记录和发布准备 | [changeset](./changeset.md) |
16
- | Husky | Git hook 入口 | [husky](./husky.md) |
17
- | lint-staged | staged 文件级 lint、stylelint 和 typecheck 路由 | [lint-staged](./lint-staged.md) |
18
- | Renovate | 依赖更新和升级 PR 治理 | [renovate](./renovate.md) |
11
+ | 工具 | 在 repoctl 工作流里的位置 | 详细页面 |
12
+ | --------------- | ----------------------------------------------- | ------------------------------- |
13
+ | pnpm | workspace、依赖安装、根脚本和包内脚本执行 | [pnpm](./pnpm.md) |
14
+ | Turborepo | build、lint、typecheck、test 等任务编排 | [turborepo](./turborepo.md) |
15
+ | pnpm versioning | 多包版本、变更记录和发布准备 | [versioning](./changeset.md) |
16
+ | Husky | Git hook 入口 | [husky](./husky.md) |
17
+ | lint-staged | staged 文件级 lint、stylelint 和 typecheck 路由 | [lint-staged](./lint-staged.md) |
18
+ | Renovate | 依赖更新和升级 PR 治理 | [renovate](./renovate.md) |
19
19
 
20
20
  ## 2. 和 repoctl 的关系
21
21
 
@@ -33,6 +33,6 @@ repoctl 不隐藏这些工具。它主要做三件事:
33
33
  | ------------------------- | ------------------------------------------------------ |
34
34
  | 让 workspace 包能互相引用 | [pnpm](./pnpm.md) |
35
35
  | 提升整仓任务速度 | [turborepo](./turborepo.md) |
36
- | 建立规范发版链路 | [changeset](./changeset.md) |
36
+ | 建立规范发版链路 | [pnpm versioning](./changeset.md) |
37
37
  | 提交前自动修复格式和 lint | [Husky](./husky.md) 与 [lint-staged](./lint-staged.md) |
38
38
  | 降低依赖升级成本 | [Renovate](./renovate.md) |
@@ -1,7 +1,7 @@
1
1
  import Vue from '@vitejs/plugin-vue'
2
2
  import { defineVitestProjectConfig } from 'repoctl/tooling'
3
3
  import { mergeConfig } from 'vitest/config'
4
- import { sharedConfig } from './vite.shared.config'
4
+ import { sharedConfig } from './vite.shared.config.ts'
5
5
 
6
6
  export default mergeConfig(sharedConfig, {
7
7
  ...await defineVitestProjectConfig({
@@ -1,21 +0,0 @@
1
- {
2
- "$schema": "https://unpkg.com/@changesets/config@3.0.2/schema.json",
3
- "changelog": [
4
- "@icebreakers/changelog-github",
5
- {
6
- "repo": "sonofmagic/monorepo-template"
7
- }
8
- ],
9
- "commit": false,
10
- "fixed": [],
11
- "linked": [
12
- [
13
- "@icebreakers/monorepo",
14
- "repoctl"
15
- ]
16
- ],
17
- "access": "public",
18
- "baseBranch": "main",
19
- "updateInternalDependencies": "patch",
20
- "ignore": []
21
- }
@@ -1,5 +0,0 @@
1
- ---
2
- "@icebreakers/monorepo": patch
3
- ---
4
-
5
- 修复 Version Packages PR 合并后正式发布被错误跳过的问题,确保已更新版本但尚未发布到 npm 的包会继续执行发布。