diff --git a/.github/workflows/ci2.yml b/.github/workflows/ci2.yml new file mode 100644 index 0000000000000..8ae4bfbbce9d9 --- /dev/null +++ b/.github/workflows/ci2.yml @@ -0,0 +1,72 @@ +name: CI v2 + +permissions: + contents: read + +on: + merge_group: + pull_request: + push: + branches: + - release-* + +env: + CARGO_TERM_COLOR: always + CARGO_INCREMENTAL: 0 + CARGO_PROFILE_TEST_DEBUG: 0 + CARGO_PROFILE_DEV_DEBUG: 0 + # If nightly is breaking CI, modify this variable to target a specific nightly version. + NIGHTLY_TOOLCHAIN: nightly + RUSTFLAGS: "-D warnings" + +jobs: + # job to list the jobs to run on rust stable + stable-prepare: + runs-on: ubuntu-latest + timeout-minutes: 30 + outputs: + jobs: ${{ steps.prepare.outputs.jobs }} + steps: + - uses: actions/checkout@v6 + - uses: dtolnay/rust-toolchain@stable + - name: Prepare CI jobs + id: prepare + run: | + echo "jobs=`cargo run -p ci -- what-to-run --trigger ${{ github.event_name }} --head ${{ github.head_ref }} --rust-version stable`" >> $GITHUB_OUTPUT + + # run all the jobs on stable + stable-run: + runs-on: ubuntu-latest + timeout-minutes: 30 + needs: [stable-prepare] + strategy: + fail-fast: false + matrix: + job: ${{ fromJson(needs.stable-prepare.outputs.jobs) }} + steps: + - uses: actions/checkout@v6 + - uses: actions/cache/restore@v4 + with: + key: ${{ runner.os }}-ci-runner--${{ hashFiles('tools/ci/Cargo.toml') }} + restore-keys: | + ${{ runner.os }}-ci-runner--${{ hashFiles('tools/ci/Cargo.toml') }} + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + - name: Install Linux dependencies + uses: ./.github/actions/install-linux-deps + - uses: dtolnay/rust-toolchain@stable + - name: Run CI job + run: | + ${{ matrix.job }} + + # single job to report status, usable in branch protection rules + stable-status: + runs-on: ubuntu-latest + needs: [stable-run] + if: always() + steps: + - run: ${{!contains(needs.*.result, 'failure')}} diff --git a/tools/ci/src/ci.rs b/tools/ci/src/ci.rs index 8b8556d90ac05..8d958330cb0c6 100644 --- a/tools/ci/src/ci.rs +++ b/tools/ci/src/ci.rs @@ -119,6 +119,8 @@ enum Commands { CompileFail(commands::CompileFailCommand), BenchCheck(commands::BenchCheckCommand), ExampleCheck(commands::ExampleCheckCommand), + // Controller (list commands that needs to run) + WhatToRun(commands::WhatToRunCommand), } impl Prepare for Commands { @@ -141,6 +143,10 @@ impl Prepare for Commands { Commands::CompileFail(subcommand) => subcommand.prepare(sh, args), Commands::BenchCheck(subcommand) => subcommand.prepare(sh, args), Commands::ExampleCheck(subcommand) => subcommand.prepare(sh, args), + Commands::WhatToRun(subcommand) => { + subcommand.run(sh, args); + vec![] + } } } } diff --git a/tools/ci/src/commands/mod.rs b/tools/ci/src/commands/mod.rs index 9247ab201627b..abdd0387dbcbb 100644 --- a/tools/ci/src/commands/mod.rs +++ b/tools/ci/src/commands/mod.rs @@ -14,6 +14,7 @@ pub use integration_test_clean::*; pub use lints::*; pub use test::*; pub use test_check::*; +pub use what_to_run::*; mod bench_check; mod clippy; @@ -31,3 +32,4 @@ mod integration_test_clean; mod lints; mod test; mod test_check; +mod what_to_run; diff --git a/tools/ci/src/commands/what_to_run.rs b/tools/ci/src/commands/what_to_run.rs new file mode 100644 index 0000000000000..c5528fdc9603b --- /dev/null +++ b/tools/ci/src/commands/what_to_run.rs @@ -0,0 +1,86 @@ +use argh::{FromArgValue, FromArgs}; +use xshell::Shell; + +use crate::args::Args; + +/// Decides which jobs to run +#[derive(FromArgs)] +#[argh(subcommand, name = "what-to-run")] +pub struct WhatToRunCommand { + /// which event triggered this run + #[argh(option)] + trigger: Trigger, + + /// which branch to diff against + #[argh(option)] + head: String, + + /// select tasks for a specific version of rust + #[argh(option)] + #[expect(dead_code, reason = "todo")] + rust_version: RustVersion, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum RustVersion { + Stable, + Beta, + Nightly, +} + +impl FromArgValue for RustVersion { + fn from_arg_value(value: &str) -> Result { + match value { + "stable" => Ok(RustVersion::Stable), + "beta" => Ok(RustVersion::Beta), + "nightly" => Ok(RustVersion::Nightly), + _ => Err(format!("Unknown rust version: {}", value)), + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Trigger { + Schedule, + MergeQueue, + ChangeRequest, + PushToBranch, +} + +impl FromArgValue for Trigger { + fn from_arg_value(value: &str) -> Result { + match value { + "schedule" => Ok(Trigger::Schedule), + "merge_group" => Ok(Trigger::MergeQueue), + "pull_request" => Ok(Trigger::ChangeRequest), + "push" => Ok(Trigger::PushToBranch), + _ => Err(format!("Unknown trigger: {}", value)), + } + } +} + +impl WhatToRunCommand { + #[expect(clippy::print_stdout, reason = "goal is to print jobs to stdout")] + #[expect( + clippy::vec_init_then_push, + reason = "temp, will be better after the todo" + )] + pub fn run(&self, _sh: &Shell, _args: Args) { + let _diff = match self.trigger { + Trigger::Schedule | Trigger::PushToBranch => vec![], + Trigger::ChangeRequest | Trigger::MergeQueue => get_diff(&self.head), + }; + + // TODO: filter jobs to run based on diff, trigger and rust version + let mut jobs = Vec::new(); + jobs.push(r#""cargo run -p ci -- test""#); + jobs.push(r#""cargo run -p ci -- lints""#); + + println!("[{}]", jobs.join(", ")); + } +} + +fn get_diff(_head: &str) -> Vec { + // TODO: Implement diff logic between local state and head branch + vec![] +}