@exadev/semantic-release-workspace 1.0.3 → 1.1.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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +16 -5
  3. package/package.json +2 -1
package/README.md CHANGED
@@ -113,7 +113,7 @@ Run it from the workspace root (or pass `--root <directory>`). A dry run analyse
113
113
  | `--plugin <spec>` | Publish-pipeline plugin, repeatable — a module name (`@semantic-release/github`) or a JSON tuple (`'["@semantic-release/git",{"assets":["package.json"]}]'`); defaults to the standard changelog/npm/github/git pipeline |
114
114
  | `--analyze-commits <json>` | Options for the wrapped @semantic-release/commit-analyzer (e.g. `'{"preset":"conventionalcommits","releaseRules":[...]}'`) |
115
115
  | `--generate-notes <json>` | Options for the wrapped @semantic-release/release-notes-generator |
116
- | `--config <file>` | A JSON file providing any of the above; explicit flags win |
116
+ | `--config <file>` | A config file (`.json`, `.yaml`, `.yml`, `.js`, `.cjs`, or `.ts`, loaded via [cosmiconfig](https://github.com/cosmiconfig/cosmiconfig)) providing any of the above; explicit flags win |
117
117
 
118
118
  Listing `@semantic-release/commit-analyzer` or `@semantic-release/release-notes-generator` as a `--plugin` is rejected: the orchestrator always provides those two steps itself (wrapped), so configuring them there would be a silent no-op — pass their options via `--analyze-commits`/`--generate-notes` instead. A real (non-dry) run must include `@semantic-release/git` in the pipeline, because without it nothing commits released manifests and changelogs back to the branch.
119
119
 
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from "node:module";
3
- import { readFileSync } from "node:fs";
3
+ import { cosmiconfigSync } from "cosmiconfig";
4
4
  import { Command, InvalidArgumentError } from "commander";
5
5
  import { dirname, relative, resolve, sep } from "node:path";
6
6
  import { analyzeCommits } from "@semantic-release/commit-analyzer";
@@ -13,7 +13,7 @@ import validateNpmPackageName from "validate-npm-package-name";
13
13
  import { glob } from "tinyglobby";
14
14
  import { parse } from "yaml";
15
15
  //#region package.json
16
- var version = "1.0.3";
16
+ var version = "1.1.0";
17
17
  //#endregion
18
18
  //#region src/errors.ts
19
19
  /**
@@ -823,7 +823,7 @@ function createProgram() {
823
823
  release.option("--plugin <spec>", "publish-pipeline plugin, repeatable: a module name, or a JSON array of [name, config]; defaults to the standard changelog/npm/github/git pipeline", collectRepeated, []);
824
824
  release.option("--analyze-commits <json>", "options for the wrapped @semantic-release/commit-analyzer, as a JSON object");
825
825
  release.option("--generate-notes <json>", "options for the wrapped @semantic-release/release-notes-generator, as a JSON object");
826
- release.option("--config <file>", "JSON file providing any of the release options (dryRun, branches, plugins, analyzeCommits, generateNotes); explicit flags win");
826
+ release.option("--config <file>", "config file (.json, .yaml, .yml, .js, .cjs, or .ts) providing any of the release options (dryRun, branches, plugins, analyzeCommits, generateNotes); explicit flags win");
827
827
  release.action(runRelease);
828
828
  return program;
829
829
  }
@@ -873,8 +873,19 @@ function parsePluginSpec(raw) {
873
873
  if (!isPluginSpecTuple(parsed)) throw new InvalidArgumentError("--plugin must be a module name or a JSON array of [name, config]");
874
874
  return parsed;
875
875
  }
876
+ function readConfigFile(path) {
877
+ const explorer = cosmiconfigSync("semantic-release-workspace");
878
+ let result;
879
+ try {
880
+ result = explorer.load(path);
881
+ } catch (cause) {
882
+ throw new InvalidArgumentError(`--config file ${path} could not be loaded: ${cause instanceof Error ? cause.message : String(cause)}`);
883
+ }
884
+ if (result === null || result.isEmpty === true) throw new InvalidArgumentError(`--config file ${path} is empty`);
885
+ return result.config;
886
+ }
876
887
  function readReleaseConfigFile(path) {
877
- const parsed = parseJson(readFileSync(path, "utf8"), "--config");
888
+ const parsed = readConfigFile(path);
878
889
  if (!isJsonObject(parsed)) throw new InvalidArgumentError(`--config file ${path} must contain a JSON object`);
879
890
  for (const key of Object.keys(parsed)) if (!CONFIG_OPTION_KEYS.has(key)) throw new InvalidArgumentError(`--config file ${path} has an unknown option "${key}"; recognised options: ${[...CONFIG_OPTION_KEYS].join(", ")}`);
880
891
  const { dryRun, branches, plugins, analyzeCommits, generateNotes } = parsed;
@@ -910,4 +921,4 @@ createProgram().parseAsync(process.argv).catch((cause) => {
910
921
  process.exitCode = 1;
911
922
  });
912
923
  //#endregion
913
- export { createProgram };
924
+ export { createProgram, readReleaseConfigFile };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exadev/semantic-release-workspace",
3
- "version": "1.0.3",
3
+ "version": "1.1.0",
4
4
  "description": "Independent per-package semantic-release orchestration for pnpm workspaces, without lockstep versioning.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -78,6 +78,7 @@
78
78
  "packageManager": "pnpm@11.6.0",
79
79
  "dependencies": {
80
80
  "commander": "^15.0.0",
81
+ "cosmiconfig": "^9.0.2",
81
82
  "tinyglobby": "^0.2.17",
82
83
  "validate-npm-package-name": "^8.0.0",
83
84
  "yaml": "^2.9.0"