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}