Skip to content

Commit

Permalink
new: Support new values for task option runInCI. (#1754)
Browse files Browse the repository at this point in the history
* Add new option.

* Update tracker.

* Add tests.

* Polish.
  • Loading branch information
milesj committed Dec 17, 2024
1 parent e75b5c2 commit 6e9a499
Show file tree
Hide file tree
Showing 24 changed files with 328 additions and 142 deletions.
23 changes: 15 additions & 8 deletions .yarn/versions/2a5a0c21.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
releases:
"@moonrepo/cli": minor
"@moonrepo/core-linux-arm64-gnu": minor
"@moonrepo/core-linux-arm64-musl": minor
"@moonrepo/core-linux-x64-gnu": minor
"@moonrepo/core-linux-x64-musl": minor
"@moonrepo/core-macos-arm64": minor
"@moonrepo/core-macos-x64": minor
"@moonrepo/core-windows-x64-msvc": minor
'@moonrepo/cli': minor
'@moonrepo/core-linux-arm64-gnu': minor
'@moonrepo/core-linux-arm64-musl': minor
'@moonrepo/core-linux-x64-gnu': minor
'@moonrepo/core-linux-x64-musl': minor
'@moonrepo/core-macos-arm64': minor
'@moonrepo/core-macos-x64': minor
'@moonrepo/core-windows-x64-msvc': minor
'@moonrepo/types': minor

declined:
- '@moonrepo/nx-compat'
- '@moonrepo/report'
- '@moonrepo/runtime'
- website
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## Unreleased

#### 🚀 Updates

- Updated task option `runInCI` to support the values "always" (always run) and "affected" (only run
if affected, same as `true`).

## 1.30.5

#### 🐞 Fixes
Expand Down
4 changes: 4 additions & 0 deletions crates/action-graph/src/action_graph_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,10 @@ impl<'app> ActionGraphBuilder<'app> {
let mut inserted_nodes = vec![];
let mut initial_targets = vec![];

if let Some(affected) = &mut self.affected {
affected.set_ci_check(reqs.ci_check);
}

// Track the qualified as an initial target
for locator in reqs.target_locators.clone() {
initial_targets.push(match locator {
Expand Down
10 changes: 5 additions & 5 deletions crates/action-graph/tests/action_graph_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use moon_action_context::TargetState;
use moon_action_graph::*;
use moon_common::path::WorkspaceRelativePathBuf;
use moon_common::Id;
use moon_config::{PlatformType, TaskArgs, TaskDependencyConfig};
use moon_config::{PlatformType, TaskArgs, TaskDependencyConfig, TaskOptionRunInCI};
use moon_platform::*;
use moon_task::{Target, TargetLocator, Task};
use moon_test_utils2::generate_workspace_graph;
Expand Down Expand Up @@ -1027,7 +1027,7 @@ mod action_graph {
let project = container.workspace_graph.get_project("bar").unwrap();

let mut task = create_task("build", "bar");
task.options.run_in_ci = true;
task.options.run_in_ci = TaskOptionRunInCI::Enabled(true);

builder
.run_task(
Expand Down Expand Up @@ -1121,7 +1121,7 @@ mod action_graph {
let project = container.workspace_graph.get_project("bar").unwrap();

let mut task = create_task("build", "bar");
task.options.run_in_ci = false;
task.options.run_in_ci = TaskOptionRunInCI::Enabled(false);

builder
.run_task(
Expand Down Expand Up @@ -1158,7 +1158,7 @@ mod action_graph {
let project = container.workspace_graph.get_project("bar").unwrap();

let mut task = create_task("build", "bar");
task.options.run_in_ci = false;
task.options.run_in_ci = TaskOptionRunInCI::Enabled(false);

builder
.run_task(
Expand Down Expand Up @@ -1188,7 +1188,7 @@ mod action_graph {
let project = container.workspace_graph.get_project("bar").unwrap();

let mut task = create_task("build", "bar");
task.options.run_in_ci = false;
task.options.run_in_ci = TaskOptionRunInCI::Enabled(false);

builder
.run_task(
Expand Down
20 changes: 19 additions & 1 deletion crates/affected/src/affected_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ use crate::affected::*;
use moon_common::path::WorkspaceRelativePathBuf;
use moon_common::{color, Id};
use moon_project::Project;
use moon_task::{Target, Task};
use moon_task::{Target, Task, TaskOptionRunInCI};
use moon_workspace_graph::{GraphConnections, WorkspaceGraph};
use rustc_hash::{FxHashMap, FxHashSet};
use std::env;
use std::fmt;
use tracing::{debug, trace};

pub struct AffectedTracker<'app> {
ci: bool,

workspace_graph: &'app WorkspaceGraph,
touched_files: &'app FxHashSet<WorkspaceRelativePathBuf>,

Expand Down Expand Up @@ -38,6 +40,7 @@ impl<'app> AffectedTracker<'app> {
tasks: FxHashMap::default(),
task_downstream: DownstreamScope::None,
task_upstream: UpstreamScope::Deep,
ci: false,
}
}

Expand Down Expand Up @@ -82,6 +85,11 @@ impl<'app> AffectedTracker<'app> {
affected
}

pub fn set_ci_check(&mut self, ci: bool) -> &mut Self {
self.ci = ci;
self
}

pub fn with_project_scopes(
&mut self,
upstream_scope: UpstreamScope,
Expand Down Expand Up @@ -322,6 +330,16 @@ impl<'app> AffectedTracker<'app> {
return Ok(Some(AffectedBy::AlreadyMarked));
}

if self.ci {
match &task.options.run_in_ci {
TaskOptionRunInCI::Always => {
return Ok(Some(AffectedBy::AlwaysAffected));
}
TaskOptionRunInCI::Enabled(false) => return Ok(None),
_ => {}
};
}

// inputs: []
if task.state.empty_inputs {
return Ok(None);
Expand Down
13 changes: 13 additions & 0 deletions crates/affected/tests/__fixtures__/tasks/ci/moon.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
tasks:
enabled:
options:
runInCI: true
disabled:
options:
runInCI: false
affected:
options:
runInCI: affected
always:
options:
runInCI: always
106 changes: 106 additions & 0 deletions crates/affected/tests/affected_tracker_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -956,4 +956,110 @@ mod affected_tasks {
);
}
}

mod ci {
use super::*;

#[tokio::test]
async fn when_ci_tracks_for_true() {
let workspace_graph = generate_workspace_graph("tasks").await;
let touched_files = FxHashSet::from_iter(["ci/file.txt".into()]);

let mut tracker = AffectedTracker::new(&workspace_graph, &touched_files);
tracker.set_ci_check(true);
tracker
.track_tasks_by_target(&[Target::parse("ci:enabled").unwrap()])
.unwrap();
let affected = tracker.build();

assert_eq!(
affected.tasks,
FxHashMap::from_iter([(
Target::parse("ci:enabled").unwrap(),
create_state_from_file("ci/file.txt")
)])
);
}

#[tokio::test]
async fn when_not_ci_tracks_for_true() {
let workspace_graph = generate_workspace_graph("tasks").await;
let touched_files = FxHashSet::from_iter(["ci/file.txt".into()]);

let mut tracker = AffectedTracker::new(&workspace_graph, &touched_files);
tracker.set_ci_check(false);
tracker
.track_tasks_by_target(&[Target::parse("ci:enabled").unwrap()])
.unwrap();
let affected = tracker.build();

assert_eq!(
affected.tasks,
FxHashMap::from_iter([(
Target::parse("ci:enabled").unwrap(),
create_state_from_file("ci/file.txt")
)])
);
}

#[tokio::test]
async fn when_ci_doesnt_track_for_false() {
let workspace_graph = generate_workspace_graph("tasks").await;
let touched_files = FxHashSet::from_iter(["ci/file.txt".into()]);

let mut tracker = AffectedTracker::new(&workspace_graph, &touched_files);
tracker.set_ci_check(true);
tracker
.track_tasks_by_target(&[Target::parse("ci:disabled").unwrap()])
.unwrap();
let affected = tracker.build();

assert!(affected.tasks.is_empty());
}

#[tokio::test]
async fn when_not_ci_tracks_for_false() {
let workspace_graph = generate_workspace_graph("tasks").await;
let touched_files = FxHashSet::from_iter(["ci/file.txt".into()]);

let mut tracker = AffectedTracker::new(&workspace_graph, &touched_files);
tracker.set_ci_check(false);
tracker
.track_tasks_by_target(&[Target::parse("ci:disabled").unwrap()])
.unwrap();
let affected = tracker.build();

assert_eq!(
affected.tasks,
FxHashMap::from_iter([(
Target::parse("ci:disabled").unwrap(),
create_state_from_file("ci/file.txt")
)])
);
}

#[tokio::test]
async fn when_ci_always_tracks_if_not_touched() {
let workspace_graph = generate_workspace_graph("tasks").await;
let touched_files = FxHashSet::default();

let mut tracker = AffectedTracker::new(&workspace_graph, &touched_files);
tracker.set_ci_check(true);
tracker
.track_tasks_by_target(&[Target::parse("ci:always").unwrap()])
.unwrap();
let affected = tracker.build();

assert_eq!(
affected.tasks,
FxHashMap::from_iter([(
Target::parse("ci:always").unwrap(),
AffectedTaskState {
other: true,
..Default::default()
}
)])
);
}
}
}
1 change: 1 addition & 0 deletions crates/config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod config_finder;
mod config_loader;
mod inherited_tasks_config;
mod language_platform;
mod macros;
pub mod patterns;
mod portable_path;
mod project;
Expand Down
32 changes: 32 additions & 0 deletions crates/config/src/macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#[macro_export]
macro_rules! generate_switch {
($name:ident, [ $($value:literal),* ]) => {
impl $name {
pub fn is_enabled(&self) -> bool {
!matches!(self, Self::Enabled(false))
}
}

impl From<bool> for $name {
fn from(value: bool) -> Self {
Self::Enabled(value)
}
}

impl Schematic for $name {
fn build_schema(mut schema: SchemaBuilder) -> Schema {
schema.union(UnionType::new_any([
schema.infer::<bool>(),
schema.nest().string(StringType {
enum_values: Some(Vec::from_iter([
$(
$value.into()
),*
])),
..Default::default()
}),
]))
}
}
};
}
Loading

0 comments on commit 6e9a499

Please sign in to comment.