From 101b31d36b1c9ea2447b35b55b123697cfdf088a Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Wed, 11 Dec 2024 08:00:41 -0800 Subject: [PATCH 1/2] add when prefixed operators --- crates/gh-workflow-tailcall/src/workflow.rs | 146 +++++++++----------- crates/gh-workflow/src/workflow.rs | 63 +++++++++ 2 files changed, 127 insertions(+), 82 deletions(-) diff --git a/crates/gh-workflow-tailcall/src/workflow.rs b/crates/gh-workflow-tailcall/src/workflow.rs index eac71dd..eb6f14c 100644 --- a/crates/gh-workflow-tailcall/src/workflow.rs +++ b/crates/gh-workflow-tailcall/src/workflow.rs @@ -41,12 +41,67 @@ impl Workflow { /// Converts the workflow into a Github workflow. pub fn to_github_workflow(&self) -> GHWorkflow { - self.clone().into() + let flags = RustFlags::deny("warnings"); + + let event = Event::default() + .push(Push::default().add_branch("main")) + .pull_request( + PullRequest::default() + .add_type(PullRequestType::Opened) + .add_type(PullRequestType::Synchronize) + .add_type(PullRequestType::Reopened) + .add_branch("main"), + ); + + let is_main = Context::github().ref_().eq("refs/heads/main".into()); + let is_push = Context::github().event_name().eq("push".into()); + let cond = is_main.and(is_push); + + // Jobs + let build = self.build_and_test(); + let permissions = Permissions::default() + .pull_requests(Level::Write) + .packages(Level::Write) + .contents(Level::Write); + let release = Job::new("Release") + .cond((&cond).clone()) + .add_needs((&build).clone()) + .add_env(Env::github()) + .add_env(Env::new( + "CARGO_REGISTRY_TOKEN", + "${{ secrets.CARGO_REGISTRY_TOKEN }}", + )) + .permissions((&permissions).clone()) + .add_step(Step::checkout()) + .add_step(Release::default().command(Command::Release)); + + let release_pr = Job::new("Release PR") + .cond((&cond).clone()) + .concurrency( + Concurrency::new(Expression::new("release-${{github.ref}}")) + .cancel_in_progress(false), + ) + .add_needs((&build).clone()) + .add_env(Env::github()) + .add_env(Env::new( + "CARGO_REGISTRY_TOKEN", + "${{ secrets.CARGO_REGISTRY_TOKEN }}", + )) + .permissions(permissions) + .add_step(Step::checkout()) + .add_step(Release::default().command(Command::ReleasePR)); + + GHWorkflow::new(self.name.clone()) + .add_env(flags) + .on(event) + .add_job("build", (&build).clone()) + .add_job_when(self.auto_release, "release", release) + .add_job_when(self.auto_release, "release-pr", release_pr) } /// Creates the "Build and Test" job for the workflow. - pub fn build_and_test(&self) -> Job { - let mut job = Job::new("Build and Test") + fn build_and_test(&self) -> Job { + Job::new("Build and Test") .permissions(Permissions::default().contents(Level::Read)) .add_step(Step::checkout()) .add_step( @@ -72,89 +127,16 @@ impl Workflow { .nightly() .args("--all-features --workspace -- -D warnings") .name("Cargo Clippy"), - ); - - if self.benchmarks { - job = job.add_step( - Cargo::new("bench") - .args("--workspace") - .name("Cargo Bench"), - ); - } - - job + ) + .add_step_when( + self.benchmarks, + Cargo::new("bench").args("--workspace").name("Cargo Bench"), + ) } } impl From for GHWorkflow { fn from(value: Workflow) -> Self { - let flags = RustFlags::deny("warnings"); - - let event = Event::default() - .push(Push::default().add_branch("main")) - .pull_request( - PullRequest::default() - .add_type(PullRequestType::Opened) - .add_type(PullRequestType::Synchronize) - .add_type(PullRequestType::Reopened) - .add_branch("main"), - ); - - let is_main = Context::github().ref_().eq("refs/heads/main".into()); - let is_push = Context::github().event_name().eq("push".into()); - let cond = is_main.and(is_push); - - // Jobs - let build = value.build_and_test(); - let mut workflow = GHWorkflow::new(value.name) - .add_env(flags) - .on(event) - .add_job("build", build.clone()); - - if value.auto_release { - let permissions = Permissions::default() - .pull_requests(Level::Write) - .packages(Level::Write) - .contents(Level::Write); - - let release = release_job(&cond, &build, &permissions); - let release_pr = release_pr_job(cond, &build, permissions); - workflow = workflow - .add_job("release", release) - .add_job("release-pr", release_pr); - } - - workflow + value.to_github_workflow() } } - -fn release_pr_job(cond: Context, build: &Job, permissions: Permissions) -> Job { - Job::new("Release PR") - .cond(cond.clone()) - .concurrency( - Concurrency::new(Expression::new("release-${{github.ref}}")).cancel_in_progress(false), - ) - .add_needs(build.clone()) - .add_env(Env::github()) - .add_env(Env::new( - "CARGO_REGISTRY_TOKEN", - "${{ secrets.CARGO_REGISTRY_TOKEN }}", - )) - .permissions(permissions) - .add_step(Step::checkout()) - .add_step(Release::default().command(Command::ReleasePR)) -} - -fn release_job(cond: &Context, build: &Job, permissions: &Permissions) -> Job { - Job::new("Release") - .cond(cond.clone()) - .add_needs(build.clone()) - .add_env(Env::github()) - .add_env(Env::new( - "CARGO_REGISTRY_TOKEN", - "${{ secrets.CARGO_REGISTRY_TOKEN }}", - )) - .permissions(permissions.clone()) - .add_step(Step::checkout()) - .add_step(Release::default().command(Command::Release)) -} diff --git a/crates/gh-workflow/src/workflow.rs b/crates/gh-workflow/src/workflow.rs index 309557b..7b11c8d 100644 --- a/crates/gh-workflow/src/workflow.rs +++ b/crates/gh-workflow/src/workflow.rs @@ -101,6 +101,15 @@ impl Workflow { Ok(serde_yaml::to_string(self)?) } + /// Adds a job to the workflow when a condition is met. + pub fn add_job_when>(self, cond: bool, id: T, job: J) -> Self { + if cond { + self.add_job(id, job) + } else { + self + } + } + /// Adds a job to the workflow with the specified ID and job configuration. pub fn add_job>(mut self, id: T, job: J) -> Self { let key = id.to_string(); @@ -133,6 +142,15 @@ impl Workflow { self } + /// Adds an event to the workflow when a condition is met. + pub fn add_event_when>(self, cond: bool, that: T) -> Self { + if cond { + self.add_event(that) + } else { + self + } + } + /// Adds an environment variable to the workflow. pub fn add_env>(mut self, new_env: T) -> Self { let mut env = self.env.unwrap_or_default(); @@ -142,6 +160,15 @@ impl Workflow { self } + /// Adds an environment variable to the workflow when a condition is met. + pub fn add_env_when>(self, cond: bool, new_env: T) -> Self { + if cond { + self.add_env(new_env) + } else { + self + } + } + /// Performs a reverse lookup to get the ID of a job. pub fn get_id(&self, job: &Job) -> Option<&str> { self.jobs @@ -237,6 +264,15 @@ impl Job { } } + /// Adds a step to the job when a condition is met. + pub fn add_step_when>>(self, cond: bool, step: S) -> Self { + if cond { + self.add_step(step) + } else { + self + } + } + /// Adds a step to the job. pub fn add_step>, T: StepType>(mut self, step: S) -> Self { let mut steps = self.steps.unwrap_or_default(); @@ -256,6 +292,15 @@ impl Job { self } + /// Adds an environment variable to the job when a condition is met. + pub fn add_env_when>(self, cond: bool, new_env: T) -> Self { + if cond { + self.add_env(new_env) + } else { + self + } + } + pub fn add_needs>(mut self, needs: J) -> Self { let job: Job = needs.into(); let mut needs = self.tmp_needs.unwrap_or_default(); @@ -263,6 +308,15 @@ impl Job { self.tmp_needs = Some(needs); self } + + /// Adds a dependency to the job when a condition is met. + pub fn add_needs_when>(self, cond: bool, needs: T) -> Self { + if cond { + self.add_needs(needs) + } else { + self + } + } } /// Represents a step in the workflow. @@ -524,6 +578,15 @@ impl Step { self } + + /// Adds a new input to the step when a condition is met. + pub fn add_with_when>(self, cond: bool, new_with: I) -> Self { + if cond { + self.add_with(new_with) + } else { + self + } + } } /// Represents a key-value pair for inputs. From 002db5397bbe76deac80ccb4cf8b5d66d76cbfd0 Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Wed, 11 Dec 2024 08:03:07 -0800 Subject: [PATCH 2/2] style fixes --- crates/gh-workflow-tailcall/src/workflow.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/gh-workflow-tailcall/src/workflow.rs b/crates/gh-workflow-tailcall/src/workflow.rs index eb6f14c..9ff6f9b 100644 --- a/crates/gh-workflow-tailcall/src/workflow.rs +++ b/crates/gh-workflow-tailcall/src/workflow.rs @@ -64,24 +64,24 @@ impl Workflow { .packages(Level::Write) .contents(Level::Write); let release = Job::new("Release") - .cond((&cond).clone()) - .add_needs((&build).clone()) + .cond(cond.clone()) + .add_needs(build.clone()) .add_env(Env::github()) .add_env(Env::new( "CARGO_REGISTRY_TOKEN", "${{ secrets.CARGO_REGISTRY_TOKEN }}", )) - .permissions((&permissions).clone()) + .permissions(permissions.clone()) .add_step(Step::checkout()) .add_step(Release::default().command(Command::Release)); let release_pr = Job::new("Release PR") - .cond((&cond).clone()) + .cond(cond.clone()) .concurrency( Concurrency::new(Expression::new("release-${{github.ref}}")) .cancel_in_progress(false), ) - .add_needs((&build).clone()) + .add_needs(build.clone()) .add_env(Env::github()) .add_env(Env::new( "CARGO_REGISTRY_TOKEN", @@ -94,7 +94,7 @@ impl Workflow { GHWorkflow::new(self.name.clone()) .add_env(flags) .on(event) - .add_job("build", (&build).clone()) + .add_job("build", build.clone()) .add_job_when(self.auto_release, "release", release) .add_job_when(self.auto_release, "release-pr", release_pr) }