Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

next major #3111

Merged
merged 9 commits into from
Jan 12, 2024
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ jobs:
strategy:
matrix:
node-version:
- 18.17.0
- 20.6.1
- 20.8.1
- 20
- 21

runs-on: ubuntu-latest
timeout-minutes: 5
Expand Down Expand Up @@ -70,7 +70,7 @@ jobs:
needs:
- test_dev
- test_matrix
if: always()
if: ${{ !cancelled() }}
steps:
- name: All matrix versions passed
if: ${{ !(contains(needs.*.result, 'failure')) }}
Expand Down
2 changes: 1 addition & 1 deletion docs/support/node-version.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Node version requirement

**semantic-release** is written using the latest [ECMAScript 2017](https://www.ecma-international.org/publications/standards/Ecma-262.htm) features, without transpilation which **requires Node version 18.0.0 or higher**.
**semantic-release** is written using the latest [ECMAScript 2017](https://www.ecma-international.org/publications/standards/Ecma-262.htm) features, without transpilation which **requires Node version 20.8.1 or higher**.

**semantic-release** is meant to be used in a CI environment as a development support tool, not as a production dependency.
Therefore, the only constraint is to run the `semantic-release` in a CI environment providing version of Node that meets our version requirement.
Expand Down
11 changes: 7 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,15 @@ async function run(context, plugins) {
if (options.dryRun) {
logger.warn(`Skip ${nextRelease.gitTag} tag creation in dry-run mode`);
} else {
await addNote({ channels: [...currentRelease.channels, nextRelease.channel] }, nextRelease.gitHead, {
await addNote({ channels: [...currentRelease.channels, nextRelease.channel] }, nextRelease.gitTag, {
cwd,
env,
});
await push(options.repositoryUrl, { cwd, env });
await pushNotes(options.repositoryUrl, { cwd, env });
await pushNotes(options.repositoryUrl, nextRelease.gitTag, {
cwd,
env,
});
logger.success(
`Add ${nextRelease.channel ? `channel ${nextRelease.channel}` : "default channel"} to tag ${
nextRelease.gitTag
Expand Down Expand Up @@ -203,9 +206,9 @@ async function run(context, plugins) {
} else {
// Create the tag before calling the publish plugins as some require the tag to exists
await tag(nextRelease.gitTag, nextRelease.gitHead, { cwd, env });
await addNote({ channels: [nextRelease.channel] }, nextRelease.gitHead, { cwd, env });
await addNote({ channels: [nextRelease.channel] }, nextRelease.gitTag, { cwd, env });
await push(options.repositoryUrl, { cwd, env });
await pushNotes(options.repositoryUrl, { cwd, env });
await pushNotes(options.repositoryUrl, nextRelease.gitTag, { cwd, env });
logger.success(`Created tag ${nextRelease.gitTag}`);
}

Expand Down
49 changes: 39 additions & 10 deletions lib/git.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import gitLogParser from "git-log-parser";
import getStream from "get-stream";
import { execa } from "execa";
import debugGit from "debug";
import { merge } from "lodash-es";
import { GIT_NOTE_REF } from "./definitions/constants.js";

const debug = debugGit("semantic-release:git");
Expand Down Expand Up @@ -141,13 +142,9 @@ export async function fetch(repositoryUrl, branch, ciBranch, execaOptions) {
*/
export async function fetchNotes(repositoryUrl, execaOptions) {
try {
await execa(
"git",
["fetch", "--unshallow", repositoryUrl, `+refs/notes/${GIT_NOTE_REF}:refs/notes/${GIT_NOTE_REF}`],
execaOptions
);
await execa("git", ["fetch", "--unshallow", repositoryUrl, `+refs/notes/*:refs/notes/*`], execaOptions);
} catch {
await execa("git", ["fetch", repositoryUrl, `+refs/notes/${GIT_NOTE_REF}:refs/notes/${GIT_NOTE_REF}`], {
await execa("git", ["fetch", repositoryUrl, `+refs/notes/*:refs/notes/*`], {
...execaOptions,
reject: false,
});
Expand Down Expand Up @@ -246,8 +243,8 @@ export async function push(repositoryUrl, execaOptions) {
*
* @throws {Error} if the push failed.
*/
export async function pushNotes(repositoryUrl, execaOptions) {
await execa("git", ["push", repositoryUrl, `refs/notes/${GIT_NOTE_REF}`], execaOptions);
export async function pushNotes(repositoryUrl, ref, execaOptions) {
await execa("git", ["push", repositoryUrl, `refs/notes/${GIT_NOTE_REF}-${ref}`], execaOptions);
}

/**
Expand Down Expand Up @@ -307,8 +304,26 @@ export async function isBranchUpToDate(repositoryUrl, branch, execaOptions) {
* @return {Object} the parsed JSON note if there is one, an empty object otherwise.
*/
export async function getNote(ref, execaOptions) {
const handleError = (error) => {
if (error.exitCode === 1) {
return { stdout: "{}" };
}

debug(error);
throw error;
};

try {
return JSON.parse((await execa("git", ["notes", "--ref", GIT_NOTE_REF, "show", ref], execaOptions)).stdout);
return merge(
JSON.parse(
// Used for retro-compatibility
(await execa("git", ["notes", "--ref", GIT_NOTE_REF, "show", ref], execaOptions).catch(handleError)).stdout
),
JSON.parse(
(await execa("git", ["notes", "--ref", `${GIT_NOTE_REF}-${ref}`, "show", ref], execaOptions).catch(handleError))
.stdout
)
);
} catch (error) {
if (error.exitCode === 1) {
return {};
Expand All @@ -327,5 +342,19 @@ export async function getNote(ref, execaOptions) {
* @param {Object} [execaOpts] Options to pass to `execa`.
*/
export async function addNote(note, ref, execaOptions) {
await execa("git", ["notes", "--ref", GIT_NOTE_REF, "add", "-f", "-m", JSON.stringify(note), ref], execaOptions);
await execa(
"git",
["notes", "--ref", `${GIT_NOTE_REF}-${ref}`, "add", "-f", "-m", JSON.stringify(note), ref],
execaOptions
);
}

/**
* Get the reference of a tag
*
* @param {String} tag The tag name to get the reference of.
* @param {Object} [execaOpts] Options to pass to `execa`.
**/
export async function getTagRef(tag, execaOptions) {
return (await execa("git", ["show-ref", tag, "--hash"], execaOptions)).stdout;
}
137 changes: 120 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@
"@semantic-release/npm": "^11.0.0",
"@semantic-release/release-notes-generator": "^12.0.0",
"aggregate-error": "^5.0.0",
"cosmiconfig": "^8.0.0",
"cosmiconfig": "^9.0.0",
"debug": "^4.0.0",
"env-ci": "^10.0.0",
"env-ci": "^11.0.0",
"execa": "^8.0.0",
"figures": "^6.0.0",
"find-versions": "^5.1.0",
Expand All @@ -45,7 +45,7 @@
"hosted-git-info": "^7.0.0",
"import-from-esm": "^1.3.1",
"lodash-es": "^4.17.21",
"marked": "^9.0.0",
"marked": "^11.0.0",
"marked-terminal": "^6.0.0",
"micromatch": "^4.0.2",
"p-each-series": "^3.0.0",
Expand Down Expand Up @@ -82,7 +82,7 @@
"testdouble": "3.20.1"
},
"engines": {
"node": "^18.17 || >=20.6.1"
"node": ">=20.8.1"
},
"files": [
"bin",
Expand Down