Skip to main content

elizaos_plugin_github/actions/
merge_pull_request.rs

1#![allow(missing_docs)]
2
3use async_trait::async_trait;
4use serde_json::json;
5
6use super::{ActionContext, ActionResult, GitHubAction};
7use crate::error::Result;
8use crate::types::{MergeMethod, MergePullRequestParams};
9use crate::GitHubService;
10
11pub struct MergePullRequestAction;
12
13#[async_trait]
14impl GitHubAction for MergePullRequestAction {
15    fn name(&self) -> &str {
16        "MERGE_GITHUB_PULL_REQUEST"
17    }
18
19    fn description(&self) -> &str {
20        "Merges a GitHub pull request using merge, squash, or rebase strategy."
21    }
22
23    fn similes(&self) -> Vec<&str> {
24        vec![
25            "MERGE_PR",
26            "SQUASH_MERGE",
27            "REBASE_MERGE",
28            "COMPLETE_PR",
29            "ACCEPT_PR",
30        ]
31    }
32
33    async fn validate(&self, context: &ActionContext) -> Result<bool> {
34        let text = context
35            .message
36            .get("content")
37            .and_then(|c| c.get("text"))
38            .and_then(|t| t.as_str())
39            .unwrap_or("")
40            .to_lowercase();
41
42        Ok(text.contains("merge"))
43    }
44
45    async fn handler(
46        &self,
47        context: &ActionContext,
48        service: &GitHubService,
49    ) -> Result<ActionResult> {
50        let text = context
51            .message
52            .get("content")
53            .and_then(|c| c.get("text"))
54            .and_then(|t| t.as_str())
55            .unwrap_or("")
56            .to_lowercase();
57
58        let merge_method = if text.contains("squash") {
59            MergeMethod::Squash
60        } else if text.contains("rebase") {
61            MergeMethod::Rebase
62        } else {
63            MergeMethod::Merge
64        };
65
66        let pull_number = context
67            .state
68            .get("pull_number")
69            .and_then(|n| n.as_u64())
70            .unwrap_or(0);
71
72        let params = MergePullRequestParams {
73            owner: context.owner.clone(),
74            repo: context.repo.clone(),
75            pull_number,
76            commit_title: None,
77            commit_message: None,
78            merge_method,
79            sha: None,
80        };
81
82        let (sha, merged, message) = service.merge_pull_request(params).await?;
83
84        if merged {
85            Ok(ActionResult::success(
86                format!("Successfully merged pull request #{}", pull_number),
87                json!({
88                    "sha": sha,
89                    "merged": merged,
90                    "merge_method": format!("{:?}", merge_method).to_lowercase(),
91                }),
92            ))
93        } else {
94            Ok(ActionResult::error(format!(
95                "Could not merge pull request #{}: {}",
96                pull_number, message
97            )))
98        }
99    }
100}