diff --git a/Cargo.lock b/Cargo.lock index 5d8cf67..43e3a92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -149,6 +149,16 @@ dependencies = [ "syn 2.0.89", ] +[[package]] +name = "gh-workflow-tailcall" +version = "0.1.0" +dependencies = [ + "derive_setters", + "gh-workflow", + "insta", + "pretty_assertions", +] + [[package]] name = "hashbrown" version = "0.15.2" diff --git a/Cargo.toml b/Cargo.toml index a0f58b8..a848b85 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,3 @@ [workspace] -edition = "2021" resolver = "2" members = ["crates/*"] diff --git a/crates/gh-workflow-tailcall/Cargo.toml b/crates/gh-workflow-tailcall/Cargo.toml new file mode 100644 index 0000000..fc8418b --- /dev/null +++ b/crates/gh-workflow-tailcall/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "gh-workflow-tailcall" +version = "0.1.0" +edition = "2021" + + +description = "macros for gh-workflow" +license = "Apache-2.0" +documentation = "https://docs.rs/gh-workflow" +homepage = "https://github.com/tailcallhq/gh-workflow" +repository = "https://github.com/tailcallhq/gh-workflow" +keywords = ["github", "actions", "workflow", "generator"] + +[dependencies] +derive_setters = { version = "0.1.6" } +gh-workflow = { path = "../gh-workflow", version = "0.5.1" } + +[dev-dependencies] +insta = "1.40.0" +pretty_assertions = "1.4.1" diff --git a/crates/gh-workflow-tailcall/src/lib.rs b/crates/gh-workflow-tailcall/src/lib.rs new file mode 100644 index 0000000..24ae5f2 --- /dev/null +++ b/crates/gh-workflow-tailcall/src/lib.rs @@ -0,0 +1,3 @@ +mod workflow; + +pub use workflow::*; diff --git a/crates/gh-workflow-tailcall/src/workflow.rs b/crates/gh-workflow-tailcall/src/workflow.rs new file mode 100644 index 0000000..d35dfd6 --- /dev/null +++ b/crates/gh-workflow-tailcall/src/workflow.rs @@ -0,0 +1,117 @@ +//! Workflow for all tailcall projects free and open source for everyone. + +use ctx::Context; +use derive_setters::Setters; +use gh_workflow::*; +use release_plz::{Command, Release}; +use toolchain::Toolchain; + +#[derive(Default, Debug, Clone, Setters)] +pub struct TailcallWorkflow { + pub release: bool, +} + +impl TailcallWorkflow {} + +impl From for Workflow { + fn from(value: TailcallWorkflow) -> 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 = build_and_test(); + let mut workflow = Workflow::new("CI") + .add_env(flags) + .on(event) + .add_job("build", build.clone()); + + if value.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 + } +} + +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)) +} + +fn build_and_test() -> Job { + Job::new("Build and Test") + .permissions(Permissions::default().contents(Level::Read)) + .add_step(Step::checkout()) + .add_step( + Toolchain::default() + .add_stable() + .add_nightly() + .add_clippy() + .add_fmt(), + ) + .add_step( + Cargo::new("test") + .args("--all-features --workspace") + .name("Cargo Test"), + ) + .add_step( + Cargo::new("fmt") + .nightly() + .args("--check") + .name("Cargo Fmt"), + ) + .add_step( + Cargo::new("clippy") + .nightly() + .args("--all-features --workspace -- -D warnings") + .name("Cargo Clippy"), + ) +} diff --git a/crates/gh-workflow/tests/ci.rs b/crates/gh-workflow-tailcall/tests/ci.rs similarity index 100% rename from crates/gh-workflow/tests/ci.rs rename to crates/gh-workflow-tailcall/tests/ci.rs