@icebreakers/monorepo-templates 2.0.3 → 2.0.5
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.
- package/assets/.github/workflows/release-intent-auto.yml +25 -1
- package/assets/.github/workflows/release.yml +34 -1
- package/assets/gitignore +6 -0
- package/assets/package.json +6 -6
- package/assets/pnpm-workspace.yaml +1 -1
- package/assets/renovate.json +2 -1
- package/assets/turbo.json +3 -0
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{prepare-OpBpZD1d.mjs → prepare-BapI8ioj.mjs} +20 -11
- package/package.json +1 -1
- package/templates/client/package.json +5 -5
- package/templates/server/package.json +2 -2
- package/templates/vitepress/tasks/release.md +15 -0
- package/templates/vitepress/zh/learn/monorepo/publish.md +1 -1
- package/templates/vitepress/zh/learn/tools/changeset.md +1 -1
- package/templates/vitepress/zh/tasks/release.md +15 -0
- package/templates/vue-lib/package.json +1 -1
|
@@ -27,14 +27,38 @@ jobs:
|
|
|
27
27
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
28
28
|
with:
|
|
29
29
|
fetch-depth: 1
|
|
30
|
+
ref: ${{ github.event.pull_request.base.sha || github.sha }}
|
|
31
|
+
persist-credentials: false
|
|
30
32
|
|
|
31
33
|
- name: Setup Node.js environment
|
|
32
34
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
33
35
|
with:
|
|
34
36
|
node-version: 24
|
|
35
37
|
|
|
38
|
+
- name: Validate GitHub App configuration
|
|
39
|
+
if: ${{ github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.full_name == github.repository }}
|
|
40
|
+
env:
|
|
41
|
+
APP_CLIENT_ID: ${{ vars.REPOCTL_APP_CLIENT_ID }}
|
|
42
|
+
APP_PRIVATE_KEY_CONFIGURED: ${{ secrets.REPOCTL_APP_PRIVATE_KEY != '' }}
|
|
43
|
+
run: |
|
|
44
|
+
if { [ -n "$APP_CLIENT_ID" ] && [ "$APP_PRIVATE_KEY_CONFIGURED" != 'true' ]; } ||
|
|
45
|
+
{ [ -z "$APP_CLIENT_ID" ] && [ "$APP_PRIVATE_KEY_CONFIGURED" = 'true' ]; }; then
|
|
46
|
+
echo 'Configure both REPOCTL_APP_CLIENT_ID and REPOCTL_APP_PRIVATE_KEY.' >&2
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
- name: Create GitHub App token
|
|
51
|
+
if: ${{ vars.REPOCTL_APP_CLIENT_ID != '' && (github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.full_name == github.repository) }}
|
|
52
|
+
id: app-token
|
|
53
|
+
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
|
|
54
|
+
with:
|
|
55
|
+
client-id: ${{ vars.REPOCTL_APP_CLIENT_ID }}
|
|
56
|
+
private-key: ${{ secrets.REPOCTL_APP_PRIVATE_KEY }}
|
|
57
|
+
permission-contents: write
|
|
58
|
+
permission-pull-requests: write
|
|
59
|
+
|
|
36
60
|
- name: Generate or backfill changesets
|
|
37
61
|
env:
|
|
38
|
-
GITHUB_TOKEN: ${{ github.token }}
|
|
62
|
+
GITHUB_TOKEN: ${{ steps.app-token.outputs.token || github.token }}
|
|
39
63
|
PR_NUMBERS: ${{ inputs.pr_numbers }}
|
|
40
64
|
run: node .github/auto-changeset/index.mjs
|
|
@@ -55,10 +55,32 @@ jobs:
|
|
|
55
55
|
name: Release
|
|
56
56
|
runs-on: ubuntu-latest
|
|
57
57
|
steps:
|
|
58
|
+
- name: Validate GitHub App configuration
|
|
59
|
+
env:
|
|
60
|
+
APP_CLIENT_ID: ${{ vars.REPOCTL_APP_CLIENT_ID }}
|
|
61
|
+
APP_PRIVATE_KEY_CONFIGURED: ${{ secrets.REPOCTL_APP_PRIVATE_KEY != '' }}
|
|
62
|
+
run: |
|
|
63
|
+
if { [ -n "$APP_CLIENT_ID" ] && [ "$APP_PRIVATE_KEY_CONFIGURED" != 'true' ]; } ||
|
|
64
|
+
{ [ -z "$APP_CLIENT_ID" ] && [ "$APP_PRIVATE_KEY_CONFIGURED" = 'true' ]; }; then
|
|
65
|
+
echo 'Configure both REPOCTL_APP_CLIENT_ID and REPOCTL_APP_PRIVATE_KEY.' >&2
|
|
66
|
+
exit 1
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
- name: Create GitHub App token
|
|
70
|
+
if: ${{ vars.REPOCTL_APP_CLIENT_ID != '' }}
|
|
71
|
+
id: app-token
|
|
72
|
+
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
|
|
73
|
+
with:
|
|
74
|
+
client-id: ${{ vars.REPOCTL_APP_CLIENT_ID }}
|
|
75
|
+
private-key: ${{ secrets.REPOCTL_APP_PRIVATE_KEY }}
|
|
76
|
+
permission-contents: write
|
|
77
|
+
permission-pull-requests: write
|
|
78
|
+
|
|
58
79
|
- name: Checkout Repo
|
|
59
80
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
60
81
|
with:
|
|
61
82
|
fetch-depth: 0
|
|
83
|
+
token: ${{ steps.app-token.outputs.token || secrets.REPOCTL_RELEASE_TOKEN || secrets.CHANGESETS_RELEASE_TOKEN || github.token }}
|
|
62
84
|
|
|
63
85
|
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
64
86
|
|
|
@@ -77,9 +99,20 @@ jobs:
|
|
|
77
99
|
|
|
78
100
|
- name: Run repo release CI
|
|
79
101
|
env:
|
|
80
|
-
GITHUB_TOKEN: ${{ secrets.REPOCTL_RELEASE_TOKEN || secrets.CHANGESETS_RELEASE_TOKEN || github.token }}
|
|
102
|
+
GITHUB_TOKEN: ${{ steps.app-token.outputs.token || secrets.REPOCTL_RELEASE_TOKEN || secrets.CHANGESETS_RELEASE_TOKEN || github.token }}
|
|
81
103
|
REPO_RELEASE_MODE: ${{ inputs.mode || 'auto' }}
|
|
82
104
|
REPO_RELEASE_PACKAGE: ${{ inputs.package }}
|
|
83
105
|
REPO_RELEASE_VERSION: ${{ inputs.version }}
|
|
84
106
|
REPO_RELEASE_DRY_RUN: ${{ inputs.dry-run }}
|
|
85
107
|
run: pnpm exec repo release ci
|
|
108
|
+
|
|
109
|
+
- name: Preserve npm publish progress
|
|
110
|
+
if: ${{ always() }}
|
|
111
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
112
|
+
with:
|
|
113
|
+
name: npm-publish-progress-${{ github.run_id }}-${{ github.run_attempt }}
|
|
114
|
+
path: |
|
|
115
|
+
pnpm-publish-summary.json
|
|
116
|
+
repoctl-publish-progress.json
|
|
117
|
+
if-no-files-found: ignore
|
|
118
|
+
retention-days: 14
|
package/assets/gitignore
CHANGED
|
@@ -40,3 +40,9 @@ config.ts.timestamp-*.mjs
|
|
|
40
40
|
|
|
41
41
|
# local AI task artifacts
|
|
42
42
|
/.qoder/
|
|
43
|
+
|
|
44
|
+
# release diagnostics (retained as CI artifacts)
|
|
45
|
+
/pnpm-publish-summary.json
|
|
46
|
+
/repoctl-publish-progress.json
|
|
47
|
+
/pnpm-publish-summary.json.*.tmp
|
|
48
|
+
/repoctl-publish-progress.json.*.tmp
|
package/assets/package.json
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"scripts": {
|
|
29
29
|
"build": "turbo run build",
|
|
30
30
|
"tooling:build": "turbo run build --filter=@icebreakers/monorepo --filter=repoctl",
|
|
31
|
-
"dev": "turbo run dev --
|
|
31
|
+
"dev": "turbo run dev --concurrency=20",
|
|
32
32
|
"test": "node -e \"require('node:fs').mkdirSync('coverage/.tmp', { recursive: true })\" && pnpm check:no-tracked-build-artifacts && vitest run && pnpm test:types",
|
|
33
33
|
"test:packaged-doctor": "node scripts/smoke-packaged-doctor.mjs",
|
|
34
34
|
"test:dev": "node -e \"require('node:fs').mkdirSync('coverage/.tmp', { recursive: true })\" && pnpm check:no-tracked-build-artifacts && vitest",
|
|
@@ -77,21 +77,21 @@
|
|
|
77
77
|
"@icebreakers/eslint-config": "workspace:*",
|
|
78
78
|
"@icebreakers/monorepo": "workspace:*",
|
|
79
79
|
"@icebreakers/stylelint-config": "workspace:*",
|
|
80
|
-
"@types/node": "^26.6.
|
|
81
|
-
"@vitest/coverage-v8": "~5.0.
|
|
80
|
+
"@types/node": "^26.6.3",
|
|
81
|
+
"@vitest/coverage-v8": "~5.0.2",
|
|
82
82
|
"eslint": "^10.11.0",
|
|
83
83
|
"execa": "^10.0.1",
|
|
84
84
|
"husky": "^9.1.7",
|
|
85
|
-
"lint-staged": "^17.
|
|
85
|
+
"lint-staged": "^17.6.0",
|
|
86
86
|
"only-allow": "^1.2.2",
|
|
87
87
|
"repoctl": "workspace:*",
|
|
88
88
|
"stylelint": "^17.15.0",
|
|
89
89
|
"tailwindcss": "^4.3.3",
|
|
90
90
|
"tsd": "^0.33.0",
|
|
91
91
|
"tsdown": "0.23.0",
|
|
92
|
-
"turbo": "^2.11.
|
|
92
|
+
"turbo": "^2.11.5",
|
|
93
93
|
"typescript": "^6.0.3",
|
|
94
|
-
"vitest": "~5.0.
|
|
94
|
+
"vitest": "~5.0.2",
|
|
95
95
|
"yaml": "^2.9.1"
|
|
96
96
|
},
|
|
97
97
|
"publishConfig": {
|
package/assets/renovate.json
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
],
|
|
8
8
|
"rangeStrategy": "bump",
|
|
9
9
|
"gitIgnoredAuthors": [
|
|
10
|
-
"41898282+github-actions[bot]@users.noreply.github.com"
|
|
10
|
+
"41898282+github-actions[bot]@users.noreply.github.com",
|
|
11
|
+
"335527025+auto-upgrade-deps[bot]@users.noreply.github.com"
|
|
11
12
|
],
|
|
12
13
|
"npm": {
|
|
13
14
|
"commitMessageTopic": "{{prettyDepType}} {{depName}}"
|
package/assets/turbo.json
CHANGED
package/dist/cli.mjs
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -32,7 +32,7 @@ export declare const templatesDir: string;
|
|
|
32
32
|
export declare const assetsDir: string;
|
|
33
33
|
export declare const skeletonDir: string;
|
|
34
34
|
//#endregion
|
|
35
|
-
//#region src/prepare.d.ts
|
|
35
|
+
//#region src/prepare/index.d.ts
|
|
36
36
|
interface PrepareAssetsOptions {
|
|
37
37
|
overwriteExisting?: boolean;
|
|
38
38
|
silent?: boolean;
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as isGitignoreFile, c as toWorkspaceGitignorePath, d as packageDir, f as skeletonDir, h as getAssetTargets$1, i as shouldSkipTemplatePath, l as templateChoices$1, m as assetTargets$1, n as sanitizePublishedWorkspaceContent, o as toPublishGitignorePath, p as templatesDir, r as createTemplateCopyFilter, s as toWorkspaceAssetPath, t as prepareAssets, u as assetsDir } from "./prepare-
|
|
1
|
+
import { a as isGitignoreFile, c as toWorkspaceGitignorePath, d as packageDir, f as skeletonDir, h as getAssetTargets$1, i as shouldSkipTemplatePath, l as templateChoices$1, m as assetTargets$1, n as sanitizePublishedWorkspaceContent, o as toPublishGitignorePath, p as templatesDir, r as createTemplateCopyFilter, s as toWorkspaceAssetPath, t as prepareAssets, u as assetsDir } from "./prepare-BapI8ioj.mjs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import fs, { access, open, readFile, rm } from "node:fs/promises";
|
|
4
4
|
import exec from "nanoexec";
|
|
@@ -168,8 +168,16 @@ function createTemplateCopyFilter(rootDir) {
|
|
|
168
168
|
return (src) => !shouldSkipTemplatePath(rootDir, src);
|
|
169
169
|
}
|
|
170
170
|
//#endregion
|
|
171
|
-
//#region src/prepare.ts
|
|
172
|
-
|
|
171
|
+
//#region src/prepare/published.ts
|
|
172
|
+
function sanitizePublishedManifestContent(content) {
|
|
173
|
+
const manifest = JSON.parse(content);
|
|
174
|
+
if (manifest.scripts) {
|
|
175
|
+
for (const name of Object.keys(manifest.scripts)) if (name.startsWith("dev:") || name === "test:dev-scenarios" || name === "test:worker-types" || name === "test:packaged-create") delete manifest.scripts[name];
|
|
176
|
+
manifest.scripts["dev"] = "turbo run dev --concurrency=20";
|
|
177
|
+
if (manifest.scripts["test"]) manifest.scripts["test"] = manifest.scripts["test"].replace(" && pnpm test:dev-scenarios", "");
|
|
178
|
+
}
|
|
179
|
+
return `${JSON.stringify(manifest, null, 2)}\n`;
|
|
180
|
+
}
|
|
173
181
|
const publishedToolingConfigs = {
|
|
174
182
|
"commitlint.config.ts": [
|
|
175
183
|
`import { defineCommitlintConfig } from 'repoctl/tooling'`,
|
|
@@ -204,9 +212,6 @@ const publishedToolingConfigs = {
|
|
|
204
212
|
].join("\n")
|
|
205
213
|
};
|
|
206
214
|
const sourceRepoReleaseToolingBuildStepPattern = /\r?\n\s+- name: Build Release Tooling\r?\n\s+run: pnpm run tooling:build\r?\n/g;
|
|
207
|
-
function toPublishedAssetPath(target) {
|
|
208
|
-
return target === ".npmrc" ? "npmrc" : toPublishGitignorePath(target);
|
|
209
|
-
}
|
|
210
215
|
function removeSourceRepoReleaseToolingBuildStepContent(content) {
|
|
211
216
|
return content.replaceAll(sourceRepoReleaseToolingBuildStepPattern, "\n");
|
|
212
217
|
}
|
|
@@ -230,6 +235,12 @@ function sanitizePublishedWorkspaceContent(content) {
|
|
|
230
235
|
}
|
|
231
236
|
return changed ? YAML.stringify(workspace) : content;
|
|
232
237
|
}
|
|
238
|
+
//#endregion
|
|
239
|
+
//#region src/prepare/index.ts
|
|
240
|
+
const huskySkippedEntryPattern = /[\\/]_$/;
|
|
241
|
+
function toPublishedAssetPath(target) {
|
|
242
|
+
return target === ".npmrc" ? "npmrc" : toPublishGitignorePath(target);
|
|
243
|
+
}
|
|
233
244
|
async function pathExists(targetPath) {
|
|
234
245
|
try {
|
|
235
246
|
await fs.access(targetPath);
|
|
@@ -345,7 +356,7 @@ async function removeSourceRepoReleaseToolingBuildStep() {
|
|
|
345
356
|
const nextContent = removeSourceRepoReleaseToolingBuildStepContent(content);
|
|
346
357
|
if (nextContent !== content) await fs.writeFile(releaseWorkflowPath, nextContent, "utf8");
|
|
347
358
|
}
|
|
348
|
-
async function
|
|
359
|
+
async function removeSourceRepoChecks() {
|
|
349
360
|
const workflowPath = path$1.join(assetsDir, ".github/workflows/ci.yml");
|
|
350
361
|
if (await pathExists(workflowPath)) {
|
|
351
362
|
const workflow = await fs.readFile(workflowPath, "utf8");
|
|
@@ -353,10 +364,8 @@ async function removeSourceRepoWorkerTypeChecks() {
|
|
|
353
364
|
}
|
|
354
365
|
const manifestPath = path$1.join(assetsDir, "package.json");
|
|
355
366
|
if (await pathExists(manifestPath)) {
|
|
356
|
-
const
|
|
357
|
-
|
|
358
|
-
delete manifest.scripts?.["test:packaged-create"];
|
|
359
|
-
await fs.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
367
|
+
const content = await fs.readFile(manifestPath, "utf8");
|
|
368
|
+
await fs.writeFile(manifestPath, sanitizePublishedManifestContent(content));
|
|
360
369
|
}
|
|
361
370
|
}
|
|
362
371
|
async function copyTemplates(repoRoot, overwriteExisting) {
|
|
@@ -382,7 +391,7 @@ async function prepareAssets(options = {}) {
|
|
|
382
391
|
await writePublishedToolingConfigs();
|
|
383
392
|
await writePublishedAgentSkill(repoRoot);
|
|
384
393
|
await removeSourceRepoReleaseToolingBuildStep();
|
|
385
|
-
await
|
|
394
|
+
await removeSourceRepoChecks();
|
|
386
395
|
await copyTemplates(repoRoot, overwriteExisting);
|
|
387
396
|
}
|
|
388
397
|
//#endregion
|
package/package.json
CHANGED
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@faker-js/faker": "^10.6.0",
|
|
40
|
-
"@tanstack/vue-query": "^5.
|
|
41
|
-
"@tanstack/vue-query-devtools": "^6.
|
|
40
|
+
"@tanstack/vue-query": "^5.104.0",
|
|
41
|
+
"@tanstack/vue-query-devtools": "^6.3.0",
|
|
42
42
|
"@tanstack/vue-table": "^9.2.4",
|
|
43
43
|
"@tanstack/vue-virtual": "^3.13.39",
|
|
44
44
|
"@trpc/client": "^11.19.0",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@cloudflare/vite-plugin": "^1.56.0",
|
|
55
|
-
"@hono/node-server": "^2.1.
|
|
55
|
+
"@hono/node-server": "^2.1.3",
|
|
56
56
|
"@hono/trpc-server": "^0.4.2",
|
|
57
57
|
"@tailwindcss/vite": "^4.3.3",
|
|
58
58
|
"@trpc/server": "^11.19.0",
|
|
@@ -60,10 +60,10 @@
|
|
|
60
60
|
"@vitejs/plugin-vue-jsx": "^5.1.6",
|
|
61
61
|
"@vue/tsconfig": "^0.9.1",
|
|
62
62
|
"consola": "^3.4.2",
|
|
63
|
-
"hono": "^4.13.
|
|
63
|
+
"hono": "^4.13.11",
|
|
64
64
|
"tailwindcss": "^4.3.3",
|
|
65
65
|
"typescript": "~6.0.3",
|
|
66
|
-
"vite": "^8.3.
|
|
66
|
+
"vite": "^8.3.1",
|
|
67
67
|
"vite-plugin-vue-devtools": "^8.2.1",
|
|
68
68
|
"vite-tsconfig-paths": "^6.1.1",
|
|
69
69
|
"vue-tsc": "3.3.11",
|
|
@@ -64,9 +64,9 @@
|
|
|
64
64
|
"types": "./dist/index.d.ts"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
|
-
"@hono/node-server": "^2.1.
|
|
67
|
+
"@hono/node-server": "^2.1.3",
|
|
68
68
|
"consola": "^3.4.2",
|
|
69
|
-
"hono": "^4.13.
|
|
69
|
+
"hono": "^4.13.11",
|
|
70
70
|
"tsdown": "0.23.0",
|
|
71
71
|
"wrangler": "^4.135.0",
|
|
72
72
|
"zod": "^4.6.5"
|
|
@@ -26,6 +26,21 @@ The release report names the packages that will change, the version decisions, a
|
|
|
26
26
|
- Fixed group mismatch: inspect the package relationships before editing versions.
|
|
27
27
|
- Registry authentication failure: refresh the local token and rerun the publish step; do not commit credentials.
|
|
28
28
|
|
|
29
|
+
## Partial publication and registry visibility
|
|
30
|
+
|
|
31
|
+
The publisher attempts uploads at most three times, waiting 20 and 40 seconds before refreshing registry state and selecting retry packages. An exact version with explicit upload acceptance is never uploaded again during that invocation, even if `npm view` cannot find it yet. Ordinary permission errors and 404 responses without transient-failure evidence fail immediately. Conflicts require read-only registry confirmation.
|
|
32
|
+
|
|
33
|
+
Accepted uploads must become queryable before post-publish hooks, Git tags, GitHub Releases, or prerelease pushes proceed. Visibility checks query pending versions every 10 seconds for up to five minutes. A timeout exits unsuccessfully and lists pending versions.
|
|
34
|
+
|
|
35
|
+
Two files remain in the workspace root:
|
|
36
|
+
|
|
37
|
+
- `pnpm-publish-summary.json`: cumulative `publishedPackages`, including accepted uploads and registry-confirmed versions. On failure, this file alone does not prove that every listed version is available.
|
|
38
|
+
- `repoctl-publish-progress.json`: `schemaVersion: 1`, `candidates`, `acceptedPackages`, `confirmedPackages`, and `status` (`publishing`, `confirming`, `complete`, or `failed`). Accepted versions missing from `confirmedPackages` still need visibility confirmation.
|
|
39
|
+
|
|
40
|
+
The managed Release workflow uploads both files as `npm-publish-progress-<run_id>-<run_attempt>` on success or failure, retained for 14 days. Missing reports are ignored. After upgrading repoctl, run `repo upgrade` to refresh managed workflows; custom workflows can add the same upload step.
|
|
41
|
+
|
|
42
|
+
After a failure, download the artifact and reconcile exact versions with `npm view <name>@<version> version`. Continue read-only checks for accepted but unconfirmed versions instead of rerunning the entire release lifecycle. Use the workflow's `reconcile` mode to repair metadata for visible versions, and `publish-unpublished` only for versions verified as still requiring upload. Reports are diagnostic: a new invocation does not trust old reports or automatically resume across processes.
|
|
43
|
+
|
|
29
44
|
## Next
|
|
30
45
|
|
|
31
46
|
Read [publishing and changelogs](/learn/monorepo/publish) for repository policy and [reports and output](/tasks/reports) for CI artifacts.
|
|
@@ -33,7 +33,7 @@ CI 将版本号、各包 `CHANGELOG.md` 和 `.changeset/ledger.yaml` 提交到 R
|
|
|
33
33
|
pnpm publish -r --report-summary --provenance --no-git-checks
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
pnpm 根据 registry 中已有的版本自动跳过已发布包。CI 读取 `pnpm-publish-summary.json` 创建 `package@version` tag 和 GitHub Release
|
|
36
|
+
pnpm 根据 registry 中已有的版本自动跳过已发布包。CI 读取 `pnpm-publish-summary.json` 创建 `package@version` tag 和 GitHub Release,发布器在本次调用内保留已接收上传的版本,确认 registry 可见性后再执行后置流程;失败后的处理见[部分发布与 registry 延迟](/zh/tasks/release#部分发布与-registry-延迟)。
|
|
37
37
|
|
|
38
38
|
## Workspace versioning 配置
|
|
39
39
|
|
|
@@ -38,7 +38,7 @@ pnpm version -r
|
|
|
38
38
|
pnpm publish -r --report-summary --provenance --no-git-checks
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
pnpm 会跳过 registry 中已经存在的版本,并把新发布包写入 `pnpm-publish-summary.json`。CI 根据 summary 创建 `package@version` Git tag 和 GitHub Release
|
|
41
|
+
pnpm 会跳过 registry 中已经存在的版本,并把新发布包写入 `pnpm-publish-summary.json`。CI 根据 summary 创建 `package@version` Git tag 和 GitHub Release,发布器会保留本次调用的部分成功状态,等待 registry 确认可见后再创建元数据;不要在传播延迟期间直接重跑整个生命周期,详见[发布任务](/zh/tasks/release)。
|
|
42
42
|
|
|
43
43
|
本地推荐使用 repoctl 包装命令:
|
|
44
44
|
|
|
@@ -26,6 +26,21 @@ repo release --dry-run
|
|
|
26
26
|
- 固定版本组不一致:先检查包之间的关系,再修改版本。
|
|
27
27
|
- registry 认证失败:刷新本地 token 后重试,不要提交凭据。
|
|
28
28
|
|
|
29
|
+
## 部分发布与 registry 延迟
|
|
30
|
+
|
|
31
|
+
发布器最多尝试上传 3 次,重试前分别等待 20、40 秒并重新查询 registry。明确上传成功的精确版本不会再次上传,即使此时 `npm view` 暂不可查询。普通权限错误和没有瞬时故障依据的 404 会直接失败;冲突只能通过只读对账确认,不能当作成功。
|
|
32
|
+
|
|
33
|
+
已接收上传的版本需要确认可查询后,才会执行后置 hooks、Git tag 和 GitHub Release。确认期间每 10 秒查询待确认版本,最多等待 5 分钟;超时会非零退出并列出待确认版本。
|
|
34
|
+
|
|
35
|
+
工作区根目录保留两份文件:
|
|
36
|
+
|
|
37
|
+
- `pnpm-publish-summary.json`:跨尝试累计的 `publishedPackages`,包括已接收上传和 registry 已确认的版本;失败时不能仅凭此文件认定所有版本已可用。
|
|
38
|
+
- `repoctl-publish-progress.json`:`schemaVersion: 1`,记录 `candidates`、`acceptedPackages`、`confirmedPackages` 及 `status`(`publishing`、`confirming`、`complete`、`failed`)。已接收但未确认的版本是前两种成功状态之差。
|
|
39
|
+
|
|
40
|
+
受管 Release 工作流会在发布成功或失败后上传 `npm-publish-progress-<run_id>-<run_attempt>` artifact,保留 14 天;没有清单时跳过上传。现有项目升级 repoctl 后运行 `repo upgrade` 更新受管工作流;自定义工作流可自行添加相同上传步骤。
|
|
41
|
+
|
|
42
|
+
失败后先下载 artifact,并用 `npm view <name>@<version> version` 对账。对于已接收但未确认的版本,继续只读确认,不要直接重跑整个发布生命周期。确认已经可用的版本可通过工作流的 `reconcile` 模式补齐元数据;仅对核实仍未上传的版本使用 `publish-unpublished`。旧清单仅用于诊断,新调用不会自动信任旧清单或跨进程续传。
|
|
43
|
+
|
|
29
44
|
## 下一步
|
|
30
45
|
|
|
31
46
|
阅读[发包与变更日志](/zh/learn/monorepo/publish),再查看[报告与输出](/zh/tasks/reports)了解 CI 产物。
|