Re-use the existing bundle steps for nightly too (#41699)

One of the reasons we didn't spot that we were missing the telemetry env
vars for the production builds was that nightly (which was working) had
its own set of build steps. This re-uses those and pushes the env vars
down from the workflow to the job.

It also fixes nightly releases to upload all-in-one go so that all
platforms update in sync.

Closes #41655

Release Notes:

- N/A
This commit is contained in:
Conrad Irwin
2025-11-03 12:29:22 -07:00
committed by GitHub
parent 5fc54986c7
commit 4da5675920
13 changed files with 839 additions and 942 deletions
+79 -118
View File
@@ -1,9 +1,11 @@
use gh_workflow::{Event, Expression, Push, Run, Step, Use, Workflow};
use crate::tasks::workflows::{
run_bundling, run_tests, runners,
steps::{self, NamedJob, dependant_job, named, release_job},
vars,
run_bundling::{bundle_linux, bundle_mac, bundle_windows},
run_tests,
runners::{self, Arch},
steps::{self, FluentBuilder, NamedJob, dependant_job, named, release_job},
vars::{self, assets},
};
pub(crate) fn release() -> Workflow {
@@ -15,12 +17,12 @@ pub(crate) fn release() -> Workflow {
let create_draft_release = create_draft_release();
let bundle = ReleaseBundleJobs {
linux_arm64: bundle_linux_arm64(&[&linux_tests, &check_scripts]),
linux_x86_64: bundle_linux_x86_64(&[&linux_tests, &check_scripts]),
mac_arm64: bundle_mac_arm64(&[&macos_tests, &check_scripts]),
mac_x86_64: bundle_mac_x86_64(&[&macos_tests, &check_scripts]),
windows_arm64: bundle_windows_arm64(&[&windows_tests, &check_scripts]),
windows_x86_64: bundle_windows_x86_64(&[&windows_tests, &check_scripts]),
linux_aarch64: bundle_linux(Arch::AARCH64, None, &[&linux_tests, &check_scripts]),
linux_x86_64: bundle_linux(Arch::X86_64, None, &[&linux_tests, &check_scripts]),
mac_aarch64: bundle_mac(Arch::AARCH64, None, &[&macos_tests, &check_scripts]),
mac_x86_64: bundle_mac(Arch::X86_64, None, &[&macos_tests, &check_scripts]),
windows_aarch64: bundle_windows(Arch::AARCH64, None, &[&windows_tests, &check_scripts]),
windows_x86_64: bundle_windows(Arch::X86_64, None, &[&windows_tests, &check_scripts]),
};
let upload_release_assets = upload_release_assets(&[&create_draft_release], &bundle);
@@ -31,47 +33,68 @@ pub(crate) fn release() -> Workflow {
.on(Event::default().push(Push::default().tags(vec!["v*".to_string()])))
.concurrency(vars::one_workflow_per_non_main_branch())
.add_env(("CARGO_TERM_COLOR", "always"))
.add_env(("CARGO_INCREMENTAL", "0"))
.add_env(("RUST_BACKTRACE", "1"))
.add_env(("ZED_CLIENT_CHECKSUM_SEED", vars::ZED_CLIENT_CHECKSUM_SEED))
.add_env(("ZED_MINIDUMP_ENDPOINT", vars::ZED_SENTRY_MINIDUMP_ENDPOINT))
.add_job(macos_tests.name, macos_tests.job)
.add_job(linux_tests.name, linux_tests.job)
.add_job(windows_tests.name, windows_tests.job)
.add_job(check_scripts.name, check_scripts.job)
.add_job(create_draft_release.name, create_draft_release.job)
.add_job(bundle.linux_arm64.name, bundle.linux_arm64.job)
.add_job(bundle.linux_x86_64.name, bundle.linux_x86_64.job)
.add_job(bundle.mac_arm64.name, bundle.mac_arm64.job)
.add_job(bundle.mac_x86_64.name, bundle.mac_x86_64.job)
.add_job(bundle.windows_arm64.name, bundle.windows_arm64.job)
.add_job(bundle.windows_x86_64.name, bundle.windows_x86_64.job)
.map(|mut workflow| {
for job in bundle.into_jobs() {
workflow = workflow.add_job(job.name, job.job);
}
workflow
})
.add_job(upload_release_assets.name, upload_release_assets.job)
.add_job(auto_release_preview.name, auto_release_preview.job)
}
struct ReleaseBundleJobs {
linux_arm64: NamedJob,
linux_x86_64: NamedJob,
mac_arm64: NamedJob,
mac_x86_64: NamedJob,
windows_arm64: NamedJob,
windows_x86_64: NamedJob,
pub(crate) struct ReleaseBundleJobs {
pub linux_aarch64: NamedJob,
pub linux_x86_64: NamedJob,
pub mac_aarch64: NamedJob,
pub mac_x86_64: NamedJob,
pub windows_aarch64: NamedJob,
pub windows_x86_64: NamedJob,
}
impl ReleaseBundleJobs {
pub fn jobs(&self) -> Vec<&NamedJob> {
vec![
&self.linux_aarch64,
&self.linux_x86_64,
&self.mac_aarch64,
&self.mac_x86_64,
&self.windows_aarch64,
&self.windows_x86_64,
]
}
pub fn into_jobs(self) -> Vec<NamedJob> {
vec![
self.linux_aarch64,
self.linux_x86_64,
self.mac_aarch64,
self.mac_x86_64,
self.windows_aarch64,
self.windows_x86_64,
]
}
}
pub(crate) fn create_sentry_release() -> Step<Use> {
named::uses(
"getsentry",
"action-release",
"526942b68292201ac6bbb99b9a0747d4abee354c", // v3
)
.add_env(("SENTRY_ORG", "zed-dev"))
.add_env(("SENTRY_PROJECT", "zed"))
.add_env(("SENTRY_AUTH_TOKEN", "${{ secrets.SENTRY_AUTH_TOKEN }}"))
.add_with(("environment", "production"))
}
fn auto_release_preview(deps: &[&NamedJob; 1]) -> NamedJob {
fn create_sentry_release() -> Step<Use> {
named::uses(
"getsentry",
"action-release",
"526942b68292201ac6bbb99b9a0747d4abee354c", // v3
)
.add_env(("SENTRY_ORG", "zed-dev"))
.add_env(("SENTRY_PROJECT", "zed"))
.add_env(("SENTRY_AUTH_TOKEN", "${{ secrets.SENTRY_AUTH_TOKEN }}"))
.add_with(("environment", "production"))
}
named::job(
dependant_job(deps)
.runs_on(runners::LINUX_SMALL)
@@ -92,75 +115,35 @@ fn auto_release_preview(deps: &[&NamedJob; 1]) -> NamedJob {
)
}
fn upload_release_assets(deps: &[&NamedJob], bundle_jobs: &ReleaseBundleJobs) -> NamedJob {
fn download_workflow_artifacts() -> Step<Use> {
named::uses(
"actions",
"download-artifact",
"018cc2cf5baa6db3ef3c5f8a56943fffe632ef53", // v6.0.0
)
.add_with(("path", "./artifacts/"))
pub(crate) fn download_workflow_artifacts() -> Step<Use> {
named::uses(
"actions",
"download-artifact",
"018cc2cf5baa6db3ef3c5f8a56943fffe632ef53", // v6.0.0
)
.add_with(("path", "./artifacts/"))
}
pub(crate) fn prep_release_artifacts() -> Step<Run> {
let mut script_lines = vec!["mkdir -p release-artifacts/\n".to_string()];
for asset in assets::all() {
let mv_command = format!("mv ./artifacts/{asset}/{asset} release-artifacts/{asset}");
script_lines.push(mv_command)
}
fn prep_release_artifacts(bundle: &ReleaseBundleJobs) -> Step<Run> {
let assets = [
(&bundle.mac_x86_64.name, "zed", "Zed-x86_64.dmg"),
(&bundle.mac_arm64.name, "zed", "Zed-aarch64.dmg"),
(&bundle.windows_x86_64.name, "zed", "Zed-x86_64.exe"),
(&bundle.windows_arm64.name, "zed", "Zed-aarch64.exe"),
(&bundle.linux_arm64.name, "zed", "zed-linux-aarch64.tar.gz"),
(&bundle.linux_x86_64.name, "zed", "zed-linux-x86_64.tar.gz"),
(
&bundle.linux_x86_64.name,
"remote-server",
"zed-remote-server-linux-x86_64.gz",
),
(
&bundle.linux_arm64.name,
"remote-server",
"zed-remote-server-linux-aarch64.gz",
),
(
&bundle.mac_x86_64.name,
"remote-server",
"zed-remote-server-macos-x86_64.gz",
),
(
&bundle.mac_arm64.name,
"remote-server",
"zed-remote-server-macos-aarch64.gz",
),
];
let mut script_lines = vec!["mkdir -p release-artifacts/\n".to_string()];
for (job_name, artifact_kind, release_artifact_name) in assets {
let artifact_path =
["${{ needs.", job_name, ".outputs.", artifact_kind, " }}"].join("");
let mv_command = format!(
"mv ./artifacts/{artifact_path}/* release-artifacts/{release_artifact_name}"
);
script_lines.push(mv_command)
}
named::bash(&script_lines.join("\n"))
}
named::bash(&script_lines.join("\n"))
}
fn upload_release_assets(deps: &[&NamedJob], bundle: &ReleaseBundleJobs) -> NamedJob {
let mut deps = deps.to_vec();
deps.extend([
&bundle_jobs.linux_arm64,
&bundle_jobs.linux_x86_64,
&bundle_jobs.mac_arm64,
&bundle_jobs.mac_x86_64,
&bundle_jobs.windows_arm64,
&bundle_jobs.windows_x86_64,
]);
deps.extend(bundle.jobs());
named::job(
dependant_job(&deps)
.runs_on(runners::LINUX_MEDIUM)
.add_step(download_workflow_artifacts())
.add_step(steps::script("ls -lR ./artifacts"))
.add_step(prep_release_artifacts(bundle_jobs))
.add_step(prep_release_artifacts())
.add_step(
steps::script("gh release upload \"$GITHUB_REF_NAME\" --repo=zed-industries/zed release-artifacts/*")
.add_env(("GITHUB_TOKEN", "${{ secrets.GITHUB_TOKEN }}")),
@@ -199,25 +182,3 @@ fn create_draft_release() -> NamedJob {
.add_step(create_release()),
)
}
fn bundle_mac_x86_64(deps: &[&NamedJob]) -> NamedJob {
named::job(run_bundling::bundle_mac_job(runners::Arch::X86_64, deps))
}
fn bundle_mac_arm64(deps: &[&NamedJob]) -> NamedJob {
named::job(run_bundling::bundle_mac_job(runners::Arch::ARM64, deps))
}
fn bundle_linux_x86_64(deps: &[&NamedJob]) -> NamedJob {
named::job(run_bundling::bundle_linux_job(runners::Arch::X86_64, deps))
}
fn bundle_linux_arm64(deps: &[&NamedJob]) -> NamedJob {
named::job(run_bundling::bundle_linux_job(runners::Arch::ARM64, deps))
}
fn bundle_windows_x86_64(deps: &[&NamedJob]) -> NamedJob {
named::job(run_bundling::bundle_windows_job(
runners::Arch::X86_64,
deps,
))
}
fn bundle_windows_arm64(deps: &[&NamedJob]) -> NamedJob {
named::job(run_bundling::bundle_windows_job(runners::Arch::ARM64, deps))
}
@@ -1,46 +1,33 @@
use crate::tasks::workflows::{
nix_build::build_nix,
run_bundling::{bundle_mac, bundle_windows},
release::{
ReleaseBundleJobs, create_sentry_release, download_workflow_artifacts,
prep_release_artifacts,
},
run_bundling::{bundle_linux, bundle_mac, bundle_windows},
run_tests::run_platform_tests,
runners::{Arch, Platform},
steps::NamedJob,
vars::{mac_bundle_envs, windows_bundle_envs},
runners::{Arch, Platform, ReleaseChannel},
steps::{FluentBuilder, NamedJob},
};
use super::{runners, steps, steps::named, vars};
use gh_workflow::*;
use indexmap::IndexMap;
/// Generates the release_nightly.yml workflow
pub fn release_nightly() -> Workflow {
let env: IndexMap<_, _> = [
("CARGO_TERM_COLOR", "always"),
("CARGO_INCREMENTAL", "0"),
("RUST_BACKTRACE", "1"),
("ZED_CLIENT_CHECKSUM_SEED", vars::ZED_CLIENT_CHECKSUM_SEED),
("ZED_MINIDUMP_ENDPOINT", vars::ZED_SENTRY_MINIDUMP_ENDPOINT),
(
"DIGITALOCEAN_SPACES_ACCESS_KEY",
vars::DIGITALOCEAN_SPACES_ACCESS_KEY,
),
(
"DIGITALOCEAN_SPACES_SECRET_KEY",
vars::DIGITALOCEAN_SPACES_SECRET_KEY,
),
]
.into_iter()
.map(|(key, value)| (key.into(), value.into()))
.collect();
let style = check_style();
let tests = run_platform_tests(Platform::Mac);
let windows_tests = run_platform_tests(Platform::Windows);
let bundle_mac_x86 = bundle_mac_nightly(Arch::X86_64, &[&style, &tests]);
let bundle_mac_arm = bundle_mac_nightly(Arch::ARM64, &[&style, &tests]);
let linux_x86 = bundle_linux_nightly(Arch::X86_64, &[&style, &tests]);
let linux_arm = bundle_linux_nightly(Arch::ARM64, &[&style, &tests]);
let windows_x86 = bundle_windows_nightly(Arch::X86_64, &[&style, &windows_tests]);
let windows_arm = bundle_windows_nightly(Arch::ARM64, &[&style, &windows_tests]);
// run only on windows as that's our fastest platform right now.
let tests = run_platform_tests(Platform::Windows);
let nightly = Some(ReleaseChannel::Nightly);
let bundle = ReleaseBundleJobs {
linux_aarch64: bundle_linux(Arch::AARCH64, nightly, &[&style, &tests]),
linux_x86_64: bundle_linux(Arch::X86_64, nightly, &[&style, &tests]),
mac_aarch64: bundle_mac(Arch::AARCH64, nightly, &[&style, &tests]),
mac_x86_64: bundle_mac(Arch::X86_64, nightly, &[&style, &tests]),
windows_aarch64: bundle_windows(Arch::AARCH64, nightly, &[&style, &tests]),
windows_x86_64: bundle_windows(Arch::X86_64, nightly, &[&style, &tests]),
};
let nix_linux_x86 = build_nix(
Platform::Linux,
@@ -51,35 +38,28 @@ pub fn release_nightly() -> Workflow {
);
let nix_mac_arm = build_nix(
Platform::Mac,
Arch::ARM64,
Arch::AARCH64,
"default",
None,
&[&style, &tests],
);
let update_nightly_tag = update_nightly_tag_job(&[
&bundle_mac_x86,
&bundle_mac_arm,
&linux_x86,
&linux_arm,
&windows_x86,
&windows_arm,
]);
let update_nightly_tag = update_nightly_tag_job(&bundle);
named::workflow()
.on(Event::default()
// Fire every day at 7:00am UTC (Roughly before EU workday and after US workday)
.schedule([Schedule::new("0 7 * * *")])
.push(Push::default().add_tag("nightly")))
.envs(env)
.add_env(("CARGO_TERM_COLOR", "always"))
.add_env(("RUST_BACKTRACE", "1"))
.add_job(style.name, style.job)
.add_job(tests.name, tests.job)
.add_job(windows_tests.name, windows_tests.job)
.add_job(bundle_mac_x86.name, bundle_mac_x86.job)
.add_job(bundle_mac_arm.name, bundle_mac_arm.job)
.add_job(linux_x86.name, linux_x86.job)
.add_job(linux_arm.name, linux_arm.job)
.add_job(windows_x86.name, windows_x86.job)
.add_job(windows_arm.name, windows_arm.job)
.map(|mut workflow| {
for job in bundle.into_jobs() {
workflow = workflow.add_job(job.name, job.job);
}
workflow
})
.add_job(nix_linux_x86.name, nix_linux_x86.job)
.add_job(nix_mac_arm.name, nix_mac_arm.job)
.add_job(update_nightly_tag.name, update_nightly_tag.job)
@@ -112,62 +92,7 @@ fn release_job(deps: &[&NamedJob]) -> Job {
}
}
fn bundle_mac_nightly(arch: Arch, deps: &[&NamedJob]) -> NamedJob {
let platform = Platform::Mac;
NamedJob {
name: format!("bundle_mac_nightly_{arch}"),
job: release_job(deps)
.runs_on(runners::MAC_DEFAULT)
.envs(mac_bundle_envs())
.add_step(steps::checkout_repo())
.add_step(steps::setup_node())
.add_step(steps::setup_sentry())
.add_step(steps::clear_target_dir_if_large(platform))
.add_step(set_release_channel_to_nightly(platform))
.add_step(bundle_mac(arch))
.add_step(upload_zed_nightly(platform, arch)),
}
}
fn bundle_linux_nightly(arch: Arch, deps: &[&NamedJob]) -> NamedJob {
let platform = Platform::Linux;
let mut job = steps::release_job(deps)
.runs_on(arch.linux_bundler())
.add_step(steps::checkout_repo())
.add_step(steps::setup_sentry())
.add_step(steps::script("./script/linux"));
// todo(ci) can we do this on arm too?
if arch == Arch::X86_64 {
job = job.add_step(steps::script("./script/install-mold"));
}
job = job
.add_step(steps::clear_target_dir_if_large(platform))
.add_step(set_release_channel_to_nightly(platform))
.add_step(steps::script("./script/bundle-linux"))
.add_step(upload_zed_nightly(platform, arch));
NamedJob {
name: format!("bundle_linux_nightly_{arch}"),
job,
}
}
fn bundle_windows_nightly(arch: Arch, deps: &[&NamedJob]) -> NamedJob {
let platform = Platform::Windows;
NamedJob {
name: format!("bundle_windows_nightly_{arch}"),
job: steps::release_job(deps)
.runs_on(runners::WINDOWS_DEFAULT)
.envs(windows_bundle_envs())
.add_step(steps::checkout_repo())
.add_step(steps::setup_sentry())
.add_step(set_release_channel_to_nightly(platform))
.add_step(bundle_windows(arch))
.add_step(upload_zed_nightly(platform, arch)),
}
}
fn update_nightly_tag_job(deps: &[&NamedJob]) -> NamedJob {
fn update_nightly_tag_job(bundle: &ReleaseBundleJobs) -> NamedJob {
fn update_nightly_tag() -> Step<Run> {
named::bash(indoc::indoc! {r#"
if [ "$(git rev-parse nightly)" = "$(git rev-parse HEAD)" ]; then
@@ -181,56 +106,26 @@ fn update_nightly_tag_job(deps: &[&NamedJob]) -> NamedJob {
"#})
}
fn create_sentry_release() -> Step<Use> {
named::uses(
"getsentry",
"action-release",
"526942b68292201ac6bbb99b9a0747d4abee354c", // v3
)
.add_env(("SENTRY_ORG", "zed-dev"))
.add_env(("SENTRY_PROJECT", "zed"))
.add_env(("SENTRY_AUTH_TOKEN", vars::SENTRY_AUTH_TOKEN))
.add_with(("environment", "production"))
}
NamedJob {
name: "update_nightly_tag".to_owned(),
job: steps::release_job(deps)
.runs_on(runners::LINUX_SMALL)
job: steps::release_job(&bundle.jobs())
.runs_on(runners::LINUX_MEDIUM)
.add_step(steps::checkout_repo().add_with(("fetch-depth", 0)))
.add_step(download_workflow_artifacts())
.add_step(steps::script("ls -lR ./artifacts"))
.add_step(prep_release_artifacts())
.add_step(
steps::script("./script/upload-nightly")
.add_env((
"DIGITALOCEAN_SPACES_ACCESS_KEY",
vars::DIGITALOCEAN_SPACES_ACCESS_KEY,
))
.add_env((
"DIGITALOCEAN_SPACES_SECRET_KEY",
vars::DIGITALOCEAN_SPACES_SECRET_KEY,
)),
)
.add_step(update_nightly_tag())
.add_step(create_sentry_release()),
}
}
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 }}"),
}
}
fn upload_zed_nightly(platform: Platform, arch: Arch) -> Step<Run> {
match platform {
Platform::Linux => named::bash(&format!("script/upload-nightly linux-targz {arch}")),
Platform::Mac => named::bash(&format!("script/upload-nightly macos {arch}")),
Platform::Windows => {
let cmd = match arch {
Arch::X86_64 => "script/upload-nightly.ps1 -Architecture x86_64",
Arch::ARM64 => "script/upload-nightly.ps1 -Architecture aarch64",
};
named::pwsh(cmd).working_directory("${{ env.ZED_WORKSPACE }}")
}
}
}
+160 -120
View File
@@ -1,13 +1,24 @@
use std::path::Path;
use crate::tasks::workflows::{
release::ReleaseBundleJobs,
runners::{Arch, Platform, ReleaseChannel},
steps::{FluentBuilder, NamedJob, dependant_job, named},
vars::{mac_bundle_envs, windows_bundle_envs},
vars::{assets, bundle_envs},
};
use super::{runners, steps, vars};
use super::{runners, steps};
use gh_workflow::*;
use indexmap::IndexMap;
pub fn run_bundling() -> Workflow {
let bundle = ReleaseBundleJobs {
linux_aarch64: bundle_linux(Arch::AARCH64, None, &[]),
linux_x86_64: bundle_linux(Arch::X86_64, None, &[]),
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()
.on(Event::default().pull_request(
PullRequest::default().types([PullRequestType::Labeled, PullRequestType::Synchronize]),
@@ -19,34 +30,13 @@ pub fn run_bundling() -> Workflow {
.cancel_in_progress(true),
)
.add_env(("CARGO_TERM_COLOR", "always"))
.add_env(("CARGO_INCREMENTAL", "0"))
.add_env(("RUST_BACKTRACE", "1"))
.add_env(("ZED_CLIENT_CHECKSUM_SEED", vars::ZED_CLIENT_CHECKSUM_SEED))
.add_env(("ZED_MINIDUMP_ENDPOINT", vars::ZED_SENTRY_MINIDUMP_ENDPOINT))
.add_job(
"bundle_mac_x86_64",
bundle_mac_job(runners::Arch::X86_64, &[]),
)
.add_job(
"bundle_mac_arm64",
bundle_mac_job(runners::Arch::ARM64, &[]),
)
.add_job(
"bundle_linux_x86_64",
bundle_linux_job(runners::Arch::X86_64, &[]),
)
.add_job(
"bundle_linux_arm64",
bundle_linux_job(runners::Arch::ARM64, &[]),
)
.add_job(
"bundle_windows_x86_64",
bundle_windows_job(runners::Arch::X86_64, &[]),
)
.add_job(
"bundle_windows_arm64",
bundle_windows_job(runners::Arch::ARM64, &[]),
)
.map(|mut workflow| {
for job in bundle.into_jobs() {
workflow = workflow.add_job(job.name, job.job);
}
workflow
})
}
fn bundle_job(deps: &[&NamedJob]) -> Job {
@@ -59,95 +49,145 @@ fn bundle_job(deps: &[&NamedJob]) -> Job {
.timeout_minutes(60u32)
}
pub(crate) fn bundle_mac_job(arch: runners::Arch, deps: &[&NamedJob]) -> Job {
use vars::GITHUB_SHA;
let artifact_name = format!("Zed_{GITHUB_SHA}-{arch}.dmg");
let remote_server_artifact_name = format!("zed-remote-server-{GITHUB_SHA}-macos-{arch}.gz");
bundle_job(deps)
.runs_on(runners::MAC_DEFAULT)
.envs(mac_bundle_envs())
.add_step(steps::checkout_repo())
.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(steps::upload_artifact(
&artifact_name,
&format!("target/{arch}-apple-darwin/release/Zed.dmg"),
))
.add_step(steps::upload_artifact(
&remote_server_artifact_name,
&format!("target/zed-remote-server-macos-{arch}.gz"),
))
.outputs(
[
("zed".to_string(), artifact_name),
("remote-server".to_string(), remote_server_artifact_name),
]
.into_iter()
.collect::<IndexMap<_, _>>(),
)
}
pub fn bundle_mac(arch: runners::Arch) -> Step<Run> {
named::bash(&format!("./script/bundle-mac {arch}-apple-darwin"))
}
pub(crate) fn bundle_linux_job(arch: runners::Arch, deps: &[&NamedJob]) -> Job {
let artifact_name = format!("zed-{}-{}.tar.gz", vars::GITHUB_SHA, arch.triple());
let remote_server_artifact_name = format!(
"zed-remote-server-{}-{}.tar.gz",
vars::GITHUB_SHA,
arch.triple()
);
bundle_job(deps)
.runs_on(arch.linux_bundler())
.add_step(steps::checkout_repo())
.add_step(steps::setup_sentry())
.map(steps::install_linux_dependencies)
.add_step(steps::script("./script/bundle-linux"))
.add_step(steps::upload_artifact(
&artifact_name,
"target/release/zed-*.tar.gz",
))
.add_step(steps::upload_artifact(
&remote_server_artifact_name,
"target/zed-remote-server-*.gz",
))
.outputs(
[
("zed".to_string(), artifact_name),
("remote-server".to_string(), remote_server_artifact_name),
]
.into_iter()
.collect::<IndexMap<_, _>>(),
)
}
pub(crate) fn bundle_windows_job(arch: runners::Arch, deps: &[&NamedJob]) -> Job {
use vars::GITHUB_SHA;
let artifact_name = format!("Zed_{GITHUB_SHA}-{arch}.exe");
bundle_job(deps)
.runs_on(runners::WINDOWS_DEFAULT)
.envs(windows_bundle_envs())
.add_step(steps::checkout_repo())
.add_step(steps::setup_sentry())
.add_step(bundle_windows(arch))
.add_step(steps::upload_artifact(
&artifact_name,
"${{ env.SETUP_PATH }}",
))
.outputs(
[("zed".to_string(), artifact_name)]
.into_iter()
.collect::<IndexMap<_, _>>(),
)
}
pub fn bundle_windows(arch: runners::Arch) -> Step<Run> {
let step = match arch {
runners::Arch::X86_64 => named::pwsh("script/bundle-windows.ps1 -Architecture x86_64"),
runners::Arch::ARM64 => named::pwsh("script/bundle-windows.ps1 -Architecture aarch64"),
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,
};
step.working_directory("${{ env.ZED_WORKSPACE }}")
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())
.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) -> Step<Use> {
let name = Path::new(path).file_name().unwrap().to_str().unwrap();
Step::new(format!("@actions/upload-artifact {}", name))
.uses(
"actions",
"upload-artifact",
"330a01c490aca151604b8cf639adc76d48f6c5d4", // v5
)
// N.B. "name" is the name for the asset. The uploaded
// file retains its filename.
.add_with(("name", name))
.add_with(("path", path))
.add_with(("if-no-files-found", "error"))
}
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_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())
.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,
};
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(bundle_windows(arch))
.add_step(upload_artifact(&format!("target/{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 }}"),
}
}
+10 -7
View File
@@ -65,7 +65,7 @@ pub(crate) fn run_tests() -> Workflow {
)),
should_build_nix.guard(build_nix(
Platform::Mac,
Arch::ARM64,
Arch::AARCH64,
"debug",
// *don't* cache the built output
Some("-zed-editor-[0-9.]*-nightly"),
@@ -74,7 +74,7 @@ pub(crate) fn run_tests() -> Workflow {
];
let tests_pass = tests_pass(&jobs);
let mut workflow = named::workflow()
named::workflow()
.add_event(Event::default()
.push(
Push::default()
@@ -89,11 +89,14 @@ pub(crate) fn run_tests() -> Workflow {
)
.add_env(( "CARGO_TERM_COLOR", "always" ))
.add_env(( "RUST_BACKTRACE", 1 ))
.add_env(( "CARGO_INCREMENTAL", 0 ));
for job in jobs {
workflow = workflow.add_job(job.name, job.job)
}
workflow.add_job(tests_pass.name, tests_pass.job)
.add_env(( "CARGO_INCREMENTAL", 0 ))
.map(|mut workflow| {
for job in jobs {
workflow = workflow.add_job(job.name, job.job)
}
workflow
})
.add_job(tests_pass.name, tests_pass.job)
}
// Generates a bash script that checks changed files against regex patterns
+8 -10
View File
@@ -22,30 +22,23 @@ impl Into<gh_workflow::RunsOn> for Runner {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Arch {
X86_64,
ARM64,
AARCH64,
}
impl std::fmt::Display for Arch {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Arch::X86_64 => write!(f, "x86_64"),
Arch::ARM64 => write!(f, "aarch64"),
Arch::AARCH64 => write!(f, "aarch64"),
}
}
}
impl Arch {
pub fn triple(&self) -> &'static str {
match self {
Arch::X86_64 => "x86_64-unknown-linux-gnu",
Arch::ARM64 => "aarch64-unknown-linux-gnu",
}
}
pub fn linux_bundler(&self) -> Runner {
match self {
Arch::X86_64 => LINUX_X86_BUNDLER,
Arch::ARM64 => LINUX_ARM_BUNDLER,
Arch::AARCH64 => LINUX_ARM_BUNDLER,
}
}
}
@@ -66,3 +59,8 @@ impl std::fmt::Display for Platform {
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ReleaseChannel {
Nightly,
}
@@ -86,18 +86,6 @@ pub fn cleanup_cargo_config(platform: Platform) -> Step<Run> {
step.if_condition(Expression::new("always()"))
}
pub fn upload_artifact(name: &str, path: &str) -> Step<Use> {
Step::new(format!("@actions/upload-artifact {}", name))
.uses(
"actions",
"upload-artifact",
"330a01c490aca151604b8cf639adc76d48f6c5d4", // v5
)
.add_with(("name", name))
.add_with(("path", path))
.add_with(("if-no-files-found", "error"))
}
pub fn clear_target_dir_if_large(platform: Platform) -> Step<Run> {
match platform {
Platform::Windows => named::pwsh("./script/clear-target-dir-if-larger-than.ps1 250"),
+55 -22
View File
@@ -2,7 +2,7 @@ use std::cell::RefCell;
use gh_workflow::{Concurrency, Env, Expression};
use crate::tasks::workflows::steps::NamedJob;
use crate::tasks::workflows::{runners::Platform, steps::NamedJob};
macro_rules! secret {
($secret_name:ident) => {
@@ -38,28 +38,31 @@ var!(AZURE_SIGNING_ACCOUNT_NAME);
var!(AZURE_SIGNING_CERT_PROFILE_NAME);
var!(AZURE_SIGNING_ENDPOINT);
pub const GITHUB_SHA: &str = "${{ github.event.pull_request.head.sha || github.sha }}";
pub fn bundle_envs(platform: Platform) -> Env {
let env = Env::default()
.add("CARGO_INCREMENTAL", 0)
.add("ZED_CLIENT_CHECKSUM_SEED", ZED_CLIENT_CHECKSUM_SEED)
.add("ZED_MINIDUMP_ENDPOINT", ZED_SENTRY_MINIDUMP_ENDPOINT);
pub fn mac_bundle_envs() -> Env {
Env::default()
.add("MACOS_CERTIFICATE", MACOS_CERTIFICATE)
.add("MACOS_CERTIFICATE_PASSWORD", MACOS_CERTIFICATE_PASSWORD)
.add("APPLE_NOTARIZATION_KEY", APPLE_NOTARIZATION_KEY)
.add("APPLE_NOTARIZATION_KEY_ID", APPLE_NOTARIZATION_KEY_ID)
.add("APPLE_NOTARIZATION_ISSUER_ID", APPLE_NOTARIZATION_ISSUER_ID)
}
pub fn windows_bundle_envs() -> Env {
Env::default()
.add("AZURE_TENANT_ID", AZURE_SIGNING_TENANT_ID)
.add("AZURE_CLIENT_ID", AZURE_SIGNING_CLIENT_ID)
.add("AZURE_CLIENT_SECRET", AZURE_SIGNING_CLIENT_SECRET)
.add("ACCOUNT_NAME", AZURE_SIGNING_ACCOUNT_NAME)
.add("CERT_PROFILE_NAME", AZURE_SIGNING_CERT_PROFILE_NAME)
.add("ENDPOINT", AZURE_SIGNING_ENDPOINT)
.add("FILE_DIGEST", "SHA256")
.add("TIMESTAMP_DIGEST", "SHA256")
.add("TIMESTAMP_SERVER", "http://timestamp.acs.microsoft.com")
match platform {
Platform::Linux => env,
Platform::Mac => env
.add("MACOS_CERTIFICATE", MACOS_CERTIFICATE)
.add("MACOS_CERTIFICATE_PASSWORD", MACOS_CERTIFICATE_PASSWORD)
.add("APPLE_NOTARIZATION_KEY", APPLE_NOTARIZATION_KEY)
.add("APPLE_NOTARIZATION_KEY_ID", APPLE_NOTARIZATION_KEY_ID)
.add("APPLE_NOTARIZATION_ISSUER_ID", APPLE_NOTARIZATION_ISSUER_ID),
Platform::Windows => env
.add("AZURE_TENANT_ID", AZURE_SIGNING_TENANT_ID)
.add("AZURE_CLIENT_ID", AZURE_SIGNING_CLIENT_ID)
.add("AZURE_CLIENT_SECRET", AZURE_SIGNING_CLIENT_SECRET)
.add("ACCOUNT_NAME", AZURE_SIGNING_ACCOUNT_NAME)
.add("CERT_PROFILE_NAME", AZURE_SIGNING_CERT_PROFILE_NAME)
.add("ENDPOINT", AZURE_SIGNING_ENDPOINT)
.add("FILE_DIGEST", "SHA256")
.add("TIMESTAMP_DIGEST", "SHA256")
.add("TIMESTAMP_SERVER", "http://timestamp.acs.microsoft.com"),
}
}
pub(crate) fn one_workflow_per_non_main_branch() -> Concurrency {
@@ -110,3 +113,33 @@ impl PathCondition {
}
}
}
pub mod assets {
// NOTE: these asset names also exist in the zed.dev codebase.
pub const MAC_AARCH64: &str = "Zed-aarch64.dmg";
pub const MAC_X86_64: &str = "Zed-x86_64.dmg";
pub const LINUX_AARCH64: &str = "zed-linux-aarch64.tar.gz";
pub const LINUX_X86_64: &str = "zed-linux-x86_64.tar.gz";
pub const WINDOWS_X86_64: &str = "Zed-x86_64.exe";
pub const WINDOWS_AARCH64: &str = "Zed-aarch64.exe";
pub const REMOTE_SERVER_MAC_AARCH64: &str = "zed-remote-server-macos-aarch64.gz";
pub const REMOTE_SERVER_MAC_X86_64: &str = "zed-remote-server-macos-x86_64.gz";
pub const REMOTE_SERVER_LINUX_AARCH64: &str = "zed-remote-server-linux-aarch64.gz";
pub const REMOTE_SERVER_LINUX_X86_64: &str = "zed-remote-server-linux-x86_64.gz";
pub fn all() -> Vec<&'static str> {
vec![
MAC_AARCH64,
MAC_X86_64,
LINUX_AARCH64,
LINUX_X86_64,
WINDOWS_X86_64,
WINDOWS_AARCH64,
REMOTE_SERVER_MAC_AARCH64,
REMOTE_SERVER_MAC_X86_64,
REMOTE_SERVER_LINUX_AARCH64,
REMOTE_SERVER_LINUX_X86_64,
]
}
}