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(managers/git-submodules): support updating git-tag versions #30104

Merged
merged 6 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
12 changes: 12 additions & 0 deletions lib/modules/manager/git-submodules/__fixtures__/.gitmodules.8
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[submodule "renovate1"]
path = deps/renovate1
url = https://github.com/renovatebot/renovate.git
branch = v0.0.1
[submodule "renovate2"]
path = deps/renovate2
url = https://github.com/renovatebot/renovate.git
branch = 0.0.1
[submodule "renovate3"]
path = deps/renovate3
url = https://github.com/renovatebot/renovate.git
branch = not-a-semver
30 changes: 30 additions & 0 deletions lib/modules/manager/git-submodules/extract.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ describe('modules/manager/git-submodules/extract', () => {
it('default to master if no branch can be detected', async () => {
const res = await extractPackageFile('', '.gitmodules.2', {});
expect(res?.deps).toHaveLength(1);
expect(res?.deps[0].versioning).toBeUndefined();
expect(res?.deps[0].currentValue).toBe('master');
});

Expand Down Expand Up @@ -336,5 +337,34 @@ describe('modules/manager/git-submodules/extract', () => {
],
});
});

it('given semver version is extracted from branch and versioning is set to semver', async () => {
const res = await extractPackageFile('', '.gitmodules.8', {});
expect(res).toEqual({
datasource: 'git-refs',
deps: [
{
currentDigest: '4b825dc642cb6eb9a060e54bf8d69288fbee4904',
currentValue: 'v0.0.1',
depName: 'deps/renovate1',
packageName: 'https://github.com/renovatebot/renovate.git',
versioning: 'semver',
},
{
currentDigest: '4b825dc642cb6eb9a060e54bf8d69288fbee4904',
currentValue: '0.0.1',
depName: 'deps/renovate2',
packageName: 'https://github.com/renovatebot/renovate.git',
versioning: 'semver',
},
{
currentDigest: '4b825dc642cb6eb9a060e54bf8d69288fbee4904',
currentValue: 'not-a-semver',
packageName: 'https://github.com/renovatebot/renovate.git',
depName: 'deps/renovate3',
},
],
});
});
});
});
4 changes: 4 additions & 0 deletions lib/modules/manager/git-submodules/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { simpleGitConfig } from '../../../util/git/config';
import { getHttpUrl } from '../../../util/git/url';
import { regEx } from '../../../util/regex';
import { GitRefsDatasource } from '../../datasource/git-refs';
import * as semVerVersioning from '../../versioning/semver';
import type { ExtractConfig, PackageFileContent } from '../types';
import type { GitModule } from './types';

Expand Down Expand Up @@ -138,6 +139,9 @@ export default async function extractPackageFile(
packageName: httpSubModuleUrl,
currentValue,
currentDigest,
...(semVerVersioning.api.isVersion(currentValue)
? { versioning: semVerVersioning.id }
: {}),
});
} catch (err) /* istanbul ignore next */ {
logger.warn(
Expand Down
15 changes: 15 additions & 0 deletions lib/modules/manager/git-submodules/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@ You can customize the per-submodule checks of the git-submodules manager like th
}
```

### Updating to Specific Tag Values

If you want to update your Git submodules to a specific tag, you can set the desired tag as the `branch` in your `.gitmodules` file.
Renovate will then automatically update this version to the latest Git tag.

```ini
[submodule "renovate"]
path = deps/renovate
url = https://github.com/renovatebot/renovate.git
branch = v0.0.1
```

**Note:** Using this approach will disrupt the native git submodule update experience when using `git submodule update --remote`. You may encounter an error like `fatal: Unable to find refs/remotes/origin/v0.0.1 revision in submodule path...` because Git can only update submodules when tracking a branch.
To manually update the submodule, navigate to the submodule directory and run the following commands: `git fetch && git checkout <new tag>`.

### 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.
Expand Down
47 changes: 47 additions & 0 deletions lib/modules/manager/git-submodules/update.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import { mock } from 'jest-mock-extended';
import { SimpleGit, simpleGit } from 'simple-git';
import { DirectoryResult, dir } from 'tmp-promise';
import { join } from 'upath';
import { fs } from '../../../../test/util';
import { GlobalConfig } from '../../../config/global';
import type { RepoGlobalConfig } from '../../../config/types';
import * as hostRules from '../../../util/host-rules';
import type { Upgrade } from '../types';
import { updateDependency } from '.';
jest.mock('../../../util/fs');

jest.mock('simple-git');
const simpleGitFactoryMock = simpleGit as jest.Mock<Partial<SimpleGit>>;
Expand Down Expand Up @@ -88,6 +90,51 @@ describe('modules/manager/git-submodules/update', () => {
});
});

it('update gitmodule branch value if value changed', async () => {
gitMock.submoduleUpdate.mockResolvedValue('');
gitMock.checkout.mockResolvedValue('');
const updatedGitModules = `[submodule "renovate"]
path = deps/renovate
url = https://github.com/renovatebot/renovate.git
branch = v0.0.2`;
fs.readLocalFile.mockResolvedValueOnce(updatedGitModules);

upgrade = {
depName: 'renovate',
currentValue: 'v0.0.1',
newValue: 'v0.0.2',
packageFile: '.gitmodules',
};
const update = await updateDependency({
fileContent: '',
upgrade,
});
expect(update).toBe(updatedGitModules);
expect(gitMock.subModule).toHaveBeenCalledWith([
'set-branch',
'--branch',
'v0.0.2',
'renovate',
]);
});

it('do not update gitmodule branch value if value not changed', async () => {
gitMock.submoduleUpdate.mockResolvedValue('');
gitMock.checkout.mockResolvedValue('');
upgrade = {
depName: 'renovate',
currentValue: 'main',
newValue: 'main',
packageFile: '.gitmodules',
};
const update = await updateDependency({
fileContent: '',
upgrade,
});
expect(update).toBe('');
expect(gitMock.subModule).toHaveBeenCalledTimes(0);
});

it('returns content on update and uses git environment variables for git-tags/git-refs', async () => {
gitMock.submoduleUpdate.mockResolvedValue('');
gitMock.checkout.mockResolvedValue('');
Expand Down
11 changes: 11 additions & 0 deletions lib/modules/manager/git-submodules/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Git from 'simple-git';
import upath from 'upath';
import { GlobalConfig } from '../../../config/global';
import { logger } from '../../../logger';
import { readLocalFile } from '../../../util/fs';
import { getGitEnvironmentVariables } from '../../../util/git/auth';
import type { UpdateDependencyConfig } from '../types';

Expand All @@ -26,6 +27,16 @@ export default async function updateDependency({
try {
await git.submoduleUpdate(['--init', upgrade.depName!]);
await submoduleGit.checkout([upgrade.newDigest!]);
if (upgrade.newValue && upgrade.currentValue !== upgrade.newValue) {
await git.subModule([
'set-branch',
'--branch',
upgrade.newValue,
upgrade.depName!,
]);
const updatedPackageContent = await readLocalFile(upgrade.packageFile!);
return updatedPackageContent!.toString();
Shegox marked this conversation as resolved.
Show resolved Hide resolved
}
return fileContent;
Shegox marked this conversation as resolved.
Show resolved Hide resolved
} catch (err) {
logger.debug({ err }, 'submodule checkout error');
Expand Down