1use gh_workflow::{
2 Event, Expression, Input, Job, Level, Permissions, PullRequest, PullRequestType, Push, Run,
3 Step, UsesJob, Workflow, WorkflowDispatch,
4};
5use indexmap::IndexMap;
6use indoc::indoc;
7
8use crate::tasks::workflows::{
9 runners,
10 steps::{CommonJobConditions, NamedJob, named},
11 vars::{self, JobOutput, StepOutput, one_workflow_per_non_main_branch_and_token},
12};
13
14pub(crate) fn bump_version() -> Workflow {
15 let (determine_bump_type, bump_type) = determine_bump_type();
16 let bump_type = bump_type.as_job_output(&determine_bump_type);
17
18 let call_bump_version = call_bump_version(&determine_bump_type, bump_type);
19
20 named::workflow()
21 .on(Event::default()
22 .push(
23 Push::default()
24 .add_branch("main")
25 .add_ignored_path(".github/**"),
26 )
27 .pull_request(PullRequest::default().add_type(PullRequestType::Labeled))
28 .workflow_dispatch(WorkflowDispatch::default()))
29 .concurrency(one_workflow_per_non_main_branch_and_token("labels"))
30 .add_job(determine_bump_type.name, determine_bump_type.job)
31 .add_job(call_bump_version.name, call_bump_version.job)
32}
33
34pub(crate) fn call_bump_version(
35 depending_job: &NamedJob,
36 bump_type: JobOutput,
37) -> NamedJob<UsesJob> {
38 let job = Job::default()
39 .cond(Expression::new(format!(
40 "github.event.action != 'labeled' || {} != 'patch'",
41 bump_type.expr()
42 )))
43 .permissions(
44 Permissions::default()
45 .contents(Level::Write)
46 .issues(Level::Write)
47 .pull_requests(Level::Write)
48 .actions(Level::Write),
49 )
50 .uses(
51 "zed-industries",
52 "zed",
53 ".github/workflows/extension_bump.yml",
54 "main",
55 )
56 .add_need(depending_job.name.clone())
57 .with(
58 Input::default()
59 .add("bump-type", bump_type.to_string())
60 .add("force-bump", true),
61 )
62 .secrets(IndexMap::from([
63 ("app-id".to_owned(), vars::ZED_ZIPPY_APP_ID.to_owned()),
64 (
65 "app-secret".to_owned(),
66 vars::ZED_ZIPPY_APP_PRIVATE_KEY.to_owned(),
67 ),
68 ]));
69
70 named::job(job)
71}
72
73fn determine_bump_type() -> (NamedJob, StepOutput) {
74 let (get_bump_type, output) = get_bump_type();
75 let job = Job::default()
76 .with_repository_owner_guard()
77 .permissions(Permissions::default())
78 .runs_on(runners::LINUX_SMALL)
79 .add_step(get_bump_type)
80 .outputs([(output.name.to_owned(), output.to_string())]);
81 (named::job(job), output)
82}
83
84fn get_bump_type() -> (Step<Run>, StepOutput) {
85 let step = named::bash(
86 indoc! {r#"
87 if [ "$HAS_MAJOR_LABEL" = "true" ]; then
88 bump_type="major"
89 elif [ "$HAS_MINOR_LABEL" = "true" ]; then
90 bump_type="minor"
91 else
92 bump_type="patch"
93 fi
94 echo "bump_type=$bump_type" >> $GITHUB_OUTPUT
95 "#},
96 )
97 .add_env(("HAS_MAJOR_LABEL",
98 indoc!{
99 "${{ (github.event.action == 'labeled' && github.event.label.name == 'major') ||
100 (github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'major')) }}"
101 }))
102 .add_env(("HAS_MINOR_LABEL",
103 indoc!{
104 "${{ (github.event.action == 'labeled' && github.event.label.name == 'minor') ||
105 (github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'minor')) }}"
106 }))
107 .id("get-bump-type");
108
109 let step_output = StepOutput::new(&step, "bump_type");
110
111 (step, step_output)
112}