@entro314labs/release-kit 2.2.1 → 2.2.2

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 +4 -0
  2. package/package.json +1 -1
  3. package/release.mjs +32 -8
package/README.md CHANGED
@@ -305,6 +305,10 @@ Anything else runs as written with no preflight. The project name comes from the
305
305
  `name` in `package.json`, `Cargo.toml` or `pyproject.toml`, `module` in `go.mod` — falling
306
306
  back to the repository directory.
307
307
 
308
+ With no `versionFile` configured it is detected from the repository — `package.json`,
309
+ `pyproject.toml`, `Cargo.toml`, then `VERSION` — so most projects need no config for it at
310
+ all. Set it explicitly to override, or to `null` for a repository that versions by tag.
311
+
308
312
  The format is inferred from the file name: `.json` reads the `"version"` field, `.toml`
309
313
  reads the first `version = "x.y.z"` line, and any other file is treated as containing just
310
314
  the version. Only the version itself is rewritten, so comments and formatting survive — and
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@entro314labs/release-kit",
3
- "version": "2.2.1",
3
+ "version": "2.2.2",
4
4
  "description": "Single-file, zero-dependency release mechanism for JS/TS/Node projects: version bump, changelog roll, commit, annotated tag, push, publish, GitHub release",
5
5
  "keywords": [
6
6
  "changelog",
package/release.mjs CHANGED
@@ -58,8 +58,8 @@ import { createInterface } from 'node:readline/promises'
58
58
  * branch string the only branch a release may run from; null to allow any
59
59
  * remote string git remote to push to
60
60
  * changelog string changelog path; null to disable changelog handling
61
- * versionFile string|object|null where the project's version lives; null when the
62
- * repository versions by git tag alone
61
+ * versionFile string|object|null where the project's version lives. Detected from
62
+ * the repository when unset; null when it versions by tag alone
63
63
  * versionFiles array further files whose version is kept in sync; each is a path
64
64
  * or { path, pattern }
65
65
  * publish string publish command; null to skip publishing entirely
@@ -98,7 +98,7 @@ const DEFAULTS = {
98
98
  branch: 'main',
99
99
  remote: 'origin',
100
100
  changelog: 'CHANGELOG.md',
101
- versionFile: 'package.json',
101
+ versionFile: undefined,
102
102
  versionFiles: [],
103
103
  publish: 'npm publish --tag %d',
104
104
  commitMessage: 'chore(release): %t',
@@ -857,10 +857,8 @@ if (existsSync(localManifest) && localManifest !== rootManifest) {
857
857
  }
858
858
  process.chdir(root)
859
859
 
860
- const config = {
861
- ...DEFAULTS,
862
- ...(existsSync('release.config.json') ? readJson('release.config.json') : {}),
863
- }
860
+ const userConfig = existsSync('release.config.json') ? readJson('release.config.json') : {}
861
+ const config = { ...DEFAULTS, ...userConfig }
864
862
  const unknownKeys = Object.keys(config).filter((key) => !(key in DEFAULTS))
865
863
  if (unknownKeys.length) abort(`release.config.json has unknown keys: ${unknownKeys.join(', ')}`)
866
864
 
@@ -881,7 +879,33 @@ const parseStepList = (value) =>
881
879
  * tag alone and the version has to be passed explicitly.
882
880
  */
883
881
  const manifest = existsSync('package.json') ? readJson('package.json') : null
884
- const versionFile = config.versionFile ? versionSource(config.versionFile) : null
882
+
883
+ /**
884
+ * Where this project keeps its version, when the config does not say. Checked in order of
885
+ * how definitively each file identifies a repository. `go.mod` resolves to null because Go
886
+ * modules carry no version — the tag is the version.
887
+ */
888
+ function detectVersionFile() {
889
+ for (const candidate of ['package.json', 'pyproject.toml', 'Cargo.toml', 'VERSION']) {
890
+ if (existsSync(candidate)) return candidate
891
+ }
892
+ return null
893
+ }
894
+
895
+ // An explicit `versionFile: null` means "versions by tag" and must not be re-detected, so
896
+ // the distinction is between the key being absent and the key being set to null.
897
+ const configuredVersionFile = Object.hasOwn(userConfig, 'versionFile')
898
+ ? userConfig.versionFile
899
+ : detectVersionFile()
900
+ const versionFile = configuredVersionFile ? versionSource(configuredVersionFile) : null
901
+ // Only worth saying when it is not the conventional default.
902
+ if (
903
+ !Object.hasOwn(userConfig, 'versionFile') &&
904
+ versionFile &&
905
+ versionFile.path !== 'package.json'
906
+ ) {
907
+ note(`version source: ${versionFile.path} (detected)`)
908
+ }
885
909
 
886
910
  if (versionFile && !existsSync(versionFile.path)) {
887
911
  abort(`versionFile ${versionFile.path} does not exist`)