release_nightly.rs

  1use crate::tasks::workflows::{
  2    nix_build::build_nix,
  3    release::{ReleaseBundleJobs, download_workflow_artifacts, prep_release_artifacts},
  4    run_bundling::{bundle_linux, bundle_mac, bundle_windows},
  5    run_tests::run_platform_tests,
  6    runners::{Arch, Platform, ReleaseChannel},
  7    steps::{FluentBuilder, NamedJob},
  8};
  9
 10use super::{runners, steps, steps::named, vars};
 11use gh_workflow::*;
 12use indexmap::IndexMap;
 13
 14/// Generates the release_nightly.yml workflow
 15pub fn release_nightly() -> Workflow {
 16    let env: IndexMap<_, _> = [("CARGO_TERM_COLOR", "always"), ("RUST_BACKTRACE", "1")]
 17        .into_iter()
 18        .map(|(key, value)| (key.into(), value.into()))
 19        .collect();
 20
 21    let style = check_style();
 22    // run only on windows as that's our fastest platform right now.
 23    let tests = run_platform_tests(Platform::Windows);
 24    let nightly = Some(ReleaseChannel::Nightly);
 25
 26    let bundle = ReleaseBundleJobs {
 27        linux_aarch64: bundle_linux(Arch::AARCH64, nightly, &[&style, &tests]),
 28        linux_x86_64: bundle_linux(Arch::X86_64, nightly, &[&style, &tests]),
 29        mac_aarch64: bundle_mac(Arch::AARCH64, nightly, &[&style, &tests]),
 30        mac_x86_64: bundle_mac(Arch::X86_64, nightly, &[&style, &tests]),
 31        windows_aarch64: bundle_windows(Arch::AARCH64, nightly, &[&style, &tests]),
 32        windows_x86_64: bundle_windows(Arch::X86_64, nightly, &[&style, &tests]),
 33    };
 34
 35    let nix_linux_x86 = build_nix(
 36        Platform::Linux,
 37        Arch::X86_64,
 38        "default",
 39        None,
 40        &[&style, &tests],
 41    );
 42    let nix_mac_arm = build_nix(
 43        Platform::Mac,
 44        Arch::AARCH64,
 45        "default",
 46        None,
 47        &[&style, &tests],
 48    );
 49    let update_nightly_tag = update_nightly_tag_job(&bundle);
 50
 51    named::workflow()
 52        .on(Event::default()
 53            // Fire every day at 7:00am UTC (Roughly before EU workday and after US workday)
 54            .schedule([Schedule::new("0 7 * * *")])
 55            .push(Push::default().add_tag("nightly")))
 56        .envs(env)
 57        .add_job(style.name, style.job)
 58        .add_job(tests.name, tests.job)
 59        .map(|mut workflow| {
 60            for job in bundle.into_jobs() {
 61                workflow = workflow.add_job(job.name, job.job);
 62            }
 63            workflow
 64        })
 65        .add_job(nix_linux_x86.name, nix_linux_x86.job)
 66        .add_job(nix_mac_arm.name, nix_mac_arm.job)
 67        .add_job(update_nightly_tag.name, update_nightly_tag.job)
 68}
 69
 70fn check_style() -> NamedJob {
 71    let job = release_job(&[])
 72        .runs_on(runners::MAC_DEFAULT)
 73        .add_step(
 74            steps::checkout_repo()
 75                .add_with(("clean", false))
 76                .add_with(("fetch-depth", 0)),
 77        )
 78        .add_step(steps::cargo_fmt())
 79        .add_step(steps::script("./script/clippy"));
 80
 81    named::job(job)
 82}
 83
 84fn release_job(deps: &[&NamedJob]) -> Job {
 85    let job = Job::default()
 86        .cond(Expression::new(
 87            "github.repository_owner == 'zed-industries'",
 88        ))
 89        .timeout_minutes(60u32);
 90    if deps.len() > 0 {
 91        job.needs(deps.iter().map(|j| j.name.clone()).collect::<Vec<_>>())
 92    } else {
 93        job
 94    }
 95}
 96
 97fn update_nightly_tag_job(bundle: &ReleaseBundleJobs) -> NamedJob {
 98    fn update_nightly_tag() -> Step<Run> {
 99        named::bash(indoc::indoc! {r#"
100            if [ "$(git rev-parse nightly)" = "$(git rev-parse HEAD)" ]; then
101              echo "Nightly tag already points to current commit. Skipping tagging."
102              exit 0
103            fi
104            git config user.name github-actions
105            git config user.email github-actions@github.com
106            git tag -f nightly
107            git push origin nightly --force
108        "#})
109    }
110
111    fn create_sentry_release() -> Step<Use> {
112        named::uses(
113            "getsentry",
114            "action-release",
115            "526942b68292201ac6bbb99b9a0747d4abee354c", // v3
116        )
117        .add_env(("SENTRY_ORG", "zed-dev"))
118        .add_env(("SENTRY_PROJECT", "zed"))
119        .add_env(("SENTRY_AUTH_TOKEN", vars::SENTRY_AUTH_TOKEN))
120        .add_with(("environment", "production"))
121    }
122
123    NamedJob {
124        name: "update_nightly_tag".to_owned(),
125        job: steps::release_job(&bundle.jobs())
126            .runs_on(runners::LINUX_MEDIUM)
127            .add_step(steps::checkout_repo().add_with(("fetch-depth", 0)))
128            .add_step(download_workflow_artifacts())
129            .add_step(steps::script("ls -lR ./artifacts"))
130            .add_step(prep_release_artifacts(bundle))
131            .add_step(
132                steps::script("./script/upload-nightly")
133                    .add_env((
134                        "DIGITALOCEAN_SPACES_ACCESS_KEY",
135                        vars::DIGITALOCEAN_SPACES_ACCESS_KEY,
136                    ))
137                    .add_env((
138                        "DIGITALOCEAN_SPACES_SECRET_KEY",
139                        vars::DIGITALOCEAN_SPACES_SECRET_KEY,
140                    )),
141            )
142            .add_step(update_nightly_tag())
143            .add_step(create_sentry_release()),
144    }
145}