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