diff --git a/.changeset/curly-parrots-applaud.md b/.changeset/curly-parrots-applaud.md new file mode 100644 index 0000000000..ddfd093cff --- /dev/null +++ b/.changeset/curly-parrots-applaud.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': minor +--- + +Update the github:publish action to allow passing required status checks by name. diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/helpers.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/helpers.ts index 75e22522d5..a6e65a169e 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/helpers.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/helpers.ts @@ -132,6 +132,7 @@ type BranchProtectionOptions = { repoName: string; logger: Logger; requireCodeOwnerReviews: boolean; + requiredStatusChecks: string[]; defaultBranch?: string; }; @@ -141,6 +142,7 @@ export const enableBranchProtectionOnDefaultRepoBranch = async ({ owner, logger, requireCodeOwnerReviews, + requiredStatusChecks = [], defaultBranch = 'master', }: BranchProtectionOptions): Promise => { const tryOnce = async () => { @@ -159,7 +161,10 @@ export const enableBranchProtectionOnDefaultRepoBranch = async ({ owner, repo: repoName, branch: defaultBranch, - required_status_checks: { strict: true, contexts: [] }, + required_status_checks: { + strict: true, + contexts: requiredStatusChecks, + }, restrictions: null, enforce_admins: true, required_pull_request_reviews: { 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 4e835657a3..80a3f77006 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 @@ -625,6 +625,7 @@ describe('publish:github', () => { logger: mockContext.logger, defaultBranch: 'master', requireCodeOwnerReviews: false, + requiredStatusChecks: [], }); await action.handler({ @@ -642,6 +643,7 @@ describe('publish:github', () => { logger: mockContext.logger, defaultBranch: 'master', requireCodeOwnerReviews: true, + requiredStatusChecks: [], }); await action.handler({ @@ -659,6 +661,67 @@ describe('publish:github', () => { logger: mockContext.logger, defaultBranch: 'master', requireCodeOwnerReviews: false, + requiredStatusChecks: [], + }); + }); + + it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of requireStatusChecks', async () => { + mockOctokit.rest.users.getByUsername.mockResolvedValue({ + data: { type: 'User' }, + }); + + mockOctokit.rest.repos.createForAuthenticatedUser.mockResolvedValue({ + data: { + name: 'repository', + }, + }); + + await action.handler(mockContext); + + expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ + owner: 'owner', + client: mockOctokit, + repoName: 'repository', + logger: mockContext.logger, + defaultBranch: 'master', + requireCodeOwnerReviews: false, + requiredStatusChecks: [], + }); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + requiredStatusChecks: ['statusCheck'], + }, + }); + + expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ + owner: 'owner', + client: mockOctokit, + repoName: 'repository', + logger: mockContext.logger, + defaultBranch: 'master', + requireCodeOwnerReviews: false, + requiredStatusChecks: ['statusCheck'], + }); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + requiredStatusChecks: [], + }, + }); + + expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ + owner: 'owner', + client: mockOctokit, + repoName: 'repository', + logger: mockContext.logger, + defaultBranch: 'master', + requireCodeOwnerReviews: false, + requiredStatusChecks: [], }); }); }); 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 7f1e7a1c93..0ef71bc6fa 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts @@ -52,6 +52,7 @@ export function createPublishGithubAction(options: { allowMergeCommit?: boolean; sourcePath?: string; requireCodeOwnerReviews?: boolean; + requiredStatusChecks?: string[]; repoVisibility?: 'private' | 'internal' | 'public'; collaborators?: Array<{ username: string; @@ -88,6 +89,15 @@ export function createPublishGithubAction(options: { 'Require an approved review in PR including files with a designated Code Owner', type: 'boolean', }, + requiredStatusChecks: { + title: 'Required Status Checks', + description: + 'The list of status checks to require in order to merge into this branch', + type: 'array', + items: { + type: 'string', + }, + }, repoVisibility: { title: 'Repository Visibility', type: 'string', @@ -178,6 +188,7 @@ export function createPublishGithubAction(options: { description, access, requireCodeOwnerReviews = false, + requiredStatusChecks = [], repoVisibility = 'private', defaultBranch = 'master', deleteBranchOnMerge = false, @@ -317,6 +328,7 @@ export function createPublishGithubAction(options: { logger: ctx.logger, defaultBranch, requireCodeOwnerReviews, + requiredStatusChecks, }); } catch (e) { assertError(e);