publish_extension_cli.rs

  1use gh_workflow::{ctx::Context, *};
  2use indoc::indoc;
  3
  4use crate::tasks::workflows::{
  5    runners,
  6    steps::{self, CommonJobConditions, NamedJob, RepositoryTarget, generate_token, named},
  7    vars::{self, StepOutput},
  8};
  9
 10pub fn publish_extension_cli() -> Workflow {
 11    let publish = publish_job();
 12    let update_sha_in_zed = update_sha_in_zed(&publish);
 13    let update_sha_in_extensions = update_sha_in_extensions(&publish);
 14
 15    named::workflow()
 16        .on(Event::default().push(Push::default().tags(vec!["extension-cli".to_string()])))
 17        .add_env(("CARGO_TERM_COLOR", "always"))
 18        .add_env(("CARGO_INCREMENTAL", 0))
 19        .add_job(publish.name, publish.job)
 20        .add_job(update_sha_in_zed.name, update_sha_in_zed.job)
 21        .add_job(update_sha_in_extensions.name, update_sha_in_extensions.job)
 22}
 23
 24fn publish_job() -> NamedJob {
 25    fn build_extension_cli() -> Step<Run> {
 26        named::bash("cargo build --release --package extension_cli")
 27    }
 28
 29    fn upload_binary() -> Step<Run> {
 30        named::bash(r#"script/upload-extension-cli "$GITHUB_SHA""#)
 31            .add_env((
 32                "DIGITALOCEAN_SPACES_ACCESS_KEY",
 33                vars::DIGITALOCEAN_SPACES_ACCESS_KEY,
 34            ))
 35            .add_env((
 36                "DIGITALOCEAN_SPACES_SECRET_KEY",
 37                vars::DIGITALOCEAN_SPACES_SECRET_KEY,
 38            ))
 39    }
 40
 41    named::job(
 42        Job::default()
 43            .with_repository_owner_guard()
 44            .runs_on(runners::LINUX_DEFAULT)
 45            .add_step(steps::checkout_repo())
 46            .add_step(steps::cache_rust_dependencies_namespace())
 47            .add_step(steps::setup_linux())
 48            .add_step(build_extension_cli())
 49            .add_step(upload_binary()),
 50    )
 51}
 52
 53fn update_sha_in_zed(publish_job: &NamedJob) -> NamedJob {
 54    let (generate_token, generated_token) =
 55        generate_token(vars::ZED_ZIPPY_APP_ID, vars::ZED_ZIPPY_APP_PRIVATE_KEY).into();
 56
 57    fn replace_sha() -> Step<Run> {
 58        named::bash(indoc! {r#"
 59            sed -i "s/ZED_EXTENSION_CLI_SHA: &str = \"[a-f0-9]*\"/ZED_EXTENSION_CLI_SHA: \&str = \"$GITHUB_SHA\"/" \
 60                tooling/xtask/src/tasks/workflows/extension_tests.rs
 61        "#})
 62    }
 63
 64    fn regenerate_workflows() -> Step<Run> {
 65        named::bash("cargo xtask workflows")
 66    }
 67
 68    let (get_short_sha_step, short_sha) = get_short_sha();
 69
 70    named::job(
 71        Job::default()
 72            .with_repository_owner_guard()
 73            .needs(vec![publish_job.name.clone()])
 74            .runs_on(runners::LINUX_LARGE)
 75            .add_step(generate_token)
 76            .add_step(steps::checkout_repo())
 77            .add_step(steps::cache_rust_dependencies_namespace())
 78            .add_step(get_short_sha_step)
 79            .add_step(replace_sha())
 80            .add_step(regenerate_workflows())
 81            .add_step(create_pull_request_zed(&generated_token, &short_sha)),
 82    )
 83}
 84
 85fn create_pull_request_zed(generated_token: &StepOutput, short_sha: &StepOutput) -> Step<Use> {
 86    let title = format!(
 87        "extension_ci: Bump extension CLI version to `{}`",
 88        short_sha
 89    );
 90
 91    named::uses("peter-evans", "create-pull-request", "98357b18bf14b5342f975ff684046ec3b2a07725").with(
 92        Input::default()
 93            .add("title", title.clone())
 94            .add(
 95                "body",
 96                indoc! {r#"
 97                    This PR bumps the extension CLI version used in the extension workflows to `${{ github.sha }}`.
 98
 99                    Release Notes:
100
101                    - N/A
102                "#},
103            )
104            .add("commit-message", title)
105            .add("branch", "update-extension-cli-sha")
106            .add(
107                "committer",
108                "zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>",
109            )
110            .add("base", "main")
111            .add("delete-branch", true)
112            .add("token", generated_token.to_string())
113            .add("sign-commits", true)
114            .add("assignees", Context::github().actor().to_string()),
115    )
116}
117
118fn update_sha_in_extensions(publish_job: &NamedJob) -> NamedJob {
119    let extensions_repo = RepositoryTarget::new("zed-industries", &["extensions"]);
120    let (generate_token, generated_token) =
121        generate_token(vars::ZED_ZIPPY_APP_ID, vars::ZED_ZIPPY_APP_PRIVATE_KEY)
122            .for_repository(extensions_repo)
123            .into();
124
125    fn checkout_extensions_repo(token: &StepOutput) -> Step<Use> {
126        named::uses(
127            "actions",
128            "checkout",
129            "11bd71901bbe5b1630ceea73d27597364c9af683", // v4
130        )
131        .add_with(("repository", "zed-industries/extensions"))
132        .add_with(("token", token.to_string()))
133    }
134
135    fn replace_sha() -> Step<Run> {
136        named::bash(indoc! {r#"
137            sed -i "s/ZED_EXTENSION_CLI_SHA: [a-f0-9]*/ZED_EXTENSION_CLI_SHA: $GITHUB_SHA/" \
138                .github/workflows/ci.yml
139        "#})
140    }
141
142    let (get_short_sha_step, short_sha) = get_short_sha();
143
144    named::job(
145        Job::default()
146            .with_repository_owner_guard()
147            .needs(vec![publish_job.name.clone()])
148            .runs_on(runners::LINUX_SMALL)
149            .add_step(generate_token)
150            .add_step(get_short_sha_step)
151            .add_step(checkout_extensions_repo(&generated_token))
152            .add_step(replace_sha())
153            .add_step(create_pull_request_extensions(&generated_token, &short_sha)),
154    )
155}
156
157fn create_pull_request_extensions(
158    generated_token: &StepOutput,
159    short_sha: &StepOutput,
160) -> Step<Use> {
161    let title = format!("Bump extension CLI version to `{}`", short_sha);
162
163    named::uses("peter-evans", "create-pull-request", "98357b18bf14b5342f975ff684046ec3b2a07725").with(
164        Input::default()
165            .add("title", title.clone())
166            .add(
167                "body",
168                indoc! {r#"
169                    This PR bumps the extension CLI version to https://github.com/zed-industries/zed/commit/${{ github.sha }}.
170                "#},
171            )
172            .add("commit-message", title)
173            .add("branch", "update-extension-cli-sha")
174            .add(
175                "committer",
176                "zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>",
177            )
178            .add("base", "main")
179            .add("delete-branch", true)
180            .add("token", generated_token.to_string())
181            .add("sign-commits", true)
182            .add("labels", "allow-no-extension")
183            .add("assignees", Context::github().actor().to_string()),
184    )
185}
186
187fn get_short_sha() -> (Step<Run>, StepOutput) {
188    let step = named::bash(indoc::indoc! {r#"
189        echo "sha_short=$(echo "$GITHUB_SHA" | cut -c1-7)" >> "$GITHUB_OUTPUT"
190    "#})
191    .id("short-sha");
192
193    let step_output = vars::StepOutput::new(&step, "sha_short");
194
195    (step, step_output)
196}