1#![allow(dead_code)]
3#![allow(unused_imports)]
4#![deny(missing_docs)]
5
6#[cfg(feature = "log")]
7extern crate log;
8
9use std::io::Write;
10use std::path::Path;
11
12pub mod actions;
13pub mod errors;
14#[cfg(feature = "log")]
16pub mod logging;
17pub mod repository;
18#[cfg(feature = "toolcache")]
19pub mod toolcache;
20
21pub use crate::actions::models::{ActionInput, ActionRuns, ActionYML};
22pub use crate::errors::ActionsError;
23pub use crate::repository::reference::RepositoryReference;
24
25pub trait ActionTrait {
27 fn init() -> Result<Self, ActionsError>
29 where
30 Self: Sized;
31
32 fn name(&self) -> &str;
34
35 fn description(&self) -> &str;
37
38 fn get_input(key: impl Into<String> + Copy) -> Result<String, ActionsError> {
40 std::env::var(&key.into()).map_err(|_| ActionsError::InputError(key.into()))
41 }
42
43 fn get_input_bool(key: impl Into<String> + Copy) -> Result<bool, ActionsError> {
45 Self::get_input(key)?
46 .parse::<bool>()
47 .map_err(|_| ActionsError::InputTypeError(key.into(), "bool".into()))
48 }
49
50 fn get_input_int(key: impl Into<String> + Copy) -> Result<i32, ActionsError> {
52 Self::get_input(key)?
53 .parse::<i32>()
54 .map_err(|_| ActionsError::InputTypeError(key.into(), "int".into()))
55 }
56
57 fn get_input_vec(
59 key: impl Into<String> + Copy,
60 seperator: &str,
61 ) -> Result<Vec<String>, ActionsError> {
62 Ok(Self::get_input(key)?
63 .split(seperator)
64 .map(|s| s.to_string())
65 .collect::<Vec<String>>())
66 }
67
68 fn set_output(key: impl Into<String>, value: impl Into<String>) -> Result<(), ActionsError> {
70 let key = key.into();
71 let value = value.into();
72
73 let output = format!("::set-output name={}::{}", key, value);
74 let output_file = std::env::var("GITHUB_OUTPUT")
75 .unwrap_or_else(|_| "/tmp/github_actions.env".to_string());
76
77 #[cfg(feature = "log")]
78 {
79 log::debug!("{}", output);
80 log::debug!("Output File: {}", output_file);
81 }
82
83 let mut file = std::fs::OpenOptions::new()
84 .create(true)
85 .append(true)
86 .open(output_file)?;
87 writeln!(file, "{}", output)?;
88
89 Ok(())
90 }
91
92 #[cfg(feature = "octocrab")]
96 fn octocrab(&self) -> Result<octocrab::Octocrab, ActionsError> {
97 #[cfg(feature = "log")]
98 {
99 log::debug!("Creating Octocrab instance");
100 log::debug!("URL: {}", self.get_api_url());
101 }
102
103 match self.get_token() {
104 Ok(token) => 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 .personal_token(token)
112 .build()
113 .map_err(|e| ActionsError::OctocrabError(e.to_string()))?),
114 Err(_) => {
115 #[cfg(feature = "log")]
116 log::warn!("No GitHub Token provided");
117
118 Ok(octocrab::Octocrab::builder()
119 .base_uri(self.get_api_url())
120 .map_err(|e| ActionsError::OctocrabError(e.to_string()))?
121 .add_header(
122 http::header::ACCEPT,
123 "application/vnd.github.v3+json".to_string(),
124 )
125 .build()
126 .map_err(|e| ActionsError::OctocrabError(e.to_string()))?)
127 }
128 }
129 }
130
131 fn get_server_url(&self) -> String {
133 Self::get_input("GITHUB_SERVER_URL").unwrap_or_else(|_| "https://github.com".into())
134 }
135 fn get_api_url(&self) -> String {
137 Self::get_input("GITHUB_API_URL").unwrap_or_else(|_| "https://api.github.com".into())
138 }
139 fn get_graphql_url(&self) -> String {
141 Self::get_input("GITHUB_GRAPHQL_URL")
142 .unwrap_or_else(|_| "https://api.github.com/graphql".into())
143 }
144
145 fn get_token(&self) -> Result<String, ActionsError> {
147 Self::get_input("GITHUB_TOKEN")
148 }
149 fn get_sha(&self) -> Result<String, ActionsError> {
151 Self::get_input("GITHUB_SHA")
152 }
153 fn get_ref(&self) -> Result<String, ActionsError> {
155 Self::get_input("GITHUB_REF")
156 }
157 fn get_ref_type(&self) -> Result<String, ActionsError> {
159 Self::get_input("GITHUB_REF_TYPE")
160 }
161 fn get_ref_name(&self) -> Result<String, ActionsError> {
163 Self::get_input("GITHUB_REF_NAME")
164 }
165
166 fn get_event_name(&self) -> Result<String, ActionsError> {
168 Self::get_input("GITHUB_EVENT_NAME")
169 }
170
171 fn get_repository(&self) -> Result<String, ActionsError> {
173 Self::get_input("GITHUB_REPOSITORY")
174 }
175 fn get_repository_owner(&self) -> Result<String, ActionsError> {
177 Self::get_input("GITHUB_REPOSITORY_OWNER").or_else(|_| {
178 self.get_repository()
179 .map(|r| r.split('/').collect::<Vec<&str>>()[0].to_string())
180 })
181 }
182 fn get_repository_name(&self) -> Result<String, ActionsError> {
184 self.get_repository()
185 .map(|r| r.split('/').collect::<Vec<&str>>()[1].to_string())
186 }
187 fn get_repository_url(&self) -> Result<String, ActionsError> {
189 Self::get_input("GITHUB_REPOSITORYURL")
190 }
191 fn get_actor(&self) -> Result<String, ActionsError> {
193 Self::get_input("GITHUB_ACTOR")
194 }
195}