History

Add Git action modal with custom commit message support

- Add a Git action confirmation modal with live commit/push/PR progress states - Accept optional `commitMessage` input and skip AI message generation when provided - Expand server and contracts tests for custom commit message handling

Julius Marminge committed 9 months ago

Commit 36bc85f1 parent 3c939e85 files · +538 −44Browse files

Showing the changes to apps/server/src/gitManager.ts (1 of 5 files). Show all

Unified · Split

apps/server/src/gitManager.ts+41−13
@@ -106,6 +106,24 @@ function sanitizeCommitMessage( · 105 unmodified lines
106 };106 };
107}107}
108 108
109function parseCustomCommitMessage(raw: string): CommitMessageGenerationResult | null {
110 const normalized = raw.replace(/\r\n/g, "\n").trim();
111 if (normalized.length === 0) {
112 return null;
113 }
114
115 const [firstLine, ...rest] = normalized.split("\n");
116 const subject = firstLine?.trim() ?? "";
117 if (subject.length === 0) {
118 return null;
119 }
120
121 return {
122 subject,
123 body: rest.join("\n").trim(),
124 };
125}
126
109function extractBranchFromRef(ref: string): string {127function extractBranchFromRef(ref: string): string {
110 const normalized = ref.trim();128 const normalized = ref.trim();
111 129
@@ -222,7 +240,11 @@ export class GitManager { · 110 unmodified lines
222 throw new Error("Cannot create a pull request from detached HEAD.");240 throw new Error("Cannot create a pull request from detached HEAD.");
223 }241 }
224 242
225 const commit = await this.runCommitStep(input.cwd, initialStatus.branch);243 const commit = await this.runCommitStep(
244 input.cwd,
245 initialStatus.branch,
246 input.commitMessage,
247 );
226 248
227 const push = wantsPush249 const push = wantsPush
228 ? await this.gitCore.pushCurrentBranch(input.cwd, initialStatus.branch)250 ? await this.gitCore.pushCurrentBranch(input.cwd, initialStatus.branch)
@@ -243,6 +265,7 @@ export class GitManager { · 14 unmodified lines
243 private async runCommitStep(265 private async runCommitStep(
244 cwd: string,266 cwd: string,
245 branch: string | null,267 branch: string | null,
268 commitMessage?: string,
246 ): Promise<{269 ): Promise<{
247 status: "created" | "skipped_no_changes";270 status: "created" | "skipped_no_changes";
248 commitSha?: string | undefined;271 commitSha?: string | undefined;
@@ -253,18 +276,23 @@ export class GitManager { · 4 unmodified lines
253 return { status: "skipped_no_changes" };276 return { status: "skipped_no_changes" };
254 }277 }
255 278
256 let generated: CommitMessageGenerationResult;279 let generated: CommitMessageGenerationResult | null = parseCustomCommitMessage(
257 try {280 commitMessage ?? "",
258 generated = sanitizeCommitMessage(281 );
259 await this.textGenerator.generateCommitMessage({282
260 cwd,283 if (!generated) {
261 branch,284 try {
262 stagedSummary: limitContext(context.stagedSummary, 8_000),285 generated = sanitizeCommitMessage(
263 stagedPatch: limitContext(context.stagedPatch, 50_000),286 await this.textGenerator.generateCommitMessage({
264 }),287 cwd,
265 );288 branch,
266 } catch (error) {289 stagedSummary: limitContext(context.stagedSummary, 8_000),
267 throw asCommandNotFound("codex", error) ?? error;290 stagedPatch: limitContext(context.stagedPatch, 50_000),
291 }),
292 );
293 } catch (error) {
294 throw asCommandNotFound("codex", error) ?? error;
295 }
268 }296 }
269 297
270 const { commitSha } = await this.gitCore.commit(cwd, generated.subject, generated.body);298 const { commitSha } = await this.gitCore.commit(cwd, generated.subject, generated.body);