Rollup merge of #114062 - Kobzol:ci-group-splitting, r=Mark-Simulacrum

CI: split nested GHA groups instead of panicking

Bootstrap uses Github Actions groups to reduce clutter in CI job output. However, GHA doesn't support group nesting, and currently, when a group would be nested, bootstrap would panic. This is causing intermittent CI failures, because it's not trivial to make sure that groups won't be nested, and subtle changes in bootstrap (or even in caches being present) can cause nesting.

This PR changes the logic so that groups are never nested. Instead, when a group would be nested, the previous group is ended, and only then is the subgroup started. When the subgroup finishes, it will then restart any previously ended parent group.

r? `@Mark-Simulacrum`
This commit is contained in:
Matthias Krüger 2023-07-25 23:34:08 +02:00 committed by GitHub
commit c80a9fa870
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -36,25 +36,26 @@ impl CiEnv {
}
pub mod gha {
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Mutex;
static GROUP_ACTIVE: AtomicBool = AtomicBool::new(false);
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 nesting these does
/// not really work.
/// 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 {
if std::env::var_os("GITHUB_ACTIONS").is_some() {
eprintln!("::group::{name}");
} else {
eprintln!("{name}")
let mut groups = ACTIVE_GROUPS.lock().unwrap();
// A group is currently active. End it first to avoid nesting.
if !groups.is_empty() {
end_group();
}
// https://github.com/actions/toolkit/issues/1001
assert!(
!GROUP_ACTIVE.swap(true, Ordering::Relaxed),
"nested groups are not supported by GHA!"
);
let name = name.to_string();
start_group(&name);
groups.push(name);
Group(())
}
@ -64,13 +65,36 @@ pub mod gha {
impl Drop for Group {
fn drop(&mut self) {
if std::env::var_os("GITHUB_ACTIONS").is_some() {
eprintln!("::endgroup::");
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)"));
}
}
assert!(
GROUP_ACTIVE.swap(false, Ordering::Relaxed),
"group dropped but no group active!"
);
}
}
fn start_group(name: impl std::fmt::Display) {
if is_in_gha() {
eprintln!("::group::{name}");
} else {
eprintln!("{name}")
}
}
fn end_group() {
if is_in_gha() {
eprintln!("::endgroup::");
}
}
fn is_in_gha() -> bool {
std::env::var_os("GITHUB_ACTIONS").is_some()
}
}