Merge pull request #15144 from Symbianx/improve-github-action

Allow setting dismissStaleReviews on github:publish action
This commit is contained in:
Patrik Oldsberg
2022-12-13 15:50:38 +01:00
committed by GitHub
9 changed files with 182 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend': minor
---
Update the `github:publish` action to allow passing wether to dismiss stale reviews on the protected default branch.
+2
View File
@@ -243,6 +243,7 @@ export function createGithubRepoPushAction(options: {
gitAuthorName?: string | undefined;
gitAuthorEmail?: string | undefined;
requireCodeOwnerReviews?: boolean | undefined;
dismissStaleReviews?: boolean | undefined;
bypassPullRequestAllowances?:
| {
users?: string[];
@@ -388,6 +389,7 @@ export function createPublishGithubAction(options: {
}
| undefined;
requireCodeOwnerReviews?: boolean | undefined;
dismissStaleReviews?: boolean | undefined;
requiredStatusCheckContexts?: string[] | undefined;
requireBranchesToBeUpToDate?: boolean | undefined;
repoVisibility?: 'internal' | 'private' | 'public' | undefined;
@@ -285,6 +285,7 @@ describe('github:repo:push', () => {
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: false,
});
await action.handler({
@@ -305,6 +306,7 @@ describe('github:repo:push', () => {
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: false,
});
await action.handler({
@@ -325,6 +327,7 @@ describe('github:repo:push', () => {
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: false,
});
});
@@ -348,6 +351,7 @@ describe('github:repo:push', () => {
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: false,
});
await action.handler({
@@ -368,6 +372,7 @@ describe('github:repo:push', () => {
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: false,
});
await action.handler({
@@ -388,6 +393,7 @@ describe('github:repo:push', () => {
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: false,
dismissStaleReviews: false,
});
});
@@ -411,6 +417,7 @@ describe('github:repo:push', () => {
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: false,
});
await action.handler({
@@ -432,6 +439,7 @@ describe('github:repo:push', () => {
requiredStatusCheckContexts: ['statusCheck'],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: false,
});
await action.handler({
@@ -453,6 +461,7 @@ describe('github:repo:push', () => {
requiredStatusCheckContexts: ['statusCheck'],
requireBranchesToBeUpToDate: false,
enforceAdmins: true,
dismissStaleReviews: false,
});
await action.handler({
@@ -474,6 +483,7 @@ describe('github:repo:push', () => {
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: false,
});
});
@@ -495,4 +505,70 @@ describe('github:repo:push', () => {
expect(enableBranchProtectionOnDefaultRepoBranch).not.toHaveBeenCalled();
});
it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of dismissStaleReviews', async () => {
mockOctokit.rest.repos.get.mockResolvedValue({
data: {
clone_url: 'https://github.com/clone/url.git',
html_url: 'https://github.com/html/url',
},
});
await action.handler(mockContext);
expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({
owner: 'owner',
client: mockOctokit,
repoName: 'repository',
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: false,
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
dismissStaleReviews: true,
},
});
expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({
owner: 'owner',
client: mockOctokit,
repoName: 'repository',
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: true,
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
dismissStaleReviews: false,
},
});
expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({
owner: 'owner',
client: mockOctokit,
repoName: 'repository',
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: false,
});
});
});
@@ -49,6 +49,7 @@ export function createGithubRepoPushAction(options: {
gitAuthorName?: string;
gitAuthorEmail?: string;
requireCodeOwnerReviews?: boolean;
dismissStaleReviews?: boolean;
bypassPullRequestAllowances?:
| {
users?: string[];
@@ -71,6 +72,7 @@ export function createGithubRepoPushAction(options: {
properties: {
repoUrl: inputProps.repoUrl,
requireCodeOwnerReviews: inputProps.requireCodeOwnerReviews,
dismissStaleReviews: inputProps.dismissStaleReviews,
requiredStatusCheckContexts: inputProps.requiredStatusCheckContexts,
bypassPullRequestAllowances: inputProps.bypassPullRequestAllowances,
requireBranchesToBeUpToDate: inputProps.requireBranchesToBeUpToDate,
@@ -102,6 +104,7 @@ export function createGithubRepoPushAction(options: {
gitAuthorName,
gitAuthorEmail,
requireCodeOwnerReviews = false,
dismissStaleReviews = false,
bypassPullRequestAllowances,
requiredStatusCheckContexts = [],
requireBranchesToBeUpToDate = true,
@@ -148,6 +151,7 @@ export function createGithubRepoPushAction(options: {
gitCommitMessage,
gitAuthorName,
gitAuthorEmail,
dismissStaleReviews,
);
ctx.output('remoteUrl', remoteUrl);
@@ -263,6 +263,7 @@ export async function initRepoPushAndProtect(
gitCommitMessage?: string,
gitAuthorName?: string,
gitAuthorEmail?: string,
dismissStaleReviews?: boolean,
) {
const gitAuthorInfo = {
name: gitAuthorName
@@ -303,6 +304,7 @@ export async function initRepoPushAndProtect(
requiredStatusCheckContexts,
requireBranchesToBeUpToDate,
enforceAdmins: protectEnforceAdmins,
dismissStaleReviews: dismissStaleReviews,
});
} catch (e) {
assertError(e);
@@ -38,6 +38,12 @@ const requireCodeOwnerReviews = {
'Require an approved review in PR including files with a designated Code Owner',
type: 'boolean',
};
const dismissStaleReviews = {
title: 'Dismiss Stale Reviews',
description:
'New reviewable commits pushed to a matching branch will dismiss pull request review approvals.',
type: 'boolean',
};
const requiredStatusCheckContexts = {
title: 'Required Status Check Contexts',
description:
@@ -207,6 +213,7 @@ export { bypassPullRequestAllowances };
export { repoUrl };
export { repoVisibility };
export { requireCodeOwnerReviews };
export { dismissStaleReviews };
export { requiredStatusCheckContexts };
export { requireBranchesToBeUpToDate };
export { sourcePath };
@@ -193,6 +193,7 @@ type BranchProtectionOptions = {
requireBranchesToBeUpToDate?: boolean;
defaultBranch?: string;
enforceAdmins?: boolean;
dismissStaleReviews?: boolean;
};
export const enableBranchProtectionOnDefaultRepoBranch = async ({
@@ -206,6 +207,7 @@ export const enableBranchProtectionOnDefaultRepoBranch = async ({
requireBranchesToBeUpToDate = true,
defaultBranch = 'master',
enforceAdmins = true,
dismissStaleReviews = false,
}: BranchProtectionOptions): Promise<void> => {
const tryOnce = async () => {
try {
@@ -233,6 +235,7 @@ export const enableBranchProtectionOnDefaultRepoBranch = async ({
required_approving_review_count: 1,
require_code_owner_reviews: requireCodeOwnerReviews,
bypass_pull_request_allowances: bypassPullRequestAllowances,
dismiss_stale_reviews: dismissStaleReviews,
},
});
} catch (e) {
@@ -671,6 +671,7 @@ describe('publish:github', () => {
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: false,
});
await action.handler({
@@ -691,6 +692,7 @@ describe('publish:github', () => {
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: false,
});
await action.handler({
@@ -711,6 +713,7 @@ describe('publish:github', () => {
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: false,
});
});
@@ -737,6 +740,7 @@ describe('publish:github', () => {
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: false,
});
await action.handler({
@@ -757,6 +761,7 @@ describe('publish:github', () => {
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: false,
dismissStaleReviews: false,
});
await action.handler({
@@ -777,6 +782,7 @@ describe('publish:github', () => {
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: false,
});
});
@@ -803,6 +809,7 @@ describe('publish:github', () => {
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: false,
});
await action.handler({
@@ -824,6 +831,7 @@ describe('publish:github', () => {
requiredStatusCheckContexts: ['statusCheck'],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: false,
});
await action.handler({
@@ -845,6 +853,7 @@ describe('publish:github', () => {
requiredStatusCheckContexts: ['statusCheck'],
requireBranchesToBeUpToDate: false,
enforceAdmins: true,
dismissStaleReviews: false,
});
await action.handler({
@@ -865,6 +874,7 @@ describe('publish:github', () => {
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: false,
});
});
@@ -922,4 +932,73 @@ describe('publish:github', () => {
names: ['node.js'],
});
});
it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of dismissStaleReviews', async () => {
mockOctokit.rest.users.getByUsername.mockResolvedValue({
data: { type: 'User' },
});
mockOctokit.rest.repos.createForAuthenticatedUser.mockResolvedValue({
data: {
name: 'repo',
},
});
await action.handler(mockContext);
expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({
owner: 'owner',
client: mockOctokit,
repoName: 'repo',
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: false,
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
dismissStaleReviews: true,
},
});
expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({
owner: 'owner',
client: mockOctokit,
repoName: 'repo',
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: true,
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
dismissStaleReviews: false,
},
});
expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({
owner: 'owner',
client: mockOctokit,
repoName: 'repo',
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
enforceAdmins: true,
dismissStaleReviews: false,
});
});
});
@@ -68,6 +68,7 @@ export function createPublishGithubAction(options: {
}
| undefined;
requireCodeOwnerReviews?: boolean;
dismissStaleReviews?: boolean;
requiredStatusCheckContexts?: string[];
requireBranchesToBeUpToDate?: boolean;
repoVisibility?: 'private' | 'internal' | 'public';
@@ -103,6 +104,7 @@ export function createPublishGithubAction(options: {
access: inputProps.access,
bypassPullRequestAllowances: inputProps.bypassPullRequestAllowances,
requireCodeOwnerReviews: inputProps.requireCodeOwnerReviews,
dismissStaleReviews: inputProps.dismissStaleReviews,
requiredStatusCheckContexts: inputProps.requiredStatusCheckContexts,
requireBranchesToBeUpToDate: inputProps.requireBranchesToBeUpToDate,
repoVisibility: inputProps.repoVisibility,
@@ -138,6 +140,7 @@ export function createPublishGithubAction(options: {
homepage,
access,
requireCodeOwnerReviews = false,
dismissStaleReviews = false,
bypassPullRequestAllowances,
requiredStatusCheckContexts = [],
requireBranchesToBeUpToDate = true,
@@ -213,6 +216,7 @@ export function createPublishGithubAction(options: {
gitCommitMessage,
gitAuthorName,
gitAuthorEmail,
dismissStaleReviews,
);
ctx.output('remoteUrl', remoteUrl);