diff --git a/.changeset/khaki-meals-hammer.md b/.changeset/khaki-meals-hammer.md new file mode 100644 index 0000000000..1deee2706d --- /dev/null +++ b/.changeset/khaki-meals-hammer.md @@ -0,0 +1,6 @@ +--- +'@backstage/backend-common': minor +--- + +- Added `force` and `remoteRef` option to `push` method in `git` actions +- Added `addRemote` and `deleteRemote` methods to `git` actions diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index d3726eb0e4..f2b60ae19e 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -338,6 +338,7 @@ export class Git { dir: string; remote: string; url: string; + force?: boolean; }): Promise; // (undocumented) checkout(options: { dir: string; ref: string }): Promise; @@ -365,6 +366,8 @@ export class Git { dir: string; fullName?: boolean; }): Promise; + // (undocumented) + deleteRemote(options: { dir: string; remote: string }): Promise; fetch(options: { dir: string; remote?: string }): Promise; // (undocumented) static fromAuth: (options: { @@ -393,6 +396,7 @@ export class Git { dir: string; remote: string; remoteRef?: string; + force?: boolean; }): Promise; readCommit(options: { dir: string; sha: string }): Promise; resolveRef(options: { dir: string; ref: string }): Promise; diff --git a/packages/backend-common/src/scm/git.test.ts b/packages/backend-common/src/scm/git.test.ts index 97342b3492..40814607a9 100644 --- a/packages/backend-common/src/scm/git.test.ts +++ b/packages/backend-common/src/scm/git.test.ts @@ -48,14 +48,32 @@ describe('Git', () => { const dir = 'mockdirectory'; const remote = 'origin'; const url = 'git@github.com/something/sads'; + const force = true; - await git.addRemote({ dir, remote, url }); + await git.addRemote({ dir, remote, url, force }); expect(isomorphic.addRemote).toHaveBeenCalledWith({ fs, dir, remote, url, + force, + }); + }); + }); + + describe('deleteRemote', () => { + it('should call isomorphic-git with the correct arguments', async () => { + const git = Git.fromAuth({}); + const dir = 'mockdirectory'; + const remote = 'origin'; + + await git.deleteRemote({ dir, remote }); + + expect(isomorphic.deleteRemote).toHaveBeenCalledWith({ + fs, + dir, + remote, }); }); }); @@ -311,14 +329,18 @@ describe('Git', () => { password: 'hunter2', }; const git = Git.fromAuth(auth); + const remoteRef = 'master'; + const force = true; - await git.push({ dir, remote }); + await git.push({ dir, remote, remoteRef, force }); expect(isomorphic.push).toHaveBeenCalledWith({ fs, http, remote, dir, + remoteRef, + force, onProgress: expect.any(Function), headers: { 'user-agent': 'git/@isomorphic-git', @@ -359,8 +381,10 @@ describe('Git', () => { password: 'hunter2', }; const git = Git.fromAuth(auth); + const remoteRef = 'master'; + const force = true; - await git.push({ remote, dir }); + await git.push({ remote, dir, remoteRef, force }); const { onAuth } = ( isomorphic.push as unknown as jest.Mock @@ -377,6 +401,8 @@ describe('Git', () => { password: 'hunter2', }; const git = Git.fromAuth(auth); + const remoteRef = 'master'; + const force = true; (isomorphic.push as jest.Mock).mockImplementation(() => { const error: Error & { data?: unknown } = new Error('mock error'); @@ -385,7 +411,7 @@ describe('Git', () => { throw error; }); - await expect(git.push({ remote, dir })).rejects.toThrow( + await expect(git.push({ remote, dir, remoteRef, force })).rejects.toThrow( 'more information here', ); }); diff --git a/packages/backend-common/src/scm/git.ts b/packages/backend-common/src/scm/git.ts index b4f6644260..c8e26420ec 100644 --- a/packages/backend-common/src/scm/git.ts +++ b/packages/backend-common/src/scm/git.ts @@ -58,12 +58,19 @@ export class Git { dir: string; remote: string; url: string; + force?: boolean; }): Promise { - const { dir, url, remote } = options; + const { dir, url, remote, force } = options; this.config.logger?.info( `Creating new remote {dir=${dir},remote=${remote},url=${url}}`, ); - return git.addRemote({ fs, dir, remote, url }); + return git.addRemote({ fs, dir, remote, url, force }); + } + + async deleteRemote(options: { dir: string; remote: string }): Promise { + const { dir, remote } = options; + this.config.logger?.info(`Deleting remote {dir=${dir},remote=${remote}}`); + return git.deleteRemote({ fs, dir, remote }); } async checkout(options: { dir: string; ref: string }): Promise { @@ -197,8 +204,13 @@ export class Git { }); } - async push(options: { dir: string; remote: string; remoteRef?: string }) { - const { dir, remote, remoteRef } = options; + async push(options: { + dir: string; + remote: string; + remoteRef?: string; + force?: boolean; + }) { + const { dir, remote, remoteRef, force } = options; this.config.logger?.info( `Pushing directory to remote {dir=${dir},remote=${remote}}`, ); @@ -208,11 +220,12 @@ export class Git { dir, http, onProgress: this.onProgressHandler(), + remoteRef, + force, headers: { 'user-agent': 'git/@isomorphic-git', }, - remote: remote, - remoteRef: remoteRef, + remote, onAuth: this.onAuth, }); } catch (ex) {