@bushizhanghan/dsh-publish-gate 0.8.0 → 0.8.1
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 +7 -0
- package/README.md +1 -1
- package/lib/engine.js +23 -0
- package/lib/index.js +14 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.8.1
|
|
4
|
+
|
|
5
|
+
- `publish_gate_verify` gained `waitMs` (capped at 90 s) and reports `waitedMs`. npm answers 202 and keeps
|
|
6
|
+
the version invisible for 60–180 s after a publish, so the single-shot check reported "not on the registry"
|
|
7
|
+
for releases that had already succeeded — it happened on this plugin own 0.8.0 publish, which stayed
|
|
8
|
+
invisible for over three minutes. `waitForPublished()` polls until the shasum appears; `waitMs: 0` keeps
|
|
9
|
+
the old single-shot behaviour, and a real mismatch stops the poll immediately.
|
|
3
10
|
## 0.8.0
|
|
4
11
|
|
|
5
12
|
- `tool-input-throws` (error): `publish_gate_tools` gained `fuzz` and `skip`. With `fuzz: true` it drives
|
package/README.md
CHANGED
package/lib/engine.js
CHANGED
|
@@ -1916,6 +1916,29 @@ export async function checkPublishedMatches(name, version, localPack, { registry
|
|
|
1916
1916
|
return out
|
|
1917
1917
|
}
|
|
1918
1918
|
|
|
1919
|
+
/**
|
|
1920
|
+
* Poll the registry until the published bytes show up.
|
|
1921
|
+
*
|
|
1922
|
+
* npm answers 202 and keeps the version invisible for 60–180 s, so a single
|
|
1923
|
+
* shot right after `npm publish` reports "not on the registry" for a release
|
|
1924
|
+
* that already succeeded — the most common false alarm this plugin produces,
|
|
1925
|
+
* including on its own publishes. `probe` is injectable so the loop tests
|
|
1926
|
+
* without the network.
|
|
1927
|
+
*/
|
|
1928
|
+
export async function waitForPublished(name, version, localPack, opts = {}) {
|
|
1929
|
+
const waitMs = Math.max(0, Number(opts.waitMs) || 0)
|
|
1930
|
+
const intervalMs = Math.max(1000, Number(opts.intervalMs) || 10_000)
|
|
1931
|
+
const probe = opts.probe || ((o) => checkPublishedMatches(name, version, localPack, o))
|
|
1932
|
+
const net = { registry: opts.registry, timeoutMs: opts.timeoutMs }
|
|
1933
|
+
const started = Date.now()
|
|
1934
|
+
let findings = await probe(net)
|
|
1935
|
+
while (!findings.some((f) => f.rule === 'publish-served') && Date.now() - started < waitMs) {
|
|
1936
|
+
await new Promise((r) => setTimeout(r, Math.min(intervalMs, waitMs - (Date.now() - started))))
|
|
1937
|
+
findings = await probe(net)
|
|
1938
|
+
}
|
|
1939
|
+
return { findings, waitedMs: Date.now() - started }
|
|
1940
|
+
}
|
|
1941
|
+
|
|
1919
1942
|
/** The async half of the gate: everything that needs a subprocess or the network. */
|
|
1920
1943
|
export async function runArtifactChecks(dir, opts = {}) {
|
|
1921
1944
|
const packResult = opts.skipPack ? { findings: [], pack: null } : await checkPack(dir, opts)
|
package/lib/index.js
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
checkClientRuntime,
|
|
25
25
|
checkPublishIdentity,
|
|
26
26
|
checkVersionTaken,
|
|
27
|
+
waitForPublished,
|
|
27
28
|
compareVersions,
|
|
28
29
|
latestPublished,
|
|
29
30
|
renderReport,
|
|
@@ -189,12 +190,17 @@ export function apply(ctx, config = {}) {
|
|
|
189
190
|
{
|
|
190
191
|
name: 'publish_gate_verify',
|
|
191
192
|
description:
|
|
192
|
-
'Check that the tarball on the npm registry is the one in this directory. Runs `npm pack --dry-run` and compares its shasum with the registry dist.shasum — an exact comparison, not a version-number guess, so it catches "I bumped and forgot to publish" and "I published, then edited lib/". Reports publish-served (match), publish-served-mismatch (the version is spent and the registry holds different bytes), or publish-not-served (not published, or still inside the registry\'s
|
|
193
|
+
'Check that the tarball on the npm registry is the one in this directory. Runs `npm pack --dry-run` and compares its shasum with the registry dist.shasum — an exact comparison, not a version-number guess, so it catches "I bumped and forgot to publish" and "I published, then edited lib/". Reports publish-served (match), publish-served-mismatch (the version is spent and the registry holds different bytes), or publish-not-served (not published, or still inside the registry\'s 202-then-404 window — pass waitMs to poll through that window instead of concluding too early). Run it right after `npm publish`. Returns {ok, name, version, published, shasumMatch, localShasum, unpackedSize, files, waitedMs, findings, report}.',
|
|
193
194
|
parameters: {
|
|
194
195
|
type: 'object',
|
|
195
196
|
properties: {
|
|
196
197
|
dir: { type: 'string', description: 'Plugin directory.' },
|
|
197
198
|
version: { type: 'string', description: 'Version to verify (defaults to package.json version).' },
|
|
199
|
+
waitMs: {
|
|
200
|
+
type: 'number',
|
|
201
|
+
description:
|
|
202
|
+
'Poll until the registry serves the bytes, up to this many milliseconds (capped at 90000). npm returns 202 and keeps the version invisible for 60-180 s after a publish, so a single shot reports "not published" on a release that already succeeded.',
|
|
203
|
+
},
|
|
198
204
|
},
|
|
199
205
|
},
|
|
200
206
|
async execute(args) {
|
|
@@ -205,7 +211,12 @@ export function apply(ctx, config = {}) {
|
|
|
205
211
|
const version = args.version || json.version
|
|
206
212
|
const { pack, findings: packFindings } = await checkPack(dir)
|
|
207
213
|
if (!pack) return { ok: false, error: `npm pack --dry-run did not run, so there is nothing to compare: ${packFindings.map((f) => f.title).join('; ')}` }
|
|
208
|
-
const
|
|
214
|
+
const waitMs = Math.min(Math.max(0, Number(args.waitMs) || 0), 90_000)
|
|
215
|
+
const { findings, waitedMs } = await waitForPublished(json.name, version, pack, {
|
|
216
|
+
registry: cfg.registry,
|
|
217
|
+
timeoutMs: cfg.networkTimeoutMs,
|
|
218
|
+
waitMs,
|
|
219
|
+
})
|
|
209
220
|
const served = findings.some((f) => f.rule === 'publish-served')
|
|
210
221
|
return {
|
|
211
222
|
ok: true,
|
|
@@ -216,6 +227,7 @@ export function apply(ctx, config = {}) {
|
|
|
216
227
|
localShasum: pack.shasum,
|
|
217
228
|
unpackedSize: pack.unpackedSize,
|
|
218
229
|
files: (pack.files || []).length,
|
|
230
|
+
waitedMs,
|
|
219
231
|
findings,
|
|
220
232
|
report: renderReport(findings, { title: `publish verify · ${json.name}@${version}` }),
|
|
221
233
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bushizhanghan/dsh-publish-gate",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
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",
|