const {parse, format} = require('url'); const {isUndefined} = require('lodash'); 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']; /** * Determine the the git repository URL to use to push, either: * - The `repositoryUrl` as is if allowed to push * - The `repositoryUrl` converted to `https` or `http` with Basic Authentication * * In addition, expand shortcut URLs (`owner/repo` => `https://github.com/owner/repo.git`) and transform `git+https` / `git+http` URLs to `https` / `http`. * * @param {String} repositoryUrl The user provided Git repository URL. * @return {String} The formatted Git repository URL. */ module.exports = async ({repositoryUrl, branch}) => { if (repositoryUrl) { const info = hostedGitInfo.fromUrl(repositoryUrl, {noGitPlus: true}); if (info && info.getDefaultRepresentation() === 'shortcut') { // Expand shorthand URLs (such as `owner/repo` or `gitlab:owner/repo`) repositoryUrl = info.https(); } else { const {protocols} = gitUrlParse(repositoryUrl); // 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'}, }); } } // 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]; const {protocols} = 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 ? format({...parse(`${gitUrlParse(repositoryUrl).toString(protocol)}.git`), ...{auth: gitCredentials}}) : repositoryUrl; } } return repositoryUrl; };