Skip to content
Snippets Groups Projects
Select Git revision
  • 456245aabe465529d6623dafd8aa32ed152f5365
  • main default protected
  • renovate/main-ghcr.io-renovatebot-base-image-10.x
  • renovate/main-ghcr.io-containerbase-devcontainer-13.x
  • next
  • 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.26.1
  • 41.26.0
  • 41.25.1
  • 41.25.0
  • 41.24.0
  • 41.23.5
  • 41.23.4
  • 41.23.3
  • 41.23.2
  • 41.23.1
  • 41.23.0
  • 41.22.0
  • 41.21.4
  • 41.21.3
  • 41.21.2
  • 41.21.1
  • 41.21.0
  • 41.20.2
  • 41.20.1
  • 41.20.0
41 results

deprecated.ts

Blame
  • storage.spec.ts 13.08 KiB
    import fs from 'fs-extra';
    import Git from 'simple-git/promise';
    import tmp from 'tmp-promise';
    import GitStorage from './storage';
    
    describe('platform/git/storage', () => {
      jest.setTimeout(15000);
    
      const git = new GitStorage();
      const masterCommitDate = new Date();
      masterCommitDate.setMilliseconds(0);
      let base: tmp.DirectoryResult;
      let origin: tmp.DirectoryResult;
      beforeAll(async () => {
        base = await tmp.dir({ unsafeCleanup: true });
        const repo = Git(base.path).silent(true);
        await repo.init();
        await repo.addConfig('user.email', 'Jest@example.com');
        await repo.addConfig('user.name', 'Jest');
        await fs.writeFile(base.path + '/past_file', 'past');
        await repo.add(['past_file']);
        await repo.commit('past message');
    
        await repo.checkoutBranch('renovate/past_branch', 'master');
        await repo.checkoutBranch('develop', 'master');
    
        await repo.checkout('master');
        await fs.writeFile(base.path + '/master_file', 'master');
        await fs.writeFile(base.path + '/file_to_delete', 'bye');
        await repo.add(['master_file', 'file_to_delete']);
        await repo.commit('master message', [
          '--date=' + masterCommitDate.toISOString(),
        ]);
    
        await repo.checkoutBranch('renovate/future_branch', 'master');
        await fs.writeFile(base.path + '/future_file', 'future');
        await repo.add(['future_file']);
        await repo.commit('future message');
    
        await repo.checkout('master');
      });
    
      let tmpDir: tmp.DirectoryResult;
    
      beforeEach(async () => {
        origin = await tmp.dir({ unsafeCleanup: true });
        const repo = Git(origin.path);
        await repo.clone(base.path, '.', ['--bare']);
        tmpDir = await tmp.dir({ unsafeCleanup: true });
        global.gitAuthor = {
          name: 'test',
          email: 'test@example.com',
        };
        await git.initRepo({
          localDir: tmpDir.path,
          url: origin.path,
          extraCloneOpts: {
            '--config': 'extra.clone.config=test-extra-config-value',
          },
        });
      });
    
      afterEach(async () => {
        await tmpDir.cleanup();
        await origin.cleanup();
        git.cleanRepo();
      });
    
      afterAll(async () => {
        await base.cleanup();
      });
    
      describe('setBaseBranch(branchName)', () => {
        it('sets the base branch as master', async () => {
          await git.setBaseBranch('master');
        });
        it('sets non-master base branch', async () => {
          await git.setBaseBranch('develop');
        });
        it('should throw if branch does not exist', async () => {
          await expect(git.setBaseBranch('not_found')).rejects.toMatchSnapshot();
        });
      });
      describe('getFileList()', () => {
        it('returns empty array if error', async () => {
          expect(await git.getFileList('not_found')).toEqual([]);
        });
        it('should return the correct files', async () => {
          expect(await git.getFileList('renovate/future_branch')).toMatchSnapshot();
        });
        it('should exclude submodules', async () => {
          const repo = Git(base.path).silent(true);
          await repo.submoduleAdd(base.path, 'submodule');
          await repo.commit('Add submodule');
          await git.initRepo({
            localDir: tmpDir.path,
            url: base.path,
          });
          expect(await fs.exists(tmpDir.path + '/.gitmodules')).toBeTruthy();
          expect(await git.getFileList('master')).toMatchSnapshot();
          await repo.reset(['--hard', 'HEAD^']);
        });
        it('defaults to master', async () => {
          expect(await git.getFileList()).toMatchSnapshot();
        });
      });
      describe('branchExists(branchName)', () => {
        it('should return true if found', async () => {
          expect(await git.branchExists('renovate/future_branch')).toBe(true);
          expect(await git.branchExists('renovate/future_branch')).toBe(true); // should come from cache
        });
        it('should return false if not found', async () => {
          expect(await git.branchExists('not_found')).toBe(false);
        });
      });
      describe('getAllRenovateBranches()', () => {
        it('should return all renovate branches', async () => {
          await git.setBranchPrefix('renovate/');
          const res = await git.getAllRenovateBranches('renovate/');
          expect(res).toContain('renovate/past_branch');
          expect(res).toContain('renovate/future_branch');
          expect(res).not.toContain('master');
        });
      });
      describe('isBranchStale()', () => {
        it('should return false if same SHA as master', async () => {
          expect(await git.isBranchStale('renovate/future_branch')).toBe(false);
        });
        it('should return true if SHA different from master', async () => {
          expect(await git.isBranchStale('renovate/past_branch')).toBe(true);
        });
        it('should throw if branch does not exist', async () => {
          await expect(git.isBranchStale('not_found')).rejects.toMatchSnapshot();
        });
      });
    
      describe('getBranchCommit(branchName)', () => {
        it('should return same value for equal refs', async () => {
          const hex = await git.getBranchCommit('renovate/past_branch');
          expect(hex).toBe(await git.getBranchCommit('master~1'));
          expect(hex).toHaveLength(40);
        });
        it('should throw if branch does not exist', async () => {
          await expect(git.getBranchCommit('not_found')).rejects.toMatchSnapshot();
        });
      });
    
      describe('createBranch(branchName, sha)', () => {
        it('resets existing branch', async () => {
          const hex = await git.getBranchCommit('renovate/past_branch');
          expect(await git.getBranchCommit('renovate/future_branch')).not.toBe(hex);
          await git.createBranch('renovate/future_branch', hex);
          expect(await git.getBranchCommit('renovate/future_branch')).toBe(hex);
        });
      });
    
      describe('mergeBranch(branchName)', () => {
        it('should perform a branch merge', async () => {
          await git.setBranchPrefix('renovate/');
          await git.mergeBranch('renovate/future_branch');
          const merged = await Git(origin.path).branch([
            '--verbose',
            '--merged',
            'master',
          ]);
          expect(merged.all).toContain('renovate/future_branch');
        });
        it('should throw if branch merge throws', async () => {
          await expect(git.mergeBranch('not_found')).rejects.toThrow();
        });
        it('should throw if branch merge is stale', async () => {
          expect.assertions(1);
          await git.setBranchPrefix('renovate/');
          await git.commitFilesToBranch({
            branchName: 'test',
            files: [{ name: 'some-new-file', contents: 'some new-contents' }],
            message: 'test mesage',
            parentBranch: 'renovate/past_branch',
          });
    
          await git.setBaseBranch('master');
    
          await expect(git.mergeBranch('test')).rejects.toThrow();
        });
      });
      describe('deleteBranch(branchName)', () => {
        it('should send delete', async () => {
          await git.deleteBranch('renovate/past_branch');
          const branches = await Git(origin.path).branch({});
          expect(branches.all).not.toContain('renovate/past_branch');
        });
      });
      describe('getBranchLastCommitTime', () => {
        it('should return a Date', async () => {
          const time = await git.getBranchLastCommitTime('master');
          expect(time).toEqual(masterCommitDate);
        });
        it('handles error', async () => {
          const res = await git.getBranchLastCommitTime('some-branch');
          expect(res).toBeDefined();
        });
      });
      describe('getFile(filePath, branchName)', () => {
        it('gets the file', async () => {
          const res = await git.getFile('master_file');
          expect(res).toBe('master');
        });
        it('short cuts 404', async () => {
          const res = await git.getFile('some-missing-path');
          expect(res).toBeNull();
        });
        it('returns null for 404', async () => {
          await expect(
            git.getFile('some-path', 'some-branch')
          ).rejects.toMatchSnapshot();
        });
      });
      describe('commitFilesToBranch({branchName, files, message, parentBranch})', () => {
        it('creates file', async () => {
          const file = {
            name: 'some-new-file',
            contents: 'some new-contents',
          };
          await git.commitFilesToBranch({
            branchName: 'renovate/past_branch',
            files: [file],
            message: 'Create something',
          });
        });
        it('deletes file', async () => {
          const file = {
            name: '|delete|',
            contents: 'file_to_delete',
          };
          await git.commitFilesToBranch({
            branchName: 'renovate/something',
            files: [file],
            message: 'Delete something',
          });
        });
        it('updates multiple files', async () => {
          const files = [
            {
              name: 'some-existing-file',
              contents: 'updated content',
            },
            {
              name: 'some-other-existing-file',
              contents: 'other updated content',
            },
          ];
          await git.commitFilesToBranch({
            branchName: 'renovate/something',
            files,
            message: 'Update something',
          });
        });
        it('updates git submodules', async () => {
          const files = [
            {
              name: '.',
              contents: 'some content',
            },
          ];
          await git.commitFilesToBranch({
            branchName: 'renovate/something',
            files,
            message: 'Update something',
          });
        });
        it('does not push when no diff', async () => {
          const branchName = 'renovate/something';
          const local = Git(tmpDir.path);
          await local.push('origin', `master:${branchName}`);
          await local.fetch([
            'origin',
            `refs/heads/${branchName}:refs/remotes/origin/${branchName}`,
          ]);
          const files = [];
          await git.commitFilesToBranch({
            branchName,
            files,
            message: 'Update something',
          });
        });
      });
    
      describe('getCommitMessages()', () => {
        it('returns commit messages', async () => {
          expect(await git.getCommitMessages()).toMatchSnapshot();
        });
      });
    
      describe('Storage.getUrl()', () => {
        const getUrl = GitStorage.getUrl;
        it('returns https url', () => {
          expect(
            getUrl({
              protocol: 'https',
              auth: 'user:pass',
              hostname: 'host',
              repository: 'some/repo',
            })
          ).toEqual('https://user:pass@host/some/repo.git');
          expect(
            getUrl({
              auth: 'user:pass',
              hostname: 'host',
              repository: 'some/repo',
            })
          ).toEqual('https://user:pass@host/some/repo.git');
        });
    
        it('returns ssh url', () => {
          expect(
            getUrl({
              protocol: 'ssh',
              auth: 'user:pass',
              hostname: 'host',
              repository: 'some/repo',
            })
          ).toEqual('git@host:some/repo.git');
        });
      });
    
      describe('initRepo())', () => {
        it('should fetch latest', async () => {
          const repo = Git(base.path).silent(true);
          await repo.checkoutBranch('test', 'master');
          await fs.writeFile(base.path + '/test', 'lorem ipsum');
          await repo.add(['test']);
          await repo.commit('past message2');
          await repo.checkout('master');
    
          expect(await git.branchExists('test')).toBeFalsy();
    
          expect(await git.getCommitMessages()).toMatchSnapshot();
    
          await git.setBaseBranch('develop');
    
          await git.initRepo({
            localDir: tmpDir.path,
            url: base.path,
          });
    
          expect(await git.branchExists('test')).toBeTruthy();
    
          await git.setBaseBranch('test');
    
          const msg = await git.getCommitMessages();
          expect(msg).toMatchSnapshot();
          expect(msg).toContain('past message2');
        });
    
        it('should set branch prefix', async () => {
          const repo = Git(base.path).silent(true);
          await repo.checkoutBranch('renovate/test', 'master');
          await fs.writeFile(base.path + '/test', 'lorem ipsum');
          await repo.add(['test']);
          await repo.commit('past message2');
          await repo.checkout('master');
    
          await git.initRepo({
            localDir: tmpDir.path,
            url: base.path,
          });
    
          await git.setBranchPrefix('renovate/');
          expect(await git.branchExists('renovate/test')).toBe(true);
          const cid = await git.getBranchCommit('renovate/test');
    
          await git.initRepo({
            localDir: tmpDir.path,
            url: base.path,
          });
    
          await repo.checkout('renovate/test');
          await repo.commit('past message3', ['--amend']);
    
          await git.setBranchPrefix('renovate/');
          expect(await git.branchExists('renovate/test')).toBe(true);
          expect(await git.getBranchCommit('renovate/test')).not.toEqual(cid);
        });
    
        it('should fail clone ssh submodule', async () => {
          const repo = Git(base.path).silent(true);
          await fs.writeFile(
            base.path + '/.gitmodules',
            '[submodule "test"]\npath=test\nurl=ssh://0.0.0.0'
          );
          await repo.add('.gitmodules');
          await repo.raw([
            'update-index',
            '--add',
            '--cacheinfo',
            '160000',
            '4b825dc642cb6eb9a060e54bf8d69288fbee4904',
            'test',
          ]);
          await repo.commit('Add submodule');
          await git.initRepo({
            localDir: tmpDir.path,
            url: base.path,
          });
          expect(await fs.exists(tmpDir.path + '/.gitmodules')).toBeTruthy();
          await repo.reset(['--hard', 'HEAD^']);
        });
    
        it('should use extra clone configuration', async () => {
          const repo = Git(tmpDir.path).silent(true);
          const res = (await repo.raw(['config', 'extra.clone.config'])).trim();
          expect(res).toBe('test-extra-config-value');
        });
      });
    });