import os from 'node:os'; import upath from 'upath'; import { mockDeep } from 'vitest-mock-extended'; import { envMock, mockExecAll, mockExecSequence } from '~test/exec-util.ts'; import { env, fs, git, logger, partial, scm } from '~test/util.ts'; import { GlobalConfig } from '../../../config/global.ts'; import type { InternalGlobalConfigOptions, RepoGlobalConfig, } from '../../../config/types.ts'; import { TEMPORARY_ERROR } from '../../../constants/error-messages.ts'; import { resetPrefetchedImages } from '../../../util/exec/docker/index.ts'; import { ExecError } from '../../../util/exec/exec-error.ts'; import type { StatusResult } from '../../../util/git/types.ts'; import { getPkgReleases } from '../../datasource/index.ts'; import { isGradleExecutionAllowed } from './artifacts.ts'; import { updateArtifacts } from './index.ts'; vi.mock('../../../util/fs/index.ts'); vi.mock('../../../util/exec/env.ts'); vi.mock('../../datasource/index.ts', () => mockDeep()); process.env.CONTAINERBASE = 'true'; const adminConfig: RepoGlobalConfig & InternalGlobalConfigOptions = { // `join` fixes Windows CI localDir: upath.join('/tmp/github/some/repo'), cacheDir: upath.join('/tmp/cache'), containerbaseDir: upath.join('/tmp/cache/containerbase'), dockerSidecarImage: 'ghcr.io/renovatebot/base-image', // although not enabled by default, let's assume it is allowedUnsafeExecutions: ['gradleWrapper'], binarySource: 'global', }; const osPlatformSpy = vi.spyOn(os, 'platform'); describe('modules/manager/gradle/artifacts', () => { beforeEach(() => { osPlatformSpy.mockReturnValue('linux'); env.getChildProcessEnv.mockReturnValue({ ...envMock.basic, LANG: 'en_US.UTF-8', LC_ALL: 'en_US', }); GlobalConfig.set(adminConfig); resetPrefetchedImages(); // java vi.mocked(getPkgReleases).mockResolvedValue({ releases: [ { version: '8.0.1' }, { version: '11.0.1' }, { version: '16.0.1' }, { version: '17.0.0' }, ], }); fs.findUpLocal.mockResolvedValue('gradlew'); scm.getFileList.mockResolvedValue([ 'gradlew', 'build.gradle', 'gradle.lockfile', 'gradle/wrapper/gradle-wrapper.properties', ]); git.getFiles.mockResolvedValue({ 'gradle.lockfile': 'Current gradle.lockfile', }); git.getRepoStatus.mockResolvedValue( partial({ modified: ['build.gradle', 'gradle.lockfile'], }), ); fs.readLocalFile.mockImplementation((fileName: string): Promise => { let content = ''; if (fileName === 'gradle.lockfile') { content = 'New gradle.lockfile'; } else if (fileName === 'gradle/wrapper/gradle-wrapper.properties') { content = 'distributionUrl=https\\://services.gradle.org/distributions/gradle-7.2-bin.zip'; } else if (fileName === 'gradle/verification-metadata.xml') { content = 'true'; } return Promise.resolve(content); }); }); describe('isGradleExecutionAllowed', () => { it('returns false when allowedUnsafeExecutions is empty (as it not enabled by default option)', () => { GlobalConfig.set({ ...adminConfig, allowedUnsafeExecutions: undefined, }); const res = isGradleExecutionAllowed('gradlew'); expect(res).toBeFalse(); }); it('returns true when allowedUnsafeExecutions includes `gradleWrapper`', () => { GlobalConfig.set({ ...adminConfig, allowedUnsafeExecutions: ['gradleWrapper'], }); const res = isGradleExecutionAllowed('gradlew'); expect(res).toBeTrue(); }); it('returns false when allowedUnsafeExecutions does not include `gradleWrapper`', () => { GlobalConfig.set({ ...adminConfig, allowedUnsafeExecutions: [], }); const res = isGradleExecutionAllowed('gradlew'); expect(res).toBeFalse(); }); it('logs when allowedUnsafeExecutions does not include `gradleWrapper`', () => { GlobalConfig.set({ ...adminConfig, allowedUnsafeExecutions: [], }); isGradleExecutionAllowed('some_gradle-wrapper.command'); expect(logger.logger.once.warn).toHaveBeenCalledWith( { command: 'some_gradle-wrapper.command' }, 'Gradle wrapper command was requested to run, but `gradleWrapper` is not permitted in the allowedUnsafeExecutions', ); }); }); describe('lockfile tests', () => { it('aborts if no lockfile is found', async () => { const execSnapshots = mockExecAll(); scm.getFileList.mockResolvedValue(['build.gradle', 'settings.gradle']); await expect( updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [], newPackageFileContent: '', config: {}, }), ).resolves.toBeNull(); expect(logger.logger.debug).toHaveBeenCalledWith( 'No Gradle dependency lockfiles or verification metadata found - skipping update', ); expect(execSnapshots).toBeEmptyArray(); }); it('aborts if lock file exists but no gradle wrapper', async () => { const execSnapshots = mockExecAll(); fs.findUpLocal.mockResolvedValue(null); await expect( updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [], newPackageFileContent: '', config: {}, }), ).resolves.toBeNull(); expect(logger.logger.debug).toHaveBeenCalledWith( 'Found Gradle dependency lockfiles but no gradlew - aborting update', ); expect(execSnapshots).toBeEmptyArray(); }); it('aborts if allowedUnsafeExecutions does not include `gradleWrapper`', async () => { GlobalConfig.set({ ...adminConfig, allowedUnsafeExecutions: [], }); const execSnapshots = mockExecAll(); await expect( updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [ { depName: 'org.junit.jupiter:junit-jupiter-api' }, { depName: 'org.junit.jupiter:junit-jupiter-engine' }, ], newPackageFileContent: '', config: {}, }), ).resolves.toBeNull(); expect(logger.logger.trace).toHaveBeenCalledWith( 'Not allowed to execute gradle due to allowedUnsafeExecutions - aborting update', ); expect(execSnapshots).toBeEmptyArray(); }); it('uses custom JVM heap settings when toolSettings are configured', async () => { const execSnapshots = mockExecAll(); GlobalConfig.set({ ...adminConfig, toolSettings: { jvmMaxMemory: 600 }, }); const res = await updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [ { depName: 'org.junit.jupiter:junit-jupiter-api' }, { depName: 'org.junit.jupiter:junit-jupiter-engine' }, ], newPackageFileContent: '', config: {}, }); expect(res).toEqual([ { file: { type: 'addition', path: 'gradle.lockfile', contents: 'New gradle.lockfile', }, }, ]); expect(execSnapshots).toMatchObject([ { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms600m -Xmx600m" --console=plain --dependency-verification lenient -q properties', options: { cwd: '/tmp/github/some/repo', }, }, { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms600m -Xmx600m" --console=plain --dependency-verification lenient -q :dependencies --update-locks org.junit.jupiter:junit-jupiter-api,org.junit.jupiter:junit-jupiter-engine', options: { cwd: '/tmp/github/some/repo', stdin: 'pipe', stdout: 'ignore', stderr: 'pipe', }, }, ]); }); it('updates lock file', async () => { const execSnapshots = mockExecAll(); const res = await updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [ { depName: 'org.junit.jupiter:junit-jupiter-api' }, { depName: 'org.junit.jupiter:junit-jupiter-engine' }, ], newPackageFileContent: '', config: {}, }); expect(res).toEqual([ { file: { type: 'addition', path: 'gradle.lockfile', contents: 'New gradle.lockfile', }, }, ]); expect(execSnapshots).toMatchObject([ { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q properties', options: { cwd: '/tmp/github/some/repo', }, }, { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q :dependencies --update-locks org.junit.jupiter:junit-jupiter-api,org.junit.jupiter:junit-jupiter-engine', options: { cwd: '/tmp/github/some/repo', stdin: 'pipe', stdout: 'ignore', stderr: 'pipe', }, }, ]); }); it('updates lock file in win32', async () => { osPlatformSpy.mockReturnValue('win32'); const execSnapshots = mockExecAll(); const res = await updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [ { depName: 'org.junit.jupiter:junit-jupiter-api' }, { depName: 'org.junit.jupiter:junit-jupiter-engine' }, ], newPackageFileContent: '', config: {}, }); expect(res).toEqual([ { file: { type: 'addition', path: 'gradle.lockfile', contents: 'New gradle.lockfile', }, }, ]); // In win32, gradle.bat will be used and /dev/null redirection isn't used yet expect(execSnapshots).toMatchObject([ { cmd: 'gradlew.bat -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q properties', options: { cwd: '/tmp/github/some/repo', }, }, { cmd: 'gradlew.bat -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q :dependencies --update-locks org.junit.jupiter:junit-jupiter-api,org.junit.jupiter:junit-jupiter-engine', options: { cwd: '/tmp/github/some/repo', stdin: 'pipe', stdout: 'ignore', stderr: 'pipe', }, }, ]); }); it('prefers packageName over depName if provided', async () => { const execSnapshots = mockExecAll(); const res = await updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [ { depType: 'plugin', depName: 'org.springframework.boot', packageName: 'org.springframework.boot:org.springframework.boot.gradle.plugin', }, ], newPackageFileContent: '', config: {}, }); expect(res).toEqual([ { file: { type: 'addition', path: 'gradle.lockfile', contents: 'New gradle.lockfile', }, }, ]); expect(execSnapshots).toMatchObject([ { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q properties', options: { cwd: '/tmp/github/some/repo', }, }, { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q :dependencies --update-locks org.springframework.boot:org.springframework.boot.gradle.plugin', options: { cwd: '/tmp/github/some/repo', stdin: 'pipe', stdout: 'ignore', stderr: 'pipe', }, }, ]); }); it('aborts lock file maintenance if packageFileName is not build.gradle(.kts) in root project', async () => { await expect( updateArtifacts({ packageFileName: 'somedir/settings.gradle', updatedDeps: [], newPackageFileContent: '', config: { isLockFileMaintenance: true }, }), ).resolves.toBeNull(); expect(logger.logger.trace).toHaveBeenCalledWith( 'No build.gradle(.kts) file or not in root project - skipping lock file maintenance', ); }); it('performs lock file maintenance', async () => { const execSnapshots = mockExecAll(); const res = await updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [], newPackageFileContent: '', config: { isLockFileMaintenance: true }, }); expect(res).toEqual([ { file: { type: 'addition', path: 'gradle.lockfile', contents: 'New gradle.lockfile', }, }, ]); expect(execSnapshots).toMatchObject([ { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q properties', options: { cwd: '/tmp/github/some/repo', }, }, { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q :dependencies --write-locks', options: { cwd: '/tmp/github/some/repo', stdin: 'pipe', stdout: 'ignore', stderr: 'pipe', }, }, ]); }); it('performs lock file maintenance (docker)', async () => { const execSnapshots = mockExecAll(); GlobalConfig.set({ ...adminConfig, binarySource: 'docker' }); const res = await updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [], newPackageFileContent: '', config: { isLockFileMaintenance: true }, }); expect(res).toEqual([ { file: { type: 'addition', path: 'gradle.lockfile', contents: 'New gradle.lockfile', }, }, ]); expect(execSnapshots).toMatchObject([ { cmd: 'docker pull ghcr.io/renovatebot/base-image' }, { cmd: 'docker ps --filter name=renovate_sidecar -aq' }, { cmd: 'docker run --rm --name=renovate_sidecar --label=renovate_child ' + '-v "/tmp/github/some/repo":"/tmp/github/some/repo" ' + '-v "/tmp/cache":"/tmp/cache" ' + '-e CI ' + '-e GRADLE_OPTS ' + '-e CONTAINERBASE_CACHE_DIR ' + '-w "/tmp/github/some/repo" ' + 'ghcr.io/renovatebot/base-image' + " bash -l -c '" + 'install-tool java 16.0.1' + ' && ' + './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q properties' + "'", options: { cwd: '/tmp/github/some/repo' }, }, { cmd: 'docker ps --filter name=renovate_sidecar -aq' }, { cmd: 'docker run --rm --name=renovate_sidecar --label=renovate_child ' + '-v "/tmp/github/some/repo":"/tmp/github/some/repo" ' + '-v "/tmp/cache":"/tmp/cache" ' + '-e CI ' + '-e GRADLE_OPTS ' + '-e CONTAINERBASE_CACHE_DIR ' + '-w "/tmp/github/some/repo" ' + 'ghcr.io/renovatebot/base-image' + " bash -l -c '" + 'install-tool java 16.0.1' + ' && ' + './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q :dependencies --write-locks' + "'", options: { cwd: '/tmp/github/some/repo', stdin: 'pipe', stdout: 'ignore', stderr: 'pipe', }, }, ]); }); it('performs lock file maintenance (install)', async () => { const execSnapshots = mockExecAll(); GlobalConfig.set({ ...adminConfig, binarySource: 'install' }); const res = await updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [], newPackageFileContent: '', config: { isLockFileMaintenance: true }, }); expect(res).toEqual([ { file: { type: 'addition', path: 'gradle.lockfile', contents: 'New gradle.lockfile', }, }, ]); expect(execSnapshots).toMatchObject([ { cmd: 'install-tool java 16.0.1' }, { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q properties', options: { cwd: '/tmp/github/some/repo' }, }, { cmd: 'install-tool java 16.0.1' }, { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q :dependencies --write-locks', options: { cwd: '/tmp/github/some/repo', stdin: 'pipe', stdout: 'ignore', stderr: 'pipe', }, }, ]); }); it('updates all included projects', async () => { const execSnapshots = mockExecSequence([ { stdout: "subprojects: [project ':sub1', project ':sub2']", stderr: '', }, { stdout: '', stderr: '' }, ]); const res = await updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [], newPackageFileContent: '', config: { isLockFileMaintenance: true }, }); expect(res).toEqual([ { file: { type: 'addition', path: 'gradle.lockfile', contents: 'New gradle.lockfile', }, }, ]); expect(execSnapshots).toMatchObject([ { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q properties', options: { cwd: '/tmp/github/some/repo', }, }, { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q :dependencies :sub1:dependencies :sub2:dependencies --write-locks', options: { cwd: '/tmp/github/some/repo', stdin: 'pipe', stdout: 'ignore', stderr: 'pipe', }, }, ]); }); it('does not update lockfile if content is unchanged', async () => { mockExecAll(); fs.readLocalFile.mockResolvedValue('Current gradle.lockfile'); await expect( updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [], newPackageFileContent: '', config: { isLockFileMaintenance: true }, }), ).resolves.toBeNull(); }); it('gradlew failed', async () => { const execSnapshots = mockExecAll(new Error('failed')); await expect( updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [], newPackageFileContent: '', config: { isLockFileMaintenance: true }, }), ).resolves.toEqual([ { artifactError: { fileName: 'build.gradle', stderr: 'failed', }, }, ]); expect(execSnapshots).toMatchObject([ { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q properties', options: { cwd: '/tmp/github/some/repo', }, }, ]); }); it('rethrows temporary error', async () => { const execError = new ExecError(TEMPORARY_ERROR, { cmd: '', stdout: '', stderr: '', options: {}, }); mockExecAll(execError); await expect( updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [], newPackageFileContent: '{}', config: {}, }), ).rejects.toThrow(TEMPORARY_ERROR); }); it('fallback to default Java version if Gradle version not extractable', async () => { const execSnapshots = mockExecAll(); GlobalConfig.set({ ...adminConfig, binarySource: 'install' }); fs.readLocalFile .mockResolvedValueOnce(null) .mockResolvedValueOnce('New gradle.lockfile'); const res = await updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [], newPackageFileContent: '', config: { isLockFileMaintenance: true }, }); expect(res).toEqual([ { file: { type: 'addition', path: 'gradle.lockfile', contents: 'New gradle.lockfile', }, }, ]); expect(execSnapshots).toMatchObject([ { cmd: 'install-tool java 11.0.1' }, { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q properties', options: { cwd: '/tmp/github/some/repo' }, }, { cmd: 'install-tool java 11.0.1' }, { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q :dependencies --write-locks', options: { cwd: '/tmp/github/some/repo', stdin: 'pipe', stdout: 'ignore', stderr: 'pipe', }, }, ]); }); }); describe('dependency verification tests', () => { it('updates verification metadata file', async () => { const execSnapshots = mockExecAll(); scm.getFileList.mockResolvedValue([ 'gradlew', 'build.gradle', 'gradle/wrapper/gradle-wrapper.properties', 'gradle/verification-metadata.xml', ]); git.getRepoStatus.mockResolvedValue( partial({ modified: ['build.gradle', 'gradle/verification-metadata.xml'], }), ); const res = await updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [ { depName: 'org.junit.jupiter:junit-jupiter-api' }, { depName: 'org.junit.jupiter:junit-jupiter-engine' }, ], newPackageFileContent: '', config: {}, }); expect(res).toEqual([ { file: { type: 'addition', path: 'gradle/verification-metadata.xml', contents: 'true', }, }, ]); expect(execSnapshots).toMatchObject([ { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q --write-verification-metadata sha256 dependencies', options: { cwd: '/tmp/github/some/repo', stdin: 'pipe', stdout: 'ignore', stderr: 'pipe', }, }, ]); }); it('aborts verification metadata updates if allowedUnsafeExecutions does not include `gradleWrapper`', async () => { GlobalConfig.set({ ...adminConfig, allowedUnsafeExecutions: [], }); const execSnapshots = mockExecAll(); scm.getFileList.mockResolvedValue([ 'gradlew', 'build.gradle', 'gradle/wrapper/gradle-wrapper.properties', 'gradle/verification-metadata.xml', ]); git.getRepoStatus.mockResolvedValue( partial({ modified: ['build.gradle', 'gradle/verification-metadata.xml'], }), ); await expect( updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [ { depName: 'org.junit.jupiter:junit-jupiter-api' }, { depName: 'org.junit.jupiter:junit-jupiter-engine' }, ], newPackageFileContent: '', config: {}, }), ).resolves.toBeNull(); expect(execSnapshots).toBeEmptyArray(); }); it('updates existing checksums also if verify-checksums is disabled', async () => { const execSnapshots = mockExecAll(); scm.getFileList.mockResolvedValue([ 'gradlew', 'build.gradle', 'gradle/wrapper/gradle-wrapper.properties', 'gradle/verification-metadata.xml', ]); git.getRepoStatus.mockResolvedValue( partial({ modified: ['build.gradle', 'gradle/verification-metadata.xml'], }), ); fs.readLocalFile.mockImplementation((fileName: string): Promise => { let content = ''; if (fileName === 'gradle/verification-metadata.xml') { content = 'false'; } return Promise.resolve(content); }); const res = await updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [ { depName: 'org.junit.jupiter:junit-jupiter-api' }, { depName: 'org.junit.jupiter:junit-jupiter-engine' }, ], newPackageFileContent: '', config: {}, }); expect(res).toEqual([ { file: { type: 'addition', path: 'gradle/verification-metadata.xml', contents: 'false', }, }, ]); expect(execSnapshots).toMatchObject([ { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q --write-verification-metadata sha256 dependencies', options: { cwd: '/tmp/github/some/repo', stdin: 'pipe', stdout: 'ignore', stderr: 'pipe', }, }, ]); }); it('updates verification metadata and lock file', async () => { const execSnapshots = mockExecAll(); scm.getFileList.mockResolvedValue([ 'gradlew', 'build.gradle', 'gradle.lockfile', 'gradle/wrapper/gradle-wrapper.properties', 'gradle/verification-metadata.xml', ]); git.getRepoStatus.mockResolvedValue( partial({ modified: [ 'build.gradle', 'gradle.lockfile', 'gradle/verification-metadata.xml', ], }), ); const res = await updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [ { depName: 'org.junit.jupiter:junit-jupiter-api' }, { depName: 'org.junit.jupiter:junit-jupiter-engine' }, ], newPackageFileContent: '', config: {}, }); expect(res).toEqual([ { file: { type: 'addition', path: 'gradle.lockfile', contents: 'New gradle.lockfile', }, }, { file: { type: 'addition', path: 'gradle/verification-metadata.xml', contents: 'true', }, }, ]); expect(execSnapshots).toMatchObject([ { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q properties', options: { cwd: '/tmp/github/some/repo', }, }, { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q :dependencies --update-locks org.junit.jupiter:junit-jupiter-api,org.junit.jupiter:junit-jupiter-engine', options: { cwd: '/tmp/github/some/repo', stdin: 'pipe', stdout: 'ignore', stderr: 'pipe', }, }, { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q --write-verification-metadata sha256 dependencies', options: { cwd: '/tmp/github/some/repo', stdin: 'pipe', stdout: 'ignore', stderr: 'pipe', }, }, ]); }); it('uses sha256 as default if only weak hash algorithms are found', async () => { const execSnapshots = mockExecAll(); scm.getFileList.mockResolvedValue([ 'gradlew', 'build.gradle', 'gradle/wrapper/gradle-wrapper.properties', 'gradle/verification-metadata.xml', ]); git.getRepoStatus.mockResolvedValue( partial({ modified: ['build.gradle', 'gradle/verification-metadata.xml'], }), ); fs.readLocalFile.mockImplementation((fileName: string): Promise => { let content = ''; if (fileName === 'gradle/verification-metadata.xml') { content = 'true'; } return Promise.resolve(content); }); await updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [ { depName: 'org.junit.jupiter:junit-jupiter-api' }, { depName: 'org.junit.jupiter:junit-jupiter-engine' }, ], newPackageFileContent: '', config: {}, }); expect(execSnapshots).toMatchObject([ { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q --write-verification-metadata sha256 dependencies', options: { cwd: '/tmp/github/some/repo', stdin: 'pipe', stdout: 'ignore', stderr: 'pipe', }, }, ]); }); it('uses pgp hashType if verify-signatures is enabled', async () => { const execSnapshots = mockExecAll(); scm.getFileList.mockResolvedValue([ 'gradlew', 'build.gradle', 'gradle/wrapper/gradle-wrapper.properties', 'gradle/verification-metadata.xml', ]); git.getRepoStatus.mockResolvedValue( partial({ modified: ['build.gradle', 'gradle/verification-metadata.xml'], }), ); fs.readLocalFile.mockImplementation((fileName: string): Promise => { let content = ''; if (fileName === 'gradle/verification-metadata.xml') { content = 'true'; } return Promise.resolve(content); }); await updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [ { depName: 'org.junit.jupiter:junit-jupiter-api' }, { depName: 'org.junit.jupiter:junit-jupiter-engine' }, ], newPackageFileContent: '', config: {}, }); expect(execSnapshots).toMatchObject([ { cmd: './gradlew -Dorg.gradle.jvmargs="-Xms512m -Xmx512m" --console=plain --dependency-verification lenient -q --write-verification-metadata sha256,pgp dependencies', options: { cwd: '/tmp/github/some/repo', stdin: 'pipe', stdout: 'ignore', stderr: 'pipe', }, }, ]); }); it('does not write verification metadata, when no checksums exist and neither checksum nor signature verification is enabled', async () => { const execSnapshots = mockExecAll(); scm.getFileList.mockResolvedValue([ 'gradlew', 'build.gradle', 'gradle/wrapper/gradle-wrapper.properties', 'gradle/verification-metadata.xml', ]); git.getRepoStatus.mockResolvedValue( partial({ modified: ['build.gradle', 'gradle/verification-metadata.xml'], }), ); fs.readLocalFile.mockImplementation((fileName: string): Promise => { let content = ''; if (fileName === 'gradle/verification-metadata.xml') { content = 'falsefalse'; } return Promise.resolve(content); }); await updateArtifacts({ packageFileName: 'build.gradle', updatedDeps: [ { depName: 'org.junit.jupiter:junit-jupiter-api' }, { depName: 'org.junit.jupiter:junit-jupiter-engine' }, ], newPackageFileContent: '', config: {}, }); expect(execSnapshots).toBeEmptyArray(); }); }); });