Skip to content

Commit

Permalink
fix(gomod): Do not tidy go.mod on major update without gomodUpdateImp…
Browse files Browse the repository at this point in the history
…ortPaths (#11976)

Co-authored-by: Rhys Arkins <rhys@arkins.net>
  • Loading branch information
at-wat and rarkins committed Oct 20, 2021
1 parent 9f08a79 commit 72d50cc
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 18 deletions.
2 changes: 1 addition & 1 deletion docs/usage/configuration-options.md
Expand Up @@ -1680,7 +1680,7 @@ Though this option is enabled by default, you can fine tune the behavior by sett

## postUpdateOptions

- `gomodTidy`: Run `go mod tidy` after Go module updates. This is implicitly enabled for major module updates.
- `gomodTidy`: Run `go mod tidy` after Go module updates. This is implicitly enabled for major module updates when `gomodUpdateImportPaths` is enabled
- `gomodUpdateImportPaths`: Update source import paths on major module updates, using [mod](https://github.com/marwan-at-work/mod)
- `npmDedupe`: Run `npm dedupe` after `package-lock.json` updates
- `yarnDedupeFewer`: Run `yarn-deduplicate --strategy fewer` after `yarn.lock` updates
Expand Down
2 changes: 1 addition & 1 deletion docs/usage/golang.md
Expand Up @@ -16,7 +16,7 @@ Renovate supports upgrading dependencies in `go.mod` files and their accompanyin
1. Renovate runs `go get` to update the `go.sum` files
1. If the user has enabled the option `gomodUpdateImportPaths` in the [`postUpdateOptions`](https://docs.renovatebot.com/configuration-options/#postupdateoptions) array, then Renovate uses [mod](https://github.com/marwan-at-work/mod) to update import paths on major updates, which can update any Go source file
1. If the user has enabled the option `gomodTidy` in the [`postUpdateOptions`](https://docs.renovatebot.com/configuration-options/#postupdateoptions) array, then Renovate runs `go mod tidy`, which itself can update `go.mod` and `go.sum`.
1. This is implicitly enabled for major updates
1. This is implicitly enabled for major updates if the user has enabled the option `gomodUpdateImportPaths` in the [`postUpdateOptions`](https://docs.renovatebot.com/configuration-options/#postupdateoptions) array
1. `go mod vendor` is run if vendored modules are detected
1. A PR will be created with `go.mod`,`go.sum`, and any updated vendored files updated in the one commit
1. If the source repository has either a "changelog" file or uses GitHub releases, then Release Notes for each version will be embedded in the generated PR
Expand Down
70 changes: 57 additions & 13 deletions lib/manager/gomod/__snapshots__/artifacts.spec.ts.snap
Expand Up @@ -2,9 +2,24 @@

exports[`manager/gomod/artifacts catches errors 1`] = `Array []`;

exports[`manager/gomod/artifacts returns if no go.sum found 1`] = `Array []`;
exports[`manager/gomod/artifacts does not execute go mod tidy when none of gomodTidy and gomodUpdateImportPaths are set 1`] = `
Array [
Object {
"file": Object {
"contents": "New go.sum",
"name": "go.sum",
},
},
Object {
"file": Object {
"contents": "New main.go",
"name": "go.mod",
},
},
]
`;

exports[`manager/gomod/artifacts returns null if unchanged 1`] = `
exports[`manager/gomod/artifacts does not execute go mod tidy when none of gomodTidy and gomodUpdateImportPaths are set 2`] = `
Array [
Object {
"cmd": "go get -d ./...",
Expand Down Expand Up @@ -34,7 +49,9 @@ Array [
]
`;

exports[`manager/gomod/artifacts returns updated go.sum 1`] = `
exports[`manager/gomod/artifacts returns if no go.sum found 1`] = `Array []`;

exports[`manager/gomod/artifacts returns null if unchanged 1`] = `
Array [
Object {
"cmd": "go get -d ./...",
Expand Down Expand Up @@ -64,7 +81,7 @@ Array [
]
`;

exports[`manager/gomod/artifacts skips updating import paths for gopkg.in dependencies 1`] = `
exports[`manager/gomod/artifacts returns updated go.sum 1`] = `
Array [
Object {
"cmd": "go get -d ./...",
Expand All @@ -91,8 +108,30 @@ Array [
"timeout": 900000,
},
},
]
`;

exports[`manager/gomod/artifacts skips gomodTidy without gomodUpdateImportPaths on major update 1`] = `
Array [
Object {
"cmd": "go mod tidy",
"file": Object {
"contents": "New go.sum",
"name": "go.sum",
},
},
Object {
"file": Object {
"contents": "New main.go",
"name": "go.mod",
},
},
]
`;

exports[`manager/gomod/artifacts skips gomodTidy without gomodUpdateImportPaths on major update 2`] = `
Array [
Object {
"cmd": "go get -d ./...",
"options": Object {
"cwd": "/tmp/github/some/repo",
"encoding": "utf-8",
Expand All @@ -116,8 +155,13 @@ Array [
"timeout": 900000,
},
},
]
`;

exports[`manager/gomod/artifacts skips updating import paths for gopkg.in dependencies 1`] = `
Array [
Object {
"cmd": "go mod tidy",
"cmd": "go get -d ./...",
"options": Object {
"cwd": "/tmp/github/some/repo",
"encoding": "utf-8",
Expand All @@ -141,13 +185,8 @@ Array [
"timeout": 900000,
},
},
]
`;

exports[`manager/gomod/artifacts skips updating import paths with gomodUpdateImportPaths on v0 to v1 1`] = `
Array [
Object {
"cmd": "go get -d ./...",
"cmd": "go mod tidy",
"options": Object {
"cwd": "/tmp/github/some/repo",
"encoding": "utf-8",
Expand Down Expand Up @@ -196,8 +235,13 @@ Array [
"timeout": 900000,
},
},
]
`;

exports[`manager/gomod/artifacts skips updating import paths with gomodUpdateImportPaths on v0 to v1 1`] = `
Array [
Object {
"cmd": "go mod tidy",
"cmd": "go get -d ./...",
"options": Object {
"cwd": "/tmp/github/some/repo",
"encoding": "utf-8",
Expand Down
51 changes: 51 additions & 0 deletions lib/manager/gomod/artifacts.spec.ts
Expand Up @@ -318,6 +318,57 @@ describe('manager/gomod/artifacts', () => {
]);
expect(execSnapshots).toMatchSnapshot();
});
it('skips gomodTidy without gomodUpdateImportPaths on major update', async () => {
fs.readFile.mockResolvedValueOnce('Current go.sum' as any);
fs.readFile.mockResolvedValueOnce(null as any); // vendor modules filename
const execSnapshots = mockExecAll(exec);
git.getRepoStatus.mockResolvedValueOnce({
modified: ['go.sum', 'main.go'],
} as StatusResult);
fs.readFile
.mockResolvedValueOnce('New go.sum' as any)
.mockResolvedValueOnce('New main.go' as any)
.mockResolvedValueOnce('New go.mod' as any);
expect(
await gomod.updateArtifacts({
packageFileName: 'go.mod',
updatedDeps: [{ depName: 'github.com/google/go-github/v24' }],
newPackageFileContent: gomod1,
config: {
...config,
updateType: 'major',
newMajor: 28,
postUpdateOptions: ['gomodTidy'],
},
})
).toMatchSnapshot();
expect(execSnapshots).toMatchSnapshot();
});
it('does not execute go mod tidy when none of gomodTidy and gomodUpdateImportPaths are set', async () => {
fs.readFile.mockResolvedValueOnce('Current go.sum' as any);
fs.readFile.mockResolvedValueOnce(null as any); // vendor modules filename
const execSnapshots = mockExecAll(exec);
git.getRepoStatus.mockResolvedValueOnce({
modified: ['go.sum', 'main.go'],
} as StatusResult);
fs.readFile
.mockResolvedValueOnce('New go.sum' as any)
.mockResolvedValueOnce('New main.go' as any)
.mockResolvedValueOnce('New go.mod' as any);
expect(
await gomod.updateArtifacts({
packageFileName: 'go.mod',
updatedDeps: [{ depName: 'github.com/google/go-github/v24' }],
newPackageFileContent: gomod1,
config: {
...config,
updateType: 'major',
newMajor: 28,
},
})
).toMatchSnapshot();
expect(execSnapshots).toMatchSnapshot();
});
it('updates import paths with specific tool version from constraint', async () => {
fs.readFile.mockResolvedValueOnce('Current go.sum' as any);
fs.readFile.mockResolvedValueOnce(null as any); // vendor modules filename
Expand Down
12 changes: 10 additions & 2 deletions lib/manager/gomod/artifacts.ts
Expand Up @@ -159,9 +159,17 @@ export async function updateArtifacts({
}
}

const isGoModTidyRequired =
config.postUpdateOptions?.includes('gomodTidy') ||
const mustSkipGoModTidy =
!config.postUpdateOptions?.includes('gomodUpdateImportPaths') &&
config.updateType === 'major';
if (mustSkipGoModTidy) {
logger.debug({ cmd, args }, 'go mod tidy command skipped');
}

const isGoModTidyRequired =
!mustSkipGoModTidy &&
(config.postUpdateOptions?.includes('gomodTidy') ||
(config.updateType === 'major' && isImportPathUpdateRequired));
if (isGoModTidyRequired) {
args = 'mod tidy';
logger.debug({ cmd, args }, 'go mod tidy command included');
Expand Down
2 changes: 1 addition & 1 deletion lib/manager/gomod/readme.md
@@ -1,7 +1,7 @@
You might be interested in the following `postUpdateOptions`:

1. `gomodTidy` - if you'd like Renovate to run `go mod tidy` after every update before raising the PR.
1. This is implicitly enabled for major updates
1. This is implicitly enabled for major updates if the user has enabled the option `gomodUpdateImportPaths`
1. `gomodUpdateImportPaths` - if you'd like Renovate to update your source import paths on major updates before raising the PR.

When Renovate is running using `binarySource=docker` (such as in the hosted WhiteSource Renovate app) then it will pick the latest compatible version of Go to run, i.e. the latest `1.x` release.
Expand Down

0 comments on commit 72d50cc

Please sign in to comment.