Merge pull request #15681 from tgrieger-sf/feature/implementing-new-github-publish-parameters

Add features for "publish:github" action
This commit is contained in:
Fredrik Adelöw
2023-01-16 15:07:03 +01:00
committed by GitHub
10 changed files with 834 additions and 3 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
Implement "Required approving review count", "Restrictions", and "Required commit signing" support for "publish:github" action
+27
View File
@@ -211,6 +211,14 @@ export function createGithubRepoCreateAction(options: {
apps?: string[] | undefined;
}
| undefined;
requiredApprovingReviewCount?: number | undefined;
restrictions?:
| {
users: string[];
teams: string[];
apps?: string[] | undefined;
}
| undefined;
requiredStatusCheckContexts?: string[] | undefined;
requireBranchesToBeUpToDate?: boolean | undefined;
requiredConversationResolution?: boolean | undefined;
@@ -236,6 +244,7 @@ export function createGithubRepoCreateAction(options: {
hasIssues?: boolean | undefined;
token?: string | undefined;
topics?: string[] | undefined;
requireCommitSigning?: boolean | undefined;
}>;
// @public
@@ -261,11 +270,20 @@ export function createGithubRepoPushAction(options: {
apps?: string[];
}
| undefined;
requiredApprovingReviewCount?: number | undefined;
restrictions?:
| {
users: string[];
teams: string[];
apps?: string[];
}
| undefined;
requiredStatusCheckContexts?: string[] | undefined;
requireBranchesToBeUpToDate?: boolean | undefined;
requiredConversationResolution?: boolean | undefined;
sourcePath?: string | undefined;
token?: string | undefined;
requiredCommitSigning?: boolean | undefined;
}>;
// @public
@@ -408,6 +426,14 @@ export function createPublishGithubAction(options: {
apps?: string[];
}
| undefined;
requiredApprovingReviewCount?: number | undefined;
restrictions?:
| {
users: string[];
teams: string[];
apps?: string[];
}
| undefined;
requireCodeOwnerReviews?: boolean | undefined;
dismissStaleReviews?: boolean | undefined;
requiredStatusCheckContexts?: string[] | undefined;
@@ -435,6 +461,7 @@ export function createPublishGithubAction(options: {
hasIssues?: boolean | undefined;
token?: string | undefined;
topics?: string[] | undefined;
requiredCommitSigning?: boolean | undefined;
}>;
// @public
@@ -59,6 +59,12 @@ export function createGithubRepoCreateAction(options: {
teams?: string[];
apps?: string[];
};
requiredApprovingReviewCount?: number;
restrictions?: {
users: string[];
teams: string[];
apps?: string[];
};
requiredStatusCheckContexts?: string[];
requireBranchesToBeUpToDate?: boolean;
requiredConversationResolution?: boolean;
@@ -83,6 +89,7 @@ export function createGithubRepoCreateAction(options: {
hasIssues?: boolean;
token?: string;
topics?: string[];
requireCommitSigning?: boolean;
}>({
id: 'github:repo:create',
description: 'Creates a GitHub repository.',
@@ -97,6 +104,8 @@ export function createGithubRepoCreateAction(options: {
access: inputProps.access,
requireCodeOwnerReviews: inputProps.requireCodeOwnerReviews,
bypassPullRequestAllowances: inputProps.bypassPullRequestAllowances,
requiredApprovingReviewCount: inputProps.requiredApprovingReviewCount,
restrictions: inputProps.restrictions,
requiredStatusCheckContexts: inputProps.requiredStatusCheckContexts,
requireBranchesToBeUpToDate: inputProps.requireBranchesToBeUpToDate,
requiredConversationResolution:
@@ -115,6 +124,7 @@ export function createGithubRepoCreateAction(options: {
hasIssues: inputProps.hasIssues,
token: inputProps.token,
topics: inputProps.topics,
requiredCommitSigning: inputProps.requiredCommitSigning,
},
},
output: {
@@ -287,6 +287,10 @@ describe('github:repo:push', () => {
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
restrictions: undefined,
});
await action.handler({
@@ -309,6 +313,10 @@ describe('github:repo:push', () => {
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
restrictions: undefined,
});
await action.handler({
@@ -331,6 +339,10 @@ describe('github:repo:push', () => {
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
restrictions: undefined,
});
});
@@ -356,6 +368,10 @@ describe('github:repo:push', () => {
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
restrictions: undefined,
});
await action.handler({
@@ -378,6 +394,10 @@ describe('github:repo:push', () => {
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
restrictions: undefined,
});
await action.handler({
@@ -400,6 +420,10 @@ describe('github:repo:push', () => {
requiredConversationResolution: false,
enforceAdmins: false,
dismissStaleReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
restrictions: undefined,
});
});
@@ -425,6 +449,10 @@ describe('github:repo:push', () => {
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
restrictions: undefined,
});
await action.handler({
@@ -449,6 +477,10 @@ describe('github:repo:push', () => {
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
restrictions: undefined,
});
await action.handler({
@@ -472,6 +504,10 @@ describe('github:repo:push', () => {
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
restrictions: undefined,
});
await action.handler({
@@ -496,6 +532,10 @@ describe('github:repo:push', () => {
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
restrictions: undefined,
});
});
@@ -540,6 +580,10 @@ describe('github:repo:push', () => {
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
restrictions: undefined,
});
await action.handler({
@@ -562,6 +606,10 @@ describe('github:repo:push', () => {
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: true,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
restrictions: undefined,
});
await action.handler({
@@ -584,6 +632,10 @@ describe('github:repo:push', () => {
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
restrictions: undefined,
});
});
@@ -609,6 +661,10 @@ describe('github:repo:push', () => {
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
restrictions: undefined,
});
await action.handler({
@@ -631,6 +687,10 @@ describe('github:repo:push', () => {
requiredConversationResolution: true,
enforceAdmins: true,
dismissStaleReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
restrictions: undefined,
});
await action.handler({
@@ -653,6 +713,10 @@ describe('github:repo:push', () => {
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
restrictions: undefined,
});
});
});
@@ -57,11 +57,20 @@ export function createGithubRepoPushAction(options: {
apps?: string[];
}
| undefined;
requiredApprovingReviewCount?: number;
restrictions?:
| {
users: string[];
teams: string[];
apps?: string[];
}
| undefined;
requiredStatusCheckContexts?: string[];
requireBranchesToBeUpToDate?: boolean;
requiredConversationResolution?: boolean;
sourcePath?: string;
token?: string;
requiredCommitSigning?: boolean;
}>({
id: 'github:repo:push',
description:
@@ -76,6 +85,8 @@ export function createGithubRepoPushAction(options: {
dismissStaleReviews: inputProps.dismissStaleReviews,
requiredStatusCheckContexts: inputProps.requiredStatusCheckContexts,
bypassPullRequestAllowances: inputProps.bypassPullRequestAllowances,
requiredApprovingReviewCount: inputProps.requiredApprovingReviewCount,
restrictions: inputProps.restrictions,
requireBranchesToBeUpToDate: inputProps.requireBranchesToBeUpToDate,
requiredConversationResolution:
inputProps.requiredConversationResolution,
@@ -87,6 +98,7 @@ export function createGithubRepoPushAction(options: {
gitAuthorEmail: inputProps.gitAuthorEmail,
sourcePath: inputProps.sourcePath,
token: inputProps.token,
requiredCommitSigning: inputProps.requiredCommitSigning,
},
},
output: {
@@ -109,10 +121,13 @@ export function createGithubRepoPushAction(options: {
requireCodeOwnerReviews = false,
dismissStaleReviews = false,
bypassPullRequestAllowances,
requiredApprovingReviewCount = 1,
restrictions,
requiredStatusCheckContexts = [],
requireBranchesToBeUpToDate = true,
requiredConversationResolution = false,
token: providedToken,
requiredCommitSigning = false,
} = ctx.input;
const { owner, repo } = parseRepoUrl(repoUrl, integrations);
@@ -148,6 +163,8 @@ export function createGithubRepoPushAction(options: {
repo,
requireCodeOwnerReviews,
bypassPullRequestAllowances,
requiredApprovingReviewCount,
restrictions,
requiredStatusCheckContexts,
requireBranchesToBeUpToDate,
requiredConversationResolution,
@@ -157,6 +174,7 @@ export function createGithubRepoPushAction(options: {
gitAuthorName,
gitAuthorEmail,
dismissStaleReviews,
requiredCommitSigning,
);
ctx.output('remoteUrl', remoteUrl);
@@ -271,6 +271,14 @@ export async function initRepoPushAndProtect(
apps?: string[];
}
| undefined,
requiredApprovingReviewCount: number,
restrictions:
| {
users: string[];
teams: string[];
apps?: string[];
}
| undefined,
requiredStatusCheckContexts: string[],
requireBranchesToBeUpToDate: boolean,
requiredConversationResolution: boolean,
@@ -280,6 +288,7 @@ export async function initRepoPushAndProtect(
gitAuthorName?: string,
gitAuthorEmail?: string,
dismissStaleReviews?: boolean,
requiredCommitSigning?: boolean,
) {
const gitAuthorInfo = {
name: gitAuthorName
@@ -316,12 +325,15 @@ export async function initRepoPushAndProtect(
logger,
defaultBranch,
bypassPullRequestAllowances,
requiredApprovingReviewCount,
restrictions,
requireCodeOwnerReviews,
requiredStatusCheckContexts,
requireBranchesToBeUpToDate,
requiredConversationResolution,
enforceAdmins: protectEnforceAdmins,
dismissStaleReviews: dismissStaleReviews,
requiredCommitSigning: requiredCommitSigning,
});
} catch (e) {
assertError(e);
@@ -225,6 +225,46 @@ const sourcePath = {
type: 'string',
};
const requiredApprovingReviewCount = {
title: 'Required approving review count',
type: 'number',
description: `Specify the number of reviewers required to approve pull requests. Use a number between 1 and 6 or 0 to not require reviewers. Defaults to 1.`,
};
const restrictions = {
title: 'Restrict who can push to the protected branch',
description:
'Restrict who can push to the protected branch. User, app, and team restrictions are only available for organization-owned repositories.',
type: 'object',
additionalProperties: false,
properties: {
apps: {
type: 'array',
items: {
type: 'string',
},
},
users: {
type: 'array',
items: {
type: 'string',
},
},
teams: {
type: 'array',
items: {
type: 'string',
},
},
},
};
const requiredCommitSigning = {
title: 'Require commit signing',
type: 'boolean',
description: `Require commit signing so that you must sign commits on this branch.`,
};
export { access };
export { allowMergeCommit };
export { allowRebaseMerge };
@@ -243,6 +283,8 @@ export { homepage };
export { protectDefaultBranch };
export { protectEnforceAdmins };
export { bypassPullRequestAllowances };
export { requiredApprovingReviewCount };
export { restrictions };
export { repoUrl };
export { repoVisibility };
export { requireCodeOwnerReviews };
@@ -256,3 +298,4 @@ export { hasWiki };
export { sourcePath };
export { token };
export { topics };
export { requiredCommitSigning };
@@ -190,11 +190,18 @@ type BranchProtectionOptions = {
teams?: string[];
apps?: string[];
};
requiredApprovingReviewCount?: number;
restrictions?: {
users: string[];
teams: string[];
apps?: string[];
};
requireBranchesToBeUpToDate?: boolean;
requiredConversationResolution?: boolean;
defaultBranch?: string;
enforceAdmins?: boolean;
dismissStaleReviews?: boolean;
requiredCommitSigning?: boolean;
};
export const enableBranchProtectionOnDefaultRepoBranch = async ({
@@ -204,12 +211,15 @@ export const enableBranchProtectionOnDefaultRepoBranch = async ({
logger,
requireCodeOwnerReviews,
bypassPullRequestAllowances,
requiredApprovingReviewCount,
restrictions,
requiredStatusCheckContexts = [],
requireBranchesToBeUpToDate = true,
requiredConversationResolution = false,
defaultBranch = 'master',
enforceAdmins = true,
dismissStaleReviews = false,
requiredCommitSigning = false,
}: BranchProtectionOptions): Promise<void> => {
const tryOnce = async () => {
try {
@@ -231,16 +241,24 @@ export const enableBranchProtectionOnDefaultRepoBranch = async ({
strict: requireBranchesToBeUpToDate,
contexts: requiredStatusCheckContexts,
},
restrictions: null,
restrictions: restrictions ?? null,
enforce_admins: enforceAdmins,
required_pull_request_reviews: {
required_approving_review_count: 1,
required_approving_review_count: requiredApprovingReviewCount,
require_code_owner_reviews: requireCodeOwnerReviews,
bypass_pull_request_allowances: bypassPullRequestAllowances,
dismiss_stale_reviews: dismissStaleReviews,
},
required_conversation_resolution: requiredConversationResolution,
});
if (requiredCommitSigning) {
await client.rest.repos.createCommitSignatureProtection({
owner,
repo: repoName,
branch: defaultBranch,
});
}
} catch (e) {
assertError(e);
if (
@@ -788,11 +788,15 @@ describe('publish:github', () => {
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
@@ -810,11 +814,15 @@ describe('publish:github', () => {
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: true,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
@@ -832,11 +840,15 @@ describe('publish:github', () => {
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
});
@@ -860,11 +872,15 @@ describe('publish:github', () => {
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
@@ -882,11 +898,15 @@ describe('publish:github', () => {
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: false,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
@@ -904,11 +924,15 @@ describe('publish:github', () => {
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
});
@@ -932,11 +956,15 @@ describe('publish:github', () => {
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
@@ -956,11 +984,15 @@ describe('publish:github', () => {
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
requiredStatusCheckContexts: ['statusCheck'],
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
@@ -979,11 +1011,15 @@ describe('publish:github', () => {
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: ['statusCheck'],
requireBranchesToBeUpToDate: false,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
@@ -1001,11 +1037,15 @@ describe('publish:github', () => {
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
});
@@ -1084,11 +1124,15 @@ describe('publish:github', () => {
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
@@ -1106,11 +1150,15 @@ describe('publish:github', () => {
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: true,
requiredCommitSigning: false,
});
await action.handler({
@@ -1128,11 +1176,15 @@ describe('publish:github', () => {
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
});
it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of requiredConversationResolution', async () => {
@@ -1155,11 +1207,15 @@ describe('publish:github', () => {
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
@@ -1177,11 +1233,15 @@ describe('publish:github', () => {
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: true,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
@@ -1199,11 +1259,567 @@ describe('publish:github', () => {
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
});
it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of requiredApprovingReviewCount', 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,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
requiredApprovingReviewCount: 2,
},
});
expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({
owner: 'owner',
client: mockOctokit,
repoName: 'repo',
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 2,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
requiredApprovingReviewCount: 0,
},
});
expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({
owner: 'owner',
client: mockOctokit,
repoName: 'repo',
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 0,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
});
it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of restrictions', 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,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
restrictions: {
users: ['user'],
teams: [],
},
},
});
expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({
owner: 'owner',
client: mockOctokit,
repoName: 'repo',
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: {
users: ['user'],
teams: [],
},
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
restrictions: {
users: [],
teams: ['team'],
},
},
});
expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({
owner: 'owner',
client: mockOctokit,
repoName: 'repo',
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: {
users: [],
teams: ['team'],
},
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
restrictions: {
users: [],
teams: [],
apps: ['app'],
},
},
});
expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({
owner: 'owner',
client: mockOctokit,
repoName: 'repo',
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: {
users: [],
teams: [],
apps: ['app'],
},
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
restrictions: {
users: ['user'],
teams: ['team'],
apps: ['app'],
},
},
});
expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({
owner: 'owner',
client: mockOctokit,
repoName: 'repo',
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: {
users: ['user'],
teams: ['team'],
apps: ['app'],
},
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
restrictions: {
users: ['user1', 'user2'],
teams: ['team1', 'team2'],
apps: ['app1', 'app2'],
},
},
});
expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({
owner: 'owner',
client: mockOctokit,
repoName: 'repo',
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: {
users: ['user1', 'user2'],
teams: ['team1', 'team2'],
apps: ['app1', 'app2'],
},
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
});
it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of requiredCommitSigning', 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,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
requiredCommitSigning: false,
},
});
expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({
owner: 'owner',
client: mockOctokit,
repoName: 'repo',
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
requiredCommitSigning: true,
},
});
expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({
owner: 'owner',
client: mockOctokit,
repoName: 'repo',
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: true,
});
});
it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of bypassPullRequestAllowances', 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,
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
bypassPullRequestAllowances: {
users: ['user'],
},
},
});
expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({
owner: 'owner',
client: mockOctokit,
repoName: 'repo',
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: {
users: ['user'],
},
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
bypassPullRequestAllowances: {
teams: ['team'],
},
},
});
expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({
owner: 'owner',
client: mockOctokit,
repoName: 'repo',
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: {
teams: ['team'],
},
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
bypassPullRequestAllowances: {
apps: ['app'],
},
},
});
expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({
owner: 'owner',
client: mockOctokit,
repoName: 'repo',
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: {
apps: ['app'],
},
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
bypassPullRequestAllowances: {
users: ['user'],
teams: ['team'],
apps: ['app'],
},
},
});
expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({
owner: 'owner',
client: mockOctokit,
repoName: 'repo',
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: {
users: ['user'],
teams: ['team'],
apps: ['app'],
},
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
bypassPullRequestAllowances: {
users: ['user1', 'user2'],
teams: ['team1', 'team2'],
apps: ['app1', 'app2'],
},
},
});
expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({
owner: 'owner',
client: mockOctokit,
repoName: 'repo',
logger: mockContext.logger,
defaultBranch: 'master',
requireCodeOwnerReviews: false,
bypassPullRequestAllowances: {
users: ['user1', 'user2'],
teams: ['team1', 'team2'],
apps: ['app1', 'app2'],
},
requiredApprovingReviewCount: 1,
restrictions: undefined,
requiredStatusCheckContexts: [],
requireBranchesToBeUpToDate: true,
requiredConversationResolution: false,
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
});
});
});
@@ -69,6 +69,14 @@ export function createPublishGithubAction(options: {
apps?: string[];
}
| undefined;
requiredApprovingReviewCount?: number;
restrictions?:
| {
users: string[];
teams: string[];
apps?: string[];
}
| undefined;
requireCodeOwnerReviews?: boolean;
dismissStaleReviews?: boolean;
requiredStatusCheckContexts?: string[];
@@ -95,6 +103,7 @@ export function createPublishGithubAction(options: {
hasIssues?: boolean | undefined;
token?: string;
topics?: string[];
requiredCommitSigning?: boolean;
}>({
id: 'publish:github',
description:
@@ -109,6 +118,8 @@ export function createPublishGithubAction(options: {
homepage: inputProps.homepage,
access: inputProps.access,
bypassPullRequestAllowances: inputProps.bypassPullRequestAllowances,
requiredApprovingReviewCount: inputProps.requiredApprovingReviewCount,
restrictions: inputProps.restrictions,
requireCodeOwnerReviews: inputProps.requireCodeOwnerReviews,
dismissStaleReviews: inputProps.dismissStaleReviews,
requiredStatusCheckContexts: inputProps.requiredStatusCheckContexts,
@@ -136,6 +147,7 @@ export function createPublishGithubAction(options: {
hasIssues: inputProps.hasIssues,
token: inputProps.token,
topics: inputProps.topics,
requiredCommitSigning: inputProps.requiredCommitSigning,
},
},
output: {
@@ -155,6 +167,8 @@ export function createPublishGithubAction(options: {
requireCodeOwnerReviews = false,
dismissStaleReviews = false,
bypassPullRequestAllowances,
requiredApprovingReviewCount = 1,
restrictions,
requiredStatusCheckContexts = [],
requireBranchesToBeUpToDate = true,
requiredConversationResolution = false,
@@ -178,6 +192,7 @@ export function createPublishGithubAction(options: {
hasIssues = undefined,
topics,
token: providedToken,
requiredCommitSigning = false,
} = ctx.input;
const octokitOptions = await getOctokitOptions({
@@ -233,6 +248,8 @@ export function createPublishGithubAction(options: {
repo,
requireCodeOwnerReviews,
bypassPullRequestAllowances,
requiredApprovingReviewCount,
restrictions,
requiredStatusCheckContexts,
requireBranchesToBeUpToDate,
requiredConversationResolution,
@@ -242,6 +259,7 @@ export function createPublishGithubAction(options: {
gitAuthorName,
gitAuthorEmail,
dismissStaleReviews,
requiredCommitSigning,
);
ctx.output('remoteUrl', remoteUrl);