Skip to content

Commit 496e0de

Browse files
committed
fix(github): match template filenames without case
1 parent d2aa0ba commit 496e0de

3 files changed

Lines changed: 69 additions & 12 deletions

File tree

‎apps/server/src/git/GitManager.test.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5221,10 +5221,10 @@ it.layer(layerGitManagerTest)("GitManager", (it) => {
52215221
yield* initRepo(repoDir);
52225222
NodeFS.mkdirSync(NodePath.join(repoDir, ".github"));
52235223
NodeFS.writeFileSync(
5224-
NodePath.join(repoDir, ".github", "pull_request_template.txt"),
5224+
NodePath.join(repoDir, ".github", "PuLl_ReQuEsT_TeMpLaTe.TXT"),
52255225
"## What changed?\n\n## Verification",
52265226
);
5227-
yield* runGit(repoDir, ["add", ".github/pull_request_template.txt"]);
5227+
yield* runGit(repoDir, ["add", ".github/PuLl_ReQuEsT_TeMpLaTe.TXT"]);
52285228
yield* runGit(repoDir, ["commit", "-m", "Add pull request template"]);
52295229
yield* runGit(repoDir, ["checkout", "-b", "feature-create-pr"]);
52305230
const remoteDir = yield* createBareRemote();

‎apps/server/src/sourceControl/gitHubChangeRequestTemplate.test.ts‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,20 @@ const SINGLE_TEMPLATE_PATHS = [
1717
".github/PULL_REQUEST_TEMPLATE.md",
1818
".github/pull_request_template.txt",
1919
".github/PULL_REQUEST_TEMPLATE.txt",
20+
".github/PULL_REQUEST_TEMPLATE.TXT",
21+
".github/PuLl_ReQuEsT_TeMpLaTe.TxT",
2022
"pull_request_template.md",
2123
"PULL_REQUEST_TEMPLATE.md",
2224
"pull_request_template.txt",
2325
"PULL_REQUEST_TEMPLATE.txt",
26+
"PULL_REQUEST_TEMPLATE.TXT",
27+
"PuLl_ReQuEsT_TeMpLaTe.TxT",
2428
"docs/pull_request_template.md",
2529
"docs/PULL_REQUEST_TEMPLATE.md",
2630
"docs/pull_request_template.txt",
2731
"docs/PULL_REQUEST_TEMPLATE.txt",
32+
"docs/PULL_REQUEST_TEMPLATE.TXT",
33+
"docs/PuLl_ReQuEsT_TeMpLaTe.TxT",
2834
] as const;
2935

3036
const TEMPLATE_DIRECTORIES = [
@@ -101,6 +107,49 @@ it.effect.each(SINGLE_TEMPLATE_PATHS)("recognizes $0", (relativePath) =>
101107
),
102108
);
103109

110+
it.effect.each([".github/PuLl_ReQuEsT_TeMpLaTe.MD", "docs/PULL_REQUEST_TEMPLATE.Md"])(
111+
"recognizes Markdown case variant $0",
112+
(relativePath) =>
113+
runWithTempDirectory((cwd) =>
114+
Effect.gen(function* () {
115+
yield* writeTemplate(cwd, relativePath, "Markdown template");
116+
yield* commitTemplates(cwd);
117+
118+
assert.strictEqual(Option.getOrUndefined(yield* detectTemplate(cwd)), "Markdown template");
119+
}),
120+
),
121+
);
122+
123+
it.effect("finds case variants from a repository subdirectory", () =>
124+
runWithTempDirectory((cwd) =>
125+
Effect.gen(function* () {
126+
const path = yield* Path.Path;
127+
yield* writeTemplate(cwd, ".github/Pull_Request_Template.TXT", "base template");
128+
yield* writeTemplate(cwd, "nested/README.md", "project");
129+
yield* commitTemplates(cwd);
130+
131+
assert.strictEqual(
132+
Option.getOrUndefined(yield* detectTemplate(path.join(cwd, "nested"))),
133+
"base template",
134+
);
135+
}),
136+
),
137+
);
138+
139+
it.effect("does not let unrelated nested documents exhaust the template listing", () =>
140+
runWithTempDirectory((cwd) =>
141+
Effect.gen(function* () {
142+
yield* writeTemplate(cwd, "docs/Pull_Request_Template.TXT", "docs template");
143+
for (let index = 0; index < 600; index += 1) {
144+
yield* writeTemplate(cwd, `docs/guides/${index}-${"a".repeat(180)}.md`, "guide");
145+
}
146+
yield* commitTemplates(cwd);
147+
148+
assert.strictEqual(Option.getOrUndefined(yield* detectTemplate(cwd)), "docs template");
149+
}),
150+
),
151+
);
152+
104153
it.effect("reads templates from the requested base tree", () =>
105154
runWithTempDirectory((cwd) =>
106155
Effect.gen(function* () {

‎packages/source-control-github/src/server/gitHubChangeRequestTemplate.ts‎

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,13 @@ const TEMPLATE_DIRECTORIES = [
2929
"docs/PULL_REQUEST_TEMPLATE",
3030
] as const;
3131

32-
const TREE_PATHS = [...TEMPLATE_PATHS, ...TEMPLATE_DIRECTORIES] as const;
32+
// Recursive listings can exhaust the byte cap on unrelated documents and hide a valid template.
33+
const TREE_PATHS = [
34+
".",
35+
".github/",
36+
"docs/",
37+
...TEMPLATE_DIRECTORIES.map((directory) => `${directory}/`),
38+
];
3339

3440
type ExecuteGit = SourceControlHost.SourceControlHost["Service"]["git"]["execute"];
3541

@@ -142,7 +148,7 @@ export const detect = Effect.fn("gitHubChangeRequestTemplate.detect")(function*
142148
const result = yield* executeGit({
143149
operation: "gitHubChangeRequestTemplate.listTemplates",
144150
cwd,
145-
args: ["ls-tree", "-r", "-z", "--full-tree", treeish, "--", ...TREE_PATHS],
151+
args: ["ls-tree", "-z", "--full-tree", treeish, "--", ...TREE_PATHS],
146152
maxOutputBytes: TREE_LIST_MAX_BYTES,
147153
appendTruncationMarker: true,
148154
});
@@ -151,15 +157,17 @@ export const detect = Effect.fn("gitHubChangeRequestTemplate.detect")(function*
151157
}
152158

153159
const entries = parseTemplateTreeEntries(result.stdout);
154-
const entriesByPath = new Map(entries.map((entry) => [entry.path, entry]));
155160
for (const templatePath of TEMPLATE_PATHS) {
156-
const entry = entriesByPath.get(templatePath);
157-
if (!entry) {
158-
continue;
159-
}
160-
const template = yield* readTemplateBlob({ cwd, executeGit, entry });
161-
if (Option.isSome(template)) {
162-
return template;
161+
const candidates = entries
162+
.filter((entry) => entry.path.toLowerCase() === templatePath.toLowerCase())
163+
.toSorted(
164+
(left, right) => Number(right.path === templatePath) - Number(left.path === templatePath),
165+
);
166+
for (const entry of candidates) {
167+
const template = yield* readTemplateBlob({ cwd, executeGit, entry });
168+
if (Option.isSome(template)) {
169+
return template;
170+
}
163171
}
164172
}
165173

0 commit comments

Comments
 (0)