Skip to content
Snippets Groups Projects
Select Git revision
  • 3f5d13ee473bb94ffcd293884eddcdfdff5ae298
  • main default protected
  • next
  • renovate/main-ghcr.io-renovatebot-base-image-10.x
  • renovate/main-ghcr.io-containerbase-devcontainer-13.x
  • revert-31645-feat/rename-gradle-wrapper-validation-action
  • renovate/main-redis-5.x
  • fix/36615b-branch-reuse-no-cache
  • chore/punycode
  • fix/36615-branch-reuse-bug
  • refactor/pin-new-value
  • feat/36219--git-x509-signing
  • feat/structured-logger
  • hotfix/39.264.1
  • feat/skip-dangling
  • gh-readonly-queue/next/pr-36034-7a061c4ca1024a19e2c295d773d9642625d1c2be
  • hotfix/39.238.3
  • refactor/gitlab-auto-approve
  • feat/template-strings
  • gh-readonly-queue/next/pr-35654-137d934242c784e0c45d4b957362214f0eade1d7
  • fix/32307-global-extends-merging
  • 41.32.1
  • 41.32.0
  • 41.31.1
  • 41.31.0
  • 41.30.5
  • 41.30.4
  • 41.30.3
  • 41.30.2
  • 41.30.1
  • 41.30.0
  • 41.29.1
  • 41.29.0
  • 41.28.2
  • 41.28.1
  • 41.28.0
  • 41.27.1
  • 41.27.0
  • 41.26.2
  • 41.26.1
  • 41.26.0
41 results

index.spec.ts

Blame
  • user avatar
    Sebastian Poxhofer authored and GitHub committed
    fix(terraform): attempt only to update lockfile for depType provider and required_provider and updateType lockFileMaintenance (#11510)
    
    3f5d13ee
    History
    index.spec.ts 14.05 KiB
    import { join } from 'upath';
    import { fs, loadFixture, mocked } from '../../../../test/util';
    import { setGlobalConfig } from '../../../config/global';
    import { getPkgReleases } from '../../../datasource';
    import type { UpdateArtifactsConfig } from '../../types';
    import { TerraformProviderHash } from './hash';
    import { updateArtifacts } from './index';
    
    // auto-mock fs
    jest.mock('../../../util/fs');
    jest.mock('./hash');
    jest.mock('../../../datasource');
    
    const config = {
      constraints: {},
    };
    
    const adminConfig = {
      // `join` fixes Windows CI
      localDir: join('/tmp/github/some/repo'),
      cacheDir: join('/tmp/renovate/cache'),
    };
    
    const validLockfile = loadFixture('validLockfile.hcl');
    
    const mockHash = mocked(TerraformProviderHash).createHashes;
    const mockGetPkgReleases = getPkgReleases as jest.MockedFunction<
      typeof getPkgReleases
    >;
    
    describe('manager/terraform/lockfile/index', () => {
      beforeEach(() => {
        jest.resetAllMocks();
        jest.resetModules();
        setGlobalConfig(adminConfig);
      });
    
      it('returns null if no .terraform.lock.hcl found', async () => {
        fs.readLocalFile.mockResolvedValueOnce(null);
    
        expect(
          await updateArtifacts({
            packageFileName: 'main.tf',
            updatedDeps: [{ depName: 'aws' }],
            newPackageFileContent: '',
            config,
          })
        ).toBeNull();
      });
    
      it('returns null if .terraform.lock.hcl is empty', async () => {
        fs.readLocalFile.mockResolvedValueOnce('empty' as any);
    
        expect(
          await updateArtifacts({
            packageFileName: 'main.tf',
            updatedDeps: [{ depName: 'aws' }],
            newPackageFileContent: '',
            config,
          })
        ).toBeNull();
      });
    
      it('update single dependency with exact constraint and depType provider', async () => {
        fs.readLocalFile.mockResolvedValueOnce(validLockfile as any);
        fs.getSiblingFileName.mockReturnValueOnce('.terraform.lock.hcl');
    
        mockHash.mockResolvedValueOnce([
          'h1:lDsKRxDRXPEzA4AxkK4t+lJd3IQIP2UoaplJGjQSp2s=',
          'h1:6zB2hX7YIOW26OrKsLJn0uLMnjqbPNxcz9RhlWEuuSY=',
        ]);
    
        const localConfig: UpdateArtifactsConfig = {
          updateType: 'minor',
          newVersion: '3.36.0',
          newValue: '3.36.0',
          ...config,
        };
    
        const result = await updateArtifacts({
          packageFileName: 'main.tf',
          updatedDeps: [
            {
              depName: 'hashicorp/aws',
              lookupName: 'hashicorp/aws',
              depType: 'provider',
            },
          ],
          newPackageFileContent: '',
          config: localConfig,
        });
        expect(result).not.toBeNull();
        expect(result).toBeArrayOfSize(1);
        expect(result[0].file).not.toBeNull();
        expect(result[0].file).toMatchSnapshot();
    
        expect(mockHash.mock.calls).toBeArrayOfSize(1);
        expect(mockHash.mock.calls).toMatchSnapshot();
      });
    
      it('update single dependency with exact constraint and and depType required_provider', async () => {
        fs.readLocalFile.mockResolvedValueOnce(validLockfile as any);
        fs.getSiblingFileName.mockReturnValueOnce('.terraform.lock.hcl');
    
        mockHash.mockResolvedValueOnce([
          'h1:lDsKRxDRXPEzA4AxkK4t+lJd3IQIP2UoaplJGjQSp2s=',
          'h1:6zB2hX7YIOW26OrKsLJn0uLMnjqbPNxcz9RhlWEuuSY=',
        ]);
    
        const localConfig: UpdateArtifactsConfig = {
          updateType: 'minor',
          newVersion: '3.36.0',
          newValue: '3.36.0',
          ...config,
        };
    
        const result = await updateArtifacts({
          packageFileName: 'main.tf',
          updatedDeps: [
            {
              depName: 'hashicorp/aws',
              lookupName: 'hashicorp/aws',
              depType: 'required_provider',
            },
          ],
          newPackageFileContent: '',
          config: localConfig,
        });
        expect(result).not.toBeNull();
        expect(result).toBeArrayOfSize(1);
        expect(result[0].file).not.toBeNull();
        expect(result[0].file).toMatchSnapshot();
    
        expect(mockHash.mock.calls).toBeArrayOfSize(1);
        expect(mockHash.mock.calls).toMatchSnapshot();
      });
    
      it('do not update dependency with depType module', async () => {
        const localConfig: UpdateArtifactsConfig = {
          updateType: 'minor',
          newVersion: '3.36.0',
          newValue: '3.36.0',
          ...config,
        };
    
        const result = await updateArtifacts({
          packageFileName: 'main.tf',
          updatedDeps: [
            {
              depName: 'terraform-aws-modules/vpc/aws',
              lookupName: 'terraform-aws-modules/vpc/aws',
              depType: 'module',
            },
          ],
          newPackageFileContent: '',
          config: localConfig,
        });
        expect(result).toBeNull();
      });
    
      it('update single dependency with range constraint and minor update from private registry', async () => {
        fs.readLocalFile.mockResolvedValueOnce(validLockfile as any);
        fs.getSiblingFileName.mockReturnValueOnce('.terraform.lock.hcl');
    
        mockHash.mockResolvedValueOnce([
          'h1:lDsKRxDRXPEzA4AxkK4t+lJd3IQIP2UoaplJGjQSp2s=',
          'h1:6zB2hX7YIOW26OrKsLJn0uLMnjqbPNxcz9RhlWEuuSY=',
        ]);
    
        const localConfig: UpdateArtifactsConfig = {
          updateType: 'minor',
          newVersion: '2.56.0',
          newValue: '~> 2.50',
          ...config,
        };
    
        const result = await updateArtifacts({
          packageFileName: 'main.tf',
          updatedDeps: [
            {
              depName: 'azurerm',
              depType: 'provider',
              lookupName: 'azurerm',
              registryUrls: ['https://registry.example.com'],
            },
          ],
          newPackageFileContent: '',
          config: localConfig,
        });
        expect(result).not.toBeNull();
        expect(result).toBeArrayOfSize(1);
        expect(result[0].file).not.toBeNull();
        expect(result[0].file).toMatchSnapshot();
    
        expect(mockHash.mock.calls).toBeArrayOfSize(1);
        expect(mockHash.mock.calls).toMatchSnapshot();
      });
    
      it('update single dependency with range constraint and major update', async () => {
        fs.readLocalFile.mockResolvedValueOnce(validLockfile as any);
        fs.getSiblingFileName.mockReturnValueOnce('.terraform.lock.hcl');
    
        mockHash.mockResolvedValueOnce([
          'h1:lDsKRxDRXPEzA4AxkK4t+lJd3IQIP2UoaplJGjQSp2s=',
          'h1:6zB2hX7YIOW26OrKsLJn0uLMnjqbPNxcz9RhlWEuuSY=',
        ]);
    
        const localConfig: UpdateArtifactsConfig = {
          updateType: 'major',
          newVersion: '3.1.0',
          newValue: '~> 3.0',
          ...config,
        };
    
        const result = await updateArtifacts({
          packageFileName: 'main.tf',
          updatedDeps: [
            {
              depName: 'random',
              lookupName: 'hashicorp/random',
              depType: 'provider',
            },
          ],
          newPackageFileContent: '',
          config: localConfig,
        });
        expect(result).not.toBeNull();
        expect(result).toBeArrayOfSize(1);
        expect(result[0].file).not.toBeNull();
        expect(result[0].file).toMatchSnapshot();
    
        expect(mockHash.mock.calls).toBeArrayOfSize(1);
        expect(mockHash.mock.calls).toMatchSnapshot();
      });
    
      it('update single dependency in subfolder', async () => {
        fs.readLocalFile.mockResolvedValueOnce(validLockfile as any);
        fs.getSiblingFileName.mockReturnValueOnce('test/.terraform.lock.hcl');
    
        mockHash.mockResolvedValueOnce([
          'h1:lDsKRxDRXPEzA4AxkK4t+lJd3IQIP2UoaplJGjQSp2s=',
          'h1:6zB2hX7YIOW26OrKsLJn0uLMnjqbPNxcz9RhlWEuuSY=',
        ]);
    
        const localConfig: UpdateArtifactsConfig = {
          updateType: 'major',
          newVersion: '3.1.0',
          newValue: '~> 3.0',
          ...config,
        };
    
        const result = await updateArtifacts({
          packageFileName: 'test/main.tf',
          updatedDeps: [
            {
              depName: 'random',
              lookupName: 'hashicorp/random',
              depType: 'provider',
            },
          ],
          newPackageFileContent: '',
          config: localConfig,
        });
        expect(result).not.toBeNull();
        expect(result).toBeArrayOfSize(1);
        expect(result[0].file).not.toBeNull();
        expect(result[0].file).toMatchSnapshot();
    
        expect(mockHash.mock.calls).toBeArrayOfSize(1);
        expect(mockHash.mock.calls).toMatchSnapshot();
      });
    
      it('do full lock file maintenance', async () => {
        fs.readLocalFile.mockResolvedValueOnce(validLockfile as any);
        fs.getSiblingFileName.mockReturnValueOnce('.terraform.lock.hcl');
    
        mockGetPkgReleases
          .mockResolvedValueOnce({
            // aws
            releases: [
              {
                version: '2.30.0',
              },
              {
                version: '3.0.0',
              },
              {
                version: '3.36.0',
              },
            ],
          })
          .mockResolvedValueOnce({
            // azurerm
            releases: [
              {
                version: '2.50.0',
              },
              {
                version: '2.55.0',
              },
              {
                version: '2.56.0',
              },
            ],
          })
          .mockResolvedValueOnce({
            // random
            releases: [
              {
                version: '2.2.1',
              },
              {
                version: '2.2.2',
              },
              {
                version: '3.0.0',
              },
            ],
          });
        mockHash.mockResolvedValue([
          'h1:lDsKRxDRXPEzA4AxkK4t+lJd3IQIP2UoaplJGjQSp2s=',
          'h1:6zB2hX7YIOW26OrKsLJn0uLMnjqbPNxcz9RhlWEuuSY=',
        ]);
    
        const localConfig: UpdateArtifactsConfig = {
          updateType: 'lockFileMaintenance',
          ...config,
        };
    
        const result = await updateArtifacts({
          packageFileName: '',
          updatedDeps: [],
          newPackageFileContent: '',
          config: localConfig,
        });
        expect(result).not.toBeNull();
        expect(result).toBeArrayOfSize(1);
    
        result.forEach((value) => expect(value.file).not.toBeNull());
        result.forEach((value) => expect(value.file).toMatchSnapshot());
    
        expect(mockHash.mock.calls).toBeArrayOfSize(2);
        expect(mockHash.mock.calls).toMatchSnapshot();
      });
    
      it('do full lock file maintenance with lockfile in subfolder', async () => {
        fs.readLocalFile.mockResolvedValueOnce(validLockfile as any);
        fs.getSiblingFileName.mockReturnValueOnce('subfolder/.terraform.lock.hcl');
    
        mockGetPkgReleases
          .mockResolvedValueOnce({
            // aws
            releases: [
              {
                version: '2.30.0',
              },
              {
                version: '3.0.0',
              },
              {
                version: '3.36.0',
              },
            ],
          })
          .mockResolvedValueOnce({
            // azurerm
            releases: [
              {
                version: '2.50.0',
              },
              {
                version: '2.55.0',
              },
              {
                version: '2.56.0',
              },
            ],
          })
          .mockResolvedValueOnce({
            // random
            releases: [
              {
                version: '2.2.1',
              },
              {
                version: '2.2.2',
              },
              {
                version: '3.0.0',
              },
            ],
          });
        mockHash.mockResolvedValue([
          'h1:lDsKRxDRXPEzA4AxkK4t+lJd3IQIP2UoaplJGjQSp2s=',
          'h1:6zB2hX7YIOW26OrKsLJn0uLMnjqbPNxcz9RhlWEuuSY=',
        ]);
    
        const localConfig: UpdateArtifactsConfig = {
          updateType: 'lockFileMaintenance',
          ...config,
        };
    
        const result = await updateArtifacts({
          packageFileName: '',
          updatedDeps: [],
          newPackageFileContent: '',
          config: localConfig,
        });
        expect(result).not.toBeNull();
        expect(result).toBeArrayOfSize(1);
    
        result.forEach((value) => expect(value.file).not.toBeNull());
        result.forEach((value) => expect(value.file).toMatchSnapshot());
    
        expect(mockHash.mock.calls).toBeArrayOfSize(2);
        expect(mockHash.mock.calls).toMatchSnapshot();
      });
    
      it('do full lock file maintenance without necessary changes', async () => {
        fs.readLocalFile.mockResolvedValueOnce(validLockfile as any);
    
        mockGetPkgReleases
          .mockResolvedValueOnce({
            // aws
            releases: [
              {
                version: '2.30.0',
              },
              {
                version: '3.0.0',
              },
            ],
          })
          .mockResolvedValueOnce({
            // azurerm
            releases: [
              {
                version: '2.50.0',
              },
            ],
          })
          .mockResolvedValueOnce({
            // random
            releases: [
              {
                version: '2.2.1',
              },
            ],
          });
        mockHash.mockResolvedValue([
          'h1:lDsKRxDRXPEzA4AxkK4t+lJd3IQIP2UoaplJGjQSp2s=',
          'h1:6zB2hX7YIOW26OrKsLJn0uLMnjqbPNxcz9RhlWEuuSY=',
        ]);
    
        const localConfig: UpdateArtifactsConfig = {
          updateType: 'lockFileMaintenance',
          ...config,
        };
        const result = await updateArtifacts({
          packageFileName: '',
          updatedDeps: [],
          newPackageFileContent: '',
          config: localConfig,
        });
        expect(result).toBeNull();
    
        expect(mockHash.mock.calls).toBeArrayOfSize(0);
        expect(mockHash.mock.calls).toMatchSnapshot();
      });
    
      it('return null if hashing fails', async () => {
        fs.readLocalFile.mockResolvedValueOnce(validLockfile as any);
    
        mockGetPkgReleases
          .mockResolvedValueOnce({
            // aws
            releases: [
              {
                version: '2.30.0',
              },
              {
                version: '3.0.0',
              },
              {
                version: '3.36.0',
              },
            ],
          })
          .mockResolvedValueOnce({
            // azurerm
            releases: [
              {
                version: '2.50.0',
              },
              {
                version: '2.55.0',
              },
              {
                version: '2.56.0',
              },
            ],
          })
          .mockResolvedValueOnce({
            // random
            releases: [
              {
                version: '2.2.1',
              },
              {
                version: '2.2.2',
              },
              {
                version: '3.0.0',
              },
            ],
          });
        mockHash.mockResolvedValue(null);
    
        const localConfig: UpdateArtifactsConfig = {
          updateType: 'lockFileMaintenance',
          ...config,
        };
    
        const result = await updateArtifacts({
          packageFileName: '',
          updatedDeps: [],
          newPackageFileContent: '',
          config: localConfig,
        });
        expect(result).toBeNull();
    
        expect(mockHash.mock.calls).toBeArrayOfSize(2);
        expect(mockHash.mock.calls).toMatchSnapshot();
      });
    
      it('return null if experimental flag is not set', async () => {
        const localConfig: UpdateArtifactsConfig = {
          updateType: 'lockFileMaintenance',
          ...config,
        };
        const result = await updateArtifacts({
          packageFileName: '',
          updatedDeps: [],
          newPackageFileContent: '',
          config: localConfig,
        });
        expect(result).toBeNull();
      });
    });