@pellux/goodvibes-toolchain 1.11.1 → 1.11.3

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.
@@ -1,9 +1,16 @@
1
1
  #!/usr/bin/env node
2
- import { readFileSync } from 'node:fs';
2
+ import { existsSync, readFileSync } from 'node:fs';
3
3
  import { resolve } from 'node:path';
4
4
  import { loadToolchainConfig } from '../lib/load-config.js';
5
5
  import { consoleLogger } from '../lib/effects.js';
6
6
  import { runPublishPackage, pollPropagation } from '../lib/publish-package.js';
7
+ /** Read the value that follows a `--flag <value>` argument, or undefined when absent. */
8
+ function flagValue(flag) {
9
+ const index = process.argv.indexOf(flag);
10
+ if (index < 0)
11
+ return undefined;
12
+ return process.argv[index + 1];
13
+ }
7
14
  const root = process.cwd();
8
15
  const config = loadToolchainConfig(root);
9
16
  if (!config.publish) {
@@ -13,7 +20,28 @@ if (!config.publish) {
13
20
  const version = JSON.parse(readFileSync(resolve(root, 'package.json'), 'utf8')).version;
14
21
  const dryRun = process.argv.includes('--dry-run');
15
22
  const registry = process.env.GOODVIBES_PUBLISH_REGISTRY ?? config.publish.defaultRegistry;
16
- const result = runPublishPackage({ cwd: root, name: config.publish.packageName, version, registry, dryRun, logger: consoleLogger });
23
+ // --tarball <path>: publish a prebuilt .tgz instead of packing cwd. Validate the
24
+ // flag value up front — a missing/empty path is a caller error (exit 2), kept
25
+ // distinct from a publish failure (exit 1) so a broken pack→publish handoff is
26
+ // unambiguous in CI logs.
27
+ const tarballPath = flagValue('--tarball');
28
+ if (process.argv.includes('--tarball') && (tarballPath === undefined || tarballPath.length === 0)) {
29
+ consoleLogger.error('publish-package: --tarball requires a file path');
30
+ process.exit(2);
31
+ }
32
+ if (tarballPath !== undefined && !existsSync(resolve(root, tarballPath))) {
33
+ consoleLogger.error(`publish-package: --tarball path does not exist: ${tarballPath}`);
34
+ process.exit(2);
35
+ }
36
+ const result = runPublishPackage({
37
+ cwd: root,
38
+ name: config.publish.packageName,
39
+ version,
40
+ registry,
41
+ dryRun,
42
+ ...(tarballPath !== undefined ? { tarballPath } : {}),
43
+ logger: consoleLogger,
44
+ });
17
45
  consoleLogger.info(`publish-package: ${result.detail}`);
18
46
  if (!result.ok)
19
47
  process.exit(1);
@@ -15,7 +15,17 @@ export interface PublishOptions {
15
15
  readonly version: string;
16
16
  readonly registry?: string;
17
17
  readonly dryRun?: boolean;
18
+ /**
19
+ * When set, publish this prebuilt tarball (`npm publish <tarballPath>`)
20
+ * instead of packing and publishing `cwd`. Used by repos whose npm bytes are
21
+ * produced by a separate pack job (e.g. the agent bundles a runtime before
22
+ * `bun pm pack`), so the publish must ship the staged .tgz rather than a bare
23
+ * checkout. The path must exist and be a readable `.tgz`.
24
+ */
25
+ readonly tarballPath?: string;
18
26
  readonly exec?: Exec;
27
+ /** File-existence seam (defaults to node `existsSync`) so tarball validation is testable. */
28
+ readonly fileExists?: (path: string) => boolean;
19
29
  readonly logger?: Logger;
20
30
  }
21
31
  export interface PublishResult {
@@ -1 +1 @@
1
- {"version":3,"file":"publish-package.d.ts","sourceRoot":"","sources":["../../src/lib/publish-package.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAIxD,mFAAmF;AACnF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK9G;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,mEAAmE;AACnE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG,aAAa,CAsBxE;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,gFAAgF;AAChF,wBAAsB,eAAe,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAiB7F"}
1
+ {"version":3,"file":"publish-package.d.ts","sourceRoot":"","sources":["../../src/lib/publish-package.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAIxD,mFAAmF;AACnF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK9G;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;IACrB,6FAA6F;IAC7F,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAChD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,mEAAmE;AACnE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG,aAAa,CAmDxE;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,gFAAgF;AAChF,wBAAsB,eAAe,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAiB7F"}
@@ -6,6 +6,8 @@
6
6
  * (re-runs are safe). Propagation poll: after publish, wait until the registry
7
7
  * actually serves the new version before downstream jobs depend on it.
8
8
  */
9
+ import { existsSync } from 'node:fs';
10
+ import { resolve } from 'node:path';
9
11
  import { realExec, consoleLogger, realSleep } from './effects.js';
10
12
  import { DEFAULT_REGISTRY } from '../config.js';
11
13
  /** Query the published version of name@version; null when absent (or on error). */
@@ -21,6 +23,34 @@ export function runPublishPackage(options) {
21
23
  const exec = options.exec ?? realExec;
22
24
  const logger = options.logger ?? consoleLogger;
23
25
  const registry = options.registry ?? DEFAULT_REGISTRY;
26
+ const fileExists = options.fileExists ?? existsSync;
27
+ // Resolved to absolute before it ever reaches npm: npm parses a bare
28
+ // relative path like `dir/pkg.tgz` as a GitHub owner/repo spec, so a
29
+ // caller-supplied relative path would publish the wrong thing entirely.
30
+ const tarball = options.tarballPath === undefined ? undefined : resolve(options.tarballPath);
31
+ if (tarball !== undefined) {
32
+ // Tarball mode: publish a prebuilt .tgz. Validate the flag value — the file
33
+ // must exist and be a `.tgz` — before doing anything with it. `npm pack
34
+ // --dry-run` is meaningless here (there is nothing to pack), so a dry run
35
+ // just confirms the staged tarball is present and readable.
36
+ if (!tarball.endsWith('.tgz') || !fileExists(tarball)) {
37
+ return { ok: false, skipped: false, detail: `tarball not found or not a .tgz: ${tarball}` };
38
+ }
39
+ if (options.dryRun) {
40
+ return { ok: true, skipped: false, detail: `dry-run: tarball present (${tarball})` };
41
+ }
42
+ const alreadyTarball = getPublishedVersion(exec, options.name, options.version, registry);
43
+ if (alreadyTarball === options.version) {
44
+ logger.info(`[publish-package] ${options.name}@${options.version} already published — skipping`);
45
+ return { ok: true, skipped: true, detail: 'already published' };
46
+ }
47
+ const res = exec('npm', ['publish', tarball, '--access', 'public', '--registry', registry], { cwd: options.cwd });
48
+ if (res.status !== 0) {
49
+ return { ok: false, skipped: false, detail: `npm publish failed: ${res.stderr.trim().slice(0, 400)}` };
50
+ }
51
+ logger.info(`[publish-package] published ${options.name}@${options.version} from ${tarball}`);
52
+ return { ok: true, skipped: false, detail: 'published' };
53
+ }
24
54
  if (options.dryRun) {
25
55
  const res = exec('npm', ['pack', '--json'], { cwd: options.cwd });
26
56
  return { ok: res.status === 0, skipped: false, detail: res.status === 0 ? 'dry-run pack ok' : `dry-run pack failed: ${res.stderr.trim()}` };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-toolchain",
3
- "version": "1.11.1",
3
+ "version": "1.11.3",
4
4
  "engines": {
5
5
  "bun": "1.3.10",
6
6
  "node": ">=22.0.0"