mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-12 06:56:24 +00:00
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:
parent
2fd6c3bf34
commit
164b9af513
9 changed files with 72 additions and 16 deletions
|
@ -182,9 +182,10 @@ const options = [
|
||||||
name: 'gitFs',
|
name: 'gitFs',
|
||||||
description: 'Use git for FS operations instead of API. GitHub only.',
|
description: 'Use git for FS operations instead of API. GitHub only.',
|
||||||
stage: 'repository',
|
stage: 'repository',
|
||||||
type: 'boolean',
|
type: 'string',
|
||||||
|
allowedValues: ['https', 'http', 'ssh'],
|
||||||
admin: true,
|
admin: true,
|
||||||
default: false,
|
default: null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'exposeEnv',
|
name: 'exposeEnv',
|
||||||
|
|
|
@ -56,6 +56,15 @@ function migrateConfig(config) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
delete migratedConfig.pathRules;
|
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)) {
|
} else if (key === 'packageFiles' && is.array(val)) {
|
||||||
isMigrated = true;
|
isMigrated = true;
|
||||||
const fileList = [];
|
const fileList = [];
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const { join } = require('path');
|
const { join } = require('path');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const URL = require('url');
|
||||||
const Git = require('simple-git/promise');
|
const Git = require('simple-git/promise');
|
||||||
const convertHrtime = require('convert-hrtime');
|
const convertHrtime = require('convert-hrtime');
|
||||||
|
|
||||||
|
@ -279,4 +280,21 @@ function localName(branchName) {
|
||||||
return branchName.replace(/^origin\//, '');
|
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;
|
module.exports = Storage;
|
||||||
|
|
|
@ -307,19 +307,18 @@ async function initRepo({
|
||||||
// istanbul ignore if
|
// istanbul ignore if
|
||||||
if (gitFs) {
|
if (gitFs) {
|
||||||
logger.debug('Enabling Git FS');
|
logger.debug('Enabling Git FS');
|
||||||
let { protocol, host } = URL.parse(opts.endpoint);
|
let { host } = URL.parse(opts.endpoint);
|
||||||
if (host === 'api.github.com') {
|
if (host === 'api.github.com') {
|
||||||
host = null;
|
host = null;
|
||||||
}
|
}
|
||||||
host = host || 'github.com';
|
host = host || 'github.com';
|
||||||
protocol = protocol || 'https:';
|
const url = GitStorage.getUrl({
|
||||||
const url = URL.format({
|
gitFs,
|
||||||
protocol,
|
|
||||||
auth:
|
auth:
|
||||||
config.forkToken ||
|
config.forkToken ||
|
||||||
(global.appMode ? `x-access-token:${opts.token}` : opts.token),
|
(global.appMode ? `x-access-token:${opts.token}` : opts.token),
|
||||||
hostname: host,
|
hostname: host,
|
||||||
pathname: repository + '.git',
|
repository,
|
||||||
});
|
});
|
||||||
config.storage = new GitStorage();
|
config.storage = new GitStorage();
|
||||||
await config.storage.initRepo({
|
await config.storage.initRepo({
|
||||||
|
|
|
@ -145,14 +145,12 @@ async function initRepo({
|
||||||
// istanbul ignore if
|
// istanbul ignore if
|
||||||
if (config.gitFs) {
|
if (config.gitFs) {
|
||||||
logger.debug('Enabling Git FS');
|
logger.debug('Enabling Git FS');
|
||||||
let { protocol, host } = URL.parse(opts.endpoint);
|
const { host } = URL.parse(opts.endpoint);
|
||||||
host = host || 'gitlab.com';
|
const url = GitStorage.getUrl({
|
||||||
protocol = protocol || 'https:';
|
gitFs,
|
||||||
const url = URL.format({
|
|
||||||
protocol,
|
|
||||||
auth: 'oauth2:' + (config.forkToken || opts.token),
|
auth: 'oauth2:' + (config.forkToken || opts.token),
|
||||||
hostname: host,
|
hostname: host || 'gitlab.com',
|
||||||
pathname: repository + '.git',
|
repository,
|
||||||
});
|
});
|
||||||
config.storage = new GitStorage();
|
config.storage = new GitStorage();
|
||||||
await config.storage.initRepo({
|
await config.storage.initRepo({
|
||||||
|
@ -241,10 +239,11 @@ async function commitFilesToBranch(
|
||||||
message,
|
message,
|
||||||
parentBranch = config.baseBranch
|
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;
|
let storage = config.storage;
|
||||||
// istanbul ignore if
|
// istanbul ignore if
|
||||||
if (config.gitFs) {
|
if (config.gitFs === 'http' || config.gitFs === 'https') {
|
||||||
storage = new Storage();
|
storage = new Storage();
|
||||||
storage.initRepo(config);
|
storage.initRepo(config);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ Object {
|
||||||
"config:js-app",
|
"config:js-app",
|
||||||
"config:js-lib",
|
"config:js-lib",
|
||||||
],
|
],
|
||||||
|
"gitFs": null,
|
||||||
"hostRules": Array [
|
"hostRules": Array [
|
||||||
Object {},
|
Object {},
|
||||||
],
|
],
|
||||||
|
@ -29,6 +30,7 @@ Object {
|
||||||
],
|
],
|
||||||
"lockFileMaintenance": Object {
|
"lockFileMaintenance": Object {
|
||||||
"automerge": true,
|
"automerge": true,
|
||||||
|
"gitFs": "https",
|
||||||
"schedule": "before 5am",
|
"schedule": "before 5am",
|
||||||
},
|
},
|
||||||
"major": Object {
|
"major": Object {
|
||||||
|
|
|
@ -11,6 +11,7 @@ describe('config/migration', () => {
|
||||||
maintainYarnLock: true,
|
maintainYarnLock: true,
|
||||||
onboarding: 'false',
|
onboarding: 'false',
|
||||||
multipleMajorPrs: true,
|
multipleMajorPrs: true,
|
||||||
|
gitFs: false,
|
||||||
separateMajorReleases: true,
|
separateMajorReleases: true,
|
||||||
separatePatchReleases: true,
|
separatePatchReleases: true,
|
||||||
automerge: 'none',
|
automerge: 'none',
|
||||||
|
@ -57,6 +58,7 @@ describe('config/migration', () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
lockFileMaintenance: {
|
lockFileMaintenance: {
|
||||||
|
gitFs: true,
|
||||||
automerge: 'any',
|
automerge: 'any',
|
||||||
schedule: 'before 5am every day',
|
schedule: 'before 5am every day',
|
||||||
},
|
},
|
||||||
|
|
|
@ -212,4 +212,29 @@ describe('platform/git/storage', () => {
|
||||||
expect(await git.getCommitMessages()).toMatchSnapshot();
|
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');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -42,6 +42,7 @@ RFC5322-compliant string if you wish to customise the git author for commits.
|
||||||
## gitFs
|
## 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.
|
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
|
## gitPrivateKey
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue