Compare commits

...
7 Commits
10 changed files with 100 additions and 104 deletions
-48
View File
@@ -1,48 +0,0 @@
<!--
Please fill the informations requested or use one of the following url:
- Bug report: https://github.com/semantic-release/semantic-release/issues/new?template=bug-report.md
- Feature request: https://github.com/semantic-release/semantic-release/issues/new?template=feature-request.md
- New plugin request: https://github.com/semantic-release/semantic-release/issues/new?template=plugin-request.md
-->
<!--------------------- FOR BUG REPORT ONLY --------------------->
## Current behavior
<!-- Describe how the issue manifests. -->
## Expected behavior
<!-- Describe what the desired behavior would be. -->
## Environment
- **semantic-release** version: <!-- Version set in package.json devDpendencies -->
- CI environment: <!-- CI service name -->
- Plugins used: <!-- List semantic-release plugin used if any -->
- **semantic-release** configuration: <!-- link to your repository or relevant part of the semantic-release config -->
- CI logs: <!-- link to your CI logs or semantic-release logs -->
<!--------------------- FOR FEATURE REQUEST ONLY --------------------->
## New feature motivation
<!-- Describe the context, the use-case and the advantages of the feature request. -->
## New feature description
<!-- Describe the functional changes that would have to be made in semantic-release or its plugins. -->
## New feature implementation
<!-- Optionally describe the technical changes to be made in semantic-release or its plugins. -->
<!--------------------- FOR NEW PLUGIN REQUEST ONLY --------------------->
## New plugin motivation
<!-- Describe the reasons to create a new plugin and why it's not covered by the existing ones. -->
## Third-party documentation
<!-- Provide explanation and documentation links for the platform to integrate with. -->
@@ -1,17 +1,21 @@
# Bug report
## Current behavior
<!-- Describe how the issue manifests. -->
## Expected behavior
<!-- Describe what the desired behavior would be. -->
## Environment
- **semantic-release** version: <!-- Version set in package.json devDpendencies -->
- CI environment: <!-- CI service name -->
- Plugins used: <!-- List semantic-release plugin used if any -->
- **semantic-release** configuration: <!-- link to your repository or relevant part of the semantic-release config -->
- CI logs: <!-- link to your CI logs or semantic-release logs -->
---
name: Bug report
about: Something not working as expected
---
## Current behavior
<!-- Describe how the issue manifests. -->
## Expected behavior
<!-- Describe what the desired behavior would be. -->
## Environment
- **semantic-release** version: <!-- Version set in package.json devDpendencies -->
- CI environment: <!-- CI service name -->
- Plugins used: <!-- List semantic-release plugin used if any -->
- **semantic-release** configuration: <!-- link to your repository or relevant part of the semantic-release config -->
- CI logs: <!-- link to your CI logs or semantic-release logs -->
@@ -1,13 +1,17 @@
# Feature request
## New feature motivation
<!-- Describe the context, the use-case and the advantages of the feature request. -->
## New feature description
<!-- Describe the functional changes that would have to be made in semantic-release or its plugins. -->
## New feature implementation
<!-- Optionally describe the technical changes to be made in semantic-release or its plugins. -->
---
name: Feature request
about: Wouldn’t it be nice if semantic-release could ...
---
## New feature motivation
<!-- Describe the context, the use-case and the advantages of the feature request. -->
## New feature description
<!-- Describe the functional changes that would have to be made in semantic-release or its plugins. -->
## New feature implementation
<!-- Optionally describe the technical changes to be made in semantic-release or its plugins. -->
@@ -1,9 +1,13 @@
# New plugin request
## New plugin motivation
<!-- Describe the reasons to create a new plugin and why it's not covered by the existing ones. -->
## Third-party documentation
<!-- Provide explanation and documentation links for the platform to integrate with. -->
---
name: New plugin suggestion
about: Integrate with a new platform, etc
---
## New plugin motivation
<!-- Describe the reasons to create a new plugin and why it's not covered by the existing ones. -->
## Third-party documentation
<!-- Provide explanation and documentation links for the platform to integrate with. -->
+7 -6
View File
@@ -10,13 +10,14 @@ See [CI configuration recipes](../recipes/README.md#ci-configurations) for more
**semantic-release** requires push access to the project Git repository in order to create [Git tags](https://git-scm.com/book/en/v2/Git-Basics-Tagging). The Git authentication can be set with one of the following environment variables:
| Variable | Description |
|------------------------------|-------------------------------------------------------------------------------------------------------------------------------|
| `GH_TOKEN` or `GITHUB_TOKEN` | A GitHub [personal access token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line). |
| `GL_TOKEN` or `GITLAB_TOKEN` | A GitLab [personal access token](https://docs.gitlab.com/ce/user/profile/personal_access_tokens.html). |
| `GIT_CREDENTIALS` | [URL encoded basic HTTP Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication#URL_encoding) credentials). |
| Variable | Description |
|---------------------------------|-------------------------------------------------------------------------------------------------------------------------------|
| `GH_TOKEN` or `GITHUB_TOKEN` | A GitHub [personal access token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line). |
| `GL_TOKEN` or `GITLAB_TOKEN` | A GitLab [personal access token](https://docs.gitlab.com/ce/user/profile/personal_access_tokens.html). |
| `BB_TOKEN` or `BITBUCKET_TOKEN` | A Bitbucket [personal access token](https://confluence.atlassian.com/bitbucketserver/personal-access-tokens-939515499.html). |
| `GIT_CREDENTIALS` | [URL encoded basic HTTP Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication#URL_encoding) credentials). |
`GIT_CREDENTIALS` can be the Git username and password in the format `<username>:<password>` or a token for certain Git providers like [Bitbucket](https://confluence.atlassian.com/bitbucketserver/personal-access-tokens-939515499.html).
`GIT_CREDENTIALS` must be the Git username and password in the format `<username>:<password>`.
Alternatively the Git authentication can be set up via [SSH keys](../recipes/git-auth-ssh-keys.md).
+4 -1
View File
@@ -56,7 +56,10 @@ async function run(options, plugins) {
return false;
}
if (!await verifyAuth(options.repositoryUrl, options.branch)) {
try {
await verifyAuth(options.repositoryUrl, options.branch);
} catch (err) {
logger.error(`The command "${err.cmd}" failed with the error message %s.`, err.stderr);
throw getError('EGITNOPERMISSION', {options});
}
+16 -7
View File
@@ -4,7 +4,15 @@ const gitUrlParse = require('git-url-parse');
const hostedGitInfo = require('hosted-git-info');
const {verifyAuth} = require('./git');
const GIT_TOKENS = ['GIT_CREDENTIALS', 'GH_TOKEN', 'GITHUB_TOKEN', 'GL_TOKEN', 'GITLAB_TOKEN'];
const GIT_TOKENS = {
GIT_CREDENTIALS: undefined,
GH_TOKEN: undefined,
GITHUB_TOKEN: undefined,
GL_TOKEN: 'gitlab-ci-token:',
GITLAB_TOKEN: 'gitlab-ci-token:',
BB_TOKEN: 'x-token-auth:',
BITBUCKET_TOKEN: 'x-token-auth:',
};
/**
* Determine the the git repository URL to use to push, either:
@@ -35,16 +43,17 @@ module.exports = async ({repositoryUrl, branch}) => {
}
// Test if push is allowed without transforming the URL (e.g. is ssh keys are set up)
if (!await verifyAuth(repositoryUrl, branch)) {
const envVar = GIT_TOKENS.find(envVar => !isUndefined(process.env[envVar]));
const gitCredentials = ['GL_TOKEN', 'GITLAB_TOKEN'].includes(envVar)
? `gitlab-ci-token:${process.env[envVar]}`
: process.env[envVar];
try {
await verifyAuth(repositoryUrl, branch);
} catch (err) {
const envVar = Object.keys(GIT_TOKENS).find(envVar => !isUndefined(process.env[envVar]));
const gitCredentials = `${GIT_TOKENS[envVar] || ''}${process.env[envVar] || ''}`;
const {protocols, ...parsed} = gitUrlParse(repositoryUrl);
const protocol = protocols.includes('https') ? 'https' : protocols.includes('http') ? 'http' : 'https';
// If credentials are set via anvironment variables, convert the URL to http/https and add basic auth, otherwise return `repositoryUrl` as is
return gitCredentials ? {...parsed, ...{token: gitCredentials}}.toString(protocol) : repositoryUrl;
return gitCredentials ? {...parsed, protocols: [protocol], user: gitCredentials}.toString(protocol) : repositoryUrl;
}
return repositoryUrl;
};
+3 -2
View File
@@ -86,13 +86,14 @@ async function isGitRepo() {
* @param {String} repositoryUrl The remote repository URL.
* @param {String} branch The repositoru branch for which to verify write access.
*
* @return {Boolean} `true` is authorized to push, falsy otherwise.
* @throws {Error} if not authorized to push.
*/
async function verifyAuth(repositoryUrl, branch) {
try {
return (await execa('git', ['push', '--dry-run', repositoryUrl, `HEAD:${branch}`])).code === 0;
await execa('git', ['push', '--dry-run', repositoryUrl, `HEAD:${branch}`]);
} catch (err) {
debug(err);
throw err;
}
}
+1 -1
View File
@@ -54,7 +54,7 @@
"delay": "^2.0.0",
"dockerode": "^2.5.2",
"file-url": "^2.0.2",
"fs-extra": "^5.0.0",
"fs-extra": "^6.0.0",
"got": "^8.0.0",
"js-yaml": "^3.10.0",
"mockserver-client": "^5.1.1",
+18
View File
@@ -13,6 +13,8 @@ test.beforeEach(() => {
delete process.env.GITHUB_TOKEN;
delete process.env.GL_TOKEN;
delete process.env.GITLAB_TOKEN;
delete process.env.BB_TOKEN;
delete process.env.BITBUCKET_TOKEN;
process.env.GIT_ASKPASS = 'echo';
process.env.GIT_TERMINAL_PROMPT = 0;
});
@@ -152,6 +154,22 @@ test.serial('Return the "https" formatted URL if "gitCredentials" is defined wit
);
});
test.serial('Return the "https" formatted URL if "gitCredentials" is defined with "BB_TOKEN"', async t => {
process.env.BB_TOKEN = 'token';
t.is(
await getAuthUrl({repositoryUrl: 'git@host.null:owner/repo.git'}),
'https://x-token-auth:token@host.null/owner/repo.git'
);
});
test.serial('Return the "https" formatted URL if "gitCredentials" is defined with "BITBUCKET_TOKEN"', async t => {
process.env.BITBUCKET_TOKEN = 'token';
t.is(
await getAuthUrl({repositoryUrl: 'git@host.null:owner/repo.git'}),
'https://x-token-auth:token@host.null/owner/repo.git'
);
});
test.serial('Handle "https" URL with group and subgroup, with "GIT_CREDENTIALS"', async t => {
process.env.GIT_CREDENTIALS = 'user:pass';
t.is(