1use crate::tasks::workflows::{
2 release::ReleaseBundleJobs,
3 runners::{Arch, Platform, ReleaseChannel},
4 steps::{FluentBuilder, NamedJob, dependant_job, named},
5 vars::{assets, bundle_envs},
6};
7
8use super::{runners, steps};
9use gh_workflow::*;
10use indexmap::IndexMap;
11
12pub fn run_bundling() -> Workflow {
13 let bundle = ReleaseBundleJobs {
14 linux_aarch64: bundle_linux(Arch::AARCH64, None, &[]),
15 linux_x86_64: bundle_linux(Arch::X86_64, None, &[]),
16 mac_aarch64: bundle_mac(Arch::AARCH64, None, &[]),
17 mac_x86_64: bundle_mac(Arch::X86_64, None, &[]),
18 windows_aarch64: bundle_windows(Arch::AARCH64, None, &[]),
19 windows_x86_64: bundle_windows(Arch::X86_64, None, &[]),
20 };
21 named::workflow()
22 .on(Event::default().pull_request(
23 PullRequest::default().types([PullRequestType::Labeled, PullRequestType::Synchronize]),
24 ))
25 .concurrency(
26 Concurrency::new(Expression::new(
27 "${{ github.workflow }}-${{ github.head_ref || github.ref }}",
28 ))
29 .cancel_in_progress(true),
30 )
31 .add_env(("CARGO_TERM_COLOR", "always"))
32 .add_env(("RUST_BACKTRACE", "1"))
33 .map(|mut workflow| {
34 for job in bundle.into_jobs() {
35 workflow = workflow.add_job(job.name, job.job);
36 }
37 workflow
38 })
39}
40
41fn bundle_job(deps: &[&NamedJob]) -> Job {
42 dependant_job(deps)
43 .when(deps.len() == 0, |job|
44 job.cond(Expression::new(
45 "(github.event.action == 'labeled' && github.event.label.name == 'run-bundling') ||
46 (github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'run-bundling'))",
47 )))
48 .timeout_minutes(60u32)
49}
50
51pub(crate) fn bundle_mac(
52 arch: Arch,
53 release_channel: Option<ReleaseChannel>,
54 deps: &[&NamedJob],
55) -> NamedJob {
56 pub fn bundle_mac(arch: Arch) -> Step<Run> {
57 named::bash(&format!("./script/bundle-mac {arch}-apple-darwin"))
58 }
59 let platform = Platform::Mac;
60 let artifact_name = match arch {
61 Arch::X86_64 => assets::MAC_X86_64,
62 Arch::AARCH64 => assets::MAC_AARCH64,
63 };
64 let remote_server_artifact_name = match arch {
65 Arch::X86_64 => assets::REMOTE_SERVER_MAC_X86_64,
66 Arch::AARCH64 => assets::REMOTE_SERVER_MAC_AARCH64,
67 };
68 NamedJob {
69 name: format!("bundle_mac_{arch}"),
70 job: bundle_job(deps)
71 .runs_on(runners::MAC_DEFAULT)
72 .envs(bundle_envs(platform))
73 .add_step(steps::checkout_repo())
74 .when_some(release_channel, |job, release_channel| {
75 job.add_step(set_release_channel(platform, release_channel))
76 })
77 .add_step(steps::setup_node())
78 .add_step(steps::setup_sentry())
79 .add_step(steps::clear_target_dir_if_large(runners::Platform::Mac))
80 .add_step(bundle_mac(arch))
81 .add_step(steps::upload_artifact(
82 &artifact_name,
83 &format!("target/{arch}-apple-darwin/release/Zed.dmg"),
84 ))
85 .add_step(steps::upload_artifact(
86 &remote_server_artifact_name,
87 &format!("target/zed-remote-server-macos-{arch}.gz"),
88 ))
89 .outputs(
90 [
91 ("zed".to_string(), artifact_name.to_string()),
92 (
93 "remote-server".to_string(),
94 remote_server_artifact_name.to_string(),
95 ),
96 ]
97 .into_iter()
98 .collect::<IndexMap<_, _>>(),
99 ),
100 }
101}
102
103pub(crate) fn bundle_linux(
104 arch: Arch,
105 release_channel: Option<ReleaseChannel>,
106 deps: &[&NamedJob],
107) -> NamedJob {
108 let platform = Platform::Linux;
109 let artifact_name = match arch {
110 Arch::X86_64 => assets::LINUX_X86_64,
111 Arch::AARCH64 => assets::LINUX_AARCH64,
112 };
113 let remote_server_artifact_name = match arch {
114 Arch::X86_64 => assets::REMOTE_SERVER_LINUX_X86_64,
115 Arch::AARCH64 => assets::REMOTE_SERVER_LINUX_AARCH64,
116 };
117 NamedJob {
118 name: format!("bundle_linux_{arch}"),
119 job: bundle_job(deps)
120 .runs_on(arch.linux_bundler())
121 .envs(bundle_envs(platform))
122 .add_step(steps::checkout_repo())
123 .when_some(release_channel, |job, release_channel| {
124 job.add_step(set_release_channel(platform, release_channel))
125 })
126 .add_step(steps::setup_sentry())
127 .map(steps::install_linux_dependencies)
128 .add_step(steps::script("./script/bundle-linux"))
129 .add_step(steps::upload_artifact(
130 &artifact_name,
131 "target/release/zed-*.tar.gz",
132 ))
133 .add_step(steps::upload_artifact(
134 &remote_server_artifact_name,
135 "target/zed-remote-server-*.gz",
136 ))
137 .outputs(
138 [
139 ("zed".to_string(), artifact_name.to_string()),
140 (
141 "remote-server".to_string(),
142 remote_server_artifact_name.to_string(),
143 ),
144 ]
145 .into_iter()
146 .collect::<IndexMap<_, _>>(),
147 ),
148 }
149}
150
151pub(crate) fn bundle_windows(
152 arch: Arch,
153 release_channel: Option<ReleaseChannel>,
154 deps: &[&NamedJob],
155) -> NamedJob {
156 let platform = Platform::Windows;
157 pub fn bundle_windows(arch: Arch) -> Step<Run> {
158 let step = match arch {
159 Arch::X86_64 => named::pwsh("script/bundle-windows.ps1 -Architecture x86_64"),
160 Arch::AARCH64 => named::pwsh("script/bundle-windows.ps1 -Architecture aarch64"),
161 };
162 step.working_directory("${{ env.ZED_WORKSPACE }}")
163 }
164 let artifact_name = match arch {
165 Arch::X86_64 => assets::WINDOWS_X86_64,
166 Arch::AARCH64 => assets::WINDOWS_AARCH64,
167 };
168 NamedJob {
169 name: format!("bundle_windows_{arch}"),
170 job: bundle_job(deps)
171 .runs_on(runners::WINDOWS_DEFAULT)
172 .envs(bundle_envs(platform))
173 .add_step(steps::checkout_repo())
174 .when_some(release_channel, |job, release_channel| {
175 job.add_step(set_release_channel(platform, release_channel))
176 })
177 .add_step(steps::setup_sentry())
178 .add_step(bundle_windows(arch))
179 .add_step(steps::upload_artifact(
180 &artifact_name,
181 "${{ env.SETUP_PATH }}",
182 ))
183 .outputs(
184 [("zed".to_string(), artifact_name.to_string())]
185 .into_iter()
186 .collect::<IndexMap<_, _>>(),
187 ),
188 }
189}
190
191fn set_release_channel(platform: Platform, release_channel: ReleaseChannel) -> Step<Run> {
192 match release_channel {
193 ReleaseChannel::Nightly => set_release_channel_to_nightly(platform),
194 }
195}
196
197fn set_release_channel_to_nightly(platform: Platform) -> Step<Run> {
198 match platform {
199 Platform::Linux | Platform::Mac => named::bash(indoc::indoc! {r#"
200 set -eu
201 version=$(git rev-parse --short HEAD)
202 echo "Publishing version: ${version} on release channel nightly"
203 echo "nightly" > crates/zed/RELEASE_CHANNEL
204 "#}),
205 Platform::Windows => named::pwsh(indoc::indoc! {r#"
206 $ErrorActionPreference = "Stop"
207 $version = git rev-parse --short HEAD
208 Write-Host "Publishing version: $version on release channel nightly"
209 "nightly" | Set-Content -Path "crates/zed/RELEASE_CHANNEL"
210 "#})
211 .working_directory("${{ env.ZED_WORKSPACE }}"),
212 }
213}