1use gh_workflow::*;
2
3use crate::tasks::workflows::{
4 runners,
5 steps::{self, CheckoutStep, CommonJobConditions, named},
6 vars::{StepOutput, WorkflowInput},
7};
8
9pub fn bump_patch_version() -> Workflow {
10 let branch = WorkflowInput::string("branch", None).description("Branch name to run on");
11 let bump_patch_version_job = run_bump_patch_version(&branch);
12 named::workflow()
13 .on(Event::default()
14 .workflow_dispatch(WorkflowDispatch::default().add_input(branch.name, branch.input())))
15 .concurrency(
16 Concurrency::new(Expression::new(format!(
17 "${{{{ github.workflow }}}}-{branch}"
18 )))
19 .cancel_in_progress(true),
20 )
21 .add_job(bump_patch_version_job.name, bump_patch_version_job.job)
22}
23
24fn run_bump_patch_version(branch: &WorkflowInput) -> steps::NamedJob {
25 fn checkout_branch(branch: &WorkflowInput, token: &StepOutput) -> CheckoutStep {
26 steps::checkout_repo()
27 .with_token(token)
28 .with_ref(branch.to_string())
29 }
30
31 fn read_channel() -> Step<Run> {
32 named::bash(indoc::indoc! {r#"
33 channel="$(cat crates/zed/RELEASE_CHANNEL)"
34
35 tag_suffix=""
36 case $channel in
37 stable)
38 ;;
39 preview)
40 tag_suffix="-pre"
41 ;;
42 *)
43 echo "::error::must be run on a stable or preview release branch"
44 exit 1
45 ;;
46 esac
47
48 version=$(script/get-crate-version zed)
49
50 {
51 echo "channel=$channel"
52 echo "version=$version"
53 echo "tag_suffix=$tag_suffix"
54 } >> "$GITHUB_OUTPUT"
55 "#})
56 .id("channel")
57 }
58
59 fn verify_prior_release_exists() -> Step<Run> {
60 named::bash(indoc::indoc! {r#"
61 status=$(curl -s -o /dev/null -w '%{http_code}' "https://cloud.zed.dev/releases/$CHANNEL/$VERSION/asset?asset=zed&os=macos&arch=aarch64")
62 if [[ "$status" != "200" ]]; then
63 echo "::error::version $VERSION has not been released on $CHANNEL yet (HTTP $status) — bump the patch version only after the current version is released"
64 exit 1
65 fi
66 "#})
67 .add_env(("CHANNEL", "${{ steps.channel.outputs.channel }}"))
68 .add_env(("VERSION", "${{ steps.channel.outputs.version }}"))
69 }
70
71 fn bump_version() -> Step<Run> {
72 named::bash(indoc::indoc! {r#"
73 version="$(cargo set-version -p zed --bump patch 2>&1 | sed 's/.* //')"
74 echo "version=$version" >> "$GITHUB_OUTPUT"
75 "#})
76 .id("bump-version")
77 }
78
79 let (authenticate, token) = steps::authenticate_as_zippy().into();
80 let channel_step = read_channel();
81 let tag_suffix = StepOutput::new(&channel_step, "tag_suffix");
82 let bump_version_step = bump_version();
83 let version = StepOutput::new(&bump_version_step, "version");
84 let commit_step: Step<Use> = steps::BotCommitStep::new(
85 format!("Bump to {version} for @${{{{ github.actor }}}}"),
86 branch,
87 &token,
88 )
89 .into();
90 let commit_sha = StepOutput::new_unchecked(&commit_step, "commit");
91
92 named::job(
93 Job::default()
94 .with_repository_owner_guard()
95 .runs_on(runners::LINUX_DEFAULT)
96 .add_step(authenticate)
97 .add_step(checkout_branch(branch, &token))
98 .add_step(channel_step)
99 .add_step(verify_prior_release_exists())
100 .add_step(steps::install_cargo_edit())
101 .add_step(bump_version_step)
102 .add_step(commit_step)
103 .add_step(steps::create_ref(
104 steps::GitRef::tag(format!("v{version}{tag_suffix}")),
105 &commit_sha,
106 &token,
107 )),
108 )
109}