Skip to content

Commit

Permalink
feat: gitUrl global option (#11221)
Browse files Browse the repository at this point in the history
  • Loading branch information
mbrandau committed Aug 20, 2021
1 parent 95f56eb commit 7e425e6
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 29 deletions.
10 changes: 10 additions & 0 deletions docs/usage/self-hosted-configuration.md
Expand Up @@ -238,6 +238,16 @@ Before the first commit in a repository, Renovate will:
The `git` commands are run locally in the cloned repo instead of globally.
This reduces the chance of unintended consequences with global Git configs on shared systems.

## gitUrl

Override the default resolution for git remote, e.g. to switch GitLab from HTTPS to SSH-based. Currently works for GitLab only.

Possible values:

- `default`: use HTTP URLs provided by the platform for Git
- `ssh`: use SSH URLs provided by the platform for Git
- `endpoint`: ignore URLs provided by the platform and use the configured endpoint directly

## logContext

`logContext` is included with each log entry only if `logFormat="json"` - it is not included in the pretty log output.
Expand Down
4 changes: 0 additions & 4 deletions docs/usage/self-hosted-experimental.md
Expand Up @@ -14,10 +14,6 @@ We do not follow Semantic Versioning for any experimental variables.
These variables may be removed or have their behavior changed in **any** version.
We will try to keep breakage to a minimum, but make no guarantees that a experimental variable will keep working.

## GITLAB_IGNORE_REPO_URL

If set to any value, Renovate will ignore the Project's `http_url_to_repo` value and instead construct the Git URL manually.

## RENOVATE_CACHE_NPM_MINUTES

If set to any integer, Renovate will use this integer instead of the default npm cache time (15 minutes) for the npm datasource.
Expand Down
10 changes: 10 additions & 0 deletions lib/config/options/index.ts
Expand Up @@ -2030,6 +2030,16 @@ const options: RenovateOptions[] = [
type: 'boolean',
default: true,
},
{
name: 'gitUrl',
description:
'Overrides the default resolution for git remote, e.g. to switch GitLab from HTTPS to SSH-based.',
type: 'string',
allowedValues: ['default', 'ssh', 'endpoint'],
default: 'default',
stage: 'repository',
globalOnly: true,
},
];

export function getOptions(): RenovateOptions[] {
Expand Down
1 change: 1 addition & 0 deletions lib/constants/error-messages.ts
Expand Up @@ -15,6 +15,7 @@ export const CONFIG_VALIDATION = 'config-validation';
export const CONFIG_PRESETS_INVALID = 'config-presets-invalid';
export const CONFIG_SECRETS_EXPOSED = 'config-secrets-exposed';
export const CONFIG_SECRETS_INVALID = 'config-secrets-invalid';
export const CONFIG_GIT_URL_UNAVAILABLE = 'config-git-url-unavailable';

// Repository Errors - causes repo to be considered as disabled
export const REPOSITORY_ACCESS_FORBIDDEN = 'forbidden';
Expand Down
33 changes: 33 additions & 0 deletions lib/platform/gitlab/__snapshots__/index.spec.ts.snap
Expand Up @@ -2653,6 +2653,39 @@ Array [
]
`;

exports[`platform/gitlab/index initRepo should use ssh_url_to_repo if gitUrl is set to ssh 1`] = `
Array [
Object {
"headers": Object {
"accept": "application/json",
"accept-encoding": "gzip, deflate, br",
"authorization": "Bearer abc123",
"host": "gitlab.com",
"user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)",
},
"method": "GET",
"url": "https://gitlab.com/api/v4/projects/some%2Frepo%2Fproject",
},
]
`;

exports[`platform/gitlab/index initRepo should use ssh_url_to_repo if gitUrl is set to ssh 2`] = `
Array [
Array [
Object {
"cloneSubmodules": undefined,
"defaultBranch": "master",
"gitAuthorEmail": undefined,
"gitAuthorName": undefined,
"ignorePrAuthor": undefined,
"mergeMethod": "merge",
"repository": "some%2Frepo%2Fproject",
"url": "ssh://git@gitlab.com/some%2Frepo%2Fproject.git",
},
],
]
`;

exports[`platform/gitlab/index initRepo should fall back respecting when GITLAB_IGNORE_REPO_URL is set 1`] = `
Array [
Array [
Expand Down
17 changes: 17 additions & 0 deletions lib/platform/gitlab/index.spec.ts
Expand Up @@ -285,6 +285,23 @@ describe('platform/gitlab/index', () => {
expect(httpMock.getTrace()).toMatchSnapshot();
});

it('should use ssh_url_to_repo if gitUrl is set to ssh', async () => {
httpMock
.scope(gitlabApiHost)
.get('/api/v4/projects/some%2Frepo%2Fproject')
.reply(200, {
default_branch: 'master',
http_url_to_repo: `https://gitlab.com/some%2Frepo%2Fproject.git`,
ssh_url_to_repo: `ssh://git@gitlab.com/some%2Frepo%2Fproject.git`,
});
await gitlab.initRepo({
repository: 'some/repo/project',
gitUrl: 'ssh',
});
expect(httpMock.getTrace()).toMatchSnapshot();
expect(git.initRepo.mock.calls).toMatchSnapshot();
});

it('should fall back respecting when GITLAB_IGNORE_REPO_URL is set', async () => {
process.env.GITLAB_IGNORE_REPO_URL = 'true';
const selfHostedUrl = 'http://mycompany.com/gitlab';
Expand Down
79 changes: 54 additions & 25 deletions lib/platform/gitlab/index.ts
Expand Up @@ -4,6 +4,7 @@ import delay from 'delay';
import pAll from 'p-all';
import { lt } from 'semver';
import {
CONFIG_GIT_URL_UNAVAILABLE,
PLATFORM_AUTHENTICATION_ERROR,
REPOSITORY_ACCESS_FORBIDDEN,
REPOSITORY_ARCHIVED,
Expand All @@ -30,6 +31,7 @@ import type {
EnsureCommentRemovalConfig,
EnsureIssueConfig,
FindPRConfig,
GitUrlOption,
Issue,
MergePRConfig,
PlatformParams,
Expand Down Expand Up @@ -162,11 +164,62 @@ export async function getJsonFile(
return JSON.parse(raw);
}

function getRepoUrl(
repository: string,
gitUrl: GitUrlOption | undefined,
res: HttpResponse<RepoResponse>
): string {
if (gitUrl === 'ssh') {
if (!res.body.ssh_url_to_repo) {
throw new Error(CONFIG_GIT_URL_UNAVAILABLE);
}
logger.debug({ url: res.body.ssh_url_to_repo }, `using ssh URL`);
return res.body.ssh_url_to_repo;
}

const opts = hostRules.find({
hostType: defaults.hostType,
url: defaults.endpoint,
});

if (
gitUrl === 'endpoint' ||
process.env.GITLAB_IGNORE_REPO_URL ||
res.body.http_url_to_repo === null
) {
if (res.body.http_url_to_repo === null) {
logger.debug('no http_url_to_repo found. Falling back to old behaviour.');
}
if (process.env.GITLAB_IGNORE_REPO_URL) {
logger.warn(
'GITLAB_IGNORE_REPO_URL environment variable is deprecated. Please use "gitUrl" option.'
);
}

const { protocol, host, pathname } = parseUrl(defaults.endpoint);
const newPathname = pathname.slice(0, pathname.indexOf('/api'));
const url = URL.format({
protocol: protocol.slice(0, -1) || 'https',
auth: 'oauth2:' + opts.token,
host,
pathname: newPathname + '/' + repository + '.git',
});
logger.debug({ url }, 'using URL based on configured endpoint');
return url;
}

logger.debug({ url: res.body.http_url_to_repo }, `using http URL`);
const repoUrl = URL.parse(`${res.body.http_url_to_repo}`);
repoUrl.auth = 'oauth2:' + opts.token;
return URL.format(repoUrl);
}

// Initialize GitLab by getting base branch
export async function initRepo({
repository,
cloneSubmodules,
ignorePrAuthor,
gitUrl,
}: RepoParams): Promise<RepoResult> {
config = {} as any;
config.repository = urlEscape(repository);
Expand Down Expand Up @@ -220,31 +273,7 @@ export async function initRepo({
logger.debug(`${repository} default branch = ${config.defaultBranch}`);
delete config.prList;
logger.debug('Enabling Git FS');
const opts = hostRules.find({
hostType: defaults.hostType,
url: defaults.endpoint,
});
let url: string;
if (
process.env.GITLAB_IGNORE_REPO_URL ||
res.body.http_url_to_repo === null
) {
logger.debug('no http_url_to_repo found. Falling back to old behaviour.');
const { protocol, host, pathname } = parseUrl(defaults.endpoint);
const newPathname = pathname.slice(0, pathname.indexOf('/api'));
url = URL.format({
protocol: protocol.slice(0, -1) || 'https',
auth: 'oauth2:' + opts.token,
host,
pathname: newPathname + '/' + repository + '.git',
});
logger.debug({ url }, 'using URL based on configured endpoint');
} else {
logger.debug(`${repository} http URL = ${res.body.http_url_to_repo}`);
const repoUrl = URL.parse(`${res.body.http_url_to_repo}`);
repoUrl.auth = 'oauth2:' + opts.token;
url = URL.format(repoUrl);
}
const url = getRepoUrl(repository, gitUrl, res);
await git.initRepo({
...config,
url,
Expand Down
1 change: 1 addition & 0 deletions lib/platform/gitlab/types.ts
Expand Up @@ -47,6 +47,7 @@ export interface RepoResponse {
mirror: boolean;
default_branch: string;
empty_repo: boolean;
ssh_url_to_repo: string;
http_url_to_repo: string;
forked_from_project: boolean;
repository_access_level: 'disabled' | 'private' | 'enabled';
Expand Down
3 changes: 3 additions & 0 deletions lib/platform/types.ts
Expand Up @@ -27,9 +27,12 @@ export interface RepoResult {
isFork: boolean;
}

export type GitUrlOption = 'default' | 'ssh' | 'endpoint';

export interface RepoParams {
repository: string;
endpoint?: string;
gitUrl?: GitUrlOption;
forkMode?: string;
forkToken?: string;
includeForks?: boolean;
Expand Down

0 comments on commit 7e425e6

Please sign in to comment.