Skip to main content

elizaos_plugin_github/actions/
create_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::CreatePullRequestParams;
9use crate::GitHubService;
10
11pub struct CreatePullRequestAction;
12
13#[async_trait]
14impl GitHubAction for CreatePullRequestAction {
15    fn name(&self) -> &str {
16        "CREATE_GITHUB_PULL_REQUEST"
17    }
18
19    fn description(&self) -> &str {
20        "Creates a new pull request in a GitHub repository to merge changes from one branch to another."
21    }
22
23    fn similes(&self) -> Vec<&str> {
24        vec![
25            "OPEN_PR",
26            "CREATE_PR",
27            "NEW_PULL_REQUEST",
28            "SUBMIT_PR",
29            "OPEN_PULL_REQUEST",
30            "MERGE_REQUEST",
31        ]
32    }
33
34    async fn validate(&self, context: &ActionContext) -> Result<bool> {
35        let text = context
36            .message
37            .get("content")
38            .and_then(|c| c.get("text"))
39            .and_then(|t| t.as_str())
40            .unwrap_or("")
41            .to_lowercase();
42
43        Ok(text.contains("pull request") || text.contains("pr") || text.contains("merge"))
44    }
45
46    async fn handler(
47        &self,
48        context: &ActionContext,
49        service: &GitHubService,
50    ) -> Result<ActionResult> {
51        let text = context
52            .message
53            .get("content")
54            .and_then(|c| c.get("text"))
55            .and_then(|t| t.as_str())
56            .unwrap_or("");
57
58        let head = context
59            .state
60            .get("head")
61            .and_then(|h| h.as_str())
62            .unwrap_or("feature");
63
64        let base = context
65            .state
66            .get("base")
67            .and_then(|b| b.as_str())
68            .unwrap_or(&service.config().branch);
69
70        let title = context
71            .state
72            .get("title")
73            .and_then(|t| t.as_str())
74            .map(|s| s.to_string())
75            .unwrap_or_else(|| text.chars().take(100).collect());
76
77        let params = CreatePullRequestParams {
78            owner: context.owner.clone(),
79            repo: context.repo.clone(),
80            title,
81            body: Some(text.to_string()),
82            head: head.to_string(),
83            base: base.to_string(),
84            draft: false,
85            maintainer_can_modify: true,
86        };
87
88        let pr = service.create_pull_request(params).await?;
89
90        Ok(ActionResult::success(
91            format!("Created pull request #{}: {}", pr.number, pr.title),
92            json!({
93                "pull_number": pr.number,
94                "html_url": pr.html_url,
95                "head": pr.head.branch_ref,
96                "base": pr.base.branch_ref,
97            }),
98        ))
99    }
100}