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