diff --git a/.github/workflows/publish_extension_cli.yml b/.github/workflows/publish_extension_cli.yml index 2daabb0de4b100f374cf7db4524d210d15a6f067..391baac1cb3aa9da76c4fde39aa6909525541a58 100644 --- a/.github/workflows/publish_extension_cli.yml +++ b/.github/workflows/publish_extension_cli.yml @@ -1,41 +1,127 @@ -name: Publish zed-extension CLI - +# Generated from xtask::workflows::publish_extension_cli +# Rebuild with `cargo xtask workflows`. +name: publish_extension_cli +env: + CARGO_TERM_COLOR: always + CARGO_INCREMENTAL: '0' on: push: tags: - - extension-cli - -env: - CARGO_TERM_COLOR: always - CARGO_INCREMENTAL: 0 - + - extension-cli jobs: - publish: - name: Publish zed-extension CLI - if: github.repository_owner == 'zed-industries' - runs-on: - - ubuntu-latest + publish_job: + if: (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions') + runs-on: namespace-profile-2x4-ubuntu-2404 steps: - - name: Checkout repo - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - with: - clean: false - - - name: Cache dependencies - uses: swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2 - with: - save-if: ${{ github.ref == 'refs/heads/main' }} - cache-provider: "github" - - - name: Configure linux - shell: bash -euxo pipefail {0} - run: script/linux + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: steps::cache_rust_dependencies_namespace + uses: namespacelabs/nscloud-cache-action@v1 + with: + cache: rust + path: ~/.rustup + - name: steps::setup_linux + run: ./script/linux + - name: publish_extension_cli::publish_job::build_extension_cli + run: cargo build --release --package extension_cli + - name: publish_extension_cli::publish_job::upload_binary + run: script/upload-extension-cli ${{ github.sha }} + env: + DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }} + DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }} + update_sha_in_zed: + needs: + - publish_job + if: (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions') + runs-on: namespace-profile-8x16-ubuntu-2204 + steps: + - id: generate-token + name: extension_bump::generate_token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.ZED_ZIPPY_APP_ID }} + private-key: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }} + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: steps::cache_rust_dependencies_namespace + uses: namespacelabs/nscloud-cache-action@v1 + with: + cache: rust + path: ~/.rustup + - id: short-sha + name: publish_extension_cli::get_short_sha + run: | + echo "sha_short=$(echo "${{ github.sha }}" | cut -c1-7)" >> "$GITHUB_OUTPUT" + - name: publish_extension_cli::update_sha_in_zed::replace_sha + run: | + sed -i "s/ZED_EXTENSION_CLI_SHA: &str = \"[a-f0-9]*\"/ZED_EXTENSION_CLI_SHA: \&str = \"${{ github.sha }}\"/" \ + tooling/xtask/src/tasks/workflows/extension_tests.rs + - name: publish_extension_cli::update_sha_in_zed::regenerate_workflows + run: cargo xtask workflows + - name: publish_extension_cli::create_pull_request_zed + uses: peter-evans/create-pull-request@v7 + with: + title: 'extension_ci: Bump extension CLI version to `${{ steps.short-sha.outputs.sha_short }}`' + body: | + This PR bumps the extension CLI version used in the extension workflows to `${{ github.sha }}`. - - name: Build extension CLI - run: cargo build --release --package extension_cli + Release Notes: - - name: Upload binary - env: - DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }} - DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }} - run: script/upload-extension-cli ${{ github.sha }} + - N/A + commit-message: 'extension_ci: Bump extension CLI version to `${{ steps.short-sha.outputs.sha_short }}`' + branch: update-extension-cli-sha + committer: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com> + base: main + delete-branch: true + token: ${{ steps.generate-token.outputs.token }} + sign-commits: true + assignees: ${{ github.actor }} + update_sha_in_extensions: + needs: + - publish_job + if: (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions') + runs-on: namespace-profile-2x4-ubuntu-2404 + steps: + - id: generate-token + name: extension_bump::generate_token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.ZED_ZIPPY_APP_ID }} + private-key: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }} + owner: zed-industries + repositories: extensions + - id: short-sha + name: publish_extension_cli::get_short_sha + run: | + echo "sha_short=$(echo "${{ github.sha }}" | cut -c1-7)" >> "$GITHUB_OUTPUT" + - name: publish_extension_cli::update_sha_in_extensions::checkout_extensions_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + repository: zed-industries/extensions + token: ${{ steps.generate-token.outputs.token }} + - name: publish_extension_cli::update_sha_in_extensions::replace_sha + run: | + sed -i "s/ZED_EXTENSION_CLI_SHA: [a-f0-9]*/ZED_EXTENSION_CLI_SHA: ${{ github.sha }}/" \ + .github/workflows/ci.yml + - name: publish_extension_cli::create_pull_request_extensions + uses: peter-evans/create-pull-request@v7 + with: + title: Bump extension CLI version to `${{ steps.short-sha.outputs.sha_short }}` + body: | + This PR bumps the extension CLI version to https://github.com/zed-industries/zed/commit/${{ github.sha }}. + commit-message: Bump extension CLI version to `${{ steps.short-sha.outputs.sha_short }}` + branch: update-extension-cli-sha + committer: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com> + base: main + delete-branch: true + token: ${{ steps.generate-token.outputs.token }} + sign-commits: true + labels: allow-no-extension + assignees: ${{ github.actor }} +defaults: + run: + shell: bash -euxo pipefail {0} diff --git a/tooling/xtask/src/tasks/workflows.rs b/tooling/xtask/src/tasks/workflows.rs index 0360d6dd1136ed575d986eb150239ba2940f5e54..17b83e35f497acad00f373e5f7fe2f7404a65ced 100644 --- a/tooling/xtask/src/tasks/workflows.rs +++ b/tooling/xtask/src/tasks/workflows.rs @@ -16,6 +16,7 @@ mod extension_tests; mod extension_workflow_rollout; mod extensions; mod nix_build; +mod publish_extension_cli; mod release_nightly; mod run_bundling; @@ -137,6 +138,7 @@ pub fn run_workflows(_: GenerateWorkflowArgs) -> Result<()> { WorkflowFile::zed(extension_release::extension_release), WorkflowFile::zed(extension_tests::extension_tests), WorkflowFile::zed(extension_workflow_rollout::extension_workflow_rollout), + WorkflowFile::zed(publish_extension_cli::publish_extension_cli), WorkflowFile::zed(release::release), WorkflowFile::zed(release_nightly::release_nightly), WorkflowFile::zed(run_agent_evals::run_agent_evals), diff --git a/tooling/xtask/src/tasks/workflows/publish_extension_cli.rs b/tooling/xtask/src/tasks/workflows/publish_extension_cli.rs new file mode 100644 index 0000000000000000000000000000000000000000..549b0fdfcfbb8f44b24ac849e2fe3c13bf5acdb0 --- /dev/null +++ b/tooling/xtask/src/tasks/workflows/publish_extension_cli.rs @@ -0,0 +1,201 @@ +use gh_workflow::{ctx::Context, *}; +use indoc::indoc; + +use crate::tasks::workflows::{ + extension_bump::{RepositoryTarget, generate_token}, + runners, + steps::{self, CommonJobConditions, NamedJob, named}, + vars::{self, StepOutput}, +}; + +pub fn publish_extension_cli() -> Workflow { + let publish = publish_job(); + let update_sha_in_zed = update_sha_in_zed(&publish); + let update_sha_in_extensions = update_sha_in_extensions(&publish); + + named::workflow() + .on(Event::default().push(Push::default().tags(vec!["extension-cli".to_string()]))) + .add_env(("CARGO_TERM_COLOR", "always")) + .add_env(("CARGO_INCREMENTAL", 0)) + .add_job(publish.name, publish.job) + .add_job(update_sha_in_zed.name, update_sha_in_zed.job) + .add_job(update_sha_in_extensions.name, update_sha_in_extensions.job) +} + +fn publish_job() -> NamedJob { + fn build_extension_cli() -> Step { + named::bash("cargo build --release --package extension_cli") + } + + fn upload_binary() -> Step { + named::bash("script/upload-extension-cli ${{ github.sha }}") + .add_env(( + "DIGITALOCEAN_SPACES_ACCESS_KEY", + vars::DIGITALOCEAN_SPACES_ACCESS_KEY, + )) + .add_env(( + "DIGITALOCEAN_SPACES_SECRET_KEY", + vars::DIGITALOCEAN_SPACES_SECRET_KEY, + )) + } + + named::job( + Job::default() + .with_repository_owner_guard() + .runs_on(runners::LINUX_SMALL) + .add_step(steps::checkout_repo()) + .add_step(steps::cache_rust_dependencies_namespace()) + .add_step(steps::setup_linux()) + .add_step(build_extension_cli()) + .add_step(upload_binary()), + ) +} + +fn update_sha_in_zed(publish_job: &NamedJob) -> NamedJob { + let (generate_token, generated_token) = generate_token( + vars::ZED_ZIPPY_APP_ID, + vars::ZED_ZIPPY_APP_PRIVATE_KEY, + Some(RepositoryTarget::current()), + ); + + fn replace_sha() -> Step { + named::bash(indoc! {r#" + sed -i "s/ZED_EXTENSION_CLI_SHA: &str = \"[a-f0-9]*\"/ZED_EXTENSION_CLI_SHA: \&str = \"${{ github.sha }}\"/" \ + tooling/xtask/src/tasks/workflows/extension_tests.rs + "#}) + } + + fn regenerate_workflows() -> Step { + named::bash("cargo xtask workflows") + } + + let (get_short_sha_step, short_sha) = get_short_sha(); + + named::job( + Job::default() + .with_repository_owner_guard() + .needs(vec![publish_job.name.clone()]) + .runs_on(runners::LINUX_LARGE) + .add_step(generate_token) + .add_step(steps::checkout_repo()) + .add_step(steps::cache_rust_dependencies_namespace()) + .add_step(get_short_sha_step) + .add_step(replace_sha()) + .add_step(regenerate_workflows()) + .add_step(create_pull_request_zed(&generated_token, &short_sha)), + ) +} + +fn create_pull_request_zed(generated_token: &StepOutput, short_sha: &StepOutput) -> Step { + let title = format!( + "extension_ci: Bump extension CLI version to `{}`", + short_sha + ); + + named::uses("peter-evans", "create-pull-request", "v7").with( + Input::default() + .add("title", title.clone()) + .add( + "body", + indoc! {r#" + This PR bumps the extension CLI version used in the extension workflows to `${{ github.sha }}`. + + Release Notes: + + - N/A + "#}, + ) + .add("commit-message", title) + .add("branch", "update-extension-cli-sha") + .add( + "committer", + "zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>", + ) + .add("base", "main") + .add("delete-branch", true) + .add("token", generated_token.to_string()) + .add("sign-commits", true) + .add("assignees", Context::github().actor().to_string()), + ) +} + +fn update_sha_in_extensions(publish_job: &NamedJob) -> NamedJob { + let extensions_repo = RepositoryTarget::new("zed-industries", &["extensions"]); + let (generate_token, generated_token) = generate_token( + vars::ZED_ZIPPY_APP_ID, + vars::ZED_ZIPPY_APP_PRIVATE_KEY, + Some(extensions_repo), + ); + + fn checkout_extensions_repo(token: &StepOutput) -> Step { + named::uses( + "actions", + "checkout", + "11bd71901bbe5b1630ceea73d27597364c9af683", // v4 + ) + .add_with(("repository", "zed-industries/extensions")) + .add_with(("token", token.to_string())) + } + + fn replace_sha() -> Step { + named::bash(indoc! {r#" + sed -i "s/ZED_EXTENSION_CLI_SHA: [a-f0-9]*/ZED_EXTENSION_CLI_SHA: ${{ github.sha }}/" \ + .github/workflows/ci.yml + "#}) + } + + let (get_short_sha_step, short_sha) = get_short_sha(); + + named::job( + Job::default() + .with_repository_owner_guard() + .needs(vec![publish_job.name.clone()]) + .runs_on(runners::LINUX_SMALL) + .add_step(generate_token) + .add_step(get_short_sha_step) + .add_step(checkout_extensions_repo(&generated_token)) + .add_step(replace_sha()) + .add_step(create_pull_request_extensions(&generated_token, &short_sha)), + ) +} + +fn create_pull_request_extensions( + generated_token: &StepOutput, + short_sha: &StepOutput, +) -> Step { + let title = format!("Bump extension CLI version to `{}`", short_sha); + + named::uses("peter-evans", "create-pull-request", "v7").with( + Input::default() + .add("title", title.clone()) + .add( + "body", + indoc! {r#" + This PR bumps the extension CLI version to https://github.com/zed-industries/zed/commit/${{ github.sha }}. + "#}, + ) + .add("commit-message", title) + .add("branch", "update-extension-cli-sha") + .add( + "committer", + "zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>", + ) + .add("base", "main") + .add("delete-branch", true) + .add("token", generated_token.to_string()) + .add("sign-commits", true) + .add("labels", "allow-no-extension") + .add("assignees", Context::github().actor().to_string()), + ) +} + +fn get_short_sha() -> (Step, StepOutput) { + let step = named::bash(indoc::indoc! {r#" + echo "sha_short=$(echo "${{ github.sha }}" | cut -c1-7)" >> "$GITHUB_OUTPUT" + "#}) + .id("short-sha"); + + let step_output = vars::StepOutput::new(&step, "sha_short"); + + (step, step_output) +}