diff --git a/lib/get-git-auth-url.js b/lib/get-git-auth-url.js index fe9493e5..eaa4243c 100644 --- a/lib/get-git-auth-url.js +++ b/lib/get-git-auth-url.js @@ -1,6 +1,5 @@ const {parse, format} = require('url'); const {isNil} = require('lodash'); -const gitUrlParse = require('git-url-parse'); const hostedGitInfo = require('hosted-git-info'); const {verifyAuth} = require('./git'); @@ -27,17 +26,14 @@ const GIT_TOKENS = { */ module.exports = async ({cwd, env, options: {repositoryUrl, branch}}) => { const info = hostedGitInfo.fromUrl(repositoryUrl, {noGitPlus: true}); + const {protocol, ...parsed} = parse(repositoryUrl); if (info && info.getDefaultRepresentation() === 'shortcut') { // Expand shorthand URLs (such as `owner/repo` or `gitlab:owner/repo`) repositoryUrl = info.https(); - } else { - const {protocols} = gitUrlParse(repositoryUrl); - + } else if (protocol && protocol.includes('http')) { // Replace `git+https` and `git+http` with `https` or `http` - if (protocols.includes('http') || protocols.includes('https')) { - repositoryUrl = format({...parse(repositoryUrl), protocol: protocols.includes('https') ? 'https' : 'http'}); - } + repositoryUrl = format({...parsed, protocol: protocol.includes('https') ? 'https' : 'http', href: null}); } // Test if push is allowed without transforming the URL (e.g. is ssh keys are set up) @@ -46,11 +42,16 @@ module.exports = async ({cwd, env, options: {repositoryUrl, branch}}) => { } catch (error) { const envVar = Object.keys(GIT_TOKENS).find(envVar => !isNil(env[envVar])); const gitCredentials = `${GIT_TOKENS[envVar] || ''}${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, protocols: [protocol], user: gitCredentials}.toString(protocol) : repositoryUrl; + if (gitCredentials) { + // If credentials are set via anvironment variables, convert the URL to http/https and add basic auth, otherwise return `repositoryUrl` as is + const [match, auth, host, path] = /^(?!.+:\/\/)(?:(.*)@)?(.*?):(.*)$/.exec(repositoryUrl) || []; + return format({ + ...parse(match ? `ssh://${auth ? `${auth}@` : ''}${host}/${path}` : repositoryUrl), + auth: gitCredentials, + protocol: protocol && /http[^s]/.test(protocol) ? 'http' : 'https', + }); + } } return repositoryUrl; diff --git a/package.json b/package.json index 26580671..e051e69a 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "@semantic-release/error": "^2.2.0", "@semantic-release/github": "^5.1.0", "@semantic-release/npm": "^5.0.5", - "@semantic-release/release-notes-generator": "^7.1.0", + "@semantic-release/release-notes-generator": "^7.1.2", "aggregate-error": "^1.0.0", "cosmiconfig": "^5.0.1", "debug": "^4.0.0", @@ -33,7 +33,6 @@ "find-versions": "^2.0.0", "get-stream": "^4.0.0", "git-log-parser": "^1.2.0", - "git-url-parse": "^10.0.1", "hook-std": "^1.1.0", "hosted-git-info": "^2.7.1", "lodash": "^4.17.4", diff --git a/test/get-git-auth-url.test.js b/test/get-git-auth-url.test.js index e0c4828a..16b58159 100644 --- a/test/get-git-auth-url.test.js +++ b/test/get-git-auth-url.test.js @@ -101,6 +101,19 @@ test('Return the "https" formatted URL if "gitCredentials" is defined and reposi ); }); +test('Return the "https" formatted URL if "gitCredentials" is defined and repositoryUrl is a "git" URL without user', async t => { + const {cwd} = await gitRepo(); + + t.is( + await getAuthUrl({ + cwd, + env: {...env, GIT_CREDENTIALS: 'user:pass'}, + options: {branch: 'master', repositoryUrl: 'host.null:owner/repo.git'}, + }), + 'https://user:pass@host.null/owner/repo.git' + ); +}); + test('Return the "https" formatted URL if "gitCredentials" is defined and repositoryUrl is a "https" URL', async t => { const {cwd} = await gitRepo(); diff --git a/test/index.test.js b/test/index.test.js index 7f3fb2b8..81cfcb16 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -1086,6 +1086,7 @@ test('Hide sensitive information passed to "success" plugin', async t => { verifyConditions: false, verifyRelease: false, prepare: false, + generateNotes: stub().resolves(`Exposing token ${env.MY_TOKEN}`), publish: stub().resolves({ name: `Name: Exposing token ${env.MY_TOKEN}`, url: `URL: Exposing token ${env.MY_TOKEN}`,