versionary 0.6.0 → 0.8.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.
package/README.md CHANGED
@@ -125,6 +125,8 @@ Current rust auto-update behavior (phase scope):
125
125
  - updates crate versions in each targeted crate `[package].version`
126
126
  - updates internal workspace dependency versions when the dependency name
127
127
  matches another targeted crate name
128
+ - refreshes `Cargo.lock` via `cargo generate-lockfile` when `Cargo.lock` exists
129
+ in repo root
128
130
  - applies dependency version rewrites in:
129
131
  - `[dependencies]`, `[dev-dependencies]`, `[build-dependencies]`
130
132
  - `[target.*.dependencies]`, `[target.*.dev-dependencies]`,
@@ -137,6 +139,8 @@ Current rust non-goals/limits:
137
139
  - does not add missing `version = ...` fields to dependency inline tables
138
140
  - does not perform Cargo publish/release to crates.io
139
141
 
142
+ If `Cargo.lock` exists, `cargo` must be available in PATH during PR preparation.
143
+
140
144
  ### Monorepo release names and tag naming
141
145
 
142
146
  For independent monorepo targets, Versionary derives release tags as:
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_child_process_1 = require("node:child_process");
4
+ const node_crypto_1 = require("node:crypto");
5
+ const node_fs_1 = require("node:fs");
6
+ function getInput(name) {
7
+ const canonical = `INPUT_${name.replace(/ /g, "_").toUpperCase()}`;
8
+ const underscoreAlias = canonical.replace(/-/g, "_");
9
+ return (process.env[canonical] ??
10
+ process.env[underscoreAlias] ??
11
+ process.env[`INPUT_${name.toUpperCase()}`] ??
12
+ "").trim();
13
+ }
14
+ function runGit(cwd, args) {
15
+ return (0, node_child_process_1.execFileSync)("git", args, {
16
+ cwd,
17
+ encoding: "utf8",
18
+ stdio: ["ignore", "pipe", "pipe"],
19
+ }).trim();
20
+ }
21
+ function hasGitConfig(cwd, key) {
22
+ try {
23
+ runGit(cwd, ["config", key]);
24
+ return true;
25
+ }
26
+ catch {
27
+ return false;
28
+ }
29
+ }
30
+ function hasOriginRemote(cwd) {
31
+ try {
32
+ runGit(cwd, ["remote", "get-url", "origin"]);
33
+ return true;
34
+ }
35
+ catch {
36
+ return false;
37
+ }
38
+ }
39
+ function setOutput(name, value) {
40
+ const outputPath = process.env.GITHUB_OUTPUT;
41
+ if (!outputPath) {
42
+ throw new Error("GITHUB_OUTPUT is not set.");
43
+ }
44
+ const delimiter = `versionary-${(0, node_crypto_1.randomUUID)()}`;
45
+ (0, node_fs_1.appendFileSync)(outputPath, `${name}<<${delimiter}\n${value}\n${delimiter}\n`, "utf8");
46
+ }
47
+ function main() {
48
+ const token = getInput("token") || getInput("github-token");
49
+ if (!token) {
50
+ throw new Error("Input required and not supplied: token (or deprecated github-token).");
51
+ }
52
+ const versionaryVersion = getInput("versionary-version") || "0.7.0";
53
+ const cwd = getInput("working-directory") || ".";
54
+ process.chdir(cwd);
55
+ if (!hasGitConfig(cwd, "user.name")) {
56
+ runGit(cwd, ["config", "user.name", "github-actions[bot]"]);
57
+ }
58
+ if (!hasGitConfig(cwd, "user.email")) {
59
+ runGit(cwd, [
60
+ "config",
61
+ "user.email",
62
+ "41898282+github-actions[bot]@users.noreply.github.com",
63
+ ]);
64
+ }
65
+ if (hasOriginRemote(cwd)) {
66
+ const serverUrl = process.env.GITHUB_SERVER_URL ?? "https://github.com";
67
+ const repository = process.env.GITHUB_REPOSITORY;
68
+ if (!repository) {
69
+ throw new Error("GITHUB_REPOSITORY is not set.");
70
+ }
71
+ const base = serverUrl.replace(/^https?:\/\//u, "");
72
+ const encodedToken = encodeURIComponent(token);
73
+ runGit(cwd, [
74
+ "remote",
75
+ "set-url",
76
+ "origin",
77
+ `https://x-access-token:${encodedToken}@${base}/${repository}.git`,
78
+ ]);
79
+ }
80
+ const raw = (0, node_child_process_1.execFileSync)("npx", ["--yes", `versionary@${versionaryVersion}`, "run", "--json"], {
81
+ cwd,
82
+ encoding: "utf8",
83
+ stdio: ["ignore", "pipe", "pipe"],
84
+ env: {
85
+ ...process.env,
86
+ GITHUB_TOKEN: token,
87
+ },
88
+ }).trim();
89
+ if (!raw) {
90
+ throw new Error("Versionary returned empty JSON output.");
91
+ }
92
+ process.stdout.write(`${raw}\n`);
93
+ let payload;
94
+ try {
95
+ payload = JSON.parse(raw);
96
+ }
97
+ catch (error) {
98
+ throw new Error(`Failed parsing Versionary JSON output: ${error instanceof Error ? error.message : String(error)}`);
99
+ }
100
+ const tagNames = Array.isArray(payload.tagNames)
101
+ ? payload.tagNames.filter((value) => typeof value === "string")
102
+ : [];
103
+ const firstTag = tagNames[0] ?? "";
104
+ const releaseCreated = payload.releaseCreated === true || tagNames.length > 0 ? "true" : "false";
105
+ setOutput("action", payload.action ?? "");
106
+ setOutput("message", payload.message ?? "");
107
+ setOutput("release_created", releaseCreated);
108
+ setOutput("tag_name", firstTag);
109
+ setOutput("tag_names", JSON.stringify(tagNames));
110
+ setOutput("review_url", payload.reviewUrl ?? "");
111
+ setOutput("branch", payload.branch ?? "");
112
+ setOutput("title", payload.title ?? "");
113
+ }
114
+ try {
115
+ main();
116
+ }
117
+ catch (error) {
118
+ const message = error instanceof Error ? error.message : String(error);
119
+ process.stderr.write(`${message}\n`);
120
+ process.exit(1);
121
+ }
@@ -11,25 +11,25 @@ const yaml_1 = __importDefault(require("yaml"));
11
11
  function isRecord(value) {
12
12
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
13
13
  }
14
- function parseJsonPath(jsonpath) {
15
- if (!jsonpath.startsWith("$")) {
16
- throw new Error(`Invalid jsonpath "${jsonpath}". Must start with "$".`);
14
+ function parseFieldPath(fieldPath) {
15
+ if (!fieldPath.startsWith("$")) {
16
+ throw new Error(`Invalid field-path "${fieldPath}". Must start with "$".`);
17
17
  }
18
18
  const tokens = [];
19
19
  let index = 1;
20
- while (index < jsonpath.length) {
21
- const current = jsonpath[index];
20
+ while (index < fieldPath.length) {
21
+ const current = fieldPath[index];
22
22
  if (current === ".") {
23
- const keyMatch = jsonpath.slice(index + 1).match(/^[A-Za-z0-9_-]+/u);
23
+ const keyMatch = fieldPath.slice(index + 1).match(/^[A-Za-z0-9_-]+/u);
24
24
  if (!keyMatch) {
25
- throw new Error(`Invalid jsonpath "${jsonpath}" near index ${index}.`);
25
+ throw new Error(`Invalid field-path "${fieldPath}" near index ${index}.`);
26
26
  }
27
27
  tokens.push(keyMatch[0]);
28
28
  index += 1 + keyMatch[0].length;
29
29
  continue;
30
30
  }
31
31
  if (current === "[") {
32
- const rest = jsonpath.slice(index + 1);
32
+ const rest = fieldPath.slice(index + 1);
33
33
  const numberMatch = rest.match(/^(\d+)\]/u);
34
34
  if (numberMatch) {
35
35
  tokens.push(Number(numberMatch[1]));
@@ -42,53 +42,60 @@ function parseJsonPath(jsonpath) {
42
42
  index += 4 + keyMatch[1].length;
43
43
  continue;
44
44
  }
45
- throw new Error(`Invalid jsonpath "${jsonpath}" near index ${index}.`);
45
+ throw new Error(`Invalid field-path "${fieldPath}" near index ${index}.`);
46
46
  }
47
- throw new Error(`Invalid jsonpath "${jsonpath}" near index ${index}.`);
47
+ throw new Error(`Invalid field-path "${fieldPath}" near index ${index}.`);
48
48
  }
49
49
  if (tokens.length === 0) {
50
- throw new Error(`Invalid jsonpath "${jsonpath}". Path must target a field.`);
50
+ throw new Error(`Invalid field-path "${fieldPath}". Path must target a field.`);
51
51
  }
52
52
  return tokens;
53
53
  }
54
- function setVersionAtJsonPath(document, jsonpath, version) {
55
- const tokens = parseJsonPath(jsonpath);
54
+ function setVersionAtJsonPath(document, fieldPath, version) {
55
+ const tokens = parseFieldPath(fieldPath);
56
56
  let cursor = document;
57
57
  for (let index = 0; index < tokens.length - 1; index += 1) {
58
58
  const token = tokens[index];
59
59
  if (typeof token === "number") {
60
60
  if (!Array.isArray(cursor) || token >= cursor.length) {
61
- throw new Error(`jsonpath "${jsonpath}" does not resolve to an existing field.`);
61
+ throw new Error(`field-path "${fieldPath}" does not resolve to an existing field.`);
62
62
  }
63
63
  cursor = cursor[token];
64
64
  continue;
65
65
  }
66
66
  if (!isRecord(cursor) || !(token in cursor)) {
67
- throw new Error(`jsonpath "${jsonpath}" does not resolve to an existing field.`);
67
+ throw new Error(`field-path "${fieldPath}" does not resolve to an existing field.`);
68
68
  }
69
69
  cursor = cursor[token];
70
70
  }
71
71
  const leaf = tokens.at(-1);
72
72
  if (typeof leaf === "number") {
73
73
  if (!Array.isArray(cursor) || leaf >= cursor.length) {
74
- throw new Error(`jsonpath "${jsonpath}" does not resolve to an existing field.`);
74
+ throw new Error(`field-path "${fieldPath}" does not resolve to an existing field.`);
75
75
  }
76
76
  const current = cursor[leaf];
77
77
  if (typeof current !== "string" && typeof current !== "number") {
78
- throw new Error(`jsonpath "${jsonpath}" must point to a string or number field for version updates.`);
78
+ throw new Error(`field-path "${fieldPath}" must point to a string or number field for version updates.`);
79
79
  }
80
80
  cursor[leaf] = version;
81
81
  return;
82
82
  }
83
83
  if (!isRecord(cursor) || !(leaf in cursor)) {
84
- throw new Error(`jsonpath "${jsonpath}" does not resolve to an existing field.`);
84
+ throw new Error(`field-path "${fieldPath}" does not resolve to an existing field.`);
85
85
  }
86
86
  const current = cursor[leaf];
87
87
  if (typeof current !== "string" && typeof current !== "number") {
88
- throw new Error(`jsonpath "${jsonpath}" must point to a string or number field for version updates.`);
88
+ throw new Error(`field-path "${fieldPath}" must point to a string or number field for version updates.`);
89
89
  }
90
90
  cursor[leaf] = version;
91
91
  }
92
+ function resolveFieldPath(rule) {
93
+ const fieldPath = rule["field-path"] ?? rule.jsonpath;
94
+ if (!fieldPath) {
95
+ throw new Error(`${rule.type} artifact rules require "field-path" (or deprecated "jsonpath").`);
96
+ }
97
+ return fieldPath;
98
+ }
92
99
  function parseRegexPattern(pattern) {
93
100
  const slashPattern = pattern.match(/^\/((?:\\\/|[^/])+)\/([a-z]*)$/u);
94
101
  if (slashPattern) {
@@ -116,22 +123,36 @@ function applyRegexRule(content, pattern, version) {
116
123
  const replacement = typeof groupOne === "string" ? full.replace(groupOne, version) : version;
117
124
  return `${content.slice(0, start)}${replacement}${content.slice(start + full.length)}`;
118
125
  }
126
+ function applyTomlRulePreservingFormatting(content, fieldPath, version) {
127
+ const simplePath = fieldPath.match(/^\$\.([A-Za-z0-9_-]+)$/u);
128
+ if (!simplePath) {
129
+ const parsed = toml_1.default.parse(content);
130
+ setVersionAtJsonPath(parsed, fieldPath, version);
131
+ return `${toml_1.default.stringify(parsed)}\n`;
132
+ }
133
+ const key = simplePath[1];
134
+ const linePattern = new RegExp(`^(\\s*${key}\\s*=\\s*)(["'])([^"']*)(\\2)(\\s*(?:#.*)?)$`, "mu");
135
+ const match = content.match(linePattern);
136
+ if (!match) {
137
+ throw new Error(`field-path "${fieldPath}" does not resolve to an existing field.`);
138
+ }
139
+ const [, prefix = "", quote = '"', , , suffix = ""] = match;
140
+ return content.replace(linePattern, `${prefix}${quote}${version}${quote}${suffix}`);
141
+ }
119
142
  function applyArtifactRuleToContent(content, rule, version) {
120
143
  if (rule.type === "regex") {
121
144
  return applyRegexRule(content, rule.pattern, version);
122
145
  }
123
146
  if (rule.type === "json") {
124
147
  const parsed = JSON.parse(content);
125
- setVersionAtJsonPath(parsed, rule.jsonpath, version);
148
+ setVersionAtJsonPath(parsed, resolveFieldPath(rule), version);
126
149
  return `${JSON.stringify(parsed, null, 2)}\n`;
127
150
  }
128
151
  if (rule.type === "toml") {
129
- const parsed = toml_1.default.parse(content);
130
- setVersionAtJsonPath(parsed, rule.jsonpath, version);
131
- return `${toml_1.default.stringify(parsed)}\n`;
152
+ return applyTomlRulePreservingFormatting(content, resolveFieldPath(rule), version);
132
153
  }
133
154
  const parsed = yaml_1.default.parse(content);
134
- setVersionAtJsonPath(parsed, rule.jsonpath, version);
155
+ setVersionAtJsonPath(parsed, resolveFieldPath(rule), version);
135
156
  return `${yaml_1.default.stringify(parsed)}`;
136
157
  }
137
158
  function normalizeRelative(base, target) {
@@ -20,4 +20,4 @@ export declare function openOrUpdateSimpleReviewRequest(cwd: string, branch: str
20
20
  logger?: VersionaryPluginContext["logger"];
21
21
  }): Promise<string>;
22
22
  export declare function pushReleaseBranch(cwd: string, branch: string): void;
23
- export declare function isReleaseCommitMessage(subject: string): boolean;
23
+ export declare function isReleaseCommitMessage(commitMessage: string): boolean;
@@ -30,6 +30,7 @@ const SAFE_DIRTY_FILES = new Set([
30
30
  "bun.lockb",
31
31
  "npm-shrinkwrap.json",
32
32
  ]);
33
+ const VERSIONARY_RELEASE_TRAILER = "Versionary-Release: true";
33
34
  function listTrackedDirtyFiles(cwd) {
34
35
  const status = (0, node_child_process_1.execFileSync)("git", ["status", "--porcelain", "--untracked-files=no"], {
35
36
  cwd,
@@ -70,6 +71,25 @@ function ensureCleanWorktree(cwd, logger) {
70
71
  logger?.warn(`Ignoring safe tracked changes before versionary pr:\n${ignored.join("\n")}`);
71
72
  }
72
73
  }
74
+ function ensureCargoLockUpToDate(cwd) {
75
+ const lockfilePath = node_path_1.default.join(cwd, "Cargo.lock");
76
+ if (!node_fs_1.default.existsSync(lockfilePath)) {
77
+ return [];
78
+ }
79
+ const before = node_fs_1.default.readFileSync(lockfilePath, "utf8");
80
+ try {
81
+ (0, node_child_process_1.execFileSync)("cargo", ["generate-lockfile"], {
82
+ cwd,
83
+ stdio: ["ignore", "pipe", "pipe"],
84
+ });
85
+ }
86
+ catch (error) {
87
+ const message = error instanceof Error ? error.message : String(error);
88
+ throw new Error(`Failed to refresh Cargo.lock via "cargo generate-lockfile". Ensure cargo is installed and available in PATH. Details: ${message}`);
89
+ }
90
+ const after = node_fs_1.default.readFileSync(lockfilePath, "utf8");
91
+ return after !== before ? ["Cargo.lock"] : [];
92
+ }
73
93
  function normalizeReleaseNameForTag(releaseName) {
74
94
  return releaseName
75
95
  .trim()
@@ -195,6 +215,7 @@ function prepareSimpleReleasePr(cwd = process.cwd(), options = {}) {
195
215
  updatedVersionFiles.push(...strategy.writeVersion(cwd, loaded.config, plan.nextVersion));
196
216
  }
197
217
  const updatedArtifactFiles = (0, artifact_rules_js_1.applyConfiguredArtifactRules)(cwd, loaded.config, plan);
218
+ const updatedRustLockFiles = ensureCargoLockUpToDate(cwd);
198
219
  const section = (0, changelog_js_1.renderSimpleChangelog)(plan);
199
220
  (0, changelog_js_1.prependChangelog)(cwd, plan.changelogFile, section);
200
221
  const releaseTargets = buildReleaseTargets(cwd, plan, loaded.config);
@@ -208,6 +229,7 @@ function prepareSimpleReleasePr(cwd = process.cwd(), options = {}) {
208
229
  ...new Set([
209
230
  ...updatedVersionFiles,
210
231
  ...updatedArtifactFiles,
232
+ ...updatedRustLockFiles,
211
233
  plan.changelogFile,
212
234
  ]),
213
235
  ];
@@ -215,7 +237,7 @@ function prepareSimpleReleasePr(cwd = process.cwd(), options = {}) {
215
237
  cwd,
216
238
  stdio: ["ignore", "pipe", "ignore"],
217
239
  });
218
- (0, node_child_process_1.execFileSync)("git", ["commit", "-m", title], {
240
+ (0, node_child_process_1.execFileSync)("git", ["commit", "-m", title, "-m", VERSIONARY_RELEASE_TRAILER], {
219
241
  cwd,
220
242
  stdio: ["ignore", "pipe", "ignore"],
221
243
  });
@@ -306,6 +328,10 @@ function pushReleaseBranch(cwd, branch) {
306
328
  stdio: ["ignore", "pipe", "ignore"],
307
329
  });
308
330
  }
309
- function isReleaseCommitMessage(subject) {
310
- return /^chore\(release\):\s+(?:v\d+\.\d+\.\d+|\S+-v\d+\.\d+\.\d+)(?:,\s+(?:v\d+\.\d+\.\d+|\S+-v\d+\.\d+\.\d+))*$/u.test(subject);
331
+ function isReleaseCommitMessage(commitMessage) {
332
+ if (/^Versionary-Release:\s*true$/imu.test(commitMessage)) {
333
+ return true;
334
+ }
335
+ const subject = commitMessage.split("\n")[0]?.trim() ?? "";
336
+ return /^chore\(release\):\s+(?:v\d+\.\d+\.\d+|\S+-v\d+\.\d+\.\d+)(?:,\s+(?:v\d+\.\d+\.\d+|\S+-v\d+\.\d+\.\d+))*(?:\s+\(#\d+\))?$/u.test(subject);
311
337
  }
@@ -15,8 +15,8 @@ const runtime_js_1 = require("../../plugins/runtime.js");
15
15
  const pr_js_1 = require("./pr.js");
16
16
  const recovery_js_1 = require("./recovery.js");
17
17
  const state_js_1 = require("./state.js");
18
- function getHeadCommitSubject(cwd) {
19
- return (0, node_child_process_1.execFileSync)("git", ["log", "-1", "--pretty=%s"], {
18
+ function getHeadCommitMessage(cwd) {
19
+ return (0, node_child_process_1.execFileSync)("git", ["log", "-1", "--pretty=%B"], {
20
20
  cwd,
21
21
  encoding: "utf8",
22
22
  stdio: ["ignore", "pipe", "ignore"],
@@ -54,8 +54,8 @@ async function runSimpleRelease(cwd = process.cwd()) {
54
54
  return result.message;
55
55
  }
56
56
  async function runSimpleReleaseDetailed(cwd = process.cwd(), options = {}) {
57
- const subject = getHeadCommitSubject(cwd);
58
- if (!(0, pr_js_1.isReleaseCommitMessage)(subject)) {
57
+ const commitMessage = getHeadCommitMessage(cwd);
58
+ if (!(0, pr_js_1.isReleaseCommitMessage)(commitMessage)) {
59
59
  return {
60
60
  action: "release-skipped",
61
61
  reason: "No release commit context detected; skipping release stage.",
package/dist/cli/index.js CHANGED
@@ -33,11 +33,11 @@ async function main() {
33
33
  const flags = parseFlags(args);
34
34
  const logger = flags.json ? undefined : console;
35
35
  if (!command || command === "run") {
36
- const subject = (0, node_child_process_1.execFileSync)("git", ["log", "-1", "--pretty=%s"], {
36
+ const commitMessage = (0, node_child_process_1.execFileSync)("git", ["log", "-1", "--pretty=%B"], {
37
37
  encoding: "utf8",
38
38
  stdio: ["ignore", "pipe", "ignore"],
39
39
  }).trim();
40
- if ((0, pr_js_1.isReleaseCommitMessage)(subject)) {
40
+ if ((0, pr_js_1.isReleaseCommitMessage)(commitMessage)) {
41
41
  if (flags.json) {
42
42
  const release = await (0, release_js_1.runSimpleReleaseDetailed)(process.cwd(), {
43
43
  logger,
@@ -31,6 +31,7 @@ export declare const configSchema: z.ZodObject<{
31
31
  regex: "regex";
32
32
  }>;
33
33
  path: z.ZodString;
34
+ "field-path": z.ZodOptional<z.ZodString>;
34
35
  jsonpath: z.ZodOptional<z.ZodString>;
35
36
  pattern: z.ZodOptional<z.ZodString>;
36
37
  }, z.core.$strip>>>;
@@ -6,16 +6,18 @@ const artifactRuleSchema = zod_1.z
6
6
  .object({
7
7
  type: zod_1.z.enum(["json", "toml", "yaml", "regex"]),
8
8
  path: zod_1.z.string().min(1),
9
+ "field-path": zod_1.z.string().optional(),
9
10
  jsonpath: zod_1.z.string().optional(),
10
11
  pattern: zod_1.z.string().optional(),
11
12
  })
12
13
  .superRefine((value, ctx) => {
13
14
  const needsJsonPath = value.type === "json" || value.type === "toml" || value.type === "yaml";
14
- if (needsJsonPath && !value.jsonpath) {
15
+ const hasFieldPath = Boolean(value["field-path"] ?? value.jsonpath);
16
+ if (needsJsonPath && !hasFieldPath) {
15
17
  ctx.addIssue({
16
18
  code: zod_1.z.ZodIssueCode.custom,
17
- message: `${value.type} artifact rules require "jsonpath".`,
18
- path: ["jsonpath"],
19
+ message: `${value.type} artifact rules require "field-path" (or deprecated "jsonpath").`,
20
+ path: ["field-path"],
19
21
  });
20
22
  }
21
23
  if (needsJsonPath && value.pattern) {
@@ -25,6 +27,13 @@ const artifactRuleSchema = zod_1.z
25
27
  path: ["pattern"],
26
28
  });
27
29
  }
30
+ if (value["field-path"] && value.jsonpath) {
31
+ ctx.addIssue({
32
+ code: zod_1.z.ZodIssueCode.custom,
33
+ message: 'Specify only one of "field-path" or deprecated "jsonpath".',
34
+ path: ["field-path"],
35
+ });
36
+ }
28
37
  if (value.type === "regex" && !value.pattern) {
29
38
  ctx.addIssue({
30
39
  code: zod_1.z.ZodIssueCode.custom,
@@ -32,11 +41,11 @@ const artifactRuleSchema = zod_1.z
32
41
  path: ["pattern"],
33
42
  });
34
43
  }
35
- if (value.type === "regex" && value.jsonpath) {
44
+ if (value.type === "regex" && (value["field-path"] || value.jsonpath)) {
36
45
  ctx.addIssue({
37
46
  code: zod_1.z.ZodIssueCode.custom,
38
- message: 'regex artifact rules do not support "jsonpath".',
39
- path: ["jsonpath"],
47
+ message: 'regex artifact rules do not support "field-path" or deprecated "jsonpath".',
48
+ path: ["field-path"],
40
49
  });
41
50
  }
42
51
  });
@@ -2,6 +2,7 @@ export type ConfigFileFormat = "jsonc" | "json" | "toml" | "js";
2
2
  export interface VersionaryArtifactRule {
3
3
  type: "json" | "toml" | "yaml" | "regex";
4
4
  path: string;
5
+ "field-path"?: string;
5
6
  jsonpath?: string;
6
7
  pattern?: string;
7
8
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "versionary",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "Automatic release framework based on conventional commits and semantic versioning",
5
5
  "keywords": [
6
6
  "releasing",