-
Notifications
You must be signed in to change notification settings - Fork 842
forge: merge API #12379
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
forge: merge API #12379
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -3,7 +3,7 @@ use std::{ | |||||
| path::{self}, | ||||||
| }; | ||||||
|
|
||||||
| use anyhow::{Error, Result}; | ||||||
| use anyhow::{Context as _, Error, Result}; | ||||||
| use but_fs::list_files; | ||||||
| use but_github::CredentialCheckResult; | ||||||
| use but_gitlab::GitLabProjectId; | ||||||
|
|
@@ -733,6 +733,50 @@ pub async fn get_forge_review( | |||||
| } | ||||||
| } | ||||||
|
|
||||||
| /// Merge a review to it's target branch | ||||||
| pub async fn merge_review( | ||||||
| preferred_forge_user: &Option<crate::ForgeUser>, | ||||||
| forge_repo_info: &crate::forge::ForgeRepoInfo, | ||||||
| review_number: usize, | ||||||
| storage: &but_forge_storage::Controller, | ||||||
| ) -> Result<()> { | ||||||
| let crate::forge::ForgeRepoInfo { forge, owner, repo, .. } = forge_repo_info; | ||||||
| match forge { | ||||||
| ForgeName::GitHub => { | ||||||
| let preferred_account = preferred_forge_user.as_ref().and_then(|user| user.github()); | ||||||
| let pr_number = review_number | ||||||
| .try_into() | ||||||
| .context("PR: Failed to cast usize to i64, somehow")?; | ||||||
|
||||||
| .context("PR: Failed to cast usize to i64, somehow")?; | |
| .context("PR number is too large")?; |
Copilot
AI
Feb 16, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message should be more user-friendly and consistent with the pattern used in other functions. Change "MR: Failed to cast usize to i64, somehow" to "MR number is too large" to match the error message in but_gitlab::mr::get (line 52 of crates/but-gitlab/src/mr.rs).
| .context("MR: Failed to cast usize to i64, somehow")?; | |
| .context("MR number is too large")?; |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -232,6 +232,39 @@ impl GitHubClient { | |||||||||
| let pr: GitHubPullRequest = response.json().await?; | ||||||||||
| Ok(pr.into()) | ||||||||||
| } | ||||||||||
|
|
||||||||||
| pub async fn merge_pull_request(&self, params: &MergePullRequestParams<'_>) -> Result<()> { | ||||||||||
| #[derive(Serialize)] | ||||||||||
| struct MergePullRequestBody<'a> { | ||||||||||
| #[serde(skip_serializing_if = "Option::is_none")] | ||||||||||
| commit_title: Option<&'a str>, | ||||||||||
| #[serde(skip_serializing_if = "Option::is_none")] | ||||||||||
| commit_message: Option<&'a str>, | ||||||||||
| #[serde(skip_serializing_if = "Option::is_none")] | ||||||||||
| merge_method: Option<&'a str>, | ||||||||||
| } | ||||||||||
|
|
||||||||||
| let url = format!( | ||||||||||
| "{}/repos/{}/{}/pulls/{}/merge", | ||||||||||
| self.base_url, params.owner, params.repo, params.pr_number | ||||||||||
| ); | ||||||||||
|
|
||||||||||
| let merge_method = params.merge_method.as_ref().map(Into::into); | ||||||||||
|
|
||||||||||
| let body = MergePullRequestBody { | ||||||||||
| commit_title: params.commit_title, | ||||||||||
| commit_message: params.commit_message, | ||||||||||
| merge_method, | ||||||||||
| }; | ||||||||||
|
|
||||||||||
| let response = self.client.put(&url).json(&body).send().await?; | ||||||||||
|
|
||||||||||
| if !response.status().is_success() { | ||||||||||
| bail!("Failed to merge pull request: {}", response.status()); | ||||||||||
|
||||||||||
| bail!("Failed to merge pull request: {}", response.status()); | |
| let status = response.status(); | |
| let error_text = response.text().await.unwrap_or_default(); | |
| bail!("Failed to merge pull request: {status} - {error_text}"); |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -183,6 +183,29 @@ impl GitLabClient { | |||||||||
| let mr: GitLabMergeRequest = response.json().await?; | ||||||||||
| Ok(mr.into()) | ||||||||||
| } | ||||||||||
|
|
||||||||||
| pub async fn merge_merge_request(&self, params: &MergeMergeRequestParams) -> Result<()> { | ||||||||||
| #[derive(Serialize)] | ||||||||||
| struct MergeMergeRequestBody { | ||||||||||
| #[serde(skip_serializing_if = "Option::is_none")] | ||||||||||
| squash: Option<bool>, | ||||||||||
| } | ||||||||||
|
|
||||||||||
| let url = format!( | ||||||||||
| "{}/projects/{}/merge_requests/{}/merge", | ||||||||||
| self.base_url, params.project_id, params.mr_iid | ||||||||||
| ); | ||||||||||
|
|
||||||||||
| let body = MergeMergeRequestBody { squash: params.squash }; | ||||||||||
|
|
||||||||||
| let response = self.client.put(&url).json(&body).send().await?; | ||||||||||
|
|
||||||||||
| if !response.status().is_success() { | ||||||||||
| bail!("Failed to merge merge request: {}", response.status()); | ||||||||||
|
||||||||||
| bail!("Failed to merge merge request: {}", response.status()); | |
| let status = response.status(); | |
| let error_text = response.text().await.unwrap_or_default(); | |
| bail!("Failed to merge merge request: {status} - {error_text}"); |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -56,3 +56,14 @@ pub async fn get( | |||||
| .context("Failed to get merge request")?; | ||||||
| Ok(mr) | ||||||
| } | ||||||
|
|
||||||
| pub async fn merge( | ||||||
| preferred_account: Option<&crate::GitlabAccountIdentifier>, | ||||||
| params: crate::client::MergeMergeRequestParams, | ||||||
| storage: &but_forge_storage::Controller, | ||||||
| ) -> Result<()> { | ||||||
| GitLabClient::from_storage(storage, preferred_account)? | ||||||
| .merge_merge_request(¶ms) | ||||||
| .await | ||||||
| .context("Faile to merge MR") | ||||||
|
||||||
| .context("Faile to merge MR") | |
| .context("Failed to merge MR") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Grammar error in comment: "it's" should be "its" (possessive form, not contraction).