Compare commits

...
17 Commits
Author SHA1 Message Date
Pierre Vanduynslager 55be0ba2b1 fix: add repositoryUrl in logs 2020-02-17 14:09:01 -05:00
Raphaël HuchetandGitHub ec516a34bf docs(configuration): fix CLI usage with --branches option (#1465) 2020-02-17 10:05:33 -08:00
greenkeeper[bot]andGregor Martynus 5f89e6bfc0 chore(package): update nock to version 12.0.0 2020-02-16 13:54:44 -08:00
greenkeeper[bot]andPierre Vanduynslager 195e5b18c7 chore(package): update xo to version 0.26.0 2020-02-12 20:09:31 -05:00
Pierre Vanduynslager e7bede1866 fix: pass a branch name to getGitAuthUrl 2020-02-12 19:56:12 -05:00
greenkeeper[bot]andPierre Vanduynslager 8426b4203e chore(package): update tempy to version 0.4.0 2020-02-12 16:09:26 -05:00
Gregor MartynusandGitHub 804fc2a943 docs(Troubleshooting): release not found in prereleases branch (e.g. beta) after rebase on master) (#1444) 2020-02-08 11:03:48 -08:00
greenkeeper[bot]andPierre Vanduynslager 389e3316e9 chore(package): update got to version 10.5.2 2020-02-07 19:00:38 -05:00
Pierre Vanduynslager a93c96fec9 revert: fix: allow plugins to set environment variables to be used by other plugins
This reverts commit 68f7e928f9.
2020-02-07 17:50:14 -05:00
Pierre VanduynslagerandGregor Martynus 68f7e928f9 fix: allow plugins to set environment variables to be used by other plugins 2020-02-07 13:51:20 -08:00
Gregor MartynusandGitHub 8ce2d6e834 fix(package): update marked-terminal to version 4.0.0 2020-01-31 11:14:54 -05:00
Pierre Vanduynslager 45695b9183 fix(package): update @semantic-release/commit-analyzer to version 8.0.0 2020-01-28 11:31:01 -05:00
Pierre Vanduynslager 3c7b114eed fix(package): update @semantic-release/release-notes-generator to version 9.0.0 2020-01-28 11:31:01 -05:00
Pierre Vanduynslager f2b5826c0c fix(package): update @semantic-release/npm to version 7.0.0 2020-01-28 11:31:01 -05:00
greenkeeper[bot]andPierre Vanduynslager c48bd3ac36 fix(package): update @semantic-release/github to version 7.0.0 2020-01-28 11:31:01 -05:00
Pierre Vanduynslager bc97537c97 test: fix copy/paste typo in test titles 2020-01-28 10:33:24 -05:00
Mario LubenkaandPierre Vanduynslager c7e461dc1c docs: add @saithodev/semantic-release-gitea to community plugins 2020-01-27 14:23:38 -05:00
11 changed files with 76 additions and 57 deletions
+4
View File
@@ -95,3 +95,7 @@
- `verifyConditions`: Checks the project.clj is syntactically valid.
- `prepare`: Update the project.clj version and package the output jar file.
- `publish`: Publish the jar (and generated Maven metadata) to a maven repository (or clojars).
- [@saithodev/semantic-release-gitea](https://github.com/saitho/semantic-release-gitea)
- `verifyConditions`: Verify the presence and the validity of the authentication and the assets option configuration.
- `publish`: Publish a Gitea release, optionally uploading file assets.
- `addChannel`: Update a Gitea release's pre-release field.
+13
View File
@@ -54,3 +54,16 @@ $ git branch --contains <tag name>
$ git tag -d <tag name>
$ git push origin :refs/tags/<tag name>
```
## release not found release branch after `git push --force`
**semantic-release** is using both [git tags](https://git-scm.com/docs/git-tag) and [git notes](https://git-scm.com/docs/git-notes) to store information about which releases happened in which branch.
After a git history rewrite due to a `git push --force`, the git tags and notes referencing the commits that were rewritten are lost.
To recover from that situation, do the following:
1. Delete the tag(s) for the release(s) that have been lost from the git history. You can delete each tag from remote using `git push origin :[TAG NAME]`, e.g. `git push origin :v2.0.0-beta.1`. You can delete tags locally using `git tag -d [TAG NAME]`, e.g. `git tag -d v2.0.0-beta.1`.
2. Re-create the tags locally: `git tag [TAG NAME] [COMMIT HASH]`, where `[COMMIT HASH]` is the new commit that created the release for the lost tag. E.g. `git tag v2.0.0-beta.1 abcdef0`
3. Re-create the git notes for each release tag, e.g. `git notes --ref semantic-release add -f -m '{"channels":["beta"]}' v3.0.0-beta.1`. If the release was also published in the default channel (usually `master`), then set the first channel to `null`, e.g. `git notes --ref semantic-release add -f -m '{"channels":[null, "beta"]}'
4. Push the local notes: `git push --force origin refs/notes/semantic-release`. The `--force` is needed after the rebase. Be careful.
+1 -1
View File
@@ -38,7 +38,7 @@ The following three examples are the same.
- Via CLI argument:
```bash
$ semantic-release --branch next
$ semantic-release --branches next
```
**Note**: CLI arguments take precedence over options configured in the configuration file.
+4 -2
View File
@@ -52,7 +52,7 @@ async function run(context, plugins) {
// Verify config
await verify(context);
options.repositoryUrl = await getGitAuthUrl(context);
options.repositoryUrl = await getGitAuthUrl({...context, branch: {name: ciBranch}});
context.branches = await getBranches(options.repositoryUrl, ciBranch, context);
context.branch = context.branches.find(({name}) => name === ciBranch);
@@ -66,7 +66,9 @@ async function run(context, plugins) {
}
logger[options.dryRun ? 'warn' : 'success'](
`Run automated release from branch ${ciBranch}${options.dryRun ? ' in dry-run mode' : ''}`
`Run automated release from branch ${ciBranch} on repository ${options.repositoryUrl}${
options.dryRun ? ' in dry-run mode' : ''
}`
);
try {
+9 -9
View File
@@ -20,11 +20,11 @@
"Pierre Vanduynslager (https://twitter.com/@pvdlg_)"
],
"dependencies": {
"@semantic-release/commit-analyzer": "^7.0.0",
"@semantic-release/commit-analyzer": "^8.0.0",
"@semantic-release/error": "^2.2.0",
"@semantic-release/github": "^6.0.0",
"@semantic-release/npm": "^6.0.0",
"@semantic-release/release-notes-generator": "^7.1.2",
"@semantic-release/github": "^7.0.0",
"@semantic-release/npm": "^7.0.0",
"@semantic-release/release-notes-generator": "^9.0.0",
"aggregate-error": "^3.0.0",
"cosmiconfig": "^6.0.0",
"debug": "^4.0.0",
@@ -38,7 +38,7 @@
"hosted-git-info": "^3.0.0",
"lodash": "^4.17.15",
"marked": "^0.8.0",
"marked-terminal": "^3.2.0",
"marked-terminal": "^4.0.0",
"micromatch": "^4.0.2",
"p-each-series": "^2.1.0",
"p-reduce": "^2.0.0",
@@ -57,17 +57,17 @@
"dockerode": "^3.0.0",
"file-url": "^3.0.0",
"fs-extra": "^8.0.0",
"got": "^10.2.1",
"got": "^10.5.2",
"js-yaml": "^3.10.0",
"mockserver-client": "^5.1.1",
"nock": "^11.1.0",
"nock": "^12.0.0",
"nyc": "^15.0.0",
"p-retry": "^4.0.0",
"proxyquire": "^2.0.0",
"sinon": "^8.0.4",
"stream-buffers": "^3.0.2",
"tempy": "^0.3.0",
"xo": "^0.25.0"
"tempy": "^0.4.0",
"xo": "^0.26.0"
},
"engines": {
"node": ">=10.18"
+1 -1
View File
@@ -135,7 +135,7 @@ test('Enforce ranges with branching release workflow', async t => {
t.is(
getBranch(result, '1.0.x').range,
'>=1.0.1 <1.0.2',
'Cannot release on 1.0.x before 1.0.x version = require(master are merged'
'Cannot release on 1.0.x before 1.0.x version from master are merged'
);
t.is(getBranch(result, '1.x').range, '>=1.1.0 <1.0.2', 'Cannot release on 1.x before >= 2.0.0 is released on master');
+1 -1
View File
@@ -28,7 +28,7 @@ test('Get the valid tags', async t => {
]);
});
test('Get the valid tags = require(multiple branches', async t => {
test('Get the valid tags from multiple branches', async t => {
const {cwd} = await gitRepo();
await gitCommits(['First'], {cwd});
await gitTagVersion('v1.0.0', undefined, {cwd});
+1 -1
View File
@@ -82,7 +82,7 @@ test('Get all commits between lastRelease.gitHead and a shas', async t => {
// Verify the commits created and retrieved by the module are identical
t.is(result.length, 1);
t.deepEqual(result, commits.slice(1, commits.length - 1));
t.deepEqual(result, commits.slice(1, -1));
});
test('Return empty array if lastRelease.gitHead is the last commit', async t => {
+39 -39
View File
@@ -20,7 +20,7 @@ test.beforeEach(t => {
t.context.getConfig = proxyquire('../lib/get-config', {'./plugins': t.context.plugins});
});
test('Default values, reading repositoryUrl = require(package.json', async t => {
test('Default values, reading repositoryUrl from package.json', async t => {
const pkg = {repository: 'https://host.null/owner/package.git'};
// Create a git repository, set the current working directory at the root of the repo
const {cwd} = await gitRepo(true);
@@ -47,7 +47,7 @@ test('Default values, reading repositoryUrl = require(package.json', async t =>
t.is(result.tagFormat, `v\${version}`);
});
test('Default values, reading repositoryUrl = require(repo if not set in package.json', async t => {
test('Default values, reading repositoryUrl from repo if not set in package.json', async t => {
// Create a git repository, set the current working directory at the root of the repo
const {cwd} = await gitRepo(true);
// Add remote.origin.url config
@@ -68,7 +68,7 @@ test('Default values, reading repositoryUrl = require(repo if not set in package
t.is(result.tagFormat, `v\${version}`);
});
test('Default values, reading repositoryUrl (http url) = require(package.json if not set in repo', async t => {
test('Default values, reading repositoryUrl (http url) from package.json if not set in repo', async t => {
const pkg = {repository: 'https://host.null/owner/module.git'};
// Create a git repository, set the current working directory at the root of the repo
const {cwd} = await gitRepo();
@@ -102,7 +102,7 @@ test('Convert "ci" option to "noCi"', async t => {
t.is(result.noCi, true);
});
test('Read options = require(package.json', async t => {
test('Read options from package.json', async t => {
// Create a git repository, set the current working directory at the root of the repo
const {cwd} = await gitRepo();
const options = {
@@ -119,13 +119,13 @@ test('Read options = require(package.json', async t => {
const {options: result} = await t.context.getConfig({cwd});
const expected = {...options, branches: ['test_branch']};
// Verify the options contains the plugin config = require(package.json
// Verify the options contains the plugin config from package.json
t.deepEqual(result, expected);
// Verify the plugins module is called with the plugin options = require(package.json
// Verify the plugins module is called with the plugin options from package.json
t.deepEqual(t.context.plugins.args[0][0], {options: expected, cwd});
});
test('Read options = require(.releaserc.yml', async t => {
test('Read options from .releaserc.yml', async t => {
// Create a git repository, set the current working directory at the root of the repo
const {cwd} = await gitRepo();
const options = {
@@ -141,13 +141,13 @@ test('Read options = require(.releaserc.yml', async t => {
const {options: result} = await t.context.getConfig({cwd});
const expected = {...options, branches: ['test_branch']};
// Verify the options contains the plugin config = require(package.json
// Verify the options contains the plugin config from package.json
t.deepEqual(result, expected);
// Verify the plugins module is called with the plugin options = require(package.json
// Verify the plugins module is called with the plugin options from package.json
t.deepEqual(t.context.plugins.args[0][0], {options: expected, cwd});
});
test('Read options = require(.releaserc.json', async t => {
test('Read options from .releaserc.json', async t => {
// Create a git repository, set the current working directory at the root of the repo
const {cwd} = await gitRepo();
const options = {
@@ -163,13 +163,13 @@ test('Read options = require(.releaserc.json', async t => {
const {options: result} = await t.context.getConfig({cwd});
const expected = {...options, branches: ['test_branch']};
// Verify the options contains the plugin config = require(package.json
// Verify the options contains the plugin config from package.json
t.deepEqual(result, expected);
// Verify the plugins module is called with the plugin options = require(package.json
// Verify the plugins module is called with the plugin options from package.json
t.deepEqual(t.context.plugins.args[0][0], {options: expected, cwd});
});
test('Read options = require(.releaserc.js', async t => {
test('Read options from .releaserc.js', async t => {
// Create a git repository, set the current working directory at the root of the repo
const {cwd} = await gitRepo();
const options = {
@@ -185,13 +185,13 @@ test('Read options = require(.releaserc.js', async t => {
const {options: result} = await t.context.getConfig({cwd});
const expected = {...options, branches: ['test_branch']};
// Verify the options contains the plugin config = require(package.json
// Verify the options contains the plugin config from package.json
t.deepEqual(result, expected);
// Verify the plugins module is called with the plugin options = require(package.json
// Verify the plugins module is called with the plugin options from package.json
t.deepEqual(t.context.plugins.args[0][0], {options: expected, cwd});
});
test('Read options = require(release.config.js', async t => {
test('Read options from release.config.js', async t => {
// Create a git repository, set the current working directory at the root of the repo
const {cwd} = await gitRepo();
const options = {
@@ -207,9 +207,9 @@ test('Read options = require(release.config.js', async t => {
const {options: result} = await t.context.getConfig({cwd});
const expected = {...options, branches: ['test_branch']};
// Verify the options contains the plugin config = require(package.json
// Verify the options contains the plugin config from package.json
t.deepEqual(result, expected);
// Verify the plugins module is called with the plugin options = require(package.json
// Verify the plugins module is called with the plugin options from package.json
t.deepEqual(t.context.plugins.args[0][0], {options: expected, cwd});
});
@@ -237,13 +237,13 @@ test('Prioritise CLI/API parameters over file configuration and git repo', async
const result = await t.context.getConfig({cwd}, options);
const expected = {...options, branches: ['branch_cli']};
// Verify the options contains the plugin config = require(CLI/API
// Verify the options contains the plugin config from CLI/API
t.deepEqual(result.options, expected);
// Verify the plugins module is called with the plugin options = require(CLI/API
// Verify the plugins module is called with the plugin options from CLI/API
t.deepEqual(t.context.plugins.args[0][0], {options: expected, cwd});
});
test('Read configuration = require(file path in "extends"', async t => {
test('Read configuration from file path in "extends"', async t => {
// Create a git repository, set the current working directory at the root of the repo
const {cwd} = await gitRepo();
const pkgOptions = {extends: './shareable.json'};
@@ -262,9 +262,9 @@ test('Read configuration = require(file path in "extends"', async t => {
const {options: result} = await t.context.getConfig({cwd});
const expected = {...options, branches: ['test_branch']};
// Verify the options contains the plugin config = require(shareable.json
// Verify the options contains the plugin config from shareable.json
t.deepEqual(result, expected);
// Verify the plugins module is called with the plugin options = require(shareable.json
// Verify the plugins module is called with the plugin options from shareable.json
t.deepEqual(t.context.plugins.args[0][0], {options: expected, cwd});
t.deepEqual(t.context.plugins.args[0][1], {
analyzeCommits: './shareable.json',
@@ -274,7 +274,7 @@ test('Read configuration = require(file path in "extends"', async t => {
});
});
test('Read configuration = require(module path in "extends"', async t => {
test('Read configuration from module path in "extends"', async t => {
// Create a git repository, set the current working directory at the root of the repo
const {cwd} = await gitRepo();
const pkgOptions = {extends: 'shareable'};
@@ -293,9 +293,9 @@ test('Read configuration = require(module path in "extends"', async t => {
const {options: result} = await t.context.getConfig({cwd});
const expected = {...options, branches: ['test_branch']};
// Verify the options contains the plugin config = require(shareable.json
// Verify the options contains the plugin config from shareable.json
t.deepEqual(result, expected);
// Verify the plugins module is called with the plugin options = require(shareable.json
// Verify the plugins module is called with the plugin options from shareable.json
t.deepEqual(t.context.plugins.args[0][0], {options: expected, cwd});
t.deepEqual(t.context.plugins.args[0][1], {
analyzeCommits: 'shareable',
@@ -303,7 +303,7 @@ test('Read configuration = require(module path in "extends"', async t => {
});
});
test('Read configuration = require(an array of paths in "extends"', async t => {
test('Read configuration from an array of paths in "extends"', async t => {
// Create a git repository, set the current working directory at the root of the repo
const {cwd} = await gitRepo();
const pkgOptions = {extends: ['./shareable1.json', './shareable2.json']};
@@ -329,9 +329,9 @@ test('Read configuration = require(an array of paths in "extends"', async t => {
const {options: result} = await t.context.getConfig({cwd});
const expected = {...options1, ...options2, branches: ['test_branch']};
// Verify the options contains the plugin config = require(shareable1.json and shareable2.json
// Verify the options contains the plugin config from shareable1.json and shareable2.json
t.deepEqual(result, expected);
// Verify the plugins module is called with the plugin options = require(shareable1.json and shareable2.json
// Verify the plugins module is called with the plugin options from shareable1.json and shareable2.json
t.deepEqual(t.context.plugins.args[0][0], {options: expected, cwd});
t.deepEqual(t.context.plugins.args[0][1], {
verifyRelease1: './shareable1.json',
@@ -342,7 +342,7 @@ test('Read configuration = require(an array of paths in "extends"', async t => {
});
});
test('Prioritize configuration = require(config file over "extends"', async t => {
test('Prioritize configuration from config file over "extends"', async t => {
// Create a git repository, set the current working directory at the root of the repo
const {cwd} = await gitRepo();
const pkgOptions = {
@@ -367,9 +367,9 @@ test('Prioritize configuration = require(config file over "extends"', async t =>
const {options: result} = await t.context.getConfig({cwd});
const expected = omit({...options1, ...pkgOptions, branches: ['test_pkg']}, 'extends');
// Verify the options contains the plugin config = require(package.json and shareable.json
// Verify the options contains the plugin config from package.json and shareable.json
t.deepEqual(result, expected);
// Verify the plugins module is called with the plugin options = require(package.json and shareable.json
// Verify the plugins module is called with the plugin options from package.json and shareable.json
t.deepEqual(t.context.plugins.args[0][0], {options: expected, cwd});
t.deepEqual(t.context.plugins.args[0][1], {
analyzeCommits: './shareable.json',
@@ -378,7 +378,7 @@ test('Prioritize configuration = require(config file over "extends"', async t =>
});
});
test('Prioritize configuration = require(cli/API options over "extends"', async t => {
test('Prioritize configuration from cli/API options over "extends"', async t => {
// Create a git repository, set the current working directory at the root of the repo
const {cwd} = await gitRepo();
const cliOptions = {
@@ -415,9 +415,9 @@ test('Prioritize configuration = require(cli/API options over "extends"', async
const {options: result} = await t.context.getConfig({cwd}, cliOptions);
const expected = omit({...options2, ...pkgOptions, ...cliOptions, branches: ['branch_opts']}, 'extends');
// Verify the options contains the plugin config = require(package.json and shareable2.json
// Verify the options contains the plugin config from package.json and shareable2.json
t.deepEqual(result, expected);
// Verify the plugins module is called with the plugin options = require(package.json and shareable2.json
// Verify the plugins module is called with the plugin options from package.json and shareable2.json
t.deepEqual(t.context.plugins.args[0][0], {options: expected, cwd});
});
@@ -443,13 +443,13 @@ test('Allow to unset properties defined in shareable config with "null"', async
const {options} = await t.context.getConfig({cwd});
// Verify the options contains the plugin config = require(shareable.json and the default `plugins`
// Verify the options contains the plugin config from shareable.json and the default `plugins`
t.deepEqual(options, {
...omit(options1, ['analyzeCommits']),
...omit(pkgOptions, ['extends', 'analyzeCommits']),
plugins: DEFAULT_PLUGINS,
});
// Verify the plugins module is called with the plugin options = require(shareable.json and the default `plugins`
// Verify the plugins module is called with the plugin options from shareable.json and the default `plugins`
t.deepEqual(t.context.plugins.args[0][0], {
options: {
...omit(options1, 'analyzeCommits'),
@@ -492,9 +492,9 @@ test('Allow to unset properties defined in shareable config with "undefined"', a
...omit(pkgOptions, ['extends', 'analyzeCommits']),
branches: ['test_branch'],
};
// Verify the options contains the plugin config = require(shareable.json
// Verify the options contains the plugin config from shareable.json
t.deepEqual(result, expected);
// Verify the plugins module is called with the plugin options = require(shareable.json
// Verify the plugins module is called with the plugin options from shareable.json
t.deepEqual(t.context.plugins.args[0][0], {options: expected, cwd});
t.deepEqual(t.context.plugins.args[0][1], {
generateNotes: './shareable.json',
+1 -1
View File
@@ -18,7 +18,7 @@ test('Get the highest non-prerelease valid tag', t => {
t.deepEqual(result, {version: '2.0.0', gitTag: 'v2.0.0', name: 'v2.0.0', gitHead: 'v2.0.0', channels: undefined});
});
test('Get the highest prerelease valid tag, ignoring other tags = require(other prerelease channels', t => {
test('Get the highest prerelease valid tag, ignoring other tags from other prerelease channels', t => {
const result = getLastRelease({
branch: {
name: 'beta',
+2 -2
View File
@@ -1,7 +1,7 @@
const test = require('ava');
const getReleaseToAdd = require('../lib/get-release-to-add');
test('Return versions merged = require(release to maintenance branch, excluding lower than branch start range', t => {
test('Return versions merged from release to maintenance branch, excluding lower than branch start range', t => {
const result = getReleaseToAdd({
branch: {
name: '2.x',
@@ -188,7 +188,7 @@ test('Ignore pre-release versions', t => {
});
});
test('Exclude versions merged = require(release to maintenance branch if they have the same "channel"', t => {
test('Exclude versions merged from release to maintenance branch if they have the same "channel"', t => {
const result = getReleaseToAdd({
branch: {
name: '2.x',