ghactions_core/
lib.rs

1//! ghactions-core is a library that provides core functionality for GitHub Actions in Rust.
2#![allow(dead_code)]
3#![allow(unused_imports)]
4#![deny(missing_docs)]
5
6#[cfg(feature = "log")]
7extern crate log;
8
9pub mod actions;
10pub mod errors;
11// pub mod ghaction;
12#[cfg(feature = "log")]
13pub mod logging;
14pub mod repository;
15#[cfg(feature = "toolcache")]
16pub mod toolcache;
17
18pub use crate::actions::models::{ActionInput, ActionRuns, ActionYML};
19pub use crate::errors::ActionsError;
20pub use crate::repository::reference::RepositoryReference;
21
22/// Action Trait
23pub trait ActionTrait {
24    /// Parse the action input
25    fn init() -> Result<Self, ActionsError>
26    where
27        Self: Sized;
28
29    /// Get the action name
30    fn name(&self) -> &str;
31
32    /// Get the action description
33    fn description(&self) -> &str;
34
35    /// Get the input value for a provided key
36    fn get_input(key: impl Into<String> + Copy) -> Result<String, ActionsError> {
37        std::env::var(&key.into()).map_err(|_| ActionsError::InputError(key.into()))
38    }
39
40    /// Get the input value for a provided key as a boolean
41    fn get_input_bool(key: impl Into<String> + Copy) -> Result<bool, ActionsError> {
42        Self::get_input(key)?
43            .parse::<bool>()
44            .map_err(|_| ActionsError::InputTypeError(key.into(), "bool".into()))
45    }
46
47    /// Get the input value for a provided key as an integer
48    fn get_input_int(key: impl Into<String> + Copy) -> Result<i32, ActionsError> {
49        Self::get_input(key)?
50            .parse::<i32>()
51            .map_err(|_| ActionsError::InputTypeError(key.into(), "int".into()))
52    }
53
54    /// Get the input value for a provided key as a vector using a seperator
55    fn get_input_vec(
56        key: impl Into<String> + Copy,
57        seperator: &str,
58    ) -> Result<Vec<String>, ActionsError> {
59        Ok(Self::get_input(key)?
60            .split(seperator)
61            .map(|s| s.to_string())
62            .collect::<Vec<String>>())
63    }
64
65    /// Set the output value for a provided key
66    fn set_output(
67        key: impl Into<String> + Copy,
68        value: impl Into<String> + Copy,
69    ) -> Result<(), ActionsError> {
70        let key = key.into();
71        let value = value.into();
72
73        setoutput!(key, value);
74
75        Ok(())
76    }
77
78    /// Get the Octocrab instance
79    ///
80    /// Uses the `GITHUB_API_URL` and `GITHUB_TOKEN` environment variable to create an Octocrab instance
81    #[cfg(feature = "octocrab")]
82    fn octocrab(&self) -> Result<octocrab::Octocrab, ActionsError> {
83        #[cfg(feature = "log")]
84        {
85            log::debug!("Creating Octocrab instance");
86            log::debug!("URL: {}", self.get_api_url());
87        }
88
89        match self.get_token() {
90            Ok(token) => Ok(octocrab::Octocrab::builder()
91                .base_uri(self.get_api_url())
92                .map_err(|e| ActionsError::OctocrabError(e.to_string()))?
93                .add_header(
94                    http::header::ACCEPT,
95                    "application/vnd.github.v3+json".to_string(),
96                )
97                .personal_token(token)
98                .build()
99                .map_err(|e| ActionsError::OctocrabError(e.to_string()))?),
100            Err(_) => {
101                #[cfg(feature = "log")]
102                log::warn!("No GitHub Token provided");
103
104                Ok(octocrab::Octocrab::builder()
105                    .base_uri(self.get_api_url())
106                    .map_err(|e| ActionsError::OctocrabError(e.to_string()))?
107                    .add_header(
108                        http::header::ACCEPT,
109                        "application/vnd.github.v3+json".to_string(),
110                    )
111                    .build()
112                    .map_err(|e| ActionsError::OctocrabError(e.to_string()))?)
113            }
114        }
115    }
116
117    /// GetHub Server URL (default: https://github.com)
118    fn get_server_url(&self) -> String {
119        Self::get_input("GITHUB_SERVER_URL").unwrap_or_else(|_| "https://github.com".into())
120    }
121    /// GitHub API URL (default: https://api.github.com)
122    fn get_api_url(&self) -> String {
123        Self::get_input("GITHUB_API_URL").unwrap_or_else(|_| "https://api.github.com".into())
124    }
125    /// GitHub GraphQL URL (default: https://api.github.com/graphql)
126    fn get_graphql_url(&self) -> String {
127        Self::get_input("GITHUB_GRAPHQL_URL")
128            .unwrap_or_else(|_| "https://api.github.com/graphql".into())
129    }
130
131    /// Get the GitHub Token
132    fn get_token(&self) -> Result<String, ActionsError> {
133        Self::get_input("GITHUB_TOKEN")
134    }
135    /// Get the GitHub SHA
136    fn get_sha(&self) -> Result<String, ActionsError> {
137        Self::get_input("GITHUB_SHA")
138    }
139    /// Get the GitHub Ref (full)
140    fn get_ref(&self) -> Result<String, ActionsError> {
141        Self::get_input("GITHUB_REF")
142    }
143    /// Get the GitHub Ref Type
144    fn get_ref_type(&self) -> Result<String, ActionsError> {
145        Self::get_input("GITHUB_REF_TYPE")
146    }
147    /// Get the GitHub Ref Name
148    fn get_ref_name(&self) -> Result<String, ActionsError> {
149        Self::get_input("GITHUB_REF_NAME")
150    }
151
152    /// Get the GitHub Workflow Event Name
153    fn get_event_name(&self) -> Result<String, ActionsError> {
154        Self::get_input("GITHUB_EVENT_NAME")
155    }
156
157    /// Get the full GitHub Repository (owner/repo)
158    fn get_repository(&self) -> Result<String, ActionsError> {
159        Self::get_input("GITHUB_REPOSITORY")
160    }
161    /// Get the GitHub Repository owner name (org/user)
162    fn get_repository_owner(&self) -> Result<String, ActionsError> {
163        Self::get_input("GITHUB_REPOSITORY_OWNER").or_else(|_| {
164            self.get_repository()
165                .map(|r| r.split('/').collect::<Vec<&str>>()[0].to_string())
166        })
167    }
168    /// Get the GitHub Repository name
169    fn get_repository_name(&self) -> Result<String, ActionsError> {
170        self.get_repository()
171            .map(|r| r.split('/').collect::<Vec<&str>>()[1].to_string())
172    }
173    /// Get the GitHub Repository URL
174    fn get_repository_url(&self) -> Result<String, ActionsError> {
175        Self::get_input("GITHUB_REPOSITORYURL")
176    }
177    /// Get the Action Triggering Author
178    fn get_actor(&self) -> Result<String, ActionsError> {
179        Self::get_input("GITHUB_ACTOR")
180    }
181}