feat: adding requiredLinearHistory property

Signed-off-by: Paul Mowat <paul.mowat@oneadvanced.com>
This commit is contained in:
Paul Mowat
2024-12-13 16:12:35 +00:00
parent 703048420a
commit 7df6179b7f
14 changed files with 136 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend-module-github': patch
---
adding requiredLinearHistory property for branch protection settings
@@ -79,6 +79,7 @@ export function createGithubBranchProtectionAction(options: {
requiredConversationResolution?: boolean | undefined;
requireLastPushApproval?: boolean | undefined;
requiredCommitSigning?: boolean | undefined;
requiredLinearHistory?: boolean | undefined;
token?: string | undefined;
},
JsonObject
@@ -270,6 +271,7 @@ export function createGithubRepoCreateAction(options: {
}
| undefined;
requireCommitSigning?: boolean | undefined;
requiredLinearHistory?: boolean | undefined;
customProperties?:
| {
[key: string]: string;
@@ -317,6 +319,7 @@ export function createGithubRepoPushAction(options: {
sourcePath?: string | undefined;
token?: string | undefined;
requiredCommitSigning?: boolean | undefined;
requiredLinearHistory?: boolean | undefined;
requireLastPushApproval?: boolean | undefined;
},
JsonObject
@@ -430,6 +433,7 @@ export function createPublishGithubAction(options: {
}
| undefined;
requiredCommitSigning?: boolean | undefined;
requiredLinearHistory?: boolean | undefined;
customProperties?:
| {
[key: string]: string;
@@ -43,6 +43,7 @@ type BranchProtectionOptions = {
enforceAdmins?: boolean;
dismissStaleReviews?: boolean;
requiredCommitSigning?: boolean;
requiredLinearHistory?: boolean;
};
export const enableBranchProtectionOnDefaultRepoBranch = async ({
@@ -62,6 +63,7 @@ export const enableBranchProtectionOnDefaultRepoBranch = async ({
enforceAdmins = true,
dismissStaleReviews = false,
requiredCommitSigning = false,
requiredLinearHistory = false,
}: BranchProtectionOptions): Promise<void> => {
const tryOnce = async () => {
try {
@@ -93,6 +95,7 @@ export const enableBranchProtectionOnDefaultRepoBranch = async ({
require_last_push_approval: requireLastPushApproval,
},
required_conversation_resolution: requiredConversationResolution,
required_linear_history: requiredLinearHistory,
});
if (requiredCommitSigning) {
@@ -1097,6 +1097,7 @@ describe('publish:github', () => {
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
requiredLinearHistory: false,
});
await action.handler({
@@ -1126,6 +1127,7 @@ describe('publish:github', () => {
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
requiredLinearHistory: false,
});
await action.handler({
@@ -1154,6 +1156,7 @@ describe('publish:github', () => {
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
requiredLinearHistory: false,
});
await action.handler({
@@ -1181,6 +1184,7 @@ describe('publish:github', () => {
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
requiredLinearHistory: false,
});
});
@@ -1269,6 +1273,7 @@ describe('publish:github', () => {
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
requiredLinearHistory: false,
});
await action.handler({
@@ -1302,6 +1307,7 @@ describe('publish:github', () => {
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
requiredLinearHistory: false,
});
await action.handler({
@@ -1335,6 +1341,7 @@ describe('publish:github', () => {
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
requiredLinearHistory: false,
});
await action.handler({
@@ -1370,6 +1377,7 @@ describe('publish:github', () => {
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
requiredLinearHistory: false,
});
await action.handler({
@@ -1405,6 +1413,7 @@ describe('publish:github', () => {
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
requiredLinearHistory: false,
});
await action.handler({
@@ -1440,6 +1449,7 @@ describe('publish:github', () => {
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
requiredLinearHistory: false,
});
});
it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of bypassPullRequestAllowances', async () => {
@@ -1472,6 +1482,7 @@ describe('publish:github', () => {
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
requiredLinearHistory: false,
});
await action.handler({
@@ -1503,6 +1514,7 @@ describe('publish:github', () => {
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
requiredLinearHistory: false,
});
await action.handler({
@@ -1534,6 +1546,7 @@ describe('publish:github', () => {
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
requiredLinearHistory: false,
});
await action.handler({
@@ -1565,6 +1578,7 @@ describe('publish:github', () => {
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
requiredLinearHistory: false,
});
await action.handler({
@@ -1600,6 +1614,7 @@ describe('publish:github', () => {
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
requiredLinearHistory: false,
});
await action.handler({
@@ -1635,6 +1650,7 @@ describe('publish:github', () => {
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
requiredLinearHistory: false,
});
});
@@ -1664,6 +1680,11 @@ describe('publish:github', () => {
defaultValue: false,
overrideValue: true,
},
{
inputProperty: 'requiredLinearHistory',
defaultValue: false,
overrideValue: true,
},
{
inputProperty: 'protectEnforceAdmins',
defaultValue: true,
@@ -1712,6 +1733,7 @@ describe('publish:github', () => {
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
requiredLinearHistory: false,
[octokitParameter || inputProperty]: defaultValue,
});
@@ -1740,6 +1762,7 @@ describe('publish:github', () => {
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
requiredLinearHistory: false,
[octokitParameter || inputProperty]: overrideValue,
});
@@ -1768,6 +1791,7 @@ describe('publish:github', () => {
enforceAdmins: true,
dismissStaleReviews: false,
requiredCommitSigning: false,
requiredLinearHistory: false,
[octokitParameter || inputProperty]: defaultValue,
});
},
@@ -115,6 +115,7 @@ export function createPublishGithubAction(options: {
includeClaimKeys?: string[];
};
requiredCommitSigning?: boolean;
requiredLinearHistory?: boolean;
customProperties?: { [key: string]: string };
}>({
id: 'publish:github',
@@ -165,6 +166,7 @@ export function createPublishGithubAction(options: {
secrets: inputProps.secrets,
oidcCustomization: inputProps.oidcCustomization,
requiredCommitSigning: inputProps.requiredCommitSigning,
requiredLinearHistory: inputProps.requiredLinearHistory,
customProperties: inputProps.customProperties,
},
},
@@ -217,6 +219,7 @@ export function createPublishGithubAction(options: {
token: providedToken,
customProperties,
requiredCommitSigning = false,
requiredLinearHistory = false,
} = ctx.input;
const octokitOptions = await getOctokitOptions({
@@ -289,6 +292,7 @@ export function createPublishGithubAction(options: {
gitAuthorEmail,
dismissStaleReviews,
requiredCommitSigning,
requiredLinearHistory,
);
ctx.output('commitHash', commitResult?.commitHash);
@@ -98,6 +98,7 @@ describe('github:branch-protection:create', () => {
require_last_push_approval: false,
},
required_conversation_resolution: false,
required_linear_history: false,
});
expect(
mockOctokit.rest.repos.createCommitSignatureProtection,
@@ -130,6 +131,7 @@ describe('github:branch-protection:create', () => {
require_last_push_approval: false,
},
required_conversation_resolution: false,
required_linear_history: false,
});
expect(
mockOctokit.rest.repos.createCommitSignatureProtection,
@@ -162,6 +164,44 @@ describe('github:branch-protection:create', () => {
require_last_push_approval: true,
},
required_conversation_resolution: true,
required_linear_history: false,
});
expect(
mockOctokit.rest.repos.createCommitSignatureProtection,
).toHaveBeenCalledWith({
owner: 'owner',
repo: 'repo',
branch: 'master',
});
});
it('should create branch protection with params and require linear history', async () => {
const input = yaml.parse(examples[3].example).steps[0].input;
const ctx = Object.assign({}, mockContext, { input });
await action.handler(ctx);
expect(mockOctokit.rest.repos.updateBranchProtection).toHaveBeenCalledWith({
mediaType: {
previews: ['luke-cage-preview'],
},
owner: 'owner',
repo: 'repo',
branch: 'master',
required_status_checks: {
strict: true,
contexts: ['test'],
},
restrictions: null,
enforce_admins: true,
required_pull_request_reviews: {
required_approving_review_count: 1,
require_code_owner_reviews: true,
bypass_pull_request_allowances: undefined,
dismiss_stale_reviews: true,
require_last_push_approval: true,
},
required_conversation_resolution: true,
required_linear_history: true,
});
expect(
mockOctokit.rest.repos.createCommitSignatureProtection,
@@ -67,4 +67,25 @@ export const examples: TemplateExample[] = [
],
}),
},
{
description: `GitHub Branch Protection and required linear history on default branch.`,
example: yaml.stringify({
steps: [
{
action: 'github:branch-protection:create',
name: 'Setup Branch Protection',
input: {
repoUrl: 'github.com?repo=repo&owner=owner',
requireCodeOwnerReviews: true,
requiredStatusCheckContexts: ['test'],
dismissStaleReviews: true,
requireLastPushApproval: true,
requiredConversationResolution: true,
requiredCommitSigning: true,
requiredLinearHistory: true,
},
},
],
}),
},
];
@@ -96,6 +96,7 @@ describe('github:branch-protection:create', () => {
require_last_push_approval: false,
},
required_conversation_resolution: false,
required_linear_history: false,
});
expect(
mockOctokit.rest.repos.createCommitSignatureProtection,
@@ -132,6 +133,7 @@ describe('github:branch-protection:create', () => {
require_last_push_approval: false,
},
required_conversation_resolution: false,
required_linear_history: false,
});
expect(
mockOctokit.rest.repos.createCommitSignatureProtection,
@@ -167,6 +169,7 @@ describe('github:branch-protection:create', () => {
requiredConversationResolution: true,
requireLastPushApproval: true,
requiredCommitSigning: true,
requiredLinearHistory: true,
},
});
@@ -199,6 +202,7 @@ describe('github:branch-protection:create', () => {
require_last_push_approval: true,
},
required_conversation_resolution: true,
required_linear_history: true,
});
expect(
mockOctokit.rest.repos.createCommitSignatureProtection,
@@ -62,6 +62,7 @@ export function createGithubBranchProtectionAction(options: {
requiredConversationResolution?: boolean;
requireLastPushApproval?: boolean;
requiredCommitSigning?: boolean;
requiredLinearHistory?: boolean;
token?: string;
}>({
id: 'github:branch-protection:create',
@@ -90,6 +91,7 @@ export function createGithubBranchProtectionAction(options: {
inputProps.requiredConversationResolution,
requireLastPushApproval: inputProps.requireLastPushApproval,
requiredCommitSigning: inputProps.requiredCommitSigning,
requiredLinearHistory: inputProps.requiredLinearHistory,
token: inputProps.token,
},
},
@@ -109,6 +111,7 @@ export function createGithubBranchProtectionAction(options: {
requiredConversationResolution = false,
requireLastPushApproval = false,
requiredCommitSigning = false,
requiredLinearHistory = false,
token: providedToken,
} = ctx.input;
@@ -147,6 +150,7 @@ export function createGithubBranchProtectionAction(options: {
enforceAdmins,
dismissStaleReviews,
requiredCommitSigning,
requiredLinearHistory,
});
},
});
@@ -100,6 +100,7 @@ export function createGithubRepoCreateAction(options: {
includeClaimKeys?: string[];
};
requireCommitSigning?: boolean;
requiredLinearHistory?: boolean;
customProperties?: { [key: string]: string };
}>({
id: 'github:repo:create',
@@ -140,6 +141,7 @@ export function createGithubRepoCreateAction(options: {
secrets: inputProps.secrets,
oidcCustomization: inputProps.oidcCustomization,
requiredCommitSigning: inputProps.requiredCommitSigning,
requiredLinearHistory: inputProps.requiredLinearHistory,
customProperties: inputProps.customProperties,
},
},
@@ -331,6 +331,7 @@ describe('github:repo:push', () => {
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
requiredLinearHistory: false,
restrictions: undefined,
});
@@ -359,6 +360,7 @@ describe('github:repo:push', () => {
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
requiredLinearHistory: false,
restrictions: undefined,
});
@@ -387,6 +389,7 @@ describe('github:repo:push', () => {
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
requiredLinearHistory: false,
restrictions: undefined,
});
@@ -415,6 +418,7 @@ describe('github:repo:push', () => {
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
requiredLinearHistory: false,
restrictions: undefined,
});
});
@@ -464,6 +468,11 @@ describe('github:repo:push', () => {
defaultValue: false,
overrideValue: true,
},
{
inputProperty: 'requiredLinearHistory',
defaultValue: false,
overrideValue: true,
},
{
inputProperty: 'protectEnforceAdmins',
defaultValue: true,
@@ -508,6 +517,7 @@ describe('github:repo:push', () => {
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
requiredLinearHistory: false,
restrictions: undefined,
[octokitParameter || inputProperty]: defaultValue,
});
@@ -536,6 +546,7 @@ describe('github:repo:push', () => {
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
requiredLinearHistory: false,
restrictions: undefined,
[octokitParameter || inputProperty]: overrideValue,
});
@@ -564,6 +575,7 @@ describe('github:repo:push', () => {
bypassPullRequestAllowances: undefined,
requiredApprovingReviewCount: 1,
requiredCommitSigning: false,
requiredLinearHistory: false,
restrictions: undefined,
[octokitParameter || inputProperty]: defaultValue,
});
@@ -75,6 +75,7 @@ export function createGithubRepoPushAction(options: {
sourcePath?: string;
token?: string;
requiredCommitSigning?: boolean;
requiredLinearHistory?: boolean;
requireLastPushApproval?: boolean;
}>({
id: 'github:repo:push',
@@ -106,6 +107,7 @@ export function createGithubRepoPushAction(options: {
sourcePath: inputProps.sourcePath,
token: inputProps.token,
requiredCommitSigning: inputProps.requiredCommitSigning,
requiredLinearHistory: inputProps.requiredLinearHistory,
},
},
output: {
@@ -137,6 +139,7 @@ export function createGithubRepoPushAction(options: {
requireLastPushApproval = false,
token: providedToken,
requiredCommitSigning = false,
requiredLinearHistory = false,
} = ctx.input;
const { owner, repo } = parseRepoUrl(repoUrl, integrations);
@@ -185,6 +188,7 @@ export function createGithubRepoPushAction(options: {
gitAuthorEmail,
dismissStaleReviews,
requiredCommitSigning,
requiredLinearHistory,
);
ctx.output('remoteUrl', remoteUrl);
@@ -371,6 +371,7 @@ export async function initRepoPushAndProtect(
gitAuthorEmail?: string,
dismissStaleReviews?: boolean,
requiredCommitSigning?: boolean,
requiredLinearHistory?: boolean,
): Promise<{ commitHash: string }> {
const gitAuthorInfo = {
name: gitAuthorName
@@ -416,6 +417,7 @@ export async function initRepoPushAndProtect(
enforceAdmins: protectEnforceAdmins,
dismissStaleReviews: dismissStaleReviews,
requiredCommitSigning: requiredCommitSigning,
requiredLinearHistory: requiredLinearHistory,
});
} catch (e) {
assertError(e);
@@ -270,6 +270,12 @@ const requiredCommitSigning = {
description: `Require commit signing so that you must sign commits on this branch.`,
};
const requiredLinearHistory = {
title: 'Require linear history',
type: 'boolean',
description: `Prevent merge commits from being pushed to matching branches.`,
};
const repoVariables = {
title: 'Repository Variables',
description: `Variables attached to the repository`,
@@ -346,6 +352,7 @@ export { sourcePath };
export { token };
export { topics };
export { requiredCommitSigning };
export { requiredLinearHistory };
export { repoVariables };
export { secrets };
export { oidcCustomization };