blob: 09489b0d9b7daa776b8477af0fc7a45a7ba8b40a [file] [log] [blame]
use std::process::Command;
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum CiEnv {
/// Not a CI environment.
None,
/// The GitHub Actions environment, for Linux (including Docker), Windows and macOS builds.
GitHubActions,
}
impl CiEnv {
/// Obtains the current CI environment.
pub fn current() -> CiEnv {
if std::env::var("GITHUB_ACTIONS").map_or(false, |e| e == "true") {
CiEnv::GitHubActions
} else {
CiEnv::None
}
}
pub fn is_ci() -> bool {
Self::current() != CiEnv::None
}
/// If in a CI environment, forces the command to run with colors.
pub fn force_coloring_in_ci(self, cmd: &mut Command) {
if self != CiEnv::None {
// Due to use of stamp/docker, the output stream of rustbuild is not
// a TTY in CI, so coloring is by-default turned off.
// The explicit `TERM=xterm` environment is needed for
// `--color always` to actually work. This env var was lost when
// compiling through the Makefile. Very strange.
cmd.env("TERM", "xterm").args(&["--color", "always"]);
}
}
}
pub mod gha {
use std::sync::Mutex;
static ACTIVE_GROUPS: Mutex<Vec<String>> = Mutex::new(Vec::new());
/// All github actions log messages from this call to the Drop of the return value
/// will be grouped and hidden by default in logs. Note that since github actions doesn't
/// support group nesting, any active group will be first finished when a subgroup is started,
/// and then re-started when the subgroup finishes.
#[track_caller]
pub fn group(name: impl std::fmt::Display) -> Group {
let mut groups = ACTIVE_GROUPS.lock().unwrap();
// A group is currently active. End it first to avoid nesting.
if !groups.is_empty() {
end_group();
}
let name = name.to_string();
start_group(&name);
groups.push(name);
Group(())
}
/// A guard that closes the current github actions log group on drop.
#[must_use]
pub struct Group(());
impl Drop for Group {
fn drop(&mut self) {
end_group();
let mut groups = ACTIVE_GROUPS.lock().unwrap();
// Remove the current group
groups.pop();
// If there was some previous group, restart it
if is_in_gha() {
if let Some(name) = groups.last() {
start_group(format!("{name} (continued)"));
}
}
}
}
fn start_group(name: impl std::fmt::Display) {
if is_in_gha() {
println!("::group::{name}");
} else {
println!("{name}")
}
}
fn end_group() {
if is_in_gha() {
println!("::endgroup::");
}
}
fn is_in_gha() -> bool {
std::env::var_os("GITHUB_ACTIONS").is_some()
}
}