From c2db794f5a0105ac6e9fc30b2802d33fda9d6feb Mon Sep 17 00:00:00 2001 From: shoukoo Date: Wed, 30 Jun 2021 19:38:58 +1000 Subject: [PATCH] feat: add default branch prop for publish:github Signed-off-by: shoukoo --- .changeset/violet-maps-smell.md | 6 ++ packages/backend-common/api-report.md | 3 +- packages/backend-common/src/scm/git.test.ts | 4 +- packages/backend-common/src/scm/git.ts | 9 ++- .../actions/builtin/publish/github.test.ts | 60 +++++++++++++++++++ .../actions/builtin/publish/github.ts | 11 +++- .../src/scaffolder/stages/publish/helpers.ts | 7 ++- 7 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 .changeset/violet-maps-smell.md diff --git a/.changeset/violet-maps-smell.md b/.changeset/violet-maps-smell.md new file mode 100644 index 0000000000..fdb4c6b46d --- /dev/null +++ b/.changeset/violet-maps-smell.md @@ -0,0 +1,6 @@ +--- +'@backstage/backend-common': patch +'@backstage/plugin-scaffolder-backend': patch +--- + +add defaultBranch property for publish GitHub action diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index fcddb8dda5..7534f8826f 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -183,8 +183,9 @@ export class Git { logger?: Logger | undefined; }) => Git; // (undocumented) - init({ dir }: { + init({ dir, defaultBranch, }: { dir: string; + defaultBranch?: string; }): Promise; // (undocumented) merge({ dir, theirs, ours, author, committer, }: { diff --git a/packages/backend-common/src/scm/git.test.ts b/packages/backend-common/src/scm/git.test.ts index af9dfeef1b..0b70edc45d 100644 --- a/packages/backend-common/src/scm/git.test.ts +++ b/packages/backend-common/src/scm/git.test.ts @@ -201,14 +201,16 @@ describe('Git', () => { describe('init', () => { it('should call isomorphic-git with the correct arguments', async () => { const dir = '/some/mock/dir'; + const defaultBranch = 'master'; const git = Git.fromAuth({}); - await git.init({ dir }); + await git.init({ dir, defaultBranch }); expect(isomorphic.init).toHaveBeenCalledWith({ fs, dir, + defaultBranch, }); }); }); diff --git a/packages/backend-common/src/scm/git.ts b/packages/backend-common/src/scm/git.ts index 3afa551d5f..e786c279a1 100644 --- a/packages/backend-common/src/scm/git.ts +++ b/packages/backend-common/src/scm/git.ts @@ -150,12 +150,19 @@ export class Git { }); } - async init({ dir }: { dir: string }): Promise { + async init({ + dir, + defaultBranch = 'master', + }: { + dir: string; + defaultBranch?: string; + }): Promise { this.config.logger?.info(`Init git repository {dir=${dir}}`); return git.init({ fs, dir, + defaultBranch, }); } diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts index 716fa704e9..910fa27b46 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts @@ -175,6 +175,36 @@ describe('publish:github', () => { expect(initRepoAndPush).toHaveBeenCalledWith({ dir: mockContext.workspacePath, remoteUrl: 'https://github.com/clone/url.git', + defaultBranch: 'master', + auth: { username: 'x-access-token', password: 'tokenlols' }, + logger: mockContext.logger, + }); + }); + + it('should call initRepoAndPush with the correct defaultBranch main', async () => { + mockGithubClient.users.getByUsername.mockResolvedValue({ + data: { type: 'User' }, + }); + + mockGithubClient.repos.createForAuthenticatedUser.mockResolvedValue({ + data: { + clone_url: 'https://github.com/clone/url.git', + html_url: 'https://github.com/html/url', + }, + }); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + defaultBranch: 'main', + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://github.com/clone/url.git', + defaultBranch: 'main', auth: { username: 'x-access-token', password: 'tokenlols' }, logger: mockContext.logger, }); @@ -430,4 +460,34 @@ describe('publish:github', () => { 'https://github.com/html/url/blob/master', ); }); + + it('should use main as default branch', async () => { + mockGithubClient.users.getByUsername.mockResolvedValue({ + data: { type: 'User' }, + }); + + mockGithubClient.repos.createForAuthenticatedUser.mockResolvedValue({ + data: { + clone_url: 'https://github.com/clone/url.git', + html_url: 'https://github.com/html/url', + }, + }); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + defaultBranch: 'main', + }, + }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'remoteUrl', + 'https://github.com/clone/url.git', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://github.com/html/url/blob/main', + ); + }); }); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts index 48d59024eb..856197a808 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts @@ -45,6 +45,7 @@ export function createPublishGithubAction(options: { repoUrl: string; description?: string; access?: string; + defaultBranch?: string; sourcePath?: string; repoVisibility: 'private' | 'internal' | 'public'; collaborators: Collaborator[]; @@ -77,6 +78,11 @@ export function createPublishGithubAction(options: { type: 'string', enum: ['private', 'public', 'internal'], }, + defaultBranch: { + title: 'Default Branch', + type: 'string', + description: `Sets the default branch on the repository. The default value is 'master'`, + }, sourcePath: { title: 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.', @@ -131,6 +137,7 @@ export function createPublishGithubAction(options: { description, access, repoVisibility = 'private', + defaultBranch = 'master', collaborators, topics, } = ctx.input; @@ -239,11 +246,12 @@ export function createPublishGithubAction(options: { } const remoteUrl = newRepo.clone_url; - const repoContentsUrl = `${newRepo.html_url}/blob/master`; + const repoContentsUrl = `${newRepo.html_url}/blob/${defaultBranch}`; await initRepoAndPush({ dir: getRepoSourceDirectory(ctx.workspacePath, ctx.input.sourcePath), remoteUrl, + defaultBranch, auth: { username: 'x-access-token', password: token, @@ -257,6 +265,7 @@ export function createPublishGithubAction(options: { client, repoName: newRepo.name, logger: ctx.logger, + defaultBranch, }); } catch (e) { throw new Error( diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/publish/helpers.ts b/plugins/scaffolder-backend/src/scaffolder/stages/publish/helpers.ts index 6eebb4692a..dff0feb5f2 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/publish/helpers.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/publish/helpers.ts @@ -24,11 +24,13 @@ export async function initRepoAndPush({ remoteUrl, auth, logger, + defaultBranch = 'master', }: { dir: string; remoteUrl: string; auth: { username: string; password: string }; logger: Logger; + defaultBranch?: string; }): Promise { const git = Git.fromAuth({ username: auth.username, @@ -38,6 +40,7 @@ export async function initRepoAndPush({ await git.init({ dir, + defaultBranch, }); const paths = await globby(['./**', './**/.*', '!.git'], { @@ -74,6 +77,7 @@ type BranchProtectionOptions = { owner: string; repoName: string; logger: Logger; + defaultBranch?: string; }; export const enableBranchProtectionOnDefaultRepoBranch = async ({ @@ -81,6 +85,7 @@ export const enableBranchProtectionOnDefaultRepoBranch = async ({ client, owner, logger, + defaultBranch = 'master', }: BranchProtectionOptions): Promise => { const tryOnce = async () => { try { @@ -97,7 +102,7 @@ export const enableBranchProtectionOnDefaultRepoBranch = async ({ }, owner, repo: repoName, - branch: 'master', + branch: defaultBranch, required_status_checks: { strict: true, contexts: [] }, restrictions: null, enforce_admins: true,