actions_core/
lib.rs

1use std::env;
2use std::ffi::OsStr;
3use std::io;
4
5pub use crate::core::*;
6pub use crate::logger::*;
7
8mod core;
9mod logger;
10mod util;
11
12trait AssertStdout<T> {
13	fn assert(self) -> T;
14}
15
16impl<T> AssertStdout<T> for io::Result<T> {
17	fn assert(self) -> T {
18		match self {
19			Ok(v) => v,
20			Err(e) => panic!("failed printing to stdout: {}", e),
21		}
22	}
23}
24
25/// Get an action's input parameter.
26///
27/// ```
28/// use actions_core as core;
29///
30/// # std::env::set_var("INPUT_MILLISECONDS", "1000");
31/// let ms: u32 = core::input("milliseconds")
32///     .expect("Failed to get milliseconds")
33///     .parse()
34///     .expect("Failed to parse milliseconds");
35/// ```
36pub fn input<K: ToString>(name: K) -> Result<String, env::VarError> {
37	util::var_from_name("INPUT", name)
38}
39
40/// Sets an action's output parameter.
41///
42/// ```
43/// use actions_core as core;
44///
45/// let count = 5;
46///
47/// core::set_output("count", 5);
48/// ```
49pub fn set_output<K: ToString, V: ToString>(k: K, v: V) {
50	Core::new().set_output(k, v).assert();
51}
52
53/// Creates or updates an environment variable for any actions running next
54/// in a job. Environment variables are immediately set and available to the
55/// currently running action. Environment variables are case-sensitive and
56/// you can include punctuation.
57///
58/// ```
59/// use actions_core as core;
60///
61/// core::set_env("MY_GREETING", "hello");
62///
63/// assert_eq!(
64///     std::env::var_os("MY_GREETING").as_deref(),
65///     Some(std::ffi::OsStr::new("hello")),
66/// );
67/// ```
68pub fn set_env<K: ToString, V: ToString>(k: K, v: V) {
69	Core::new().set_env(k, v).assert();
70}
71
72/// Masking a value prevents a string or variable from being printed in the
73/// log. Each masked word separated by whitespace is replaced with the `*`
74/// character.
75///
76/// ```
77/// use actions_core as core;
78///
79/// core::add_mask("supersecret");
80/// ```
81pub fn add_mask<V: ToString>(v: V) {
82	Core::new().add_mask(v).assert();
83}
84
85/// Appends a directory to the system PATH variable for all subsequent
86/// actions in the current job as well as the currently running action.
87///
88/// ```
89/// use actions_core as core;
90///
91/// core::add_path("/opt/my-app/bin");
92/// ```
93pub fn add_path<P: ToString>(v: P) {
94	Core::new().add_path(v).assert();
95}
96
97/// Similar to `set_output`, but, shares data from a wrapper action.
98///
99/// ```
100/// use actions_core as core;
101///
102/// core::save_state("my_greeting", "hello");
103/// ```
104pub fn save_state<K: ToString, V: ToString>(k: K, v: V) {
105	Core::new().save_state(k, v).assert();
106}
107
108/// Similar to `input`, but, gets data shared from a wrapper action.
109///
110/// ```
111/// use actions_core as core;
112///
113/// let greeting = core::state("my_greeting")
114///     .unwrap_or_else(|_| "hello".to_owned());
115/// ```
116pub fn state<K: ToString>(name: K) -> Result<String, env::VarError> {
117	util::var_from_name("STATE", name)
118}
119
120/// Stops processing workflow commands while the provided function runs. A
121/// token is randomly generated and used to re-enable commands after
122/// completion.
123///
124/// ```
125/// use actions_core as core;
126///
127/// core::stop_logging(|| {
128///     println!("::set-env name=ignored::value");
129/// });
130/// ```
131pub fn stop_logging<F, T>(f: F) -> T
132where
133	F: FnOnce() -> T,
134{
135	Core::new().stop_logging(f).assert()
136}
137
138/// Returns `true` if debugging is enabled Action debugging may be enabled
139/// by setting a `ACTION_STEP_DEBUG` secret to `true` in the repo.
140///
141/// ```
142/// use actions_core as core;
143///
144/// let is_debug = core::is_debug();
145/// ```
146pub fn is_debug() -> bool {
147	env::var_os("RUNNER_DEBUG").as_deref() == Some(OsStr::new("1"))
148}
149
150/// Prints a debug message to the log. Action debugging may be enabled by
151/// setting a `ACTION_STEP_DEBUG` secret to `true` in the repo. You can
152/// optionally provide a `file`, `line` and `col` with the `log_error`
153/// function.
154///
155/// ```
156/// use actions_core as core;
157///
158/// core::debug("shaving a yak");
159/// ```
160pub fn debug<M: ToString>(message: M) {
161	Core::new().debug(message).assert();
162}
163
164/// Prints an error message to the log. You can optionally provide a `file`,
165/// `line` and `col` with the `log_error` function.
166///
167/// ```
168/// use actions_core as core;
169///
170/// core::error("shaving a yak");
171/// ```
172pub fn error<M: ToString>(message: M) {
173	Core::new().error(message).assert();
174}
175
176/// Prints a warning message to the log. You can optionally provide a `file`,
177/// `line` and `col` with the `log_warning` function.
178///
179/// ```
180/// use actions_core as core;
181///
182/// core::warning("shaving a yak");
183/// ```
184pub fn warning<M: ToString>(message: M) {
185	Core::new().warning(message).assert();
186}
187
188pub fn log_message<M: ToString>(level: LogLevel, message: M) {
189	Core::new().log_message(level, message).assert();
190}
191
192pub fn log<M: ToString>(level: LogLevel, log: Log<M>) {
193	Core::new().log(level, log).assert();
194}
195
196pub fn log_debug<M: ToString>(log: Log<M>) {
197	Core::new().log_debug(log).assert();
198}
199
200pub fn log_error<M: ToString>(log: Log<M>) {
201	Core::new().log_error(log).assert();
202}
203
204pub fn log_warning<M: ToString>(log: Log<M>) {
205	Core::new().log_warning(log).assert();
206}