run_bundling.rs

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