Skip to content
Snippets Groups Projects
Unverified Commit 01ee73c2 authored by Tobias's avatar Tobias Committed by GitHub
Browse files

feat(manager/git-submodule): add authentication support (#22061)


Co-authored-by: default avatarRhys Arkins <rhys@arkins.net>
parent d9a24c5d
No related branches found
No related tags found
No related merge requests found
......@@ -57,6 +57,29 @@ describe('modules/manager/git-submodules/extract', () => {
expect(res?.deps[0].currentValue).toBe('main');
});
it('default branch is detected with using git environment variables when no branch is specified', async () => {
gitMock.listRemote.mockResolvedValueOnce(
'ref: refs/heads/main HEAD\n5701164b9f5edba1f6ca114c491a564ffb55a964 HEAD'
);
hostRules.add({
hostType: 'github',
matchHost: 'github.com',
token: 'abc123',
});
const res = await extractPackageFile('', '.gitmodules.2', {});
expect(res?.deps).toHaveLength(1);
expect(res?.deps[0].currentValue).toBe('main');
expect(gitMock.env).toHaveBeenCalledWith({
GIT_CONFIG_COUNT: '3',
GIT_CONFIG_KEY_0: 'url.https://ssh:abc123@github.com/.insteadOf',
GIT_CONFIG_KEY_1: 'url.https://git:abc123@github.com/.insteadOf',
GIT_CONFIG_KEY_2: 'url.https://abc123@github.com/.insteadOf',
GIT_CONFIG_VALUE_0: 'ssh://git@github.com/',
GIT_CONFIG_VALUE_1: 'git@github.com:',
GIT_CONFIG_VALUE_2: 'https://github.com/',
});
});
it('default to master if no branch can be detected', async () => {
const res = await extractPackageFile('', '.gitmodules.2', {});
expect(res?.deps).toHaveLength(1);
......
......@@ -4,6 +4,7 @@ import upath from 'upath';
import { GlobalConfig } from '../../../config/global';
import { logger } from '../../../logger';
import { detectPlatform } from '../../../util/common';
import { getGitEnvironmentVariables } from '../../../util/git/auth';
import { simpleGitConfig } from '../../../util/git/config';
import { getHttpUrl, getRemoteUrlWithToken } from '../../../util/git/url';
import { regEx } from '../../../util/regex';
......@@ -37,11 +38,16 @@ async function getUrl(
const headRefRe = regEx(/ref: refs\/heads\/(?<branch>\w+)\s/);
async function getDefaultBranch(subModuleUrl: string): Promise<string> {
const val = await Git(simpleGitConfig()).listRemote([
'--symref',
subModuleUrl,
'HEAD',
]);
const gitSubmoduleAuthEnvironmentVariables = getGitEnvironmentVariables();
const gitEnv = {
// pass all existing env variables
...process.env,
// add all known git Variables
...gitSubmoduleAuthEnvironmentVariables,
};
const val = await Git(simpleGitConfig())
.env(gitEnv)
.listRemote(['--symref', subModuleUrl, 'HEAD']);
return headRefRe.exec(val)?.groups?.branch ?? 'master';
}
......
Keeps publicly accessible Git submodules updated within a repository.
Renovate does not support updating Git submodules that are hosted on a private repository.
Subscribe to [issue #10149 on GitHub](https://github.com/renovatebot/renovate/issues/10149) to keep track of our progress towards supporting private Git submodules.
Keeps Git submodules updated within a repository.
You can customize the per-submodule checks of the git-submodules manager like this:
......@@ -13,3 +10,19 @@ You can customize the per-submodule checks of the git-submodules manager like th
}
}
```
### Private Modules Authentication
Before running the `git` commands to update the submodules, Renovate exports `git` [`insteadOf`](https://git-scm.com/docs/git-config#Documentation/git-config.txt-urlltbasegtinsteadOf) directives in environment variables.
The following logic is executed prior to "submodules" updating:
The token from the `hostRules` entry matching `hostType=github` and `matchHost=api.github.com` is added as the default authentication for `github.com`.
For those running against `github.com`, this token will be the default platform token.
Next, all `hostRules` with both a token and `matchHost` will be fetched, except for any github.com one from above.
Rules from this list are converted to environment variable directives if they match _any_ of the following characteristics:
- No `hostType` is defined, or
- `hostType` is a platform (`github`, `gitlab`, `azure`, etc.)
......@@ -62,5 +62,30 @@ describe('modules/manager/git-submodules/update', () => {
});
expect(update).toBe('');
});
it('returns content on update and uses git environment variables', async () => {
gitMock.submoduleUpdate.mockResolvedValue('');
gitMock.checkout.mockResolvedValue('');
hostRules.add({
hostType: 'github',
matchHost: 'github.com',
token: 'abc123',
});
const update = await updateDependency({
fileContent: '',
upgrade,
});
expect(update).toBe('');
expect(gitMock.env).toHaveBeenCalledWith({
GIT_CONFIG_COUNT: '3',
GIT_CONFIG_KEY_0: 'url.https://ssh:abc123@github.com/.insteadOf',
GIT_CONFIG_KEY_1: 'url.https://git:abc123@github.com/.insteadOf',
GIT_CONFIG_KEY_2: 'url.https://abc123@github.com/.insteadOf',
GIT_CONFIG_VALUE_0: 'ssh://git@github.com/',
GIT_CONFIG_VALUE_1: 'git@github.com:',
GIT_CONFIG_VALUE_2: 'https://github.com/',
});
});
});
});
......@@ -2,6 +2,7 @@ import Git from 'simple-git';
import upath from 'upath';
import { GlobalConfig } from '../../../config/global';
import { logger } from '../../../logger';
import { getGitEnvironmentVariables } from '../../../util/git/auth';
import type { UpdateDependencyConfig } from '../types';
export default async function updateDependency({
......@@ -9,7 +10,14 @@ export default async function updateDependency({
upgrade,
}: UpdateDependencyConfig): Promise<string | null> {
const localDir = GlobalConfig.get('localDir');
const git = Git(localDir);
const gitSubmoduleAuthEnvironmentVariables = getGitEnvironmentVariables();
const gitEnv = {
// pass all existing env variables
...process.env,
// add all known git Variables
...gitSubmoduleAuthEnvironmentVariables,
};
const git = Git(localDir).env(gitEnv);
const submoduleGit = Git(upath.join(localDir, upgrade.depName));
try {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment