Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
14c71b4
refactor: Update code to use ES6 module syntax
babblebey Oct 11, 2024
d634740
refactor: replace `lodash` with `lodash-es`
babblebey Oct 11, 2024
dd8c485
refactor: modify `"package.json".homepage` import; remove `#readme` f…
babblebey Oct 11, 2024
c62b8db
fix: add missing `function` keyword
babblebey Oct 11, 2024
e0b8550
refactor: adapt `debug` import in `git.js` and `prepare.js`
babblebey Oct 11, 2024
8885350
refactor: replace `xo` with `prettier`
babblebey Oct 11, 2024
58907a0
Merge branch 'master' into esm
babblebey Mar 3, 2026
6fb2c75
chore: update dependencies and devDependencies; improve Node.js engin…
babblebey Mar 3, 2026
5736bef
refactor: migrate to ES modules and improve code readability in git-u…
babblebey Mar 3, 2026
228998d
refactor: migrate tests to use ES module syntax and improve readability
babblebey Mar 3, 2026
3bddb49
chore: update GitHub Actions workflows to use latest action versions …
babblebey Mar 3, 2026
2a57c5b
refactor: standardize code formatting and improve readability across …
babblebey Mar 3, 2026
e8bf6e4
chore: enhance Node.js compatibility check by cleaning npm cache befo…
babblebey Mar 3, 2026
6efc38b
chore: update dependencies and improve test scripts
babblebey Mar 9, 2026
65cf115
chore: update Node.js versions and improve workflow steps in test.yml
babblebey Mar 9, 2026
99ee085
chore: add .nvmrc file to specify Node.js version
babblebey Mar 9, 2026
6e3e268
chore: update peer dependency for semantic-release to allow earlier v…
babblebey Mar 9, 2026
c399438
chore: exclude integration tests from AVA test files
babblebey Mar 9, 2026
eac13f1
test: update AVA configuration for integration tests and adjust timeo…
babblebey Mar 9, 2026
18b3c3c
refactor: simplify homepage retrieval in error definitions
babblebey Mar 13, 2026
8daf453
fix(test): set default git user configuration for test repositories
babblebey Mar 15, 2026
440b9a4
fix(git): set default user configuration for shallow clone and detach…
babblebey Mar 15, 2026
709c976
chore: update dependencies and enhance linting scripts
babblebey Mar 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ jobs:
name: release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
with:
cache: npm
node-version: lts/*
- run: npm ci
- run: npm clean-install
- run: npx semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
50 changes: 30 additions & 20 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,35 +13,45 @@ jobs:
strategy:
matrix:
node-version:
- '14.17'
- 16
- 22.14.0
- 22
- 24
os:
- ubuntu-latest
- macos-latest
- windows-latest
runs-on: "${{ matrix.os }}"
steps:
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
- run: git config --global user.name github-actions
- run: git config --global user.email github-actions@github.com
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: "Use Node.js ${{ matrix.node-version }}"
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: "${{ matrix.node-version }}"
cache: npm
- run: npm ci
- name: Ensure dependencies are compatible with the version of node
run: npx ls-engines
- run: "npm run test:ci"
test:
- run: npm clean-install
- run: corepack npm audit signatures
- run: npm test

test_dev:
runs-on: ubuntu-latest
needs: test_matrix
steps:
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
- name: "Use Node.js ${{ matrix.node-version }}"
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: "${{ matrix.node-version }}"
node-version-file: .nvmrc
cache: npm
- run: npm ci
- run: npm run lint
- run: npm clean-install
- run: corepack npm audit signatures
- run: npm test

test:
runs-on: ubuntu-latest
needs:
- test_dev
- test_matrix
if: ${{ !cancelled() }}
steps:
- name: All matrix versions passed
if: ${{ !(contains(needs.*.result, 'failure')) }}
run: exit 0
- name: Some matrix version failed
if: ${{ contains(needs.*.result, 'failure') }}
run: exit 1
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
24
45 changes: 27 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
[![npm beta version](https://img.shields.io/npm/v/@semantic-release/git/beta.svg)](https://www.npmjs.com/package/@semantic-release/git)

| Step | Description |
|--------------------|------------------------------------------------------------------------------------------------------------------------------------|
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| `verifyConditions` | Verify the access to the remote Git repository, the commit [`message`](#message) and the [`assets`](#assets) option configuration. |
| `prepare` | Create a release commit, including configurable file assets. |

Expand All @@ -30,15 +30,19 @@ The plugin can be configured in the [**semantic-release** configuration file](ht
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
["@semantic-release/git", {
"assets": ["dist/**/*.{js,css}", "docs", "package.json"],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}]
[
"@semantic-release/git",
{
"assets": ["dist/**/*.{js,css}", "docs", "package.json"],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}
]
]
}
```

With this example, for each release a release commit will be pushed to the remote Git repository with:

- a message formatted like `chore(release): <version> [skip ci]\n\n<release notes>`
- the `.js` and `.css` files in the `dist` directory, the files in the `docs` directory and the `package.json`

Expand All @@ -61,7 +65,7 @@ When configuring branches permission on a Git hosting service (e.g. [GitHub prot
### Environment variables

| Variable | Description | Default |
|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------|
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------ |
| `GIT_AUTHOR_NAME` | The author name associated with the release commit. See [Git environment variables](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables#_committing). | @semantic-release-bot. |
| `GIT_AUTHOR_EMAIL` | The author email associated with the release commit. See [Git environment variables](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables#_committing). | @semantic-release-bot email address. |
| `GIT_COMMITTER_NAME` | The committer name associated with the release commit. See [Git environment variables](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables#_committing). | @semantic-release-bot. |
Expand All @@ -70,36 +74,37 @@ When configuring branches permission on a Git hosting service (e.g. [GitHub prot
### Options

| Options | Description | Default |
|-----------|------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------|
| --------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| `message` | The message for the release commit. See [message](#message). | `chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}` |
| `assets` | Files to include in the release commit. Set to `false` to disable adding files to the release commit. See [assets](#assets). | `['CHANGELOG.md', 'package.json', 'package-lock.json', 'npm-shrinkwrap.json']` |

#### `message`

The message for the release commit is generated with [Lodash template](https://lodash.com/docs#template). The following variables are available:

| Parameter | Description |
|---------------------|-----------------------------------------------------------------------------------------------------------------------------------------|
| `branch` | The branch from which the release is done. |
| `branch.name` | The branch name. |
| Parameter | Description |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `branch` | The branch from which the release is done. |
| `branch.name` | The branch name. |
| `branch.type` | The [type of branch](https://github.com/semantic-release/semantic-release/blob/master/docs/usage/workflow-configuration.md#branch-types). |
| `branch.channel` | The distribution channel on which to publish releases from this branch. |
| `branch.range` | The range of [semantic versions](https://semver.org) to support on this branch. |
| `branch.prerelease` | The pre-release detonation to append to [semantic versions](https://semver.org) released from this branch. |
| `lastRelease` | `Object` with `version`, `gitTag` and `gitHead` of the last release. |
| `nextRelease` | `Object` with `version`, `gitTag`, `gitHead` and `notes` of the release being done. |
| `branch.channel` | The distribution channel on which to publish releases from this branch. |
| `branch.range` | The range of [semantic versions](https://semver.org) to support on this branch. |
| `branch.prerelease` | The pre-release detonation to append to [semantic versions](https://semver.org) released from this branch. |
| `lastRelease` | `Object` with `version`, `gitTag` and `gitHead` of the last release. |
| `nextRelease` | `Object` with `version`, `gitTag`, `gitHead` and `notes` of the release being done. |

**Note**: It is recommended to include `[skip ci]` in the commit message to not trigger a new build. Some CI service support the `[skip ci]` keyword only in the subject of the message.

##### `message` examples

The `message` `Release <%= nextRelease.version %> - <%= new Date().toLocaleDateString('en-US', {year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric' }) %> [skip ci]\n\n<%= nextRelease.notes %>` will generate the commit message:

> Release v1.0.0 - Oct. 21, 2015 1:24 AM \[skip ci\]<br><br>## 1.0.0<br><br>### Features<br>* Generate 1.21 gigawatts of electricity<br>...
> Release v1.0.0 - Oct. 21, 2015 1:24 AM \[skip ci\]<br><br>## 1.0.0<br><br>### Features<br>\* Generate 1.21 gigawatts of electricity<br>...

#### `assets`

Can be an `Array` or a single entry. Each entry can be either:

- a [glob](https://github.com/micromatch/micromatch#matching-features)
- or an `Object` with a `path` property containing a [glob](https://github.com/micromatch/micromatch#matching-features).

Expand All @@ -124,6 +129,7 @@ If a directory is configured, all the files under this directory and its childre
### Examples

When used with the [@semantic-release/changelog](https://github.com/semantic-release/changelog) or [@semantic-release/npm](https://github.com/semantic-release/npm) plugins:

- The [@semantic-release/changelog](https://github.com/semantic-release/changelog) plugin must be called first in order to update the changelog file so the `@semantic-release/git` and [@semantic-release/npm](https://github.com/semantic-release/npm) plugins can include it in the release.
- The [@semantic-release/npm](https://github.com/semantic-release/npm) plugin must be called second in order to update the `package.json` file so the `@semantic-release/git` plugin can include it in the release commit.

Expand All @@ -135,7 +141,7 @@ When used with the [@semantic-release/changelog](https://github.com/semantic-rel
"@semantic-release/changelog",
"@semantic-release/npm",
"@semantic-release/git"
],
]
}
```

Expand Down Expand Up @@ -169,6 +175,7 @@ sec rsa4096/XXXXXXXXXXXXXXXX 2017-12-01 [SC]
uid <your_name> <your_email>
ssb rsa4096/YYYYYYYYYYYYYYYY 2017-12-01 [E]
```

the GPG key ID is the 16 character string, on the `sec` line, after `rsa4096`. In this example, the GPG key ID is `XXXXXXXXXXXXXXXX`.

Export the public key (replace XXXXXXXXXXXXXXXX with your key ID):
Expand Down Expand Up @@ -213,6 +220,7 @@ $ travis login
```

Add the following [environment](https://github.com/travis-ci/travis.rb#env) variables to Travis:

- `GPG_PASSPHRASE` to Travis with the value set during the [GPG keys generation](#generate-the-gpg-keys) step
- `GPG_KEY_ID` to Travis with the value of your GPG key ID retrieved during the [GPG keys generation](#generate-the-gpg-keys) (replace XXXXXXXXXXXXXXXX with your key ID)
- `GIT_EMAIL` with the email address you set during the [GPG keys generation](#generate-the-gpg-keys) step
Expand All @@ -237,6 +245,7 @@ $ gpg --export-secret-key -a XXXXXXXXXXXXXXXX >> git_gpg_keys.asc
```bash
$ travis encrypt-file git_gpg_keys.asc
```

The `travis encrypt-file` will encrypt the keys into the `git_gpg_keys.asc.enc` file and output in the console the command to add to your `.travis.yml` file. It should look like `openssl aes-256-cbc -K $encrypted_AAAAAAAAAAAA_key -iv $encrypted_BBBBBBBBBBBB_iv -in git_gpg_keys.asc.enc -out git_gpg_keys.asc -d`.

Copy this command to your `.travis.yml` file in the `before_install` step. Change the output path to write the unencrypted key in `/tmp`: `-out git_gpg_keys.asc` => `/tmp/git_gpg_keys.asc`. This will avoid to commit / modify / delete the unencrypted keys by mistake on the CI. Then add the commands to decrypt the GPG keys and make it available to `git`:
Expand Down
23 changes: 13 additions & 10 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,34 @@
const {defaultTo, castArray} = require('lodash');
const verifyGit = require('./lib/verify.js');
const prepareGit = require('./lib/prepare.js');
import { defaultTo, castArray } from "lodash-es";
import verifyGit from "./lib/verify.js";
import prepareGit from "./lib/prepare.js";

let verified;

function verifyConditions(pluginConfig, context) {
const {options} = context;
export function verifyConditions(pluginConfig, context) {
const { options } = context;
// If the Git prepare plugin is used and has `assets` or `message` configured, validate them now in order to prevent any release if the configuration is wrong
if (options.prepare) {
const preparePlugin =
castArray(options.prepare).find((config) => config.path && config.path === '@semantic-release/git') || {};
castArray(options.prepare).find(
(config) => config.path && config.path === "@semantic-release/git",
) || {};

pluginConfig.assets = defaultTo(pluginConfig.assets, preparePlugin.assets);
pluginConfig.message = defaultTo(pluginConfig.message, preparePlugin.message);
pluginConfig.message = defaultTo(
pluginConfig.message,
preparePlugin.message,
);
}

verifyGit(pluginConfig);
verified = true;
}

async function prepare(pluginConfig, context) {
export async function prepare(pluginConfig, context) {
if (!verified) {
verifyGit(pluginConfig);
verified = true;
}

await prepareGit(pluginConfig, context);
}

module.exports = {verifyConditions, prepare};
18 changes: 9 additions & 9 deletions lib/definitions/errors.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
const pkg = require('../../package.json');
import pkg from "../../package.json" with { type: "json" };

const [homepage] = pkg.homepage.split('#');
const [homepage] = pkg.homepage.split("#");
const linkify = (file) => `${homepage}/blob/master/${file}`;

module.exports = {
EINVALIDASSETS: ({assets}) => ({
message: 'Invalid `assets` option.',
export default {
EINVALIDASSETS: ({ assets }) => ({
message: "Invalid `assets` option.",
details: `The [assets option](${linkify(
'README.md#assets'
"README.md#assets",
)}) option must be an \`Array\` of \`Strings\` or \`Objects\` with a \`path\` property.

Your configuration for the \`assets\` option is \`${assets}\`.`,
}),
EINVALIDMESSAGE: ({message}) => ({
message: 'Invalid `message` option.',
details: `The [message option](${linkify('README.md#message')}) option, if defined, must be a non empty \`String\`.
EINVALIDMESSAGE: ({ message }) => ({
message: "Invalid `message` option.",
details: `The [message option](${linkify("README.md#message")}) option, if defined, must be a non empty \`String\`.

Your configuration for the \`successComment\` option is \`${message}\`.`,
}),
Expand Down
10 changes: 5 additions & 5 deletions lib/get-error.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const SemanticReleaseError = require('@semantic-release/error');
const ERROR_DEFINITIONS = require('./definitions/errors.js');
import SemanticReleaseError from "@semantic-release/error";
import ERROR_DEFINITIONS from "./definitions/errors.js";

module.exports = (code, ctx) => {
const {message, details} = ERROR_DEFINITIONS[code](ctx);
export default function getError(code, ctx) {
const { message, details } = ERROR_DEFINITIONS[code](ctx);
return new SemanticReleaseError(message, code, details);
};
}
Loading