@bushizhanghan/dsh-publish-gate 0.19.0 → 0.20.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.20.0
4
+
5
+ - `publish_gate_commands` now agrees with the rules: a prerelease version gets `npm publish --tag next`
6
+ instead of a bare publish that would move `latest`.
7
+ - New step `tag the shipped commit` (`git tag v<version> && git push origin v<version>`). The gate has
8
+ warned about a missing tag since 0.5.0 and the command list never mentioned tagging — I wrote a
9
+ separate script to do it because the instructions never said to.
10
+
3
11
  ## 0.19.0
4
12
 
5
13
  - `prerelease-published-as-latest` (warn): a `-beta` / `-rc` version with no `publishConfig.tag`.
package/README.md CHANGED
@@ -45,7 +45,7 @@ dsh plugin --profile desktop add @bushizhanghan/dsh-publish-gate
45
45
  | `publish_gate_market` | 校验市场条目 YAML(url/name/category/description 双语);传 `dir` 则改查只有线上才能回答的三件事:这个仓库**已经在目录里**(再开 PR 就是重复条目)、另一个条目也在发同一个 npm 包、仓库还**不满 24 小时**(提交门禁会失败并自己重跑) |
46
46
  | `publish_gate_next_version` | 当前版本、是否已被 registry 占用、建议 bump 到多少(本地比 npm 旧时从 npm 的 latest 往上加,不会推荐一个已被占用的版本) |
47
47
  | `publish_gate_doctor` | 扫整个目录,按 blocker 数排序,附带每个插件的真实包体积,看哪个还不能发 |
48
- | `publish_gate_commands` | 按顺序列出发布命令,并标出这台机器已经走到哪一步。命令是**这台机器上真能跑的形式**:Windows 下 `npm publish` 走 `cmd /c`(PowerShell 的 `npm.ps1` 常被执行策略拦掉),`npm publish` 后面紧跟一条 `publish_gate_verify` |
48
+ | `publish_gate_commands` | 按顺序列出发布命令,并标出这台机器已经走到哪一步。命令是**这台机器上真能跑的形式**:Windows 下 `npm publish` 走 `cmd /c`(PowerShell 的 `npm.ps1` 常被执行策略拦掉),`npm publish` 后面紧跟一条 `publish_gate_verify`;版本是预发版时命令自带 `--tag next`;最后一步是给发出去的 commit 打 tag |
49
49
 
50
50
  ## 检查清单
51
51
 
@@ -236,7 +236,7 @@ dsh plugin --profile desktop add @bushizhanghan/dsh-publish-gate
236
236
 
237
237
  ```sh
238
238
  node --test # 120 个引擎单测
239
- node test/integration.test.mjs # 27 条集成断言(9 个真实插件作 fixture)
239
+ node test/integration.test.mjs # 28 条集成断言(9 个真实插件作 fixture)
240
240
  ```
241
241
 
242
242
  ## License
package/lib/index.js CHANGED
@@ -28,8 +28,8 @@ import {
28
28
  compareVersions,
29
29
  latestPublished,
30
30
  renderReport,
31
- runArtifactChecks,
32
- checkTestRun,
31
+ runArtifactChecks,
32
+ checkTestRun,
33
33
  straySeverities,
34
34
  runStaticChecks,
35
35
  } from './engine.js'
@@ -104,7 +104,7 @@ export function apply(ctx, config = {}) {
104
104
  skipNetwork: { type: 'boolean', description: 'Skip the npm registry and GitHub checks (default false).' },
105
105
  skipPack: { type: 'boolean', description: 'Skip `npm pack --dry-run` (default false). Faster, but says nothing about the real tarball.' },
106
106
  skipTools: { type: 'boolean', description: 'Skip the isolated import of the plugin entry (default false).' },
107
- skipClient: { type: 'boolean', description: 'Skip the isolated load of the browser bundle (default false).' },
107
+ skipClient: { type: 'boolean', description: 'Skip the isolated load of the browser bundle (default false).' },
108
108
  skipTests: { type: 'boolean', description: 'Skip running the test suite (default false). The suite is the only check that reads the code rather than the paperwork.' },
109
109
  },
110
110
  },
@@ -114,21 +114,21 @@ export function apply(ctx, config = {}) {
114
114
  const findings = runStaticChecks(dir)
115
115
  const artifact = await runArtifactChecks(dir, { skipPack: args.skipPack, skipTools: args.skipTools, skipClient: args.skipClient })
116
116
  findings.push(...artifact.findings)
117
- const tests = args.skipTests ? null : await checkTestRun(dir, { timeoutMs: cfg.testTimeoutMs })
118
- if (tests) findings.push(...tests)
117
+ const tests = args.skipTests ? null : await checkTestRun(dir, { timeoutMs: cfg.testTimeoutMs })
118
+ if (tests) findings.push(...tests)
119
119
  if (!args.skipNetwork) findings.push(...(await networkGate(dir)))
120
- // A finding with an unexpected severity is invisible to the counters
121
- // below, so the rule silently never reports. Make that loud instead.
122
- const stray = straySeverities(findings)
123
- if (stray.length > 0) {
124
- findings.push({
125
- rule: 'internal-bad-severity',
126
- severity: 'error',
127
- title: `these rules built a finding with an unknown severity: ${stray.join(", ")}`,
128
- detail: 'The gate counted them as nothing, so they never appeared in a report. This is a bug in publish-gate, not in the plugin being gated.',
129
- fix: 'Report it: the severity slot of F(...) took something other than error/warn/info.',
130
- })
131
- }
120
+ // A finding with an unexpected severity is invisible to the counters
121
+ // below, so the rule silently never reports. Make that loud instead.
122
+ const stray = straySeverities(findings)
123
+ if (stray.length > 0) {
124
+ findings.push({
125
+ rule: 'internal-bad-severity',
126
+ severity: 'error',
127
+ title: `these rules built a finding with an unknown severity: ${stray.join(", ")}`,
128
+ detail: 'The gate counted them as nothing, so they never appeared in a report. This is a bug in publish-gate, not in the plugin being gated.',
129
+ fix: 'Report it: the severity slot of F(...) took something other than error/warn/info.',
130
+ })
131
+ }
132
132
  const counts = {
133
133
  error: findings.filter((f) => f.severity === 'error').length,
134
134
  warn: findings.filter((f) => f.severity === 'warn').length,
@@ -412,6 +412,11 @@ export function apply(ctx, config = {}) {
412
412
  const repo = json.repository?.url?.match(/github\.com[:/]([^/]+)\/([^/.]+)/)?.[2] || json.name.replace(/^@[^/]+\//, '')
413
413
  const { existsSync } = await import('node:fs')
414
414
  const hasGit = existsSync(join(dir, '.git'))
415
+ // npm publishes to `latest` whatever the version suffix says, so a
416
+ // prerelease needs an explicit tag or it goes out to everyone.
417
+ const preTag = /^\d+\.\d+\.\d+-/.test(json.version || '')
418
+ const tag = preTag ? (json.publishConfig?.tag && json.publishConfig.tag !== 'latest' ? json.publishConfig.tag : 'next') : null
419
+ const publishCmd = `npm publish --access public${tag ? ` --tag ${tag}` : ''}`
415
420
  const steps = [
416
421
  {
417
422
  name: 'git init and commit',
@@ -433,7 +438,7 @@ export function apply(ctx, config = {}) {
433
438
  },
434
439
  {
435
440
  name: 'npm publish',
436
- command: process.platform === 'win32' ? 'cmd /c "npm publish --access public"' : 'npm publish --access public',
441
+ command: process.platform === 'win32' ? `cmd /c "${publishCmd}"` : publishCmd,
437
442
  done: false,
438
443
  note:
439
444
  `a bare (unscoped) name can return 403 with a granular token — "${json.name}" is ${json.name.startsWith('@') ? 'scoped, fine' : 'UNSCOPED, rename it'}` +
@@ -447,7 +452,14 @@ export function apply(ctx, config = {}) {
447
452
  command: `publish_gate_verify({ dir: "${dir.replace(/\\/g, '\\\\')}" })`,
448
453
  done: false,
449
454
  note: 'the registry answers 202 and then 404s for about a minute, so a mismatch right after publish is normal; the shasum comparison is exact once it settles',
450
- }, {
455
+ },
456
+ {
457
+ name: 'tag the shipped commit',
458
+ command: `git tag v${json.version} && git push origin v${json.version}`,
459
+ done: false,
460
+ note: 'a GitHub release, a changelog entry and the market listing all point at a commit — none of them can point at one that was never tagged',
461
+ },
462
+ {
451
463
  name: 'market entry',
452
464
  command: `write data/plugins/${owner}__${repo}.yml with url / name / category / description{en,zh}`,
453
465
  done: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bushizhanghan/dsh-publish-gate",
3
- "version": "0.19.0",
3
+ "version": "0.20.0",
4
4
  "description": "Pre-publish gate for DSH plugins: manifest, dependencies, artifact, runtime, browser half, traceability and market readiness — plus an input fuzzer that drives every declared parameter with the wrong type. 发布前的七层门禁 + 入参模糊测试。",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",