1use gh_workflow::*;
2use indoc::indoc;
3
4use crate::tasks::workflows::{
5 run_tests::{orchestrate, tests_pass},
6 runners,
7 steps::{self, CommonJobConditions, FluentBuilder, NamedJob, named},
8 vars::{PathCondition, StepOutput, one_workflow_per_non_main_branch},
9};
10
11const RUN_TESTS_INPUT: &str = "run_tests";
12pub(crate) const ZED_EXTENSION_CLI_SHA: &str = "7cfce605704d41ca247e3f84804bf323f6c6caaf";
13
14// This is used by various extensions repos in the zed-extensions org to run automated tests.
15pub(crate) fn extension_tests() -> Workflow {
16 let should_check_rust = PathCondition::new("check_rust", r"^(Cargo.lock|Cargo.toml|.*\.rs)$");
17 let should_check_extension = PathCondition::new("check_extension", r"^.*\.scm$");
18
19 let orchestrate = orchestrate(&[&should_check_rust, &should_check_extension]);
20
21 let jobs = [
22 orchestrate,
23 should_check_rust.guard(check_rust()),
24 should_check_extension.guard(check_extension()),
25 ];
26
27 let tests_pass = tests_pass(&jobs);
28
29 named::workflow()
30 .add_event(
31 Event::default().workflow_call(WorkflowCall::default().add_input(
32 RUN_TESTS_INPUT,
33 WorkflowCallInput {
34 description: "Whether the workflow should run rust tests".into(),
35 required: true,
36 input_type: "boolean".into(),
37 default: None,
38 },
39 )),
40 )
41 .concurrency(one_workflow_per_non_main_branch())
42 .add_env(("CARGO_TERM_COLOR", "always"))
43 .add_env(("RUST_BACKTRACE", 1))
44 .add_env(("CARGO_INCREMENTAL", 0))
45 .add_env(("ZED_EXTENSION_CLI_SHA", ZED_EXTENSION_CLI_SHA))
46 .map(|workflow| {
47 jobs.into_iter()
48 .chain([tests_pass])
49 .fold(workflow, |workflow, job| {
50 workflow.add_job(job.name, job.job)
51 })
52 })
53}
54
55fn run_clippy() -> Step<Run> {
56 named::bash("cargo clippy --release --all-targets --all-features -- --deny warnings")
57}
58
59fn check_rust() -> NamedJob {
60 let job = Job::default()
61 .with_repository_owner_guard()
62 .runs_on(runners::LINUX_DEFAULT)
63 .timeout_minutes(3u32)
64 .add_step(steps::checkout_repo())
65 .add_step(steps::cache_rust_dependencies_namespace())
66 .add_step(steps::cargo_fmt())
67 .add_step(run_clippy())
68 .add_step(
69 steps::cargo_install_nextest()
70 .if_condition(Expression::new(format!("inputs.{RUN_TESTS_INPUT}"))),
71 )
72 .add_step(
73 steps::cargo_nextest(runners::Platform::Linux)
74 .if_condition(Expression::new(format!("inputs.{RUN_TESTS_INPUT}"))),
75 );
76
77 named::job(job)
78}
79
80pub(crate) fn check_extension() -> NamedJob {
81 let (cache_download, cache_hit) = cache_zed_extension_cli();
82 let job = Job::default()
83 .with_repository_owner_guard()
84 .runs_on(runners::LINUX_SMALL)
85 .timeout_minutes(1u32)
86 .add_step(steps::checkout_repo())
87 .add_step(cache_download)
88 .add_step(download_zed_extension_cli(cache_hit))
89 .add_step(check());
90
91 named::job(job)
92}
93
94pub fn cache_zed_extension_cli() -> (Step<Use>, StepOutput) {
95 let step = named::uses(
96 "actions",
97 "cache",
98 "0057852bfaa89a56745cba8c7296529d2fc39830",
99 )
100 .id("cache-zed-extension-cli")
101 .with(
102 Input::default()
103 .add("path", "zed-extension")
104 .add("key", "zed-extension-${{ env.ZED_EXTENSION_CLI_SHA }}"),
105 );
106 let output = StepOutput::new(&step, "cache-hit");
107 (step, output)
108}
109
110pub fn download_zed_extension_cli(cache_hit: StepOutput) -> Step<Run> {
111 named::bash(
112 indoc! {
113 r#"
114 wget --quiet "https://zed-extension-cli.nyc3.digitaloceanspaces.com/$ZED_EXTENSION_CLI_SHA/x86_64-unknown-linux-gnu/zed-extension"
115 chmod +x zed-extension
116 "#,
117 }
118 ).if_condition(Expression::new(format!("{} != 'true'", cache_hit.expr())))
119}
120
121pub fn check() -> Step<Run> {
122 named::bash(indoc! {
123 r#"
124 mkdir -p /tmp/ext-scratch
125 mkdir -p /tmp/ext-output
126 ./zed-extension --source-dir . --scratch-dir /tmp/ext-scratch --output-dir /tmp/ext-output
127 "#
128 })
129}