publish_extension_cli.rs

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