diff --git a/lib/manager/gomod/__snapshots__/artifacts.spec.ts.snap b/lib/manager/gomod/__snapshots__/artifacts.spec.ts.snap index d524642ff16a022827d55b05fd492527a1c21ad2..7ee74cb187c32aef3d6280b1f2b1cc6b3835b4aa 100644 --- a/lib/manager/gomod/__snapshots__/artifacts.spec.ts.snap +++ b/lib/manager/gomod/__snapshots__/artifacts.spec.ts.snap @@ -23,7 +23,10 @@ Array [ "cwd": "/tmp/github/some/repo", "encoding": "utf-8", "env": Object { + "CGO_ENABLED": "1", + "GONOSUMDB": "1", "GOPATH": "/tmp/renovate/cache/others/go", + "GOPROXY": "proxy.example.com", "HOME": "/home/user", "HTTPS_PROXY": "https://example.com", "HTTP_PROXY": "http://example.com", @@ -45,7 +48,10 @@ Array [ "cwd": "/tmp/github/some/repo", "encoding": "utf-8", "env": Object { + "CGO_ENABLED": "1", + "GONOSUMDB": "1", "GOPATH": "/tmp/renovate/cache/others/go", + "GOPROXY": "proxy.example.com", "HOME": "/home/user", "HTTPS_PROXY": "https://example.com", "HTTP_PROXY": "http://example.com", @@ -62,12 +68,21 @@ Array [ exports[`.updateArtifacts() supports docker mode with credentials 1`] = ` Array [ Object { - "cmd": "docker run --rm -v \\"/tmp/github/some/repo\\":\\"/tmp/github/some/repo\\" -v \\"/tmp/renovate/cache/others/go\\":\\"/tmp/renovate/cache/others/go\\" -e GOPATH -e GOPROXY -e GONOSUMDB -e CGO_ENABLED=0 -w \\"/tmp/github/some/repo\\" renovate/go bash -c \\"git config --global url.\\\\\\"https://some-token@github.com/\\\\\\".insteadOf \\\\\\"https://github.com/\\\\\\" && go get -d ./...\\"", + "cmd": "docker pull renovate/go", + "options": Object { + "encoding": "utf-8", + }, + }, + Object { + "cmd": "docker run --rm --user=foobar -v \\"/tmp/github/some/repo\\":\\"/tmp/github/some/repo\\" -v \\"/tmp/renovate/cache\\":\\"/tmp/renovate/cache\\" -v \\"/tmp/renovate/cache/others/go\\":\\"/tmp/renovate/cache/others/go\\" -e GOPATH -e GOPROXY -e GONOSUMDB -e CGO_ENABLED -w \\"/tmp/github/some/repo\\" renovate/go bash -l -c \\"git config --global url.\\\\\\\\\\\\\\"https://some-token@github.com/\\\\\\\\\\\\\\".insteadOf \\\\\\\\\\\\\\"https://github.com/\\\\\\\\\\\\\\" && go get -d ./...\\"", "options": Object { "cwd": "/tmp/github/some/repo", "encoding": "utf-8", "env": Object { + "CGO_ENABLED": "1", + "GONOSUMDB": "1", "GOPATH": "/tmp/renovate/cache/others/go", + "GOPROXY": "proxy.example.com", "HOME": "/home/user", "HTTPS_PROXY": "https://example.com", "HTTP_PROXY": "http://example.com", @@ -84,12 +99,21 @@ Array [ exports[`.updateArtifacts() supports docker mode with credentials and appMode enabled 1`] = ` Array [ Object { - "cmd": "docker run --rm -v \\"/tmp/github/some/repo\\":\\"/tmp/github/some/repo\\" -v \\"/tmp/renovate/cache/others/go\\":\\"/tmp/renovate/cache/others/go\\" -e GOPATH -e GOPROXY -e GONOSUMDB -e CGO_ENABLED=0 -w \\"/tmp/github/some/repo\\" renovate/go bash -c \\"git config --global url.\\\\\\"https://x-access-token:some-token@github.com/\\\\\\".insteadOf \\\\\\"https://github.com/\\\\\\" && go get -d ./...\\"", + "cmd": "docker pull renovate/go", + "options": Object { + "encoding": "utf-8", + }, + }, + Object { + "cmd": "docker run --rm --user=foobar -v \\"/tmp/github/some/repo\\":\\"/tmp/github/some/repo\\" -v \\"/tmp/renovate/cache\\":\\"/tmp/renovate/cache\\" -v \\"/tmp/renovate/cache/others/go\\":\\"/tmp/renovate/cache/others/go\\" -e GOPATH -e GOPROXY -e GONOSUMDB -e CGO_ENABLED -w \\"/tmp/github/some/repo\\" renovate/go bash -l -c \\"git config --global url.\\\\\\\\\\\\\\"https://x-access-token:some-token@github.com/\\\\\\\\\\\\\\".insteadOf \\\\\\\\\\\\\\"https://github.com/\\\\\\\\\\\\\\" && go get -d ./...\\"", "options": Object { "cwd": "/tmp/github/some/repo", "encoding": "utf-8", "env": Object { + "CGO_ENABLED": "1", + "GONOSUMDB": "1", "GOPATH": "/tmp/renovate/cache/others/go", + "GOPROXY": "proxy.example.com", "HOME": "/home/user", "HTTPS_PROXY": "https://example.com", "HTTP_PROXY": "http://example.com", @@ -101,12 +125,15 @@ Array [ }, }, Object { - "cmd": "docker run --rm -v \\"/tmp/github/some/repo\\":\\"/tmp/github/some/repo\\" -v \\"/tmp/renovate/cache/others/go\\":\\"/tmp/renovate/cache/others/go\\" -e GOPATH -e GOPROXY -e GONOSUMDB -e CGO_ENABLED=0 -w \\"/tmp/github/some/repo\\" renovate/go bash -c \\"git config --global url.\\\\\\"https://x-access-token:some-token@github.com/\\\\\\".insteadOf \\\\\\"https://github.com/\\\\\\" && go mod tidy\\"", + "cmd": "docker run --rm --user=foobar -v \\"/tmp/github/some/repo\\":\\"/tmp/github/some/repo\\" -v \\"/tmp/renovate/cache\\":\\"/tmp/renovate/cache\\" -v \\"/tmp/renovate/cache/others/go\\":\\"/tmp/renovate/cache/others/go\\" -e GOPATH -e GOPROXY -e GONOSUMDB -e CGO_ENABLED -w \\"/tmp/github/some/repo\\" renovate/go bash -l -c \\"git config --global url.\\\\\\\\\\\\\\"https://x-access-token:some-token@github.com/\\\\\\\\\\\\\\".insteadOf \\\\\\\\\\\\\\"https://github.com/\\\\\\\\\\\\\\" && go mod tidy\\"", "options": Object { "cwd": "/tmp/github/some/repo", "encoding": "utf-8", "env": Object { + "CGO_ENABLED": "1", + "GONOSUMDB": "1", "GOPATH": "/tmp/renovate/cache/others/go", + "GOPROXY": "proxy.example.com", "HOME": "/home/user", "HTTPS_PROXY": "https://example.com", "HTTP_PROXY": "http://example.com", @@ -123,12 +150,21 @@ Array [ exports[`.updateArtifacts() supports docker mode without credentials 1`] = ` Array [ Object { - "cmd": "docker run --rm --user=foobar -v \\"/tmp/github/some/repo\\":\\"/tmp/github/some/repo\\" -v \\"/tmp/renovate/cache/others/go\\":\\"/tmp/renovate/cache/others/go\\" -e GOPATH -e GOPROXY -e GONOSUMDB -e CGO_ENABLED=0 -w \\"/tmp/github/some/repo\\" renovate/go go get -d ./...", + "cmd": "docker pull renovate/go", + "options": Object { + "encoding": "utf-8", + }, + }, + Object { + "cmd": "docker run --rm --user=foobar -v \\"/tmp/github/some/repo\\":\\"/tmp/github/some/repo\\" -v \\"/tmp/renovate/cache\\":\\"/tmp/renovate/cache\\" -v \\"/tmp/renovate/cache/others/go\\":\\"/tmp/renovate/cache/others/go\\" -e GOPATH -e GOPROXY -e GONOSUMDB -e CGO_ENABLED -w \\"/tmp/github/some/repo\\" renovate/go bash -l -c \\"go get -d ./...\\"", "options": Object { "cwd": "/tmp/github/some/repo", "encoding": "utf-8", "env": Object { + "CGO_ENABLED": "1", + "GONOSUMDB": "1", "GOPATH": "/tmp/renovate/cache/others/go", + "GOPROXY": "proxy.example.com", "HOME": "/home/user", "HTTPS_PROXY": "https://example.com", "HTTP_PROXY": "http://example.com", @@ -150,7 +186,10 @@ Array [ "cwd": "/tmp/github/some/repo", "encoding": "utf-8", "env": Object { + "CGO_ENABLED": "1", + "GONOSUMDB": "1", "GOPATH": "/tmp/renovate/cache/others/go", + "GOPROXY": "proxy.example.com", "HOME": "/home/user", "HTTPS_PROXY": "https://example.com", "HTTP_PROXY": "http://example.com", diff --git a/lib/manager/gomod/artifacts.spec.ts b/lib/manager/gomod/artifacts.spec.ts index 47902cf24bb21cc6fdadfe9c0c96d63ffe19fa54..52b5332ec992c80b5b3480d8948fb6578676ffeb 100644 --- a/lib/manager/gomod/artifacts.spec.ts +++ b/lib/manager/gomod/artifacts.spec.ts @@ -1,3 +1,4 @@ +import { join } from 'upath'; import _fs from 'fs-extra'; import { exec as _exec } from 'child_process'; import * as gomod from './artifacts'; @@ -6,7 +7,9 @@ import { mocked } from '../../../test/util'; import { StatusResult } from '../../platform/git/storage'; import { envMock, mockExecAll } from '../../../test/execUtil'; import * as _env from '../../util/exec/env'; +import { setUtilConfig } from '../../util'; import { BinarySource } from '../../util/exec/common'; +import { resetPrefetchedImages } from '../../util/exec/docker'; jest.mock('fs-extra'); jest.mock('child_process'); @@ -33,8 +36,16 @@ replace github.com/pkg/errors => ../errors `; const config = { - localDir: '/tmp/github/some/repo', - cacheDir: '/tmp/renovate/cache', + // `join` fixes Windows CI + localDir: join('/tmp/github/some/repo'), + cacheDir: join('/tmp/renovate/cache'), + dockerUser: 'foobar', +}; + +const goEnv = { + GONOSUMDB: '1', + GOPROXY: 'proxy.example.com', + CGO_ENABLED: '1', }; describe('.updateArtifacts()', () => { @@ -42,7 +53,9 @@ describe('.updateArtifacts()', () => { jest.resetAllMocks(); jest.resetModules(); - env.getChildProcessEnv.mockReturnValue(envMock.basic); + env.getChildProcessEnv.mockReturnValue({ ...envMock.basic, ...goEnv }); + setUtilConfig(config); + resetPrefetchedImages(); }); it('returns if no go.sum found', async () => { const execSnapshots = mockExecAll(exec); @@ -90,6 +103,7 @@ describe('.updateArtifacts()', () => { expect(execSnapshots).toMatchSnapshot(); }); it('supports docker mode without credentials', async () => { + setUtilConfig({ ...config, binarySource: BinarySource.Docker }); platform.getFile.mockResolvedValueOnce('Current go.sum'); const execSnapshots = mockExecAll(exec); platform.getRepoStatus.mockResolvedValueOnce({ @@ -104,7 +118,6 @@ describe('.updateArtifacts()', () => { config: { ...config, binarySource: BinarySource.Docker, - dockerUser: 'foobar', }, }) ).not.toBeNull(); @@ -131,6 +144,7 @@ describe('.updateArtifacts()', () => { expect(execSnapshots).toMatchSnapshot(); }); it('supports docker mode with credentials', async () => { + setUtilConfig({ ...config, binarySource: BinarySource.Docker }); hostRules.find.mockReturnValueOnce({ token: 'some-token', }); @@ -154,6 +168,7 @@ describe('.updateArtifacts()', () => { expect(execSnapshots).toMatchSnapshot(); }); it('supports docker mode with credentials and appMode enabled', async () => { + setUtilConfig({ ...config, binarySource: BinarySource.Docker }); hostRules.find.mockReturnValueOnce({ token: 'some-token', }); diff --git a/lib/manager/gomod/artifacts.ts b/lib/manager/gomod/artifacts.ts index 63b1fde5f6fcbc61f212a2c081ddf54897855fd9..6c7c02f855b608180cc79594d8796a4c0e722859 100644 --- a/lib/manager/gomod/artifacts.ts +++ b/lib/manager/gomod/artifacts.ts @@ -1,14 +1,31 @@ -import { ensureDir, outputFile, readFile } from 'fs-extra'; +import { ensureDir } from 'fs-extra'; import { join, dirname } from 'upath'; -import { exec } from '../../util/exec'; +import { exec, ExecOptions } from '../../util/exec'; import { find } from '../../util/host-rules'; -import { getChildProcessEnv } from '../../util/exec/env'; import { logger } from '../../logger'; import { UpdateArtifact, UpdateArtifactsResult } from '../common'; import { platform } from '../../platform'; import { BinarySource } from '../../util/exec/common'; +import { readLocalFile, writeLocalFile } from '../../util/fs'; import { PLATFORM_TYPE_GITHUB } from '../../constants/platforms'; +function getPreCommands(): string[] | null { + const credentials = find({ + hostType: PLATFORM_TYPE_GITHUB, + url: 'https://api.github.com/', + }); + let preCommands = null; + if (credentials && credentials.token) { + const token = global.appMode + ? `x-access-token:${credentials.token}` + : credentials.token; + preCommands = [ + `git config --global url.\\\\"https://${token}@github.com/\\\\".insteadOf \\\\"https://github.com/\\\\"`, + ]; + } + return preCommands; +} + export async function updateArtifacts({ packageFileName: goModFileName, updatedDeps: _updatedDeps, @@ -16,20 +33,18 @@ export async function updateArtifacts({ config, }: UpdateArtifact): Promise<UpdateArtifactsResult[] | null> { logger.debug(`gomod.updateArtifacts(${goModFileName})`); - const customEnv = ['GOPATH', 'GOPROXY', 'GONOSUMDB']; - const env = getChildProcessEnv(customEnv); - env.GOPATH = env.GOPATH || join(config.cacheDir, './others/go'); - await ensureDir(env.GOPATH); - logger.debug('Using GOPATH: ' + env.GOPATH); + + const goPath = process.env.GOPATH || join(config.cacheDir, './others/go'); + await ensureDir(goPath); + logger.debug(`Using GOPATH: ${goPath}`); + const sumFileName = goModFileName.replace(/\.mod$/, '.sum'); const existingGoSumContent = await platform.getFile(sumFileName); if (!existingGoSumContent) { logger.debug('No go.sum found'); return null; } - const cwd = join(config.localDir, dirname(goModFileName)); try { - const localGoModFileName = join(config.localDir, goModFileName); const massagedGoMod = newGoModContent.replace( /\n(replace\s+[^\s]+\s+=>\s+\.\.\/.*)/g, '\n// renovate-replace $1' @@ -37,68 +52,32 @@ export async function updateArtifacts({ if (massagedGoMod !== newGoModContent) { logger.debug('Removed some relative replace statements from go.mod'); } - await outputFile(localGoModFileName, massagedGoMod); - const localGoSumFileName = join(config.localDir, sumFileName); - let cmd: string; - if (config.binarySource === BinarySource.Docker) { - logger.info('Running go via docker'); - cmd = `docker run --rm `; - if (config.dockerUser) { - cmd += `--user=${config.dockerUser} `; - } - const volumes = [config.localDir, env.GOPATH]; - cmd += volumes.map(v => `-v "${v}":"${v}" `).join(''); - const envVars = customEnv; - cmd += envVars.map(e => `-e ${e} `).join(''); - cmd += '-e CGO_ENABLED=0 '; - cmd += `-w "${cwd}" `; - cmd += `renovate/go `; - const credentials = find({ - hostType: PLATFORM_TYPE_GITHUB, - url: 'https://api.github.com/', - }); - if (credentials && credentials.token) { - logger.debug('Setting github.com credentials'); - cmd += `bash -c "git config --global url.\\"https://${ - global.appMode - ? `x-access-token:${credentials.token}` - : credentials.token - }@github.com/\\".insteadOf \\"https://github.com/\\" && go`; - } else { - cmd += 'go'; - } - } else if ( - config.binarySource === BinarySource.Auto || - config.binarySource === BinarySource.Global - ) { - logger.info('Running go via global command'); - cmd = 'go'; - } else { - logger.warn({ config }, 'Unsupported binarySource'); - cmd = 'go'; - } + await writeLocalFile(goModFileName, massagedGoMod); + const cmd = 'go'; + const execOptions: ExecOptions = { + cwd: join(config.localDir, dirname(goModFileName)), + extraEnv: { + GOPATH: goPath, + GOPROXY: process.env.GOPROXY, + GONOSUMDB: process.env.GONOSUMDB, + CGO_ENABLED: config.binarySource === BinarySource.Docker ? '0' : null, + }, + docker: { + image: 'renovate/go', + volumes: [goPath], + preCommands: getPreCommands(), + }, + }; let args = 'get -d ./...'; - if (cmd.includes('.insteadOf')) { - args += '"'; - } logger.debug({ cmd, args }, 'go get command'); - await exec(`${cmd} ${args}`, { - cwd, - env, - }); + await exec(`${cmd} ${args}`, execOptions); if ( config.postUpdateOptions && config.postUpdateOptions.includes('gomodTidy') ) { args = 'mod tidy'; - if (cmd.includes('.insteadOf')) { - args += '"'; - } logger.debug({ cmd, args }, 'go mod tidy command'); - await exec(`${cmd} ${args}`, { - cwd, - env, - }); + await exec(`${cmd} ${args}`, execOptions); } const res = []; let status = await platform.getRepoStatus(); @@ -109,7 +88,7 @@ export async function updateArtifacts({ res.push({ file: { name: sumFileName, - contents: await readFile(localGoSumFileName, 'utf8'), + contents: await readLocalFile(sumFileName), }, }); const vendorDir = join(dirname(goModFileName), 'vendor/'); @@ -117,14 +96,8 @@ export async function updateArtifacts({ // istanbul ignore if if (await platform.getFile(vendorModulesFileName)) { args = 'mod vendor'; - if (cmd.includes('.insteadOf')) { - args += '"'; - } logger.debug({ cmd, args }, 'go mod vendor command'); - await exec(`${cmd} ${args}`, { - cwd, - env, - }); + await exec(`${cmd} ${args}`, execOptions); if ( config.postUpdateOptions && config.postUpdateOptions.includes('gomodTidy') @@ -134,19 +107,15 @@ export async function updateArtifacts({ args += '"'; } logger.debug({ cmd, args }, 'go mod tidy command'); - await exec(`${cmd} ${args}`, { - cwd, - env, - }); + await exec(`${cmd} ${args}`, execOptions); } status = await platform.getRepoStatus(); for (const f of status.modified.concat(status.not_added)) { if (f.startsWith(vendorDir)) { - const localModified = join(config.localDir, f); res.push({ file: { name: f, - contents: await readFile(localModified, 'utf8'), + contents: await readLocalFile(f), }, }); } @@ -160,9 +129,10 @@ export async function updateArtifacts({ }); } } - const finalGoModContent = ( - await readFile(localGoModFileName, 'utf8') - ).replace(/\/\/ renovate-replace /g, ''); + const finalGoModContent = (await readLocalFile(goModFileName)).replace( + /\/\/ renovate-replace /g, + '' + ); if (finalGoModContent !== newGoModContent) { logger.info('Found updated go.mod after go.sum update'); res.push({