247 lines · 9.3 KB · Rust
RawDownload
use std::path::Path; use crate::tasks::workflows::{    release::ReleaseBundleJobs,    runners::{Arch, Platform, ReleaseChannel},    steps::{        CommonPermissionSets, FluentBuilder, IfNoFilesFound, NamedJob, UploadArtifactStep,        dependant_job, named,    },    vars::{self, assets, bundle_envs},}; use super::{runners, steps};use gh_workflow::*;use indoc::indoc; pub fn run_bundling() -> Workflow {    let bundle = ReleaseBundleJobs {        linux_aarch64: bundle_linux(Arch::AARCH64, None, &[]),        linux_x86_64: bundle_linux(Arch::X86_64, None, &[]),        bwrap_linux_aarch64: build_static_bwrap(Arch::AARCH64, &[]),        bwrap_linux_x86_64: build_static_bwrap(Arch::X86_64, &[]),        mac_aarch64: bundle_mac(Arch::AARCH64, None, &[]),        mac_x86_64: bundle_mac(Arch::X86_64, None, &[]),        windows_aarch64: bundle_windows(Arch::AARCH64, None, &[]),        windows_x86_64: bundle_windows(Arch::X86_64, None, &[]),    };    named::workflow()        .with_minimal_permissions()        .on(Event::default().pull_request(            PullRequest::default().types([PullRequestType::Labeled, PullRequestType::Synchronize]),        ))        .concurrency(            Concurrency::new(Expression::new(                "${{ github.workflow }}-${{ github.head_ref || github.ref }}",            ))            .cancel_in_progress(true),        )        .add_env(("CARGO_TERM_COLOR", "always"))        .add_env(("RUST_BACKTRACE", "1"))        .map(|mut workflow| {            for job in bundle.into_jobs() {                workflow = workflow.add_job(job.name, job.job);            }            workflow        })} fn bundle_job(deps: &[&NamedJob]) -> Job {    dependant_job(deps)        .when(deps.len() == 0, |job|            job.cond(Expression::new(                indoc! {                    r#"(github.event.action == 'labeled' && github.event.label.name == 'run-bundling') ||                    (github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'run-bundling'))"#,                })))        .timeout_minutes(60u32)} pub(crate) fn bundle_mac(    arch: Arch,    release_channel: Option<ReleaseChannel>,    deps: &[&NamedJob],) -> NamedJob {    pub fn bundle_mac(arch: Arch) -> Step<Run> {        named::bash(&format!("./script/bundle-mac {arch}-apple-darwin"))    }    let platform = Platform::Mac;    let artifact_name = match arch {        Arch::X86_64 => assets::MAC_X86_64,        Arch::AARCH64 => assets::MAC_AARCH64,    };    let remote_server_artifact_name = match arch {        Arch::X86_64 => assets::REMOTE_SERVER_MAC_X86_64,        Arch::AARCH64 => assets::REMOTE_SERVER_MAC_AARCH64,    };    NamedJob {        name: format!("bundle_mac_{arch}"),        job: bundle_job(deps)            .runs_on(runners::MAC_DEFAULT)            .envs(bundle_envs(platform))            .add_step(steps::checkout_repo())            .add_step(steps::cache_rust_dependencies_namespace())            .when_some(release_channel, |job, release_channel| {                job.add_step(set_release_channel(platform, release_channel))            })            .add_step(steps::setup_node())            .add_step(steps::setup_sentry())            .add_step(steps::clear_target_dir_if_large(runners::Platform::Mac))            .add_step(bundle_mac(arch))            .add_step(upload_artifact(&format!(                "target/{arch}-apple-darwin/release/{artifact_name}"            )))            .add_step(upload_artifact(&format!(                "target/{remote_server_artifact_name}"            ))),    }} pub fn upload_artifact(path: &str) -> UploadArtifactStep {    let name = Path::new(path).file_name().unwrap().to_str().unwrap();    steps::upload_artifact(name, path).if_no_files_found(IfNoFilesFound::Error)} pub(crate) fn build_static_bwrap(arch: Arch, deps: &[&NamedJob]) -> NamedJob {    let artifact_name = match arch {        Arch::X86_64 => assets::BWRAP_LINUX_X86_64,        Arch::AARCH64 => assets::BWRAP_LINUX_AARCH64,    };    let binary_name = artifact_name        .strip_suffix(".gz")        .expect("static bwrap artifact name should end in .gz");    let copy_artifact = indoc::formatdoc! {r#"        cp result/bin/bwrap {binary_name}        chmod 755 {binary_name}        gzip -f --stdout --best {binary_name} > {artifact_name}    "#};     NamedJob {        name: format!("build_static_bwrap_linux_{arch}"),        job: bundle_job(deps)            .runs_on(arch.linux_bundler())            .timeout_minutes(60u32)            .add_step(steps::cache_nix_dependencies_namespace())            .add_step(                named::uses(                    "cachix",                    "install-nix-action",                    "02a151ada4993995686f9ed4f1be7cfbb229e56f", // v31                )                .add_with(("github_access_token", vars::GITHUB_TOKEN)),            )            .add_step(                named::uses(                    "cachix",                    "cachix-action",                    "0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad", // v16                )                .add_with(("name", "zed"))                .add_with(("authToken", vars::CACHIX_AUTH_TOKEN))                .add_with(("cachixArgs", "-v")),            )            .add_step(named::bash("nix build nixpkgs#pkgsStatic.bubblewrap -L"))            .add_step(named::bash(&copy_artifact))            .add_step(upload_artifact(artifact_name)),    }} pub(crate) fn bundle_linux(    arch: Arch,    release_channel: Option<ReleaseChannel>,    deps: &[&NamedJob],) -> NamedJob {    let platform = Platform::Linux;    let artifact_name = match arch {        Arch::X86_64 => assets::LINUX_X86_64,        Arch::AARCH64 => assets::LINUX_AARCH64,    };    let remote_server_artifact_name = match arch {        Arch::X86_64 => assets::REMOTE_SERVER_LINUX_X86_64,        Arch::AARCH64 => assets::REMOTE_SERVER_LINUX_AARCH64,    };    NamedJob {        name: format!("bundle_linux_{arch}"),        job: bundle_job(deps)            .runs_on(arch.linux_bundler())            .envs(bundle_envs(platform))            .add_env(Env::new("CC", "clang-18"))            .add_env(Env::new("CXX", "clang++-18"))            .add_step(steps::checkout_repo())            .add_step(steps::cache_rust_dependencies_namespace())            .when_some(release_channel, |job, release_channel| {                job.add_step(set_release_channel(platform, release_channel))            })            .add_step(steps::setup_sentry())            .map(steps::install_linux_dependencies)            .add_step(steps::script("./script/bundle-linux"))            .add_step(upload_artifact(&format!("target/release/{artifact_name}")))            .add_step(upload_artifact(&format!(                "target/{remote_server_artifact_name}"            ))),    }} pub(crate) fn bundle_windows(    arch: Arch,    release_channel: Option<ReleaseChannel>,    deps: &[&NamedJob],) -> NamedJob {    let platform = Platform::Windows;    pub fn bundle_windows(arch: Arch) -> Step<Run> {        let step = match arch {            Arch::X86_64 => named::pwsh("script/bundle-windows.ps1 -Architecture x86_64"),            Arch::AARCH64 => named::pwsh("script/bundle-windows.ps1 -Architecture aarch64"),        };        step.working_directory("${{ env.ZED_WORKSPACE }}")    }    let artifact_name = match arch {        Arch::X86_64 => assets::WINDOWS_X86_64,        Arch::AARCH64 => assets::WINDOWS_AARCH64,    };    let remote_server_artifact_name = match arch {        Arch::X86_64 => assets::REMOTE_SERVER_WINDOWS_X86_64,        Arch::AARCH64 => assets::REMOTE_SERVER_WINDOWS_AARCH64,    };    NamedJob {        name: format!("bundle_windows_{arch}"),        job: bundle_job(deps)            .runs_on(runners::WINDOWS_DEFAULT)            .envs(bundle_envs(platform))            .add_step(steps::checkout_repo())            .when_some(release_channel, |job, release_channel| {                job.add_step(set_release_channel(platform, release_channel))            })            .add_step(steps::setup_sentry())            .add_step(steps::clear_target_dir_if_large(platform))            .add_step(bundle_windows(arch))            .add_step(upload_artifact(&format!("target/{artifact_name}")))            .add_step(upload_artifact(&format!(                "target/{remote_server_artifact_name}"            ))),    }} fn set_release_channel(platform: Platform, release_channel: ReleaseChannel) -> Step<Run> {    match release_channel {        ReleaseChannel::Nightly => set_release_channel_to_nightly(platform),    }} fn set_release_channel_to_nightly(platform: Platform) -> Step<Run> {    match platform {        Platform::Linux | Platform::Mac => named::bash(indoc::indoc! {r#"            set -eu            version=$(git rev-parse --short HEAD)            echo "Publishing version: ${version} on release channel nightly"            echo "nightly" > crates/zed/RELEASE_CHANNEL        "#}),        Platform::Windows => named::pwsh(indoc::indoc! {r#"            $ErrorActionPreference = "Stop"            $version = git rev-parse --short HEAD            Write-Host "Publishing version: $version on release channel nightly"            "nightly" | Set-Content -Path "crates/zed/RELEASE_CHANNEL"        "#})        .working_directory("${{ env.ZED_WORKSPACE }}"),    }}