Skip to content

Commit 3a8c7c0

Browse files
authoredFeb 15, 2024
fix: gate branch protection settings on options exclusions (#1310)
## PR Checklist - [x] Addresses an existing open issue: fixes #1171 - [x] That issue was marked as [`status: accepting prs`](https://github.com/JoshuaKGoldberg/create-typescript-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22status%3A+accepting+prs%22) - [x] Steps in [CONTRIBUTING.md](https://github.com/JoshuaKGoldberg/create-typescript-app/blob/main/.github/CONTRIBUTING.md) were taken ## Overview This way, when creating/initializing/migrating a repository, branch protection settings won't be created for excluded options' CI flows.
1 parent 050cacf commit 3a8c7c0

File tree

2 files changed

+137
-14
lines changed

2 files changed

+137
-14
lines changed
 

‎src/steps/initializeBranchProtectionSettings.test.ts

+123-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,27 @@
11
import { Octokit } from "octokit";
22
import { MockInstance, describe, expect, it, vi } from "vitest";
33

4+
import { Options } from "../shared/types.js";
45
import { initializeBranchProtectionSettings } from "./initializeGitHubRepository/initializeBranchProtectionSettings.js";
56

67
const createMockOctokit = (request: MockInstance) =>
78
({
89
request,
910
}) as unknown as Octokit;
1011

11-
const stubValues = { owner: "", repository: "" };
12+
const stubOptions = {
13+
access: "public",
14+
description: "",
15+
directory: "",
16+
email: {
17+
github: "",
18+
npm: "",
19+
},
20+
mode: "create",
21+
owner: "",
22+
repository: "",
23+
title: "",
24+
} satisfies Options;
1225

1326
describe("migrateBranchProtectionSettings", () => {
1427
it("does not throw when the request receives a non-error response", async () => {
@@ -17,17 +30,72 @@ describe("migrateBranchProtectionSettings", () => {
1730
await expect(
1831
initializeBranchProtectionSettings(
1932
createMockOctokit(mockRequest),
20-
stubValues,
33+
stubOptions,
2134
),
2235
).resolves.not.toThrow();
36+
37+
expect(mockRequest.mock.calls).toMatchInlineSnapshot(`
38+
[
39+
[
40+
"PUT /repos///branches/main/protection",
41+
{
42+
"allow_deletions": false,
43+
"allow_force_pushes": true,
44+
"allow_fork_pushes": false,
45+
"allow_fork_syncing": true,
46+
"block_creations": false,
47+
"branch": "main",
48+
"enforce_admins": false,
49+
"owner": "",
50+
"repo": "",
51+
"required_conversation_resolution": true,
52+
"required_linear_history": false,
53+
"required_pull_request_reviews": null,
54+
"required_status_checks": {
55+
"checks": [
56+
{
57+
"context": "build",
58+
},
59+
{
60+
"context": "lint",
61+
},
62+
{
63+
"context": "prettier",
64+
},
65+
{
66+
"context": "compliance",
67+
},
68+
{
69+
"context": "lint_knip",
70+
},
71+
{
72+
"context": "lint_markdown",
73+
},
74+
{
75+
"context": "lint_packages",
76+
},
77+
{
78+
"context": "lint_spelling",
79+
},
80+
{
81+
"context": "test",
82+
},
83+
],
84+
"strict": false,
85+
},
86+
"restrictions": null,
87+
},
88+
],
89+
]
90+
`);
2391
});
2492

2593
it("returns false when the request receives a 403 response", async () => {
2694
const mockRequest = vi.fn().mockRejectedValue({ status: 403 });
2795

2896
const actual = await initializeBranchProtectionSettings(
2997
createMockOctokit(mockRequest),
30-
stubValues,
98+
stubOptions,
3199
);
32100

33101
expect(actual).toBe(false);
@@ -40,8 +108,59 @@ describe("migrateBranchProtectionSettings", () => {
40108
await expect(() =>
41109
initializeBranchProtectionSettings(
42110
createMockOctokit(mockRequest),
43-
stubValues,
111+
stubOptions,
44112
),
45113
).rejects.toBe(error);
46114
});
115+
116+
it("doesn't create workflows for excluded options when specified", async () => {
117+
const mockRequest = vi.fn().mockResolvedValue({ status: 200 });
118+
119+
await initializeBranchProtectionSettings(createMockOctokit(mockRequest), {
120+
...stubOptions,
121+
excludeCompliance: true,
122+
excludeLintKnip: true,
123+
excludeLintMd: true,
124+
excludeLintPackages: true,
125+
excludeLintSpelling: true,
126+
excludeTests: true,
127+
});
128+
129+
expect(mockRequest.mock.calls).toMatchInlineSnapshot(`
130+
[
131+
[
132+
"PUT /repos///branches/main/protection",
133+
{
134+
"allow_deletions": false,
135+
"allow_force_pushes": true,
136+
"allow_fork_pushes": false,
137+
"allow_fork_syncing": true,
138+
"block_creations": false,
139+
"branch": "main",
140+
"enforce_admins": false,
141+
"owner": "",
142+
"repo": "",
143+
"required_conversation_resolution": true,
144+
"required_linear_history": false,
145+
"required_pull_request_reviews": null,
146+
"required_status_checks": {
147+
"checks": [
148+
{
149+
"context": "build",
150+
},
151+
{
152+
"context": "lint",
153+
},
154+
{
155+
"context": "prettier",
156+
},
157+
],
158+
"strict": false,
159+
},
160+
"restrictions": null,
161+
},
162+
],
163+
]
164+
`);
165+
});
47166
});

‎src/steps/initializeGitHubRepository/initializeBranchProtectionSettings.ts

+14-10
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import { Options } from "../../shared/types.js";
55

66
export async function initializeBranchProtectionSettings(
77
octokit: Octokit,
8-
{ owner, repository }: Pick<Options, "owner" | "repository">,
8+
options: Options,
99
) {
1010
try {
1111
await octokit.request(
12-
`PUT /repos/${owner}/${repository}/branches/main/protection`,
12+
`PUT /repos/${options.owner}/${options.repository}/branches/main/protection`,
1313
{
1414
allow_deletions: false,
1515
allow_force_pushes: true,
@@ -18,22 +18,26 @@ export async function initializeBranchProtectionSettings(
1818
block_creations: false,
1919
branch: "main",
2020
enforce_admins: false,
21-
owner,
22-
repo: repository,
21+
owner: options.owner,
22+
repo: options.repository,
2323
required_conversation_resolution: true,
2424
required_linear_history: false,
2525
required_pull_request_reviews: null,
2626
required_status_checks: {
2727
checks: [
2828
{ context: "build" },
29-
{ context: "compliance" },
3029
{ context: "lint" },
31-
{ context: "lint_knip" },
32-
{ context: "lint_markdown" },
33-
{ context: "lint_packages" },
34-
{ context: "lint_spelling" },
3530
{ context: "prettier" },
36-
{ context: "test" },
31+
...(options.excludeCompliance ? [] : [{ context: "compliance" }]),
32+
...(options.excludeLintKnip ? [] : [{ context: "lint_knip" }]),
33+
...(options.excludeLintMd ? [] : [{ context: "lint_markdown" }]),
34+
...(options.excludeLintPackages
35+
? []
36+
: [{ context: "lint_packages" }]),
37+
...(options.excludeLintSpelling
38+
? []
39+
: [{ context: "lint_spelling" }]),
40+
...(options.excludeTests ? [] : [{ context: "test" }]),
3741
],
3842
strict: false,
3943
},

0 commit comments

Comments
 (0)
Please sign in to comment.