dsh-plugin-toolkit 0.8.5 → 0.8.6

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,3 +1,12 @@
1
+ ## 0.8.6
2
+
3
+ - `release --publish`: run `npm publish` locally instead of waiting for a
4
+ publish workflow. Plenty of small plugins have no release pipeline; before
5
+ this, `release` tagged, pushed and then waited for a registry that would never
6
+ receive the version.
7
+ - The publish failure reports the last line of npm's stderr, so a 403 reads like
8
+ a 403.
9
+
1
10
  ## 0.8.5
2
11
 
3
12
  - `release --market <dir>`: write the index entry into a checkout of the
package/README.md CHANGED
@@ -320,6 +320,15 @@ merged
320
320
 
321
321
  Without `--pr` it prints the `git add` / `gh pr create` commands instead of running them; `--dry-run` prints the whole sequence before anything happens. A re-run after a failure is safe: the same version with the same publish time is a no-op.
322
322
 
323
+ ### When nothing publishes for you
324
+
325
+ `release` assumes a tag starts a workflow that publishes. Repositories without
326
+ one use `--publish`, which runs `npm publish` in the same step:
327
+
328
+ ```sh
329
+ $ dsh-plugin release . --publish
330
+ ```
331
+
323
332
  ### When the index lives in someone else's repository
324
333
 
325
334
  Most plugins are listed in a central market repository, not their own. Point
package/lib/cli.mjs CHANGED
@@ -38,6 +38,7 @@ Flags
38
38
  --dry-run show the steps without touching anything
39
39
  --index <path> index file, default market/index.json
40
40
  --market <dir> with release: a checkout of the repository that holds the index
41
+ --publish with release: run npm publish here, for repos without a publish workflow
41
42
  --tag-prefix <prefix> default plugin-v
42
43
  --budget <seconds> how long to wait for npm, default 480
43
44
  --pr commit the index on a branch, push it, open the pull request
@@ -72,6 +73,7 @@ function flags(argv) {
72
73
  else if (token === '--timeout') parsed.timeout = Number(argv[++index]);
73
74
  else if (token === '--pr') parsed.pr = true;
74
75
  else if (token === '--merge') parsed.merge = true;
76
+ else if (token === '--publish') parsed.publish = true;
75
77
  else if (token === '--base') parsed.base = argv[++index];
76
78
  else if (token === '--market') parsed.market = argv[++index];
77
79
  else if (token.startsWith('--') === true) throw new Error(`unknown flag ${token}`);
@@ -213,6 +215,7 @@ export async function run(argv, io = console) {
213
215
  dir,
214
216
  indexFile: options.index,
215
217
  marketDir: options.market,
218
+ publish: options.publish === true,
216
219
  tagPrefix: options.tagPrefix,
217
220
  budgetMs: options.budget === undefined ? undefined : options.budget * 1000,
218
221
  pr: options.pr === true,
package/lib/release.mjs CHANGED
@@ -5,7 +5,7 @@
5
5
  * registry, then touch the index — the index entry carries the publish time the
6
6
  * registry reported, so writing it earlier would mean guessing.
7
7
  */
8
- import { run } from './exec.mjs';
8
+ import { run as runCommand } from './exec.mjs';
9
9
  import fs from 'node:fs';
10
10
  import path from 'node:path';
11
11
 
@@ -14,11 +14,15 @@ import { addVersion, buildEntry, readIndex, writeIndex } from './index-file.mjs'
14
14
  import { publishedAt, waitForVersion } from './registry.mjs';
15
15
  import { defaultGh, mergePr, openIndexPr, waitForChecks } from './pr.mjs';
16
16
 
17
+ function publishPackage(dir) {
18
+ runCommand('npm', ['publish'], { cwd: dir, stdio: 'pipe' });
19
+ }
20
+
17
21
  function git(dir, args) {
18
22
  // stderr is dropped on purpose: `rev-parse` on a tag that does not exist yet is
19
23
  // an expected miss, and git prints "fatal: ambiguous argument" for it, which
20
24
  // reads like a failure in the middle of a successful release.
21
- return run('git', args, { cwd: dir, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trim();
25
+ return runCommand('git', args, { cwd: dir, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trim();
22
26
  }
23
27
 
24
28
  export function tagName(version, prefix = 'plugin-v') {
@@ -122,6 +126,17 @@ export async function release(options) {
122
126
  gitRun(['tag', tag]);
123
127
  gitRun(['push', 'origin', tag]);
124
128
 
129
+ // Not every plugin publishes from CI. `--publish` runs the publish here, so
130
+ // the same command covers both kinds of repository.
131
+ if (options.publish === true) {
132
+ try {
133
+ (options.publishPackage ?? publishPackage)(dir);
134
+ } catch (error) {
135
+ const detail = String(error.stderr ?? error.message).trim().split('\n').slice(-1)[0];
136
+ return { ok: false, stage: 'publish', failures: [{ check: 'publish', message: `npm publish failed: ${detail}` }] };
137
+ }
138
+ }
139
+
125
140
  const waited = await waitForVersion(name, version, {
126
141
  // Wait for the publish *time* as well: `versions` can appear a moment before
127
142
  // `time`, and an index entry with a null timestamp fails the market checker.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-toolkit",
3
- "version": "0.8.5",
3
+ "version": "0.8.6",
4
4
  "description": "Preflight, release and test DeepSeek Harness plugins: checks what the host needs, waits for npm to actually serve the version, and keeps the market index honest.",
5
5
  "type": "module",
6
6
  "bin": {