Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b8fb35c7e1 | ||
|
|
18e35b28ad | ||
|
|
e35e5bb73f | ||
|
|
311c46580f | ||
|
|
b4c5d0a436 | ||
|
|
c982249f87 | ||
|
|
9635f50da6 | ||
|
|
d036a899d5 | ||
|
|
9303d1dba0 | ||
|
|
b72cdb331b | ||
|
|
ee44ee80c8 | ||
|
|
b24d2474b1 | ||
|
|
6d118c6c14 | ||
|
|
b5c9dea215 | ||
|
|
1405b94296 |
+6
-6
@@ -107,11 +107,11 @@ To ensure consistency and quality, all documentation modifications must:
|
||||
- a third-party product/brand/service, i.e. Integrate with [GitHub](https://github.com)
|
||||
- an external concept or feature, i.e. Create a [GitHub release](https://help.github.com/articles/creating-releases)
|
||||
- a package or module, i.e. The [`@semantic-release/github`](https://github.com/semantic-release/github) module
|
||||
- Use the the [single backtick `code` quoting](https://help.github.com/articles/basic-writing-and-formatting-syntax/#quoting-code) for:
|
||||
- Use the [single backtick `code` quoting](https://help.github.com/articles/basic-writing-and-formatting-syntax/#quoting-code) for:
|
||||
- commands inside sentences, i.e. the `semantic-release` command
|
||||
- programming language keywords, i.e. `function`, `async`, `String`
|
||||
- packages or modules, i.e. The [`@semantic-release/github`](https://github.com/semantic-release/github) module
|
||||
- Use the the [triple backtick `code` formatting](https://help.github.com/articles/creating-and-highlighting-code-blocks) for:
|
||||
- Use the [triple backtick `code` formatting](https://help.github.com/articles/creating-and-highlighting-code-blocks) for:
|
||||
- code examples
|
||||
- configuration examples
|
||||
- sequence of command lines
|
||||
@@ -183,17 +183,17 @@ The footer should contain any information about **Breaking Changes** and is also
|
||||
#### Examples
|
||||
|
||||
```commit
|
||||
`fix(pencil): stop graphite breaking when too much pressure applied`
|
||||
fix(pencil): stop graphite breaking when too much pressure applied
|
||||
```
|
||||
|
||||
```commit
|
||||
`feat(pencil): add 'graphiteWidth' option`
|
||||
feat(pencil): add 'graphiteWidth' option
|
||||
|
||||
Fix #42
|
||||
```
|
||||
|
||||
```commit
|
||||
perf(pencil): remove graphiteWidth option`
|
||||
perf(pencil): remove graphiteWidth option
|
||||
|
||||
BREAKING CHANGE: The graphiteWidth option has been removed.
|
||||
|
||||
@@ -229,7 +229,7 @@ Before pushing your code changes make sure there are no linting errors with `npm
|
||||
|
||||
### Tests
|
||||
|
||||
Running the integration test requires you to install [Docker](https://docs.docker.com/engine/installation) on your machine.
|
||||
Running the integration test requires you to install [Docker](https://docs.docker.com/engine/installation) on your machine. Note: the tests assume that running `git init` will create a `master` branch by default. If your local `git` is configured differently (see [`init.defaultBranch`](https://github.blog/2020-07-27-highlights-from-git-2-28/#introducing-init-defaultbranch)), change it temporarily when running the tests.
|
||||
|
||||
All the [semantic-release](https://github.com/semantic-release) repositories use [AVA](https://github.com/avajs/ava) for writing and running tests.
|
||||
|
||||
|
||||
@@ -150,9 +150,16 @@ Let people know that your package is published using **semantic-release** by inc
|
||||
|
||||
## Team
|
||||
|
||||
| [](https://github.com/boennemann) | [](https://github.com/relekang) | [](https://github.com/jo) | [](https://github.com/gr2m) | [](https://github.com/finnp) | [](https://github.com/pvdlg) | [](https://github.com/christophwitzko) |
|
||||
|---------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------|
|
||||
| [Stephan Bönnemann](https://github.com/boennemann) | [Rolf Erik Lekang](https://github.com/relekang) | [Johannes Jörg Schmidt](https://github.com/jo) | [Gregor Martynus](https://github.com/gr2m) | [Finn Pauls](https://github.com/finnp) | [Pierre Vanduynslager](https://github.com/pvdlg) | [Christoph Witzko](https://github.com/christophwitzko) |
|
||||
| [](https://github.com/gr2m) | [](https://github.com/pvdlg) | [](https://github.com/travi) |
|
||||
| ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------- |
|
||||
| [Gregor Martynus](https://github.com/gr2m) | [Pierre Vanduynslager](https://github.com/pvdlg) | [Matt Travi](https://github.com/travi) |
|
||||
|
||||
## Alumni
|
||||
|
||||
| [](https://github.com/boennemann) | [](https://github.com/relekang) | [](https://github.com/jo) | [](https://github.com/finnp) | [](https://github.com/christophwitzko) |
|
||||
| ------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
|
||||
| [Stephan Bönnemann](https://github.com/boennemann) | [Rolf Erik Lekang](https://github.com/relekang) | [Johannes Jörg Schmidt](https://github.com/jo) | [Finn Pauls](https://github.com/finnp) | [Christoph Witzko](https://github.com/christophwitzko) |
|
||||
|
||||
|
||||
<p align="center">
|
||||
<img alt="Kill all humans" src="media/bender.png">
|
||||
|
||||
@@ -101,3 +101,7 @@
|
||||
- `addChannel`: Update a Gitea release's pre-release field.
|
||||
- [@google/semantic-release-replace-plugin](https://github.com/google/semantic-release-replace-plugin)
|
||||
- `prepare`: Replace version strings in files using regex and glob.
|
||||
- [semantic-release-rubygem](https://github.com/Gusto/semantic-release-rubygem)
|
||||
- `verifyConditions`: Locate and validate a `.gemspec` file, locate and validate a `lib/**/version.rb` file, verify the presence of the `GEM_HOST_API_KEY` environment variable, and create a credentials file with the API key.
|
||||
- `prepare`: Update the version in the `lib/**/version.rb` version file and [build](https://guides.rubygems.org/command-reference/#gem-build) the gem.
|
||||
- `publish`: [Push the Ruby gem](https://guides.rubygems.org/command-reference/#gem-push) to the gem server.
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
- [Travis CI](travis.md)
|
||||
- [GitLab CI](gitlab-ci.md)
|
||||
- [GitHub Actions](github-actions.md)
|
||||
- [Jenkins CI](jenkins-ci.md)
|
||||
|
||||
## Git hosted services
|
||||
- [Git authentication with SSH keys](git-auth-ssh-keys.md)
|
||||
|
||||
@@ -28,7 +28,9 @@ jobs:
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v1
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
@@ -48,9 +50,23 @@ To keep `package.json` updated in the `master` branch, [`@semantic-release/git`]
|
||||
|
||||
**Note**: Automatically populated `GITHUB_TOKEN` cannot be used if branch protection is enabled for the target branch. It is **not** advised to mitigate this limitation by overriding an automatically populated `GITHUB_TOKEN` variable with a [Personal Access Tokens](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line), as it poses a security risk. Since Secret Variables are available for Workflows triggered by any branch, it becomes a potential vector of attack, where a Workflow triggered from a non-protected branch can expose and use a token with elevated permissions, yielding branch protection insignificant. One can use Personal Access Tokens in trusted environments, where all developers should have the ability to perform administrative actions in the given repository and branch protection is enabled solely for convenience purposes, to remind about required reviews or CI checks.
|
||||
|
||||
If the risk is acceptible, some extra configuration is needed. The [actions/checkout `persist-credentials`](https://github.com/marketplace/actions/checkout#usage) option needs to be `false`, otherwise the generated `GITHUB_TOKEN` will interfere with the custom one. Example:
|
||||
|
||||
```yaml
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false # <--- this
|
||||
```
|
||||
|
||||
## Trigger semantic-release on demand
|
||||
|
||||
There is a way to trigger semantic-relase on demand. Use [`repository_dispatch`](https://help.github.com/en/articles/events-that-trigger-workflows#external-events-repository_dispatch) event to have control on when to generate a release by making an HTTP request, e.g.:
|
||||
### Using GUI:
|
||||
You can use [Manual Triggers](https://github.blog/changelog/2020-07-06-github-actions-manual-triggers-with-workflow_dispatch/) for GitHub Actions.
|
||||
|
||||
### Using HTTP:
|
||||
Use [`repository_dispatch`](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#repository_dispatch) event to have control on when to generate a release by making an HTTP request, e.g.:
|
||||
|
||||
```yaml
|
||||
name: Release
|
||||
@@ -67,6 +83,7 @@ To trigger a release, call (with a [Personal Access Tokens](https://help.github.
|
||||
$ curl -v -H "Accept: application/vnd.github.everest-preview+json" -H "Authorization: token ${GITHUB_TOKEN}" https://api.github.com/repos/[org-name-or-username]/[repository]/dispatches -d '{ "event_type": "semantic-release" }'
|
||||
```
|
||||
|
||||
### Using 3rd party apps:
|
||||
If you'd like to use a GitHub app to manage this instead of creating a personal access token, you could consider using a project like:
|
||||
|
||||
* [Actions Panel](https://www.actionspanel.app/) - A declaratively configured way for triggering GitHub Actions
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
# Using semantic-release with [Jenkins CI](https://www.jenkins.io/doc/book/pipeline/)
|
||||
|
||||
## Environment variables
|
||||
|
||||
The [Authentication](../usage/ci-configuration.md#authentication) environment variables can be configured in [Jenkins Project Settings](https://www.jenkins.io/doc/pipeline/tour/environment/)..
|
||||
|
||||
Alternatively, the default `NPM_TOKEN` and `GH_TOKEN` can be easily [setup with semantic-release-cli](../usage/getting-started.md#getting-started).
|
||||
|
||||
## Node.js project configuration
|
||||
|
||||
### `Jenkinsfile (Declarative Pipeline)` configuration for a Node.js job
|
||||
|
||||
**Note**: The publish pipeline must run a [Node >= 10.18 version](../support/FAQ.md#why-does-semantic-release-require-node-version--1018).
|
||||
|
||||
This example is a minimal configuration for **semantic-release** with a build running Node 10.18. See [Jenkins documentation](https://www.jenkins.io/doc/) for additional configuration options.
|
||||
|
||||
The`semantic-release` execution command varies depending if you are using a [local](../usage/installation.md#local-installation) or [global](../usage/installation.md#global-installation) **semantic-release** installation.
|
||||
|
||||
```yaml
|
||||
// The release stage in the pipeline will run only if the test stage in the pipeline is successful
|
||||
pipeline {
|
||||
agent any
|
||||
environment {
|
||||
GH_TOKEN = credentials('some-id')
|
||||
}
|
||||
stages {
|
||||
stage('Test') {
|
||||
steps {
|
||||
sh '''
|
||||
# Configure your test steps here (checkout, npm install, tests etc)
|
||||
npm install
|
||||
npm test
|
||||
'''
|
||||
}
|
||||
}
|
||||
stage('Release') {
|
||||
tools {
|
||||
nodejs "node 10.18"
|
||||
}
|
||||
steps {
|
||||
sh '''
|
||||
# Run optional required steps before releasing
|
||||
npx semantic-release
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `package.json` configuration for a Node job
|
||||
|
||||
A `package.json` is required only for [local](../usage/installation.md#local-installation) **semantic-release** installation.
|
||||
|
||||
```json
|
||||
{
|
||||
"devDependencies": {
|
||||
"semantic-release": "^15.0.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
+3
-1
@@ -2,12 +2,14 @@
|
||||
|
||||
## Why is the `package.json`’s version not updated in my repository?
|
||||
|
||||
**semantic-release** takes care of updating the `package.json`’s version before publishing to [npm](https://www.npmjs.com).
|
||||
[`@semantic-release/npm`](https://github.com/semantic-release/npm) takes care of updating the `package.json`’s version before publishing to [npm](https://www.npmjs.com).
|
||||
|
||||
By default, only the published package will contain the version, which is the only place where it is *really* required, but the updated `package.json` will not be pushed to the Git repository
|
||||
|
||||
However, the [`@semantic-release/git`](https://github.com/semantic-release/git) plugin can be used to push the updated `package.json` as well as other files to the Git repository.
|
||||
|
||||
If you wish to only update the `package.json` and push via Git you can set the project to `"private": true,` within your `package.json` to prevent publishing to [npm](https://www.npmjs.com). This can be useful for using **semantic-release** with a non-node project.
|
||||
|
||||
## How can I use a npm build script that requires the `package.json`’s version ?
|
||||
|
||||
The `package.json`’s version will be updated by the `semantic-release` command just before publishing to [npm](https://www.npmjs.com), therefore it won't be available for scripts ran before the `semantic-release` command.
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
- ["Introduction to SemVer" - Irina Gebauer](https://blog.greenkeeper.io/introduction-to-semver-d272990c44f2)
|
||||
- ["Introduction to Semantic Release" - liv](https://blog.greenkeeper.io/introduction-to-semantic-release-33f73b117c8)
|
||||
- ["Series - Semantic Release Automation" - Abdelrahman Wahdan](https://dev.to/abdelrahmanahmed/semantic-release-and-how-to-automate-it-part-1-4pa2)
|
||||
|
||||
## Tutorials
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ The branches on which releases should happen. By default **semantic-release** wi
|
||||
|
||||
**Note**: If your repository does not have a release branch, then **semantic-release** will fail with an `ERELEASEBRANCHES` error message. If you are using the default configuration, you can fix this error by pushing a `master` branch.
|
||||
|
||||
**Note**: Once **semantic-release** is configured, any user with the permission to push commits on one of those branches will be able to publish a release. It is recommended to protect those branches, for example with [GitHub protected branches](https://help.github.com/articles/about-protected-branches).
|
||||
**Note**: Once **semantic-release** is configured, any user with the permission to push commits on one of those branches will be able to publish a release. It is recommended to protect those branches, for example with [GitHub protected branches](https://docs.github.com/github/administering-a-repository/about-protected-branches).
|
||||
|
||||
See [Workflow configuration](workflow-configuration.md#workflow-configuration) for more details.
|
||||
|
||||
@@ -116,7 +116,9 @@ Type: `Boolean`<br>
|
||||
Default: `false` if running in a CI environment, `true` otherwise<br>
|
||||
CLI arguments: `-d`, `--dry-run`
|
||||
|
||||
Dry-run mode, skip publishing, print next version and release notes.
|
||||
The objective of the dry-run mode is to get a preview of the pending release. Dry-run mode skips the following steps: prepare, publish, success and fail. In addition to this it prints the next version and release notes to the console.
|
||||
|
||||
**Note**: The Dry-run mode verifies the repository push permission, even though nothing will be pushed. The verification is done to help user to figure out potential configuration issues.
|
||||
|
||||
### ci
|
||||
|
||||
|
||||
@@ -21,12 +21,12 @@ A plugin is a npm module that can implement one or more of the following steps:
|
||||
|
||||
### Default plugins
|
||||
|
||||
These four plugins are already part of **semantic-release** and don't have to be installed separately:
|
||||
These four plugins are already part of **semantic-release** and are listed in order of execution. They do not have to be installed separately:
|
||||
```
|
||||
"@semantic-release/commit-analyzer"
|
||||
"@semantic-release/github"
|
||||
"@semantic-release/npm"
|
||||
"@semantic-release/release-notes-generator"
|
||||
"@semantic-release/npm"
|
||||
"@semantic-release/github"
|
||||
```
|
||||
|
||||
### Additional plugins
|
||||
|
||||
@@ -29,6 +29,10 @@ Please make sure to add the \`repositoryUrl\` to the [semantic-release configura
|
||||
'docs/usage/configuration.md'
|
||||
)}).`,
|
||||
}),
|
||||
EDUPLICATEREPOSITORYKEY: ({packageJsonPath}) => ({
|
||||
message: 'Duplicate `"repository"` key in package.json.',
|
||||
details: `Your package.json file at ${packageJsonPath} has more than one "repository" keys.`,
|
||||
}),
|
||||
EGITNOPERMISSION: ({options: {repositoryUrl}, branch: {name}}) => ({
|
||||
message: 'Cannot push to the Git repository.',
|
||||
details: `**semantic-release** cannot push the version tag to the branch \`${name}\` on the remote Git repository with URL \`${repositoryUrl}\`.
|
||||
|
||||
+19
-4
@@ -1,12 +1,15 @@
|
||||
const {readFile} = require('fs').promises;
|
||||
const {castArray, pickBy, isNil, isString, isPlainObject} = require('lodash');
|
||||
const readPkgUp = require('read-pkg-up');
|
||||
const findPkgUp = require('pkg-up');
|
||||
const {cosmiconfig} = require('cosmiconfig');
|
||||
const resolveFrom = require('resolve-from');
|
||||
const findDuplicatedPropertyKeys = require('find-duplicated-property-keys');
|
||||
const debug = require('debug')('semantic-release:config');
|
||||
const {repoUrl} = require('./git');
|
||||
const PLUGINS_DEFINITIONS = require('./definitions/plugins');
|
||||
const plugins = require('./plugins');
|
||||
const {validatePlugin, parseConfig} = require('./plugins/utils');
|
||||
const getError = require('./get-error');
|
||||
|
||||
const CONFIG_NAME = 'release';
|
||||
const CONFIG_FILES = [
|
||||
@@ -74,7 +77,7 @@ module.exports = async (context, cliOptions) => {
|
||||
{name: 'beta', prerelease: true},
|
||||
{name: 'alpha', prerelease: true},
|
||||
],
|
||||
repositoryUrl: (await pkgRepoUrl({normalize: false, cwd})) || (await repoUrl({cwd, env})),
|
||||
repositoryUrl: (await pkgRepoUrl({cwd})) || (await repoUrl({cwd, env})),
|
||||
tagFormat: `v\${version}`,
|
||||
plugins: [
|
||||
'@semantic-release/commit-analyzer',
|
||||
@@ -93,6 +96,18 @@ module.exports = async (context, cliOptions) => {
|
||||
};
|
||||
|
||||
async function pkgRepoUrl(options) {
|
||||
const {packageJson} = (await readPkgUp(options)) || {};
|
||||
return packageJson && (isPlainObject(packageJson.repository) ? packageJson.repository.url : packageJson.repository);
|
||||
const packageJsonPath = await findPkgUp(options);
|
||||
if (!packageJsonPath) return;
|
||||
|
||||
const packageJsonString = await readFile(packageJsonPath, 'utf-8');
|
||||
const result = findDuplicatedPropertyKeys(packageJsonString);
|
||||
|
||||
if (result.length > 0) {
|
||||
throw getError('EDUPLICATEREPOSITORYKEY', {packageJsonPath});
|
||||
}
|
||||
|
||||
const {repository} = require(packageJsonPath);
|
||||
if (!repository) return;
|
||||
|
||||
return isPlainObject(repository) ? repository.url : repository;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ const {parse, format} = require('url'); // eslint-disable-line node/no-deprecate
|
||||
const {isNil} = require('lodash');
|
||||
const hostedGitInfo = require('hosted-git-info');
|
||||
const {verifyAuth} = require('./git');
|
||||
const debug = require('debug')('semantic-release:get-git-auth-url');
|
||||
|
||||
/**
|
||||
* Determine the the git repository URL to use to push, either:
|
||||
@@ -42,8 +43,11 @@ module.exports = async ({cwd, env, branch, options: {repositoryUrl}}) => {
|
||||
|
||||
// Test if push is allowed without transforming the URL (e.g. is ssh keys are set up)
|
||||
try {
|
||||
debug('Verifying ssh auth by attempting to push to %s', repositoryUrl);
|
||||
await verifyAuth(repositoryUrl, branch.name, {cwd, env});
|
||||
} catch (_) {
|
||||
debug('SSH key auth failed, falling back to https.');
|
||||
|
||||
const envVar = Object.keys(GIT_TOKENS).find((envVar) => !isNil(env[envVar]));
|
||||
const gitCredentials = `${GIT_TOKENS[envVar] || ''}${env[envVar] || ''}`;
|
||||
|
||||
|
||||
+4
-2
@@ -31,6 +31,7 @@
|
||||
"env-ci": "^5.0.0",
|
||||
"execa": "^4.0.0",
|
||||
"figures": "^3.0.0",
|
||||
"find-duplicated-property-keys": "^1.2.2",
|
||||
"find-versions": "^3.0.0",
|
||||
"get-stream": "^5.0.0",
|
||||
"git-log-parser": "^1.2.0",
|
||||
@@ -42,7 +43,7 @@
|
||||
"micromatch": "^4.0.2",
|
||||
"p-each-series": "^2.1.0",
|
||||
"p-reduce": "^2.0.0",
|
||||
"read-pkg-up": "^7.0.0",
|
||||
"pkg-up": "^3.1.0",
|
||||
"resolve-from": "^5.0.0",
|
||||
"semver": "^7.3.2",
|
||||
"semver-diff": "^3.1.1",
|
||||
@@ -128,7 +129,8 @@
|
||||
"prettier": true,
|
||||
"space": true,
|
||||
"rules": {
|
||||
"unicorn/string-content": "off"
|
||||
"unicorn/string-content": "off",
|
||||
"node/no-unsupported-features/node-builtins": "off"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -516,3 +516,21 @@ test('Throw an Error if one of the shareable config cannot be found', async (t)
|
||||
code: 'MODULE_NOT_FOUND',
|
||||
});
|
||||
});
|
||||
|
||||
test('Throw an Error if package.json has duplicate "repository" key', async (t) => {
|
||||
// Create a git repository, set the current working directory at the root of the repo
|
||||
const {cwd} = await gitRepo();
|
||||
|
||||
// Create package.json with duplicate "repository" key
|
||||
await writeFile(
|
||||
path.resolve(cwd, 'package.json'),
|
||||
`{
|
||||
"repository": "https://github.com/octocat/repository",
|
||||
"repository": "https://github.com/octocat/repository"
|
||||
}`
|
||||
);
|
||||
|
||||
const error = await t.throwsAsync(t.context.getConfig({cwd}));
|
||||
t.is(error.code, 'EDUPLICATEREPOSITORYKEY');
|
||||
t.is(error.message, 'Duplicate `"repository"` key in package.json.');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user