Skip to content

Commit 188b17e

Browse files
authored
allow try to specify tests, and add no-ci-tests label to skip tests (#1431)
2 parents 21f25fb + 5ae2acd commit 188b17e

File tree

3 files changed

+108
-12
lines changed

3 files changed

+108
-12
lines changed

.github/workflows/ci.yml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ jobs:
110110
runs-on: ubuntu-latest
111111
outputs:
112112
matrix: ${{ steps.generate-matrix.outputs.matrix }}
113+
tests: ${{ steps.generate-matrix.outputs.tests }}
113114
steps:
114115
- uses: actions/checkout@v3
115116
with:
@@ -255,7 +256,8 @@ jobs:
255256

256257
# we should always have an artifact from a previous build.
257258
remote:
258-
needs: [test, check]
259+
needs: [test, check, generate-matrix]
260+
if: needs.generate-matrix.outputs.tests.remote
259261
runs-on: ubuntu-latest
260262
steps:
261263
- uses: actions/checkout@v3
@@ -275,7 +277,8 @@ jobs:
275277
shell: bash
276278

277279
bisect:
278-
needs: [test, check]
280+
needs: [test, check, generate-matrix]
281+
if: needs.generate-matrix.outputs.tests.bisect
279282
runs-on: ubuntu-latest
280283
steps:
281284
- uses: actions/checkout@v3
@@ -295,7 +298,8 @@ jobs:
295298
shell: bash
296299

297300
foreign:
298-
needs: [test, check]
301+
needs: [test, check, generate-matrix]
302+
if: needs.generate-matrix.outputs.tests.foreign
299303
runs-on: ubuntu-latest
300304
steps:
301305
- uses: actions/checkout@v3
@@ -321,7 +325,8 @@ jobs:
321325
shell: bash
322326

323327
docker-in-docker:
324-
needs: [test, check]
328+
needs: [test, check, generate-matrix]
329+
if: needs.generate-matrix.outputs.tests.docker-in-docker
325330
runs-on: ubuntu-latest
326331
steps:
327332
- uses: actions/checkout@v3
@@ -344,7 +349,8 @@ jobs:
344349
podman:
345350
name: podman
346351
runs-on: ubuntu-latest
347-
needs: [shellcheck, test, check]
352+
needs: [shellcheck, test, check, generate-matrix]
353+
if: needs.generate-matrix.outputs.tests.podman
348354
strategy:
349355
fail-fast: false
350356
outputs:

xtask/src/ci/target_matrix.rs

Lines changed: 96 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::process::Command;
22

3-
use clap::builder::BoolishValueParser;
3+
use clap::builder::{BoolishValueParser, PossibleValuesParser};
44
use clap::Parser;
55
use cross::{shell::Verbosity, CommandExt};
66
use serde::{Deserialize, Serialize};
@@ -61,6 +61,7 @@ impl TargetMatrix {
6161
none: false,
6262
has_image: true,
6363
verbose: false,
64+
tests: vec!["all".to_owned()],
6465
},
6566
),
6667
TargetMatrix {
@@ -74,6 +75,8 @@ impl TargetMatrix {
7475
_ => (vec![], TargetMatrixArgs::default()),
7576
};
7677

78+
// only apply ci labels on prs and `/ci try`,
79+
// if the try command is not the default, we don't want to apply ci labels
7780
if matches!(
7881
self,
7982
Self {
@@ -83,7 +86,7 @@ impl TargetMatrix {
8386
}
8487
) || is_default_try
8588
{
86-
apply_ci_target_labels(&prs, &mut app)?
89+
apply_ci_labels(&prs, &mut app)?
8790
}
8891

8992
app.filter(&mut matrix);
@@ -108,13 +111,15 @@ impl TargetMatrix {
108111
.collect::<Vec<_>>();
109112

110113
let json = serde_json::to_string(&matrix)?;
111-
gha_print(&json);
112114
gha_output("matrix", &json)?;
115+
let tests = serde_json::to_string(&app.tests()?)?;
116+
gha_output("tests", &tests)?;
113117
Ok(())
114118
}
115119
}
116120

117-
fn apply_ci_target_labels(prs: &[&str], app: &mut TargetMatrixArgs) -> Result<(), eyre::Error> {
121+
fn apply_ci_labels(prs: &[&str], app: &mut TargetMatrixArgs) -> Result<(), eyre::Error> {
122+
apply_has_no_ci_tests(prs, app)?;
118123
apply_has_no_ci_target(prs, app)?;
119124

120125
let mut to_add = vec![];
@@ -135,10 +140,22 @@ fn apply_ci_target_labels(prs: &[&str], app: &mut TargetMatrixArgs) -> Result<()
135140
Ok(())
136141
}
137142

143+
fn apply_has_no_ci_tests(prs: &[&str], app: &mut TargetMatrixArgs) -> Result<(), eyre::Error> {
144+
if !prs.is_empty()
145+
&& prs.iter().try_fold(true, |b, pr| {
146+
Ok::<_, eyre::Report>(b && has_no_ci_tests_label(pr)?)
147+
})?
148+
{
149+
app.none = true;
150+
app.tests.push("none".to_owned());
151+
}
152+
Ok(())
153+
}
154+
138155
fn apply_has_no_ci_target(prs: &[&str], app: &mut TargetMatrixArgs) -> Result<(), eyre::Error> {
139156
if !prs.is_empty()
140157
&& prs.iter().try_fold(true, |b, pr| {
141-
Ok::<_, eyre::Report>(b && has_no_ci_target(pr)?)
158+
Ok::<_, eyre::Report>(b && has_no_ci_target_label(pr)?)
142159
})?
143160
{
144161
app.none = true;
@@ -168,10 +185,14 @@ fn parse_gh_labels(pr: &str) -> cross::Result<Vec<String>> {
168185
Ok(pr_info.labels.into_iter().map(|l| l.name).collect())
169186
}
170187

171-
fn has_no_ci_target(pr: &str) -> cross::Result<bool> {
188+
fn has_no_ci_target_label(pr: &str) -> cross::Result<bool> {
172189
Ok(parse_gh_labels(pr)?.contains(&"no-ci-targets".to_owned()))
173190
}
174191

192+
fn has_no_ci_tests_label(pr: &str) -> cross::Result<bool> {
193+
Ok(parse_gh_labels(pr)?.contains(&"no-ci-tests".to_owned()))
194+
}
195+
175196
/// Convert a `GITHUB_REF` into it's merge group pr
176197
fn process_merge_group(ref_: &str) -> cross::Result<&str> {
177198
ref_.split('/')
@@ -227,7 +248,7 @@ struct TargetMatrixElement<'a> {
227248
verbose: bool,
228249
}
229250

230-
#[derive(Parser, Debug, Default, PartialEq, Eq)]
251+
#[derive(Parser, Debug, PartialEq, Eq)]
231252
#[clap(no_binary_name = true)]
232253
struct TargetMatrixArgs {
233254
#[clap(long, short, num_args = 0..)]
@@ -248,6 +269,37 @@ struct TargetMatrixArgs {
248269
has_image: bool,
249270
#[clap(long, short)]
250271
verbose: bool,
272+
#[clap(long, value_parser = PossibleValuesParser::new(&[
273+
"remote",
274+
"bisect",
275+
"foreign",
276+
"docker-in-docker",
277+
"podman",
278+
"none",
279+
"all"
280+
]),
281+
num_args = 0..,
282+
value_delimiter = ',',
283+
default_value = "all"
284+
)]
285+
tests: Vec<String>,
286+
}
287+
288+
impl Default for TargetMatrixArgs {
289+
fn default() -> Self {
290+
Self {
291+
target: Vec::new(),
292+
std: None,
293+
cpp: None,
294+
dylib: None,
295+
run: None,
296+
runners: Vec::new(),
297+
none: false,
298+
has_image: false,
299+
verbose: false,
300+
tests: vec!["all".to_owned()],
301+
}
302+
}
251303
}
252304

253305
impl TargetMatrixArgs {
@@ -298,6 +350,43 @@ impl TargetMatrixArgs {
298350
});
299351
}
300352
}
353+
354+
fn tests(&self) -> Result<serde_json::Value, serde_json::Error> {
355+
use clap::CommandFactory;
356+
use serde::ser::SerializeMap;
357+
struct Ser(Vec<String>);
358+
impl serde::Serialize for Ser {
359+
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
360+
let mut map = serializer.serialize_map(Some(self.0.len()))?;
361+
for e in &self.0 {
362+
map.serialize_entry(&e, &true)?;
363+
}
364+
map.end()
365+
}
366+
}
367+
let mut tests = match (
368+
self.tests.iter().any(|t| t == "all"),
369+
self.tests.iter().any(|t| t == "none"),
370+
) {
371+
(_, true) => vec![],
372+
(true, false) => {
373+
let possible: Vec<String> = Self::command()
374+
.get_arguments()
375+
.find(|arg| arg.get_id() == "tests")
376+
.expect("a `tests` argument should exist")
377+
.get_possible_values()
378+
.into_iter()
379+
.map(|p| p.get_name().to_owned())
380+
.collect();
381+
382+
possible
383+
}
384+
_ => self.tests.clone(),
385+
};
386+
tests.retain(|p| p != "all");
387+
tests.retain(|p| p != "none");
388+
serde_json::to_value(Ser(tests))
389+
}
301390
}
302391

303392
#[cfg(test)]

xtask/src/util.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ pub fn write_to_string(path: &Path, contents: &str) -> cross::Result<()> {
348348

349349
// https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#environment-files
350350
pub fn write_to_gha_env_file(env_name: &str, contents: &str) -> cross::Result<()> {
351+
eprintln!("{contents}");
351352
let path = if let Ok(path) = env::var(env_name) {
352353
PathBuf::from(path)
353354
} else {

0 commit comments

Comments
 (0)