actions_github/
core.rs

1//! Utility methods to interact with the GitHub actions ecosystem
2//!
3//! You can obtain injected inputs or produce an output for another step
4use std::io::Write;
5use std::{env, io};
6
7use crate::error::ActionsError;
8use crate::util::{issue_file_command, issue_old_command, prepare_key_value_message, EOL};
9
10/// Obtain an input from a variable
11///
12/// If the input is not found, an [ActionsError] is returned
13///
14/// This method was copied
15/// from [core.ts](https://github.com/actions/toolkit/blob/d1df13e178816d69d96bdc5c753b36a66ad03728/packages/core/src/core.ts#L126)
16///
17/// ```rust
18/// use actions_github::logger;
19/// use actions_github::core;
20///
21/// let name = core::get_input("name").unwrap_or_else(|_| {
22///     logger::warn_log("Input 'name' was not defined", Option::None);
23///     String::from("")
24/// });
25/// ```
26pub fn get_input(name: &str) -> Result<String, ActionsError> {
27    let mut clean_input = str::replace(name, ' ', "_");
28    clean_input.insert_str(0, "INPUT_");
29    let value = env::var(clean_input.to_uppercase());
30    match value {
31        Ok(input) => Ok(input),
32        Err(_) => Err(ActionsError::InputNotFound(name.to_string())),
33    }
34}
35
36/// Produces an [output](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter)
37/// that can be used in another step
38///
39/// ```rust
40/// use actions_github::core;
41/// if let Err(err) = core::set_output("name", "value") {
42///     panic!("{:#?}", err);
43/// }
44/// ```
45pub fn set_output(name: &str, value: &str) -> Result<(), ActionsError> {
46    if env::var("GITHUB_OUTPUT").is_ok() {
47        return match prepare_key_value_message(name, value) {
48            Ok(key_value_message) => match issue_file_command("OUTPUT", key_value_message) {
49                Ok(_) => Ok(()),
50                Err(err) => Err(ActionsError::Output(err)),
51            },
52            Err(err) => Err(ActionsError::Output(err)),
53        };
54    }
55
56    io::stdout()
57        .write_all(EOL.as_bytes())
58        .expect("Failed to write EOL");
59    issue_old_command("set-output", name, value);
60    Ok(())
61}
62
63#[cfg(test)]
64mod test {
65    use crate::core::{get_input, set_output};
66    use std::env;
67
68    #[test]
69    fn returns_input_when_env_is_set() {
70        env::set_var("INPUT_EXAMPLE", "test");
71        let input = get_input("example");
72        assert_eq!(input.unwrap(), "test")
73    }
74
75    #[test]
76    fn returns_error_when_env_is_not_set() {
77        let input = get_input("test");
78        assert!(input.is_err())
79    }
80
81    #[test]
82    fn writes_output() {
83        assert!(set_output("hi", "bye").is_ok());
84    }
85}