Compare commits

..

No commits in common. "master" and "v22.0.8" have entirely different histories.

15 changed files with 1514 additions and 1487 deletions

View File

@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1 - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
with: with:
cache: npm cache: npm
node-version: lts/* node-version: lts/*

View File

@ -25,12 +25,12 @@ jobs:
results_format: sarif results_format: sarif
publish_results: true publish_results: true
- name: Upload artifact - name: Upload artifact
uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0 uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
with: with:
name: SARIF file name: SARIF file
path: results.sarif path: results.sarif
retention-days: 5 retention-days: 5
- name: Upload to code-scanning - name: Upload to code-scanning
uses: github/codeql-action/upload-sarif@e8893c57a1f3a2b659b6b55564fdfdbbd2982911 # v3.24.0 uses: github/codeql-action/upload-sarif@66b90a5db151a8042fa97405c6cf843bbe433f7b # v2.22.7
with: with:
sarif_file: results.sarif sarif_file: results.sarif

View File

@ -25,9 +25,9 @@ jobs:
strategy: strategy:
matrix: matrix:
node-version: node-version:
- 20.8.1 - 18.17.0
- 20.6.1
- 20 - 20
- 21
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 5 timeout-minutes: 5
@ -37,7 +37,7 @@ jobs:
- run: git config --global user.name github-actions - run: git config --global user.name github-actions
- run: git config --global user.email github-actions@github.com - run: git config --global user.email github-actions@github.com
- name: Use Node.js ${{ matrix.node-version }} - name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1 uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
cache: npm cache: npm
@ -55,7 +55,7 @@ jobs:
- run: git config --global user.name github-actions - run: git config --global user.name github-actions
- run: git config --global user.email github-actions@github.com - run: git config --global user.email github-actions@github.com
- name: Use Node.js from .nvmrc - name: Use Node.js from .nvmrc
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1 uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
with: with:
node-version-file: .nvmrc node-version-file: .nvmrc
cache: npm cache: npm
@ -70,7 +70,7 @@ jobs:
needs: needs:
- test_dev - test_dev
- test_matrix - test_matrix
if: ${{ !cancelled() }} if: always()
steps: steps:
- name: All matrix versions passed - name: All matrix versions passed
if: ${{ !(contains(needs.*.result, 'failure')) }} if: ${{ !(contains(needs.*.result, 'failure')) }}

View File

@ -69,7 +69,7 @@ The table below shows which commit message gets you which release type when `sem
### Automation with CI ### Automation with CI
**semantic-release** is meant to be executed on the CI environment after every successful build on the release branch. **semantic-release** is meant to be executed on the CI environment after every successful build on the release branch.
This way no human is directly involved in the release process and the releases are guaranteed to be [unromantic and unsentimental](https://github.com/dominictarr/sentimental-versioning#readme). This way no human is directly involved in the release process and the releases are guaranteed to be [unromantic and unsentimental](http://sentimentalversioning.org).
### Triggering a release ### Triggering a release
@ -110,9 +110,9 @@ In order to use **semantic-release** you need:
## Documentation ## Documentation
- Usage - Usage
- [Getting started](docs/usage/getting-started.md) - [Getting started](docs/usage/getting-started.md#getting-started)
- [Installation](docs/usage/installation.md) - [Installation](docs/usage/installation.md#installation)
- [CI Configuration](docs/usage/ci-configuration.md) - [CI Configuration](docs/usage/ci-configuration.md#ci-configuration)
- [Configuration](docs/usage/configuration.md#configuration) - [Configuration](docs/usage/configuration.md#configuration)
- [Plugins](docs/usage/plugins.md) - [Plugins](docs/usage/plugins.md)
- [Workflow configuration](docs/usage/workflow-configuration.md) - [Workflow configuration](docs/usage/workflow-configuration.md)

View File

@ -2,7 +2,7 @@
## Usage ## Usage
- [Getting started](docs/usage/getting-started.md) - [Getting started](docs/usage/getting-started.md#getting-started)
- [Installation](docs/usage/installation.md) - [Installation](docs/usage/installation.md)
- [CI Configuration](docs/usage/ci-configuration.md) - [CI Configuration](docs/usage/ci-configuration.md)
- [Configuration](docs/usage/configuration.md) - [Configuration](docs/usage/configuration.md)

View File

@ -127,7 +127,7 @@ It allows to configure **semantic-release** to write errors to a specific stream
Type: `Object` `Boolean`<br> Type: `Object` `Boolean`<br>
An object with [`lastRelease`](#lastrelease), [`nextRelease`](#nextrelease), [`commits`](#commits) and [`releases`](#releases) if a release is published or `false` if no release was published. And object with [`lastRelease`](#lastrelease), [`nextRelease`](#nextrelease), [`commits`](#commits) and [`releases`](#releases) if a release is published or `false` if no release was published.
#### lastRelease #### lastRelease
@ -159,7 +159,7 @@ Example:
Type: `Array<Object>` Type: `Array<Object>`
The list of commit(s) included in the new release.<br> The list of commit included in the new release.<br>
Each commit object has the following properties: Each commit object has the following properties:
| Name | Type | Description | | Name | Type | Description |

View File

@ -1,6 +1,6 @@
# Node version requirement # 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 20.8.1 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 18.0.0 or higher**.
**semantic-release** is meant to be used in a CI environment as a development support tool, not as a production dependency. **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. Therefore, the only constraint is to run the `semantic-release` in a CI environment providing version of Node that meets our version requirement.

View File

@ -6,3 +6,16 @@ In order to use **semantic-release** you must follow these steps:
2. Configure your Continuous Integration service to [run **semantic-release**](./ci-configuration.md#run-semantic-release-only-after-all-tests-succeeded) 2. Configure your Continuous Integration service to [run **semantic-release**](./ci-configuration.md#run-semantic-release-only-after-all-tests-succeeded)
3. Configure your Git repository and package manager repository [authentication](ci-configuration.md#authentication) in your Continuous Integration service 3. Configure your Git repository and package manager repository [authentication](ci-configuration.md#authentication) in your Continuous Integration service
4. Configure **semantic-release** [options and plugins](./configuration.md#configuration) 4. Configure **semantic-release** [options and plugins](./configuration.md#configuration)
Alternatively those steps can be easily done with the [**semantic-release** interactive CLI](https://github.com/semantic-release/cli):
```bash
cd your-module
npx semantic-release-cli setup
```
![dialogue](../../media/semantic-release-cli.png)
See the [semantic-release-cli](https://github.com/semantic-release/cli#what-it-does) documentation for more details.
**Note**: only a limited number of options, CI services and plugins are currently supported by `semantic-release-cli`.

View File

@ -123,15 +123,12 @@ async function run(context, plugins) {
if (options.dryRun) { if (options.dryRun) {
logger.warn(`Skip ${nextRelease.gitTag} tag creation in dry-run mode`); logger.warn(`Skip ${nextRelease.gitTag} tag creation in dry-run mode`);
} else { } else {
await addNote({ channels: [...currentRelease.channels, nextRelease.channel] }, nextRelease.gitTag, { await addNote({ channels: [...currentRelease.channels, nextRelease.channel] }, nextRelease.gitHead, {
cwd, cwd,
env, env,
}); });
await push(options.repositoryUrl, { cwd, env }); await push(options.repositoryUrl, { cwd, env });
await pushNotes(options.repositoryUrl, nextRelease.gitTag, { await pushNotes(options.repositoryUrl, { cwd, env });
cwd,
env,
});
logger.success( logger.success(
`Add ${nextRelease.channel ? `channel ${nextRelease.channel}` : "default channel"} to tag ${ `Add ${nextRelease.channel ? `channel ${nextRelease.channel}` : "default channel"} to tag ${
nextRelease.gitTag nextRelease.gitTag
@ -206,9 +203,9 @@ async function run(context, plugins) {
} else { } else {
// Create the tag before calling the publish plugins as some require the tag to exists // Create the tag before calling the publish plugins as some require the tag to exists
await tag(nextRelease.gitTag, nextRelease.gitHead, { cwd, env }); await tag(nextRelease.gitTag, nextRelease.gitHead, { cwd, env });
await addNote({ channels: [nextRelease.channel] }, nextRelease.gitTag, { cwd, env }); await addNote({ channels: [nextRelease.channel] }, nextRelease.gitHead, { cwd, env });
await push(options.repositoryUrl, { cwd, env }); await push(options.repositoryUrl, { cwd, env });
await pushNotes(options.repositoryUrl, nextRelease.gitTag, { cwd, env }); await pushNotes(options.repositoryUrl, { cwd, env });
logger.success(`Created tag ${nextRelease.gitTag}`); logger.success(`Created tag ${nextRelease.gitTag}`);
} }

View File

@ -74,8 +74,8 @@ export default async (context, cliOptions) => {
plugins: [ plugins: [
"@semantic-release/commit-analyzer", "@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator", "@semantic-release/release-notes-generator",
//"@semantic-release/npm", "@semantic-release/npm",
//"@semantic-release/github", "@semantic-release/github",
], ],
// Remove `null` and `undefined` options, so they can be replaced with default ones // Remove `null` and `undefined` options, so they can be replaced with default ones
...pickBy(options, (option) => !isNil(option)), ...pickBy(options, (option) => !isNil(option)),

View File

@ -2,7 +2,6 @@ import gitLogParser from "git-log-parser";
import getStream from "get-stream"; import getStream from "get-stream";
import { execa } from "execa"; import { execa } from "execa";
import debugGit from "debug"; import debugGit from "debug";
import { merge } from "lodash-es";
import { GIT_NOTE_REF } from "./definitions/constants.js"; import { GIT_NOTE_REF } from "./definitions/constants.js";
const debug = debugGit("semantic-release:git"); const debug = debugGit("semantic-release:git");
@ -142,9 +141,13 @@ export async function fetch(repositoryUrl, branch, ciBranch, execaOptions) {
*/ */
export async function fetchNotes(repositoryUrl, execaOptions) { export async function fetchNotes(repositoryUrl, execaOptions) {
try { try {
await execa("git", ["fetch", "--unshallow", repositoryUrl, `+refs/notes/*:refs/notes/*`], execaOptions); await execa(
"git",
["fetch", "--unshallow", repositoryUrl, `+refs/notes/${GIT_NOTE_REF}:refs/notes/${GIT_NOTE_REF}`],
execaOptions
);
} catch { } catch {
await execa("git", ["fetch", repositoryUrl, `+refs/notes/*:refs/notes/*`], { await execa("git", ["fetch", repositoryUrl, `+refs/notes/${GIT_NOTE_REF}:refs/notes/${GIT_NOTE_REF}`], {
...execaOptions, ...execaOptions,
reject: false, reject: false,
}); });
@ -243,8 +246,8 @@ export async function push(repositoryUrl, execaOptions) {
* *
* @throws {Error} if the push failed. * @throws {Error} if the push failed.
*/ */
export async function pushNotes(repositoryUrl, ref, execaOptions) { export async function pushNotes(repositoryUrl, execaOptions) {
await execa("git", ["push", repositoryUrl, `refs/notes/${GIT_NOTE_REF}-${ref}`], execaOptions); await execa("git", ["push", repositoryUrl, `refs/notes/${GIT_NOTE_REF}`], execaOptions);
} }
/** /**
@ -304,26 +307,8 @@ export async function isBranchUpToDate(repositoryUrl, branch, execaOptions) {
* @return {Object} the parsed JSON note if there is one, an empty object otherwise. * @return {Object} the parsed JSON note if there is one, an empty object otherwise.
*/ */
export async function getNote(ref, execaOptions) { export async function getNote(ref, execaOptions) {
const handleError = (error) => {
if (error.exitCode === 1) {
return { stdout: "{}" };
}
debug(error);
throw error;
};
try { try {
return merge( return JSON.parse((await execa("git", ["notes", "--ref", GIT_NOTE_REF, "show", ref], execaOptions)).stdout);
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) { } catch (error) {
if (error.exitCode === 1) { if (error.exitCode === 1) {
return {}; return {};
@ -342,19 +327,5 @@ export async function getNote(ref, execaOptions) {
* @param {Object} [execaOpts] Options to pass to `execa`. * @param {Object} [execaOpts] Options to pass to `execa`.
*/ */
export async function addNote(note, ref, execaOptions) { export async function addNote(note, ref, execaOptions) {
await execa( await execa("git", ["notes", "--ref", GIT_NOTE_REF, "add", "-f", "-m", JSON.stringify(note), ref], execaOptions);
"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;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

2854
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -33,9 +33,9 @@
"@semantic-release/npm": "^11.0.0", "@semantic-release/npm": "^11.0.0",
"@semantic-release/release-notes-generator": "^12.0.0", "@semantic-release/release-notes-generator": "^12.0.0",
"aggregate-error": "^5.0.0", "aggregate-error": "^5.0.0",
"cosmiconfig": "^9.0.0", "cosmiconfig": "^8.0.0",
"debug": "^4.0.0", "debug": "^4.0.0",
"env-ci": "^11.0.0", "env-ci": "^10.0.0",
"execa": "^8.0.0", "execa": "^8.0.0",
"figures": "^6.0.0", "figures": "^6.0.0",
"find-versions": "^5.1.0", "find-versions": "^5.1.0",
@ -45,8 +45,8 @@
"hosted-git-info": "^7.0.0", "hosted-git-info": "^7.0.0",
"import-from-esm": "^1.3.1", "import-from-esm": "^1.3.1",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"marked": "^11.0.0", "marked": "^9.0.0",
"marked-terminal": "^7.0.0", "marked-terminal": "^6.0.0",
"micromatch": "^4.0.2", "micromatch": "^4.0.2",
"p-each-series": "^3.0.0", "p-each-series": "^3.0.0",
"p-reduce": "^3.0.0", "p-reduce": "^3.0.0",
@ -58,31 +58,31 @@
"yargs": "^17.5.1" "yargs": "^17.5.1"
}, },
"devDependencies": { "devDependencies": {
"ava": "6.1.1", "ava": "5.3.1",
"c8": "9.1.0", "c8": "8.0.1",
"clear-module": "4.1.2", "clear-module": "4.1.2",
"codecov": "3.8.3", "codecov": "3.8.3",
"cz-conventional-changelog": "3.3.0", "cz-conventional-changelog": "3.3.0",
"dockerode": "4.0.2", "dockerode": "4.0.0",
"file-url": "4.0.0", "file-url": "4.0.0",
"fs-extra": "11.2.0", "fs-extra": "11.1.1",
"got": "14.2.0", "got": "13.0.0",
"js-yaml": "4.1.0", "js-yaml": "4.1.0",
"lockfile-lint": "4.12.1", "lockfile-lint": "4.12.1",
"ls-engines": "0.9.1", "ls-engines": "0.9.1",
"mockserver-client": "5.15.0", "mockserver-client": "5.15.0",
"nock": "13.5.1", "nock": "13.3.8",
"npm-run-all2": "6.1.2", "npm-run-all2": "6.1.1",
"p-retry": "6.2.0", "p-retry": "6.1.0",
"prettier": "3.2.5", "prettier": "3.1.0",
"publint": "0.2.7", "publint": "0.2.5",
"sinon": "17.0.1", "sinon": "17.0.1",
"stream-buffers": "3.0.2", "stream-buffers": "3.0.2",
"tempy": "3.1.0", "tempy": "3.1.0",
"testdouble": "3.20.1" "testdouble": "3.20.1"
}, },
"engines": { "engines": {
"node": ">=20.8.1" "node": "^18.17 || >=20.6.1"
}, },
"files": [ "files": [
"bin", "bin",
@ -159,7 +159,7 @@
}, },
"renovate": { "renovate": {
"extends": [ "extends": [
"github>semantic-release/.github:renovate-config" "github>semantic-release/.github"
] ]
} }
} }

View File

@ -315,7 +315,7 @@ export async function rebase(ref, execaOptions) {
* @param {Object} [execaOpts] Options to pass to `execa`. * @param {Object} [execaOpts] Options to pass to `execa`.
*/ */
export async function gitAddNote(note, ref, execaOptions) { export async function gitAddNote(note, ref, execaOptions) {
await execa("git", ["notes", "--ref", `${GIT_NOTE_REF}-${ref}`, "add", "-m", note, ref], execaOptions); await execa("git", ["notes", "--ref", GIT_NOTE_REF, "add", "-m", note, ref], execaOptions);
} }
/** /**
@ -325,5 +325,5 @@ export async function gitAddNote(note, ref, execaOptions) {
* @param {Object} [execaOpts] Options to pass to `execa`. * @param {Object} [execaOpts] Options to pass to `execa`.
*/ */
export async function gitGetNote(ref, execaOptions) { export async function gitGetNote(ref, execaOptions) {
return (await execa("git", ["notes", "--ref", `${GIT_NOTE_REF}-${ref}`, "show", ref], execaOptions)).stdout; return (await execa("git", ["notes", "--ref", GIT_NOTE_REF, "show", ref], execaOptions)).stdout;
} }