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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(esm): converted the package to esm-only #491

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 9 additions & 4 deletions .github/workflows/test.yml
Expand Up @@ -13,8 +13,9 @@ jobs:
strategy:
matrix:
node-version:
- '14.17'
- 16
- 18.0.0
- 19
- 20
os:
- ubuntu-latest
- macos-latest
Expand All @@ -29,7 +30,8 @@ jobs:
with:
node-version: "${{ matrix.node-version }}"
cache: npm
- run: npm ci
- run: npm clean-install
- run: npm audit signatures
- name: Ensure dependencies are compatible with the version of node
run: npx ls-engines
- run: "npm run test:ci"
Expand All @@ -43,5 +45,8 @@ jobs:
with:
node-version: "${{ matrix.node-version }}"
cache: npm
- run: npm ci
- run: npm clean-install
- run: npm run lint
# https://github.com/lirantal/lockfile-lint#readme
- name: Scan lockfile for security issues
run: npx lockfile-lint --path package-lock.json
3 changes: 0 additions & 3 deletions .gitignore
Expand Up @@ -63,9 +63,6 @@ lib-cov
# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

Expand Down
45 changes: 27 additions & 18 deletions README.md
Expand Up @@ -7,7 +7,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 @@ -26,15 +26,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 @@ -57,7 +61,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 @@ -66,36 +70,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 @@ -120,6 +125,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 @@ -131,7 +137,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 @@ -165,6 +171,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 @@ -209,6 +216,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 @@ -233,6 +241,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
16 changes: 7 additions & 9 deletions index.js
@@ -1,15 +1,15 @@
const {defaultTo, castArray} = require('lodash');
const verifyGit = require('./lib/verify.js');
const prepareGit = require('./lib/prepare.js');
import { defaultTo, castArray } from "lodash";
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);
Expand All @@ -19,13 +19,11 @@ function verifyConditions(pluginConfig, context) {
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};
4 changes: 2 additions & 2 deletions lib/definitions/errors.js
@@ -1,9 +1,9 @@
const pkg = require('../../package.json');
import pkg from '../../package.json';

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

module.exports = {
export default {
EINVALIDASSETS: ({assets}) => ({
message: 'Invalid `assets` option.',
details: `The [assets option](${linkify(
Expand Down
8 changes: 4 additions & 4 deletions lib/get-error.js
@@ -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 (code, ctx) => {
const { message, details } = ERROR_DEFINITIONS[code](ctx);
return new SemanticReleaseError(message, code, details);
};
22 changes: 12 additions & 10 deletions lib/git.js
@@ -1,5 +1,7 @@
const execa = require('execa');
const debug = require('debug')('semantic-release:git');
import execa from "execa";
import createDebug from "debug";

const debug = createDebug("semantic-release:git");

/**
* Retrieve the list of files modified on the local repository.
Expand All @@ -9,8 +11,8 @@ const debug = require('debug')('semantic-release:git');
* @return {Array<String>} Array of modified files path.
*/
async function getModifiedFiles(execaOptions) {
return (await execa('git', ['ls-files', '-m', '-o'], execaOptions)).stdout
.split('\n')
return (await execa("git", ["ls-files", "-m", "-o"], execaOptions)).stdout
.split("\n")
.map((file) => file.trim())
.filter((file) => Boolean(file));
}
Expand All @@ -22,8 +24,8 @@ async function getModifiedFiles(execaOptions) {
* @param {Object} [execaOpts] Options to pass to `execa`.
*/
async function add(files, execaOptions) {
const shell = await execa('git', ['add', '--force', '--ignore-errors', ...files], {...execaOptions, reject: false});
debug('add file to git index', shell);
const shell = await execa("git", ["add", "--force", "--ignore-errors", ...files], { ...execaOptions, reject: false });
debug("add file to git index", shell);
}

/**
Expand All @@ -35,7 +37,7 @@ async function add(files, execaOptions) {
* @throws {Error} if the commit failed.
*/
async function commit(message, execaOptions) {
await execa('git', ['commit', '-m', message], execaOptions);
await execa("git", ["commit", "-m", message], execaOptions);
}

/**
Expand All @@ -48,7 +50,7 @@ async function commit(message, execaOptions) {
* @throws {Error} if the push failed.
*/
async function push(origin, branch, execaOptions) {
await execa('git', ['push', '--tags', origin, `HEAD:${branch}`], execaOptions);
await execa("git", ["push", "--tags", origin, `HEAD:${branch}`], execaOptions);
}

/**
Expand All @@ -59,7 +61,7 @@ async function push(origin, branch, execaOptions) {
* @return {String} The sha of the head commit on the local repository
*/
async function gitHead(execaOptions) {
return (await execa('git', ['rev-parse', 'HEAD'], execaOptions)).stdout;
return (await execa("git", ["rev-parse", "HEAD"], execaOptions)).stdout;
}

module.exports = {getModifiedFiles, add, gitHead, commit, push};
export default { getModifiedFiles, add, gitHead, commit, push };