semantic-release 25.0.0-beta.3 → 25.0.0-beta.4

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.
@@ -66,6 +66,9 @@
66
66
  - `publish`: Publish the package to the Visual Studio Code marketplace
67
67
  - [semantic-release-verify-deps](https://github.com/piercus/semantic-release-verify-deps)
68
68
  - `verifyConditions`: Check the dependencies format against a regexp before a release
69
+ - [semantic-release-openapi](https://github.com/aensley/semantic-release-openapi)
70
+ - `verifyConditions`: Verify `apiSpecFiles` is specified with at least one file name and all matching files have a .json, .yaml, or .yml extension.
71
+ - `prepare`: Write the correct version to all OpenAPI / Swagger files specified in `apiSpecFiles`.
69
72
  - [semantic-release-chrome](https://github.com/GabrielDuarteM/semantic-release-chrome)
70
73
  - `verifyConditions`: Verify the presence of the authentication (set via environment variables)
71
74
  - `prepare`: Write the correct version to the `manifest.json` and creates a zip file of the whole dist folder
@@ -204,3 +207,6 @@
204
207
  - [semantic-release-kaniko](https://github.com/brendangeck/semantic-release-kaniko)
205
208
  - `verifyConditions`: Verify that all needed configuration is present and login to the Docker registry.
206
209
  - `publish`: Build a container image using [Kaniko](https://github.com/GoogleContainerTools/kaniko) and (optionally) push it to a Docker registry.
210
+ - [semantic-release-skopeo](https://github.com/LukasWestholt/semantic-release-skopeo)
211
+ - `verifyConditions`: Verify that all needed configuration is present and check if destination is writeable (unless force=true).
212
+ - `publish`: Copy OCI images to a custom (Docker) registry using daemonless open-source tool [skopeo](https://github.com/containers/skopeo/).
@@ -2,7 +2,7 @@ import { escapeRegExp, template } from "lodash-es";
2
2
  import semver from "semver";
3
3
  import pReduce from "p-reduce";
4
4
  import debugTags from "debug";
5
- import { getNote, getTags } from "../../lib/git.js";
5
+ import { getTags, getTagsNotes } from "../../lib/git.js";
6
6
 
7
7
  const debug = debugTags("semantic-release:get-tags");
8
8
 
@@ -13,6 +13,9 @@ export default async ({ cwd, env, options: { tagFormat } }, branches) => {
13
13
  // so it's guaranteed to no be present in the `tagFormat`.
14
14
  const tagRegexp = `^${escapeRegExp(template(tagFormat)({ version: " " })).replace(" ", "(.+)")}`;
15
15
 
16
+ // Get the tags notes for all the tags in the repository
17
+ const tagsNotesMap = await getTagsNotes({ cwd, env });
18
+
16
19
  return pReduce(
17
20
  branches,
18
21
  async (branches, branch) => {
@@ -20,8 +23,9 @@ export default async ({ cwd, env, options: { tagFormat } }, branches) => {
20
23
  await getTags(branch.name, { cwd, env }),
21
24
  async (branchTags, tag) => {
22
25
  const [, version] = tag.match(tagRegexp) || [];
26
+ const channels = tagsNotesMap.has(tag) ? tagsNotesMap.get(tag).channels : [null];
23
27
  return version && semver.valid(semver.clean(version))
24
- ? [...branchTags, { gitTag: tag, version, channels: (await getNote(tag, { cwd, env })).channels || [null] }]
28
+ ? [...branchTags, { gitTag: tag, version, channels }]
25
29
  : branchTags;
26
30
  },
27
31
  []
package/lib/git.js CHANGED
@@ -4,6 +4,7 @@ import { execa } from "execa";
4
4
  import debugGit from "debug";
5
5
  import { merge } from "lodash-es";
6
6
  import { GIT_NOTE_REF } from "./definitions/constants.js";
7
+ import { extractGitLogTags } from "./utils.js";
7
8
 
8
9
  const debug = debugGit("semantic-release:git");
9
10
 
@@ -296,42 +297,62 @@ export async function isBranchUpToDate(repositoryUrl, branch, execaOptions) {
296
297
  }
297
298
 
298
299
  /**
299
- * Get and parse the JSON note of a given reference.
300
+ * Retrieves a map of Git tags to their associated notes from the repository.
300
301
  *
301
- * @param {String} ref The Git reference for which to retrieve the note.
302
- * @param {Object} [execaOpts] Options to pass to `execa`.
302
+ * Executes a `git log` command to list tags and their notes, then parses the output into a Map
303
+ * where each key is a tag name (e.g., "v24.2.3") and the value is the parsed JSON note object.
303
304
  *
304
- * @return {Object} the parsed JSON note if there is one, an empty object otherwise.
305
+ * @async
306
+ * @param {import('execa').Options} execaOptions - Options to pass to `execa`
307
+ * @returns {Promise<Map<string, Object>>} A promise that resolves to a Map of tag names to their notes.
305
308
  */
306
- export async function getNote(ref, execaOptions) {
307
- const handleError = (error) => {
308
- if (error.exitCode === 1) {
309
- return { stdout: "{}" };
310
- }
309
+ export async function getTagsNotes(execaOptions) {
310
+ /**
311
+ * git log --tags="*" --decorate-refs="refs/tags/*" --no-walk --format="%d%x09%N" --notes="refs/notes/semantic-release*"
312
+ *
313
+ * (tag: v1.2.3)
314
+ * (tag: v2.0.0) {"channels":[null]}
315
+ * (tag: v3.0.0, tag: 5833/merge) {"channels":[null]}
316
+ * ...
317
+ */
318
+ const { stdout } = await execa(
319
+ "git",
320
+ [
321
+ "log",
322
+ "--tags=*",
323
+ "--decorate-refs=refs/tags/*", // This filters the refs shown in the %d format specifier to only include tags matching refs/tags/*.
324
+ "--no-walk", // This ensures that only the commits directly pointed to by the tags are shown, not their historical parents.
325
+ "--format=%d%x09%N", // <refName><tab><notes> eg. (tag: v24.2.3) {"channels":[null]}
326
+ `--notes=refs/notes/${GIT_NOTE_REF}*`, // handles both patterns for notes - `semantic-release` (old) and `semantic-release-<version>` (current)
327
+ ],
328
+ execaOptions
329
+ );
311
330
 
312
- debug(error);
313
- throw error;
314
- };
331
+ // drop empty lines
332
+ const lines = stdout.split("\n").filter((line) => line.trim() !== "");
315
333
 
316
- try {
317
- return merge(
318
- JSON.parse(
319
- // Used for retro-compatibility
320
- (await execa("git", ["notes", "--ref", GIT_NOTE_REF, "show", ref], execaOptions).catch(handleError)).stdout
321
- ),
322
- JSON.parse(
323
- (await execa("git", ["notes", "--ref", `${GIT_NOTE_REF}-${ref}`, "show", ref], execaOptions).catch(handleError))
324
- .stdout
325
- )
326
- );
327
- } catch (error) {
328
- if (error.exitCode === 1) {
329
- return {};
334
+ // parse and create a map of tags to notes
335
+ const tagNotesMap = new Map();
336
+
337
+ for (const line of lines) {
338
+ const [tagPart, notePart] = line.trim().split("\t"); // tab separator is defined in the git command above (%x09)
339
+ const tags = extractGitLogTags(tagPart);
340
+ if (tags.length === 0) {
341
+ debug(`Cannot parse tags from line: ${line}`);
342
+ continue;
330
343
  }
331
344
 
332
- debug(error);
333
- throw error;
345
+ try {
346
+ const parsed = JSON.parse(notePart);
347
+ tags.forEach((tag) => {
348
+ tagNotesMap.set(tag, parsed);
349
+ });
350
+ } catch (error) {
351
+ debug(error);
352
+ }
334
353
  }
354
+
355
+ return tagNotesMap;
335
356
  }
336
357
 
337
358
  /**
package/lib/utils.js CHANGED
@@ -1,4 +1,4 @@
1
- import { isFunction, template, union } from "lodash-es";
1
+ import { template, union } from "lodash-es";
2
2
  import semver from "semver";
3
3
  import hideSensitive from "./hide-sensitive.js";
4
4
 
@@ -81,3 +81,13 @@ export function makeTag(tagFormat, version) {
81
81
  export function isSameChannel(channel, otherChannel) {
82
82
  return channel === otherChannel || (!channel && !otherChannel);
83
83
  }
84
+
85
+ export function extractGitLogTags(tagsString) {
86
+ const regex = /tag: ([^,)]+)/g;
87
+ let match;
88
+ const tags = [];
89
+ while ((match = regex.exec(tagsString)) !== null) {
90
+ tags.push(match[1]);
91
+ }
92
+ return tags;
93
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "semantic-release",
3
3
  "description": "Automated semver compliant package publishing",
4
- "version": "25.0.0-beta.3",
4
+ "version": "25.0.0-beta.4",
5
5
  "type": "module",
6
6
  "author": "Stephan Bönnemann <stephan@boennemann.me> (http://boennemann.me)",
7
7
  "ava": {
@@ -58,9 +58,9 @@
58
58
  "yargs": "^18.0.0"
59
59
  },
60
60
  "devDependencies": {
61
- "@types/node": "22.16.0",
61
+ "@types/node": "22.16.5",
62
62
  "@types/signale": "1.4.7",
63
- "ava": "6.4.0",
63
+ "ava": "6.4.1",
64
64
  "c8": "10.1.3",
65
65
  "clear-module": "4.1.2",
66
66
  "cz-conventional-changelog": "3.3.0",
@@ -72,7 +72,7 @@
72
72
  "lockfile-lint": "4.14.1",
73
73
  "ls-engines": "0.9.3",
74
74
  "mockserver-client": "5.15.0",
75
- "nock": "14.0.5",
75
+ "nock": "14.0.6",
76
76
  "npm-run-all2": "8.0.4",
77
77
  "p-retry": "6.2.1",
78
78
  "prettier": "3.6.2",