From 3a3ca244794103746257c40a6cd8a6c4626987ee Mon Sep 17 00:00:00 2001 From: Ben Hillis Date: Wed, 30 Apr 2025 23:57:09 +0000 Subject: [PATCH 1/2] flowey: add ADO trigger for tags --- .../src/pipeline_resolver/ado_yaml.rs | 40 +++++++++++++++---- flowey/flowey_core/src/pipeline.rs | 14 +++++-- flowey/schema_ado_yaml/src/lib.rs | 15 ++++++- 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/flowey/flowey_cli/src/pipeline_resolver/ado_yaml.rs b/flowey/flowey_cli/src/pipeline_resolver/ado_yaml.rs index 61f27c3d89..099fc3312c 100644 --- a/flowey/flowey_cli/src/pipeline_resolver/ado_yaml.rs +++ b/flowey/flowey_cli/src/pipeline_resolver/ado_yaml.rs @@ -571,18 +571,44 @@ EOF let flowey_core::pipeline::AdoCiTriggers { branches, exclude_branches, + tags, + exclude_tags, batch, } = t; schema_ado_yaml::CiTrigger::Some { batch, - branches: schema_ado_yaml::TriggerBranches { - include: branches, - exclude: if exclude_branches.is_empty() { - None - } else { - Some(exclude_branches) - }, + branches: if branches.is_empty() { + if !exclude_branches.is_empty() { + anyhow::bail!("empty branch trigger with non-empty exclude") + } + + None + } else { + Some(schema_ado_yaml::TriggerBranches { + include: branches, + exclude: if exclude_branches.is_empty() { + None + } else { + Some(exclude_branches) + }, + }) + }, + tags: if tags.is_empty() { + if !exclude_tags.is_empty() { + anyhow::bail!("empty tags trigger with non-empty exclude") + } + + None + } else { + Some(schema_ado_yaml::TriggerTags { + include: tags, + exclude: if exclude_tags.is_empty() { + None + } else { + Some(exclude_tags) + }, + }) }, } } diff --git a/flowey/flowey_core/src/pipeline.rs b/flowey/flowey_core/src/pipeline.rs index a4b7e14f8c..f49116ece7 100644 --- a/flowey/flowey_core/src/pipeline.rs +++ b/flowey/flowey_core/src/pipeline.rs @@ -157,12 +157,18 @@ pub struct AdoPrTriggers { /// Trigger ADO pipelines per PR #[derive(Debug, Default)] pub struct AdoCiTriggers { - /// Run the pipeline whenever there is a PR to these specified branches + /// Run the pipeline whenever there is a change to these specified branches /// (supports glob syntax) pub branches: Vec, /// Specify any branches which should be filtered out from the list of /// `branches` (supports glob syntax) pub exclude_branches: Vec, + /// Run the pipeline whenever a matching tag is created (supports glob + /// syntax) + pub tags: Vec, + /// Specify any tags which should be filtered out from the list of `tags` + /// (supports glob syntax) + pub exclude_tags: Vec, /// Whether to batch changes per branch. pub batch: bool, } @@ -238,14 +244,14 @@ pub struct GhPrTriggers { /// Trigger Github Actions pipelines per PR #[derive(Debug, Default)] pub struct GhCiTriggers { - /// Run the pipeline whenever there is a PR to these specified branches + /// Run the pipeline whenever there is a change to these specified branches /// (supports glob syntax) pub branches: Vec, /// Specify any branches which should be filtered out from the list of /// `branches` (supports glob syntax) pub exclude_branches: Vec, - /// Run the pipeline whenever there is a PR to these specified tags - /// (supports glob syntax) + /// Run the pipeline whenever a matching tag is created (supports glob + /// syntax) pub tags: Vec, /// Specify any tags which should be filtered out from the list of `tags` /// (supports glob syntax) diff --git a/flowey/schema_ado_yaml/src/lib.rs b/flowey/schema_ado_yaml/src/lib.rs index 4d10c72e4c..8a03896edb 100644 --- a/flowey/schema_ado_yaml/src/lib.rs +++ b/flowey/schema_ado_yaml/src/lib.rs @@ -64,6 +64,16 @@ pub struct TriggerBranches { pub exclude: Option>, } +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TriggerTags { + #[serde(skip_serializing_if = "Vec::is_empty")] + pub include: Vec, + // Wrapping this in an Option is necessary to prevent problems when deserializing and exclude isn't present + #[serde(skip_serializing_if = "Option::is_none")] + pub exclude: Option>, +} + #[derive(Debug, Serialize, Deserialize)] #[serde(untagged)] #[serde(rename_all = "camelCase")] @@ -87,7 +97,10 @@ pub enum CiTrigger { #[serde(rename_all = "camelCase")] Some { batch: bool, - branches: TriggerBranches, + #[serde(skip_serializing_if = "Option::is_none")] + branches: Option, + #[serde(skip_serializing_if = "Option::is_none")] + tags: Option, }, // serde has a bug with untagged and `with` during deserialization NoneWorkaround(String), From e480ad44b2a102cf14b5c272ca0046063a959d99 Mon Sep 17 00:00:00 2001 From: Ben Hillis Date: Thu, 1 May 2025 00:14:52 +0000 Subject: [PATCH 2/2] add error for empty branches and tags --- flowey/flowey_cli/src/pipeline_resolver/ado_yaml.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/flowey/flowey_cli/src/pipeline_resolver/ado_yaml.rs b/flowey/flowey_cli/src/pipeline_resolver/ado_yaml.rs index 099fc3312c..0ba6156c66 100644 --- a/flowey/flowey_cli/src/pipeline_resolver/ado_yaml.rs +++ b/flowey/flowey_cli/src/pipeline_resolver/ado_yaml.rs @@ -576,6 +576,10 @@ EOF batch, } = t; + if branches.is_empty() && tags.is_empty() { + anyhow::bail!("branches and tags cannot both be empty") + } + schema_ado_yaml::CiTrigger::Some { batch, branches: if branches.is_empty() {