feat: gitFs over SSH (#2768)

Support setting git clone protocol `http`, `https` or `ssh`.
Config name: `gitFsProtocol`.
Platform independent.

Closes #2708
This commit is contained in:
Ayoub Kaanich 2018-11-08 13:21:36 +01:00 committed by Rhys Arkins
parent 2fd6c3bf34
commit 164b9af513
9 changed files with 72 additions and 16 deletions

View file

@ -182,9 +182,10 @@ const options = [
name: 'gitFs',
description: 'Use git for FS operations instead of API. GitHub only.',
stage: 'repository',
type: 'boolean',
type: 'string',
allowedValues: ['https', 'http', 'ssh'],
admin: true,
default: false,
default: null,
},
{
name: 'exposeEnv',

View file

@ -56,6 +56,15 @@ function migrateConfig(config) {
);
}
delete migratedConfig.pathRules;
} else if (key === 'gitFs') {
if (val === false) {
isMigrated = true;
migratedConfig.gitFs = null;
}
if (val === true) {
isMigrated = true;
migratedConfig.gitFs = 'https';
}
} else if (key === 'packageFiles' && is.array(val)) {
isMigrated = true;
const fileList = [];

View file

@ -1,6 +1,7 @@
const fs = require('fs-extra');
const { join } = require('path');
const path = require('path');
const URL = require('url');
const Git = require('simple-git/promise');
const convertHrtime = require('convert-hrtime');
@ -279,4 +280,21 @@ function localName(branchName) {
return branchName.replace(/^origin\//, '');
}
Storage.getUrl = ({ gitFs, auth, hostname, repository }) => {
let protocol = gitFs || 'https';
// istanbul ignore if
if (protocol.toString() === 'true') {
protocol = 'https';
}
if (protocol === 'ssh') {
return `git@${hostname}:${repository}.git`;
}
return URL.format({
protocol,
auth,
hostname,
pathname: repository + '.git',
});
};
module.exports = Storage;

View file

@ -307,19 +307,18 @@ async function initRepo({
// istanbul ignore if
if (gitFs) {
logger.debug('Enabling Git FS');
let { protocol, host } = URL.parse(opts.endpoint);
let { host } = URL.parse(opts.endpoint);
if (host === 'api.github.com') {
host = null;
}
host = host || 'github.com';
protocol = protocol || 'https:';
const url = URL.format({
protocol,
const url = GitStorage.getUrl({
gitFs,
auth:
config.forkToken ||
(global.appMode ? `x-access-token:${opts.token}` : opts.token),
hostname: host,
pathname: repository + '.git',
repository,
});
config.storage = new GitStorage();
await config.storage.initRepo({

View file

@ -145,14 +145,12 @@ async function initRepo({
// istanbul ignore if
if (config.gitFs) {
logger.debug('Enabling Git FS');
let { protocol, host } = URL.parse(opts.endpoint);
host = host || 'gitlab.com';
protocol = protocol || 'https:';
const url = URL.format({
protocol,
const { host } = URL.parse(opts.endpoint);
const url = GitStorage.getUrl({
gitFs,
auth: 'oauth2:' + (config.forkToken || opts.token),
hostname: host,
pathname: repository + '.git',
hostname: host || 'gitlab.com',
repository,
});
config.storage = new GitStorage();
await config.storage.initRepo({
@ -241,10 +239,11 @@ async function commitFilesToBranch(
message,
parentBranch = config.baseBranch
) {
// GitLab does not support push with GitFs
// GitLab does not support push with GitFs token
// See https://gitlab.com/gitlab-org/gitlab-ce/issues/18106
let storage = config.storage;
// istanbul ignore if
if (config.gitFs) {
if (config.gitFs === 'http' || config.gitFs === 'https') {
storage = new Storage();
storage.initRepo(config);
}

View file

@ -21,6 +21,7 @@ Object {
"config:js-app",
"config:js-lib",
],
"gitFs": null,
"hostRules": Array [
Object {},
],
@ -29,6 +30,7 @@ Object {
],
"lockFileMaintenance": Object {
"automerge": true,
"gitFs": "https",
"schedule": "before 5am",
},
"major": Object {

View file

@ -11,6 +11,7 @@ describe('config/migration', () => {
maintainYarnLock: true,
onboarding: 'false',
multipleMajorPrs: true,
gitFs: false,
separateMajorReleases: true,
separatePatchReleases: true,
automerge: 'none',
@ -57,6 +58,7 @@ describe('config/migration', () => {
},
],
lockFileMaintenance: {
gitFs: true,
automerge: 'any',
schedule: 'before 5am every day',
},

View file

@ -212,4 +212,29 @@ describe('platform/git/storage', () => {
expect(await git.getCommitMessages()).toMatchSnapshot();
});
});
describe('Storage.getUrl()', () => {
const getUrl = GitStorage.getUrl;
it('returns https url', () => {
expect(
getUrl({
gitFs: 'https',
auth: 'user:pass',
hostname: 'host',
repository: 'some/repo',
})
).toEqual('https://user:pass@host/some/repo.git');
});
it('returns ssh url', () => {
expect(
getUrl({
gitFs: 'ssh',
auth: 'user:pass',
hostname: 'host',
repository: 'some/repo',
})
).toEqual('git@host:some/repo.git');
});
});
});

View file

@ -42,6 +42,7 @@ RFC5322-compliant string if you wish to customise the git author for commits.
## gitFs
This setting is experimental, and works for GitHub repositories only. If enabled, Renovate will `git clone` repos and use `git` for file operations such as creating branches and committing files.
Set it to a string specifing the transport used by Git (`https`, `http` or `ssh`).
## gitPrivateKey