Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(git): insteadOf environment variables for authentication #11077

Merged
merged 5 commits into from
Oct 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/usage/getting-started/private-packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ Any `hostRules` with `hostType=packagist` are also included.

### gomod

If a `github.com` token is found in `hostRules`, then it is written out to local git config prior to running `go` commands.
The command run is `git config --global url."https://${token}@github.com/".insteadOf "https://github.com/"`.
If a `github.com` token is found in `hostRules`, then it is written out to local [GIT*CONFIG*](https://git-scm.com/docs/git-config#Documentation/git-config.txt-GITCONFIGCOUNT) variables prior to running `go` commands.
The environment variables used are: `GIT_CONFIG_KEY_0=url.https://${token}@github.com/.insteadOf GIT_CONFIG_VALUE_0=https://github.com/ GIT_CONFIG_COUNT=1`.

### npm

Expand Down
5 changes: 4 additions & 1 deletion lib/manager/gomod/__snapshots__/artifacts.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -239,12 +239,15 @@ Array [
},
},
Object {
"cmd": "docker run --rm --name=renovate_go --label=renovate_child -v \\"/tmp/github/some/repo\\":\\"/tmp/github/some/repo\\" -v \\"/tmp/renovate/cache\\":\\"/tmp/renovate/cache\\" -e GOPATH -e GOPROXY -e GOPRIVATE -e GONOPROXY -e GONOSUMDB -e GOFLAGS -e CGO_ENABLED -w \\"/tmp/github/some/repo\\" renovate/go:latest bash -l -c \\"git config --global url.\\\\\\"https://some-token@github.com/\\\\\\".insteadOf \\\\\\"https://github.com/\\\\\\" && go get -d ./...\\"",
"cmd": "docker run --rm --name=renovate_go --label=renovate_child -v \\"/tmp/github/some/repo\\":\\"/tmp/github/some/repo\\" -v \\"/tmp/renovate/cache\\":\\"/tmp/renovate/cache\\" -e GOPATH -e GOPROXY -e GOPRIVATE -e GONOPROXY -e GONOSUMDB -e GOFLAGS -e CGO_ENABLED -e GIT_CONFIG_KEY_0 -e GIT_CONFIG_VALUE_0 -e GIT_CONFIG_COUNT -w \\"/tmp/github/some/repo\\" renovate/go:latest bash -l -c \\"go get -d ./...\\"",
"options": Object {
"cwd": "/tmp/github/some/repo",
"encoding": "utf-8",
"env": Object {
"CGO_ENABLED": "1",
"GIT_CONFIG_COUNT": "1",
"GIT_CONFIG_KEY_0": "url.https://some-token@github.com/.insteadOf",
"GIT_CONFIG_VALUE_0": "https://github.com/",
"GOFLAGS": "-modcacherw",
"GONOPROXY": "noproxy.example.com/*",
"GONOSUMDB": "1",
Expand Down
21 changes: 12 additions & 9 deletions lib/manager/gomod/artifacts.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import is from '@sindresorhus/is';
import { quote } from 'shlex';
import { dirname, join } from 'upath';
import { getGlobalConfig } from '../../config/global';
import { PlatformId } from '../../constants';
Expand All @@ -8,6 +7,7 @@ import { logger } from '../../logger';
import { ExecOptions, exec } from '../../util/exec';
import { ensureCacheDir, readLocalFile, writeLocalFile } from '../../util/fs';
import { getRepoStatus } from '../../util/git';
import { getGitAuthenticatedEnvironmentVariables } from '../../util/git/auth';
import { find } from '../../util/host-rules';
import { regEx } from '../../util/regex';
import { isValid } from '../../versioning/semver';
Expand All @@ -18,19 +18,22 @@ import type {
UpdateArtifactsResult,
} from '../types';

function getPreCommands(): string[] | null {
function getGitEnvironmentVariables(): NodeJS.ProcessEnv {
let environmentVariables: NodeJS.ProcessEnv = {};

const credentials = find({
hostType: PlatformId.Github,
url: 'https://api.github.com/',
});
let preCommands = null;

if (credentials?.token) {
const token = quote(credentials.token);
preCommands = [
`git config --global url.\"https://${token}@github.com/\".insteadOf \"https://github.com/\"`, // eslint-disable-line no-useless-escape
];
environmentVariables = getGitAuthenticatedEnvironmentVariables(
'https://github.com/',
credentials.token
);
}
return preCommands;

return environmentVariables;
}

function getUpdateImportPathCmds(
Expand Down Expand Up @@ -127,12 +130,12 @@ export async function updateArtifacts({
GONOSUMDB: process.env.GONOSUMDB,
GOFLAGS: useModcacherw(config.constraints?.go) ? '-modcacherw' : null,
CGO_ENABLED: getGlobalConfig().binarySource === 'docker' ? '0' : null,
...getGitEnvironmentVariables(),
},
docker: {
image: 'go',
tagConstraint: config.constraints?.go,
tagScheme: 'npm',
preCommands: getPreCommands(),
},
};

Expand Down
106 changes: 106 additions & 0 deletions lib/util/git/auth.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { getGitAuthenticatedEnvironmentVariables } from './auth';

describe('util/git/auth', () => {
afterEach(() => {
delete process.env.GIT_CONFIG_COUNT;
});
describe('getGitAuthenticatedEnvironmentVariables()', () => {
it('returns url with token', () => {
expect(
getGitAuthenticatedEnvironmentVariables(
'https://github.com/',
'token1234'
)
).toStrictEqual({
GIT_CONFIG_KEY_0: 'url.https://token1234@github.com/.insteadOf',
GIT_CONFIG_VALUE_0: 'https://github.com/',
GIT_CONFIG_COUNT: '1',
});
});

it('returns url with correctly encoded token', () => {
expect(
getGitAuthenticatedEnvironmentVariables(
'https://github.com/',
'token:1234'
)
).toStrictEqual({
GIT_CONFIG_KEY_0: 'url.https://token%3A1234@github.com/.insteadOf',
GIT_CONFIG_VALUE_0: 'https://github.com/',
GIT_CONFIG_COUNT: '1',
});
});

it('returns url with token and already existing GIT_CONFIG_COUNT from parameter', () => {
expect(
getGitAuthenticatedEnvironmentVariables(
'https://github.com/',
'token1234',
{ GIT_CONFIG_COUNT: '1' }
)
).toStrictEqual({
GIT_CONFIG_KEY_1: 'url.https://token1234@github.com/.insteadOf',
GIT_CONFIG_VALUE_1: 'https://github.com/',
GIT_CONFIG_COUNT: '2',
});
});

it('returns url with token and already existing GIT_CONFIG_COUNT from parameter over environment', () => {
process.env.GIT_CONFIG_COUNT = '54';
expect(
getGitAuthenticatedEnvironmentVariables(
'https://github.com/',
'token1234',
{ GIT_CONFIG_COUNT: '1' }
)
).toStrictEqual({
GIT_CONFIG_KEY_1: 'url.https://token1234@github.com/.insteadOf',
GIT_CONFIG_VALUE_1: 'https://github.com/',
GIT_CONFIG_COUNT: '2',
});
});

it('returns url with token and already existing GIT_CONFIG_COUNT from environment', () => {
process.env.GIT_CONFIG_COUNT = '1';
expect(
getGitAuthenticatedEnvironmentVariables(
'https://github.com/',
'token1234'
)
).toStrictEqual({
GIT_CONFIG_KEY_1: 'url.https://token1234@github.com/.insteadOf',
GIT_CONFIG_VALUE_1: 'https://github.com/',
GIT_CONFIG_COUNT: '2',
});
});

it('returns url with token and passthrough existing variables', () => {
expect(
getGitAuthenticatedEnvironmentVariables(
'https://github.com/',
'token1234',
{ RANDOM_VARIABLE: 'random' }
)
).toStrictEqual({
GIT_CONFIG_KEY_0: 'url.https://token1234@github.com/.insteadOf',
GIT_CONFIG_VALUE_0: 'https://github.com/',
GIT_CONFIG_COUNT: '1',
RANDOM_VARIABLE: 'random',
});
});

it('return url with token with invalid GIT_CONFIG_COUNT from environment', () => {
process.env.GIT_CONFIG_COUNT = 'notvalid';
expect(
getGitAuthenticatedEnvironmentVariables(
'https://github.com/',
'token1234'
)
).toStrictEqual({
GIT_CONFIG_KEY_0: 'url.https://token1234@github.com/.insteadOf',
GIT_CONFIG_VALUE_0: 'https://github.com/',
GIT_CONFIG_COUNT: '1',
});
});
});
});
40 changes: 40 additions & 0 deletions lib/util/git/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { logger } from '../../logger';
import { getHttpUrl } from './url';

/*
Add authorization to a Git Url and returns the updated environment variables
*/
export function getGitAuthenticatedEnvironmentVariables(
gitUrl: string,
token: string,
environmentVariables?: NodeJS.ProcessEnv
Shegox marked this conversation as resolved.
Show resolved Hide resolved
): NodeJS.ProcessEnv {
// check if the environmentVariables already contain a GIT_CONFIG_COUNT or if the process has one
const gitConfigCountEnvVariable =
environmentVariables?.GIT_CONFIG_COUNT || process.env.GIT_CONFIG_COUNT;
let gitConfigCount = 0;
if (gitConfigCountEnvVariable) {
// passthrough the gitConfigCountEnvVariable environment variable as start value of the index count
gitConfigCount = parseInt(gitConfigCountEnvVariable, 10);
if (Number.isNaN(gitConfigCount)) {
logger.warn(
`Found GIT_CONFIG_COUNT env variable, but couldn't parse the value to an integer: ${process.env.GIT_CONFIG_COUNT}. Ignoring it.`
);
gitConfigCount = 0;
}
}

const gitUrlWithToken = getHttpUrl(gitUrl, encodeURIComponent(token));
Shegox marked this conversation as resolved.
Show resolved Hide resolved

// create a shallow copy of the environmentVariables as base so we don't modify the input parameter object
// add the two new config key and value to the returnEnvironmentVariables object
// increase the CONFIG_COUNT by one and add it to the object
const returnEnvironmentVariables = {
...environmentVariables,
[`GIT_CONFIG_KEY_${gitConfigCount}`]: `url.${gitUrlWithToken}.insteadOf`,
[`GIT_CONFIG_VALUE_${gitConfigCount}`]: gitUrl,
GIT_CONFIG_COUNT: (gitConfigCount + 1).toString(),
};

return returnEnvironmentVariables;
}