Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions apps/web/src/lib/provider-review/gitlab-write.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,42 @@ describe('mergePullRequest', () => {
});
});

it('squashes the collected title and body into squash_commit_message', async () => {
const result = await mergePullRequest({
...TARGET,
expectedHeadSha: 'sha-head',
squash: true,
commitTitle: 'Add nested deploy script',
commitMessage: 'Explain the deploy script.',
});

expect(result).toEqual({ done: true, replayed: false });
const { init } = lastRequest();
expect(JSON.parse(String(init.body))).toEqual({
sha: 'sha-head',
squash: true,
squash_commit_message: 'Add nested deploy script\n\nExplain the deploy script.',
});
});

it('uses the collected title and body as merge_commit_message when not squashing', async () => {
const result = await mergePullRequest({
...TARGET,
expectedHeadSha: 'sha-head',
squash: false,
commitTitle: 'Add nested deploy script',
commitMessage: 'Explain the deploy script.',
});

expect(result).toEqual({ done: true, replayed: false });
const { init } = lastRequest();
expect(JSON.parse(String(init.body))).toEqual({
sha: 'sha-head',
squash: false,
merge_commit_message: 'Add nested deploy script\n\nExplain the deploy script.',
});
});

it('refuses a stale revision with the exact reason and never merges', async () => {
mockFetchGitLabMergeRequest.mockResolvedValue(openMrFixture('sha-moved'));

Expand Down
16 changes: 13 additions & 3 deletions apps/web/src/lib/provider-review/gitlab-write.ts
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,11 @@ function requireHeadShaFence(mr: GitLabMergeRequestDetail, expectedHeadSha: stri
/**
* Merge the MR. The caller's `expectedHeadSha` is re-verified against a fresh
* fetch and passed to GitLab as `sha`, so the merge can only land the exact
* revision the reviewer saw.
* revision the reviewer saw. GitLab's merge endpoint accepts only a whole
* commit message (`squash_commit_message` when `squash` is true, otherwise
* `merge_commit_message`) and has no separate title parameter, so the sheet's
* `commitTitle` becomes the message's leading line and `commitMessage` follows
* as the body.
*/
export async function mergePullRequest(
target: GitLabMrTarget & {
Expand All @@ -450,6 +454,9 @@ export async function mergePullRequest(
if (mr.state === 'closed' || mr.state === 'locked') {
throw new GitLabReviewError('bad_request', 'The merge request is closed.');
}
const fullCommitMessage = [target.commitTitle, target.commitMessage]
.filter((part): part is string => Boolean(part))
.join('\n\n');
await requestGitLabJson(access, `${mrPath(access, target.mrIid)}/merge`, {
method: 'PUT',
body: {
Expand All @@ -458,8 +465,11 @@ export async function mergePullRequest(
...(target.shouldRemoveSourceBranch !== undefined
? { should_remove_source_branch: target.shouldRemoveSourceBranch }
: {}),
...(target.commitTitle ? { merge_commit_title: target.commitTitle } : {}),
...(target.commitMessage ? { merge_commit_message: target.commitMessage } : {}),
...(fullCommitMessage
Comment thread
iscekic marked this conversation as resolved.
? target.squash
? { squash_commit_message: fullCommitMessage }
: { merge_commit_message: fullCommitMessage }
: {}),
},
});
return { done: true, replayed: false };
Expand Down