diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e1d5d59c551976c94272b682250e100ed3957ed..448c81bcdb99680f8ac4fd3b824ba22bd0e53e91 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,6 +4,7 @@ on: push: tags: - "v*" + - "!v00.00.00-test" # todo! remove concurrency: # Allow only one workflow per any non-`main` branch. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000000000000000000000000000000000..49fe8f82b1fb1b395c70b0813f79ea882cf83860 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,478 @@ +# Generated from xtask::workflows::release +# Rebuild with `cargo xtask workflows`. +name: release +on: + push: + tags: + - v* +jobs: + run_tests_mac: + if: github.repository_owner == 'zed-industries' + runs-on: self-mini-macos + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: steps::setup_cargo_config + run: | + mkdir -p ./../.cargo + cp ./.cargo/ci-config.toml ./../.cargo/config.toml + shell: bash -euxo pipefail {0} + - name: steps::setup_node + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 + with: + node-version: '20' + - name: steps::clippy + run: ./script/clippy + shell: bash -euxo pipefail {0} + - name: steps::cargo_install_nextest + run: cargo install cargo-nextest --locked + shell: bash -euxo pipefail {0} + - name: steps::clear_target_dir_if_large + run: ./script/clear-target-dir-if-larger-than 300 + shell: bash -euxo pipefail {0} + - name: steps::cargo_nextest + run: cargo nextest run --workspace --no-fail-fast --failure-output immediate-final + shell: bash -euxo pipefail {0} + - name: steps::cleanup_cargo_config + if: always() + run: | + rm -rf ./../.cargo + shell: bash -euxo pipefail {0} + timeout-minutes: 60 + run_tests_linux: + if: github.repository_owner == 'zed-industries' + runs-on: namespace-profile-16x32-ubuntu-2204 + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: steps::setup_cargo_config + run: | + mkdir -p ./../.cargo + cp ./.cargo/ci-config.toml ./../.cargo/config.toml + shell: bash -euxo pipefail {0} + - name: steps::setup_linux + run: ./script/linux + shell: bash -euxo pipefail {0} + - name: steps::install_mold + run: ./script/install-mold + shell: bash -euxo pipefail {0} + - name: steps::setup_node + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 + with: + node-version: '20' + - name: steps::clippy + run: ./script/clippy + shell: bash -euxo pipefail {0} + - name: steps::cargo_install_nextest + run: cargo install cargo-nextest --locked + shell: bash -euxo pipefail {0} + - name: steps::clear_target_dir_if_large + run: ./script/clear-target-dir-if-larger-than 100 + shell: bash -euxo pipefail {0} + - name: steps::cargo_nextest + run: cargo nextest run --workspace --no-fail-fast --failure-output immediate-final + shell: bash -euxo pipefail {0} + - name: steps::cleanup_cargo_config + if: always() + run: | + rm -rf ./../.cargo + shell: bash -euxo pipefail {0} + timeout-minutes: 60 + run_tests_windows: + if: github.repository_owner == 'zed-industries' + runs-on: self-32vcpu-windows-2022 + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: steps::setup_cargo_config + run: | + New-Item -ItemType Directory -Path "./../.cargo" -Force + Copy-Item -Path "./.cargo/ci-config.toml" -Destination "./../.cargo/config.toml" + shell: pwsh + - name: steps::setup_node + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 + with: + node-version: '20' + - name: steps::clippy + run: ./script/clippy.ps1 + shell: pwsh + - name: steps::cargo_install_nextest + run: cargo install cargo-nextest --locked + shell: pwsh + - name: steps::clear_target_dir_if_large + run: ./script/clear-target-dir-if-larger-than.ps1 250 + shell: pwsh + - name: steps::cargo_nextest + run: cargo nextest run --workspace --no-fail-fast --failure-output immediate-final + shell: pwsh + - name: steps::cleanup_cargo_config + if: always() + run: | + Remove-Item -Recurse -Path "./../.cargo" -Force -ErrorAction SilentlyContinue + shell: pwsh + timeout-minutes: 60 + check_scripts: + if: github.repository_owner == 'zed-industries' + runs-on: namespace-profile-2x4-ubuntu-2404 + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: run_tests::check_scripts::run_shellcheck + run: ./script/shellcheck-scripts error + shell: bash -euxo pipefail {0} + - id: get_actionlint + name: run_tests::check_scripts::download_actionlint + run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) + shell: bash -euxo pipefail {0} + - name: run_tests::check_scripts::run_actionlint + run: | + ${{ steps.get_actionlint.outputs.executable }} -color + shell: bash -euxo pipefail {0} + - name: run_tests::check_scripts::check_xtask_workflows + run: | + cargo xtask workflows + if ! git diff --exit-code .github; then + echo "Error: .github directory has uncommitted changes after running 'cargo xtask workflows'" + echo "Please run 'cargo xtask workflows' locally and commit the changes" + exit 1 + fi + shell: bash -euxo pipefail {0} + timeout-minutes: 60 + create_draft_release: + if: github.repository_owner == 'zed-industries' + runs-on: namespace-profile-2x4-ubuntu-2404 + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + fetch-depth: 25 + ref: ${{ github.ref }} + - name: script/determine-release-channel + run: script/determine-release-channel + shell: bash -euxo pipefail {0} + - name: mkdir -p target/ + run: mkdir -p target/ + shell: bash -euxo pipefail {0} + - name: script/draft-release-notes "$RELEASE_VERSION" "$RELEASE_CHANNEL" > target/release-notes.md || true + run: script/draft-release-notes "$RELEASE_VERSION" "$RELEASE_CHANNEL" > target/release-notes.md || true + shell: bash -euxo pipefail {0} + - name: script/create-draft-release target/release-notes.md + run: script/create-draft-release target/release-notes.md + shell: bash -euxo pipefail {0} + timeout-minutes: 60 + bundle_linux_arm64: + needs: + - run_tests_linux + - check_scripts + runs-on: namespace-profile-8x32-ubuntu-2004-arm-m4 + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: steps::setup_sentry + uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b + with: + token: ${{ secrets.SENTRY_AUTH_TOKEN }} + - name: steps::setup_linux + run: ./script/linux + shell: bash -euxo pipefail {0} + - name: steps::install_mold + run: ./script/install-mold + shell: bash -euxo pipefail {0} + - name: ./script/bundle-linux + run: ./script/bundle-linux + shell: bash -euxo pipefail {0} + - name: '@actions/upload-artifact zed-${{ github.event.pull_request.head.sha || github.sha }}-aarch64-unknown-linux-gnu.tar.gz' + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + with: + name: zed-${{ github.event.pull_request.head.sha || github.sha }}-aarch64-unknown-linux-gnu.tar.gz + path: target/release/zed-*.tar.gz + if-no-files-found: error + - name: '@actions/upload-artifact zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-aarch64-unknown-linux-gnu.tar.gz' + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + with: + name: zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-aarch64-unknown-linux-gnu.tar.gz + path: target/zed-remote-server-*.gz + if-no-files-found: error + outputs: + zed: zed-${{ github.event.pull_request.head.sha || github.sha }}-aarch64-unknown-linux-gnu.tar.gz + remote-server: zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-aarch64-unknown-linux-gnu.tar.gz + timeout-minutes: 60 + bundle_linux_x86_64: + needs: + - run_tests_linux + - check_scripts + runs-on: namespace-profile-32x64-ubuntu-2004 + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: steps::setup_sentry + uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b + with: + token: ${{ secrets.SENTRY_AUTH_TOKEN }} + - name: steps::setup_linux + run: ./script/linux + shell: bash -euxo pipefail {0} + - name: steps::install_mold + run: ./script/install-mold + shell: bash -euxo pipefail {0} + - name: ./script/bundle-linux + run: ./script/bundle-linux + shell: bash -euxo pipefail {0} + - name: '@actions/upload-artifact zed-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-linux-gnu.tar.gz' + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + with: + name: zed-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-linux-gnu.tar.gz + path: target/release/zed-*.tar.gz + if-no-files-found: error + - name: '@actions/upload-artifact zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-linux-gnu.tar.gz' + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + with: + name: zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-linux-gnu.tar.gz + path: target/zed-remote-server-*.gz + if-no-files-found: error + outputs: + zed: zed-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-linux-gnu.tar.gz + remote-server: zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-linux-gnu.tar.gz + timeout-minutes: 60 + bundle_mac_arm64: + needs: + - run_tests_mac + - check_scripts + runs-on: self-mini-macos + env: + MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }} + MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }} + APPLE_NOTARIZATION_KEY: ${{ secrets.APPLE_NOTARIZATION_KEY }} + APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }} + APPLE_NOTARIZATION_ISSUER_ID: ${{ secrets.APPLE_NOTARIZATION_ISSUER_ID }} + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: steps::setup_node + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 + with: + node-version: '20' + - name: steps::setup_sentry + uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b + with: + token: ${{ secrets.SENTRY_AUTH_TOKEN }} + - name: steps::clear_target_dir_if_large + run: ./script/clear-target-dir-if-larger-than 300 + shell: bash -euxo pipefail {0} + - name: run_bundling::bundle_mac + run: ./script/bundle-mac aarch64-apple-darwin + shell: bash -euxo pipefail {0} + - name: '@actions/upload-artifact Zed_${{ github.event.pull_request.head.sha || github.sha }}-aarch64.dmg' + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + with: + name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-aarch64.dmg + path: target/aarch64-apple-darwin/release/Zed.dmg + if-no-files-found: error + - name: '@actions/upload-artifact zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-macos-aarch64.gz' + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + with: + name: zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-macos-aarch64.gz + path: target/zed-remote-server-macos-aarch64.gz + if-no-files-found: error + outputs: + zed: Zed_${{ github.event.pull_request.head.sha || github.sha }}-aarch64.dmg + remote-server: zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-macos-aarch64.gz + timeout-minutes: 60 + bundle_mac_x86_64: + needs: + - run_tests_mac + - check_scripts + runs-on: self-mini-macos + env: + MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }} + MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }} + APPLE_NOTARIZATION_KEY: ${{ secrets.APPLE_NOTARIZATION_KEY }} + APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }} + APPLE_NOTARIZATION_ISSUER_ID: ${{ secrets.APPLE_NOTARIZATION_ISSUER_ID }} + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: steps::setup_node + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 + with: + node-version: '20' + - name: steps::setup_sentry + uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b + with: + token: ${{ secrets.SENTRY_AUTH_TOKEN }} + - name: steps::clear_target_dir_if_large + run: ./script/clear-target-dir-if-larger-than 300 + shell: bash -euxo pipefail {0} + - name: run_bundling::bundle_mac + run: ./script/bundle-mac x86_64-apple-darwin + shell: bash -euxo pipefail {0} + - name: '@actions/upload-artifact Zed_${{ github.event.pull_request.head.sha || github.sha }}-x86_64.dmg' + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + with: + name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-x86_64.dmg + path: target/x86_64-apple-darwin/release/Zed.dmg + if-no-files-found: error + - name: '@actions/upload-artifact zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-macos-x86_64.gz' + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + with: + name: zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-macos-x86_64.gz + path: target/zed-remote-server-macos-x86_64.gz + if-no-files-found: error + outputs: + zed: Zed_${{ github.event.pull_request.head.sha || github.sha }}-x86_64.dmg + remote-server: zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-macos-x86_64.gz + timeout-minutes: 60 + bundle_windows_arm64: + needs: + - run_tests_windows + - check_scripts + runs-on: self-32vcpu-windows-2022 + env: + AZURE_TENANT_ID: ${{ secrets.AZURE_SIGNING_TENANT_ID }} + AZURE_CLIENT_ID: ${{ secrets.AZURE_SIGNING_CLIENT_ID }} + AZURE_CLIENT_SECRET: ${{ secrets.AZURE_SIGNING_CLIENT_SECRET }} + ACCOUNT_NAME: ${{ vars.AZURE_SIGNING_ACCOUNT_NAME }} + CERT_PROFILE_NAME: ${{ vars.AZURE_SIGNING_CERT_PROFILE_NAME }} + ENDPOINT: ${{ vars.AZURE_SIGNING_ENDPOINT }} + FILE_DIGEST: SHA256 + TIMESTAMP_DIGEST: SHA256 + TIMESTAMP_SERVER: http://timestamp.acs.microsoft.com + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: steps::setup_sentry + uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b + with: + token: ${{ secrets.SENTRY_AUTH_TOKEN }} + - name: run_bundling::bundle_windows + run: script/bundle-windows.ps1 -Architecture aarch64 + shell: pwsh + working-directory: ${{ env.ZED_WORKSPACE }} + - name: '@actions/upload-artifact Zed_${{ github.event.pull_request.head.sha || github.sha }}-aarch64.exe' + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + with: + name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-aarch64.exe + path: ${{ env.SETUP_PATH }} + if-no-files-found: error + outputs: + zed: Zed_${{ github.event.pull_request.head.sha || github.sha }}-aarch64.exe + timeout-minutes: 60 + bundle_windows_x86_64: + needs: + - run_tests_windows + - check_scripts + runs-on: self-32vcpu-windows-2022 + env: + AZURE_TENANT_ID: ${{ secrets.AZURE_SIGNING_TENANT_ID }} + AZURE_CLIENT_ID: ${{ secrets.AZURE_SIGNING_CLIENT_ID }} + AZURE_CLIENT_SECRET: ${{ secrets.AZURE_SIGNING_CLIENT_SECRET }} + ACCOUNT_NAME: ${{ vars.AZURE_SIGNING_ACCOUNT_NAME }} + CERT_PROFILE_NAME: ${{ vars.AZURE_SIGNING_CERT_PROFILE_NAME }} + ENDPOINT: ${{ vars.AZURE_SIGNING_ENDPOINT }} + FILE_DIGEST: SHA256 + TIMESTAMP_DIGEST: SHA256 + TIMESTAMP_SERVER: http://timestamp.acs.microsoft.com + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: steps::setup_sentry + uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b + with: + token: ${{ secrets.SENTRY_AUTH_TOKEN }} + - name: run_bundling::bundle_windows + run: script/bundle-windows.ps1 -Architecture x86_64 + shell: pwsh + working-directory: ${{ env.ZED_WORKSPACE }} + - name: '@actions/upload-artifact Zed_${{ github.event.pull_request.head.sha || github.sha }}-x86_64.exe' + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + with: + name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-x86_64.exe + path: ${{ env.SETUP_PATH }} + if-no-files-found: error + outputs: + zed: Zed_${{ github.event.pull_request.head.sha || github.sha }}-x86_64.exe + timeout-minutes: 60 + upload_release_assets: + needs: + - create_draft_release + - bundle_linux_arm64 + - bundle_linux_x86_64 + - bundle_mac_arm64 + - bundle_mac_x86_64 + - bundle_windows_arm64 + - bundle_windows_x86_64 + runs-on: namespace-profile-4x8-ubuntu-2204 + steps: + - name: release::upload_release_assets::download_workflow_artifacts + uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 + with: + path: ./artifacts/ + - name: ls -lR ./artifacts + run: ls -lR ./artifacts + shell: bash -euxo pipefail {0} + - name: release::upload_release_assets::prep_release_artifacts + run: |- + mkdir -p release-artifacts/ + + mv ./artifacts/${{ needs.bundle_mac_x86_64.outputs.zed }}/* release-artifacts/Zed-x86_64.dmg + mv ./artifacts/${{ needs.bundle_mac_arm64.outputs.zed }}/* release-artifacts/Zed-aarch64.dmg + mv ./artifacts/${{ needs.bundle_windows_x86_64.outputs.zed }}/* release-artifacts/Zed-x86_64.exe + mv ./artifacts/${{ needs.bundle_windows_arm64.outputs.zed }}/* release-artifacts/Zed-aarch64.exe + mv ./artifacts/${{ needs.bundle_linux_arm64.outputs.zed }}/* release-artifacts/zed-linux-aarch64.tar.gz + mv ./artifacts/${{ needs.bundle_linux_x86_64.outputs.zed }}/* release-artifacts/zed-linux-x86_64.tar.gz + mv ./artifacts/${{ needs.bundle_linux_x86_64.outputs.remote-server }}/* release-artifacts/zed-remote-server-linux-x86_64.gz + mv ./artifacts/${{ needs.bundle_linux_arm64.outputs.remote-server }}/* release-artifacts/zed-remote-server-linux-aarch64.gz + mv ./artifacts/${{ needs.bundle_mac_x86_64.outputs.remote-server }}/* release-artifacts/zed-remote-server-macos-x86_64.gz + mv ./artifacts/${{ needs.bundle_mac_arm64.outputs.remote-server }}/* release-artifacts/zed-remote-server-macos-aarch64.gz + shell: bash -euxo pipefail {0} + - name: gh release upload "$GITHUB_REF_NAME" --repo=zed-industries/zed release-artifacts/* + run: gh release upload "$GITHUB_REF_NAME" --repo=zed-industries/zed release-artifacts/* + shell: bash -euxo pipefail {0} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + auto_release_preview: + needs: + - upload_release_assets + if: | + false + && startsWith(github.ref, 'refs/tags/v') + && endsWith(github.ref, '-pre') && !endsWith(github.ref, '.0-pre') + runs-on: namespace-profile-2x4-ubuntu-2404 + steps: + - name: gh release edit "$GITHUB_REF_NAME" --repo=zed-industries/zed --draft=false + run: gh release edit "$GITHUB_REF_NAME" --repo=zed-industries/zed --draft=false + shell: bash -euxo pipefail {0} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: release::create_sentry_release + uses: getsentry/action-release@526942b68292201ac6bbb99b9a0747d4abee354c + with: + environment: production + env: + SENTRY_ORG: zed-dev + SENTRY_PROJECT: zed + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }} + cancel-in-progress: true diff --git a/.github/workflows/run_bundling.yml b/.github/workflows/run_bundling.yml index 9766c7c14b64007692cfb1c68efead5b23382426..a6d563b5b12faa2d5f2cf03b644cfcacbdd17400 100644 --- a/.github/workflows/run_bundling.yml +++ b/.github/workflows/run_bundling.yml @@ -48,11 +48,16 @@ jobs: with: name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-x86_64.dmg path: target/x86_64-apple-darwin/release/Zed.dmg + if-no-files-found: error - name: '@actions/upload-artifact zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-macos-x86_64.gz' uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 with: name: zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-macos-x86_64.gz path: target/zed-remote-server-macos-x86_64.gz + if-no-files-found: error + outputs: + zed: Zed_${{ github.event.pull_request.head.sha || github.sha }}-x86_64.dmg + remote-server: zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-macos-x86_64.gz timeout-minutes: 60 bundle_mac_arm64: if: |- @@ -89,11 +94,16 @@ jobs: with: name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-aarch64.dmg path: target/aarch64-apple-darwin/release/Zed.dmg + if-no-files-found: error - name: '@actions/upload-artifact zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-macos-aarch64.gz' uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 with: name: zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-macos-aarch64.gz path: target/zed-remote-server-macos-aarch64.gz + if-no-files-found: error + outputs: + zed: Zed_${{ github.event.pull_request.head.sha || github.sha }}-aarch64.dmg + remote-server: zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-macos-aarch64.gz timeout-minutes: 60 bundle_linux_x86_64: if: |- @@ -123,11 +133,16 @@ jobs: with: name: zed-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-linux-gnu.tar.gz path: target/release/zed-*.tar.gz + if-no-files-found: error - name: '@actions/upload-artifact zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-linux-gnu.tar.gz' uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 with: name: zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-linux-gnu.tar.gz - path: target/release/zed-remote-server-*.tar.gz + path: target/zed-remote-server-*.gz + if-no-files-found: error + outputs: + zed: zed-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-linux-gnu.tar.gz + remote-server: zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-linux-gnu.tar.gz timeout-minutes: 60 bundle_linux_arm64: if: |- @@ -157,11 +172,16 @@ jobs: with: name: zed-${{ github.event.pull_request.head.sha || github.sha }}-aarch64-unknown-linux-gnu.tar.gz path: target/release/zed-*.tar.gz + if-no-files-found: error - name: '@actions/upload-artifact zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-aarch64-unknown-linux-gnu.tar.gz' uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 with: name: zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-aarch64-unknown-linux-gnu.tar.gz - path: target/release/zed-remote-server-*.tar.gz + path: target/zed-remote-server-*.gz + if-no-files-found: error + outputs: + zed: zed-${{ github.event.pull_request.head.sha || github.sha }}-aarch64-unknown-linux-gnu.tar.gz + remote-server: zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-aarch64-unknown-linux-gnu.tar.gz timeout-minutes: 60 bundle_windows_x86_64: if: |- @@ -196,6 +216,9 @@ jobs: with: name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-x86_64.exe path: ${{ env.SETUP_PATH }} + if-no-files-found: error + outputs: + zed: Zed_${{ github.event.pull_request.head.sha || github.sha }}-x86_64.exe timeout-minutes: 60 bundle_windows_arm64: if: |- @@ -230,6 +253,9 @@ jobs: with: name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-aarch64.exe path: ${{ env.SETUP_PATH }} + if-no-files-found: error + outputs: + zed: Zed_${{ github.event.pull_request.head.sha || github.sha }}-aarch64.exe timeout-minutes: 60 concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} diff --git a/tooling/xtask/src/tasks/workflows.rs b/tooling/xtask/src/tasks/workflows.rs index f29a590ca19d8be4781aaba9d7fd23d90933f34c..a8472606ffd6aea48775f3fca28f9c30b2223cc5 100644 --- a/tooling/xtask/src/tasks/workflows.rs +++ b/tooling/xtask/src/tasks/workflows.rs @@ -9,6 +9,7 @@ mod nix_build; mod release_nightly; mod run_bundling; +mod release; mod run_tests; mod runners; mod steps; @@ -25,6 +26,7 @@ pub fn run_workflows(_: GenerateWorkflowArgs) -> Result<()> { ("run_bundling.yml", run_bundling::run_bundling()), ("release_nightly.yml", release_nightly::release_nightly()), ("run_tests.yml", run_tests::run_tests()), + ("release.yml", release::release()), ("compare_perf.yml", compare_perf::compare_perf()), ]; fs::create_dir_all(dir) diff --git a/tooling/xtask/src/tasks/workflows/release.rs b/tooling/xtask/src/tasks/workflows/release.rs new file mode 100644 index 0000000000000000000000000000000000000000..1a6533d0a4c9ede450930b0f0561562cf2556c45 --- /dev/null +++ b/tooling/xtask/src/tasks/workflows/release.rs @@ -0,0 +1,207 @@ +use gh_workflow::{Event, Expression, Push, Run, Step, Use, Workflow}; + +use crate::tasks::workflows::{ + run_bundling, run_tests, runners, + steps::{self, NamedJob, dependant_job, named, release_job}, + vars, +}; + +pub(crate) fn release() -> Workflow { + let macos_tests = run_tests::run_platform_tests(runners::Platform::Mac); + let linux_tests = run_tests::run_platform_tests(runners::Platform::Linux); + let windows_tests = run_tests::run_platform_tests(runners::Platform::Windows); + let check_scripts = run_tests::check_scripts(); + + let create_draft_release = create_draft_release(); + + let bundle = ReleaseBundleJobs { + linux_arm64: bundle_linux_arm64(&[&linux_tests, &check_scripts]), + linux_x86_64: bundle_linux_x86_64(&[&linux_tests, &check_scripts]), + mac_arm64: bundle_mac_arm64(&[&macos_tests, &check_scripts]), + mac_x86_64: bundle_mac_x86_64(&[&macos_tests, &check_scripts]), + windows_arm64: bundle_windows_arm64(&[&windows_tests, &check_scripts]), + windows_x86_64: bundle_windows_x86_64(&[&windows_tests, &check_scripts]), + }; + + let upload_release_assets = upload_release_assets(&[&create_draft_release], &bundle); + + let auto_release_preview = auto_release_preview(&[&upload_release_assets]); + + named::workflow() + .on(Event::default().push(Push::default().tags(vec!["v*".to_string()]))) + .concurrency(vars::one_workflow_per_non_main_branch()) + .add_job(macos_tests.name, macos_tests.job) + .add_job(linux_tests.name, linux_tests.job) + .add_job(windows_tests.name, windows_tests.job) + .add_job(check_scripts.name, check_scripts.job) + .add_job(create_draft_release.name, create_draft_release.job) + .add_job(bundle.linux_arm64.name, bundle.linux_arm64.job) + .add_job(bundle.linux_x86_64.name, bundle.linux_x86_64.job) + .add_job(bundle.mac_arm64.name, bundle.mac_arm64.job) + .add_job(bundle.mac_x86_64.name, bundle.mac_x86_64.job) + .add_job(bundle.windows_arm64.name, bundle.windows_arm64.job) + .add_job(bundle.windows_x86_64.name, bundle.windows_x86_64.job) + .add_job(upload_release_assets.name, upload_release_assets.job) + .add_job(auto_release_preview.name, auto_release_preview.job) +} + +fn auto_release_preview(deps: &[&NamedJob; 1]) -> NamedJob { + named::job( + dependant_job(deps) + .runs_on(runners::LINUX_SMALL) + .cond(Expression::new(indoc::indoc!( + r#" + false + && startsWith(github.ref, 'refs/tags/v') + && endsWith(github.ref, '-pre') && !endsWith(github.ref, '.0-pre') + "# // todo(ci-release) enable + ))) + .add_step( + steps::script( + r#"gh release edit "$GITHUB_REF_NAME" --repo=zed-industries/zed --draft=false"#, + ) + .add_env(("GITHUB_TOKEN", "${{ secrets.GITHUB_TOKEN }}")), + ) + .add_step(create_sentry_release()), + ) +} + +fn create_sentry_release() -> Step { + named::uses( + "getsentry", + "action-release", + "526942b68292201ac6bbb99b9a0747d4abee354c", // v3 + ) + .add_env(("SENTRY_ORG", "zed-dev")) + .add_env(("SENTRY_PROJECT", "zed")) + .add_env(("SENTRY_AUTH_TOKEN", "${{ secrets.SENTRY_AUTH_TOKEN }}")) + .add_with(("environment", "production")) +} + +struct ReleaseBundleJobs { + linux_arm64: NamedJob, + linux_x86_64: NamedJob, + mac_arm64: NamedJob, + mac_x86_64: NamedJob, + windows_arm64: NamedJob, + windows_x86_64: NamedJob, +} + +fn upload_release_assets(deps: &[&NamedJob], bundle_jobs: &ReleaseBundleJobs) -> NamedJob { + fn download_workflow_artifacts() -> Step { + named::uses( + "actions", + "download-artifact", + "018cc2cf5baa6db3ef3c5f8a56943fffe632ef53", // v6.0.0 + ) + .add_with(("path", "./artifacts/")) + } + + fn prep_release_artifacts(bundle: &ReleaseBundleJobs) -> Step { + let assets = [ + (&bundle.mac_x86_64.name, "zed", "Zed-x86_64.dmg"), + (&bundle.mac_arm64.name, "zed", "Zed-aarch64.dmg"), + (&bundle.windows_x86_64.name, "zed", "Zed-x86_64.exe"), + (&bundle.windows_arm64.name, "zed", "Zed-aarch64.exe"), + (&bundle.linux_arm64.name, "zed", "zed-linux-aarch64.tar.gz"), + (&bundle.linux_x86_64.name, "zed", "zed-linux-x86_64.tar.gz"), + ( + &bundle.linux_x86_64.name, + "remote-server", + "zed-remote-server-linux-x86_64.gz", + ), + ( + &bundle.linux_arm64.name, + "remote-server", + "zed-remote-server-linux-aarch64.gz", + ), + ( + &bundle.mac_x86_64.name, + "remote-server", + "zed-remote-server-macos-x86_64.gz", + ), + ( + &bundle.mac_arm64.name, + "remote-server", + "zed-remote-server-macos-aarch64.gz", + ), + ]; + + let mut script_lines = vec!["mkdir -p release-artifacts/\n".to_string()]; + for (job_name, artifact_kind, release_artifact_name) in assets { + let artifact_path = + ["${{ needs.", job_name, ".outputs.", artifact_kind, " }}"].join(""); + let mv_command = format!( + "mv ./artifacts/{artifact_path}/* release-artifacts/{release_artifact_name}" + ); + script_lines.push(mv_command) + } + + named::bash(&script_lines.join("\n")) + } + + let mut deps = deps.to_vec(); + deps.extend([ + &bundle_jobs.linux_arm64, + &bundle_jobs.linux_x86_64, + &bundle_jobs.mac_arm64, + &bundle_jobs.mac_x86_64, + &bundle_jobs.windows_arm64, + &bundle_jobs.windows_x86_64, + ]); + + named::job( + dependant_job(&deps) + .runs_on(runners::LINUX_MEDIUM) + .add_step(download_workflow_artifacts()) + .add_step(steps::script("ls -lR ./artifacts")) + .add_step(prep_release_artifacts(bundle_jobs)) + .add_step( + steps::script("gh release upload \"$GITHUB_REF_NAME\" --repo=zed-industries/zed release-artifacts/*") + .add_env(("GITHUB_TOKEN", "${{ secrets.GITHUB_TOKEN }}")), + ), + ) +} + +fn create_draft_release() -> NamedJob { + named::job( + release_job(&[]) + .runs_on(runners::LINUX_SMALL) + // We need to fetch more than one commit so that `script/draft-release-notes` + // is able to diff between the current and previous tag. + // + // 25 was chosen arbitrarily. + .add_step( + steps::checkout_repo() + .add_with(("fetch-depth", 25)) + .add_with(("clean", false)) + .add_with(("ref", "${{ github.ref }}")), + ) + .add_step(steps::script("script/determine-release-channel")) // export RELEASE_CHANNEL and RELEASE_VERSION + .add_step(steps::script("mkdir -p target/")) + .add_step(steps::script(r#"script/draft-release-notes "$RELEASE_VERSION" "$RELEASE_CHANNEL" > target/release-notes.md || true"#)) + .add_step(steps::script("script/create-draft-release target/release-notes.md")), + ) +} + +fn bundle_mac_x86_64(deps: &[&NamedJob]) -> NamedJob { + named::job(run_bundling::bundle_mac_job(runners::Arch::X86_64, deps)) +} +fn bundle_mac_arm64(deps: &[&NamedJob]) -> NamedJob { + named::job(run_bundling::bundle_mac_job(runners::Arch::ARM64, deps)) +} +fn bundle_linux_x86_64(deps: &[&NamedJob]) -> NamedJob { + named::job(run_bundling::bundle_linux_job(runners::Arch::X86_64, deps)) +} +fn bundle_linux_arm64(deps: &[&NamedJob]) -> NamedJob { + named::job(run_bundling::bundle_linux_job(runners::Arch::ARM64, deps)) +} +fn bundle_windows_x86_64(deps: &[&NamedJob]) -> NamedJob { + named::job(run_bundling::bundle_windows_job( + runners::Arch::X86_64, + deps, + )) +} +fn bundle_windows_arm64(deps: &[&NamedJob]) -> NamedJob { + named::job(run_bundling::bundle_windows_job(runners::Arch::ARM64, deps)) +} diff --git a/tooling/xtask/src/tasks/workflows/run_bundling.rs b/tooling/xtask/src/tasks/workflows/run_bundling.rs index 2e83678967ca030ec64493ec0d802ba42664496b..2e8990faf8b5fef7a9b4fbcdc2ad2fe91bfed4b2 100644 --- a/tooling/xtask/src/tasks/workflows/run_bundling.rs +++ b/tooling/xtask/src/tasks/workflows/run_bundling.rs @@ -1,10 +1,11 @@ use crate::tasks::workflows::{ - steps::{FluentBuilder, named}, + steps::{FluentBuilder, NamedJob, dependant_job, named}, vars::{mac_bundle_envs, windows_bundle_envs}, }; use super::{runners, steps, vars}; use gh_workflow::*; +use indexmap::IndexMap; pub fn run_bundling() -> Workflow { named::workflow() @@ -22,32 +23,47 @@ pub fn run_bundling() -> Workflow { .add_env(("RUST_BACKTRACE", "1")) .add_env(("ZED_CLIENT_CHECKSUM_SEED", vars::ZED_CLIENT_CHECKSUM_SEED)) .add_env(("ZED_MINIDUMP_ENDPOINT", vars::ZED_SENTRY_MINIDUMP_ENDPOINT)) - .add_job("bundle_mac_x86_64", bundle_mac_job(runners::Arch::X86_64)) - .add_job("bundle_mac_arm64", bundle_mac_job(runners::Arch::ARM64)) - .add_job("bundle_linux_x86_64", bundle_linux(runners::Arch::X86_64)) - .add_job("bundle_linux_arm64", bundle_linux(runners::Arch::ARM64)) + .add_job( + "bundle_mac_x86_64", + bundle_mac_job(runners::Arch::X86_64, &[]), + ) + .add_job( + "bundle_mac_arm64", + bundle_mac_job(runners::Arch::ARM64, &[]), + ) + .add_job( + "bundle_linux_x86_64", + bundle_linux_job(runners::Arch::X86_64, &[]), + ) + .add_job( + "bundle_linux_arm64", + bundle_linux_job(runners::Arch::ARM64, &[]), + ) .add_job( "bundle_windows_x86_64", - bundle_windows_job(runners::Arch::X86_64), + bundle_windows_job(runners::Arch::X86_64, &[]), ) .add_job( "bundle_windows_arm64", - bundle_windows_job(runners::Arch::ARM64), + bundle_windows_job(runners::Arch::ARM64, &[]), ) } -fn bundle_job() -> Job { - Job::default() - .cond(Expression::new( +fn bundle_job(deps: &[&NamedJob]) -> Job { + dependant_job(deps) + .when(deps.len() == 0, |job| + job.cond(Expression::new( "(github.event.action == 'labeled' && github.event.label.name == 'run-bundling') || (github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'run-bundling'))", - )) + ))) .timeout_minutes(60u32) } -fn bundle_mac_job(arch: runners::Arch) -> Job { +pub(crate) fn bundle_mac_job(arch: runners::Arch, deps: &[&NamedJob]) -> Job { use vars::GITHUB_SHA; - bundle_job() + let artifact_name = format!("Zed_{GITHUB_SHA}-{arch}.dmg"); + let remote_server_artifact_name = format!("zed-remote-server-{GITHUB_SHA}-macos-{arch}.gz"); + bundle_job(deps) .runs_on(runners::MAC_DEFAULT) .envs(mac_bundle_envs()) .add_step(steps::checkout_repo()) @@ -56,27 +72,35 @@ fn bundle_mac_job(arch: runners::Arch) -> Job { .add_step(steps::clear_target_dir_if_large(runners::Platform::Mac)) .add_step(bundle_mac(arch)) .add_step(steps::upload_artifact( - &format!("Zed_{GITHUB_SHA}-{arch}.dmg"), + &artifact_name, &format!("target/{arch}-apple-darwin/release/Zed.dmg"), )) .add_step(steps::upload_artifact( - &format!("zed-remote-server-{GITHUB_SHA}-macos-{arch}.gz"), + &remote_server_artifact_name, &format!("target/zed-remote-server-macos-{arch}.gz"), )) + .outputs( + [ + ("zed".to_string(), artifact_name), + ("remote-server".to_string(), remote_server_artifact_name), + ] + .into_iter() + .collect::>(), + ) } pub fn bundle_mac(arch: runners::Arch) -> Step { named::bash(&format!("./script/bundle-mac {arch}-apple-darwin")) } -fn bundle_linux(arch: runners::Arch) -> Job { +pub(crate) fn bundle_linux_job(arch: runners::Arch, deps: &[&NamedJob]) -> Job { let artifact_name = format!("zed-{}-{}.tar.gz", vars::GITHUB_SHA, arch.triple()); let remote_server_artifact_name = format!( "zed-remote-server-{}-{}.tar.gz", vars::GITHUB_SHA, arch.triple() ); - bundle_job() + bundle_job(deps) .runs_on(arch.linux_bundler()) .add_step(steps::checkout_repo()) .add_step(steps::setup_sentry()) @@ -88,22 +112,36 @@ fn bundle_linux(arch: runners::Arch) -> Job { )) .add_step(steps::upload_artifact( &remote_server_artifact_name, - "target/release/zed-remote-server-*.tar.gz", + "target/zed-remote-server-*.gz", )) + .outputs( + [ + ("zed".to_string(), artifact_name), + ("remote-server".to_string(), remote_server_artifact_name), + ] + .into_iter() + .collect::>(), + ) } -fn bundle_windows_job(arch: runners::Arch) -> Job { +pub(crate) fn bundle_windows_job(arch: runners::Arch, deps: &[&NamedJob]) -> Job { use vars::GITHUB_SHA; - bundle_job() + let artifact_name = format!("Zed_{GITHUB_SHA}-{arch}.exe"); + bundle_job(deps) .runs_on(runners::WINDOWS_DEFAULT) .envs(windows_bundle_envs()) .add_step(steps::checkout_repo()) .add_step(steps::setup_sentry()) .add_step(bundle_windows(arch)) .add_step(steps::upload_artifact( - &format!("Zed_{GITHUB_SHA}-{arch}.exe"), + &artifact_name, "${{ env.SETUP_PATH }}", )) + .outputs( + [("zed".to_string(), artifact_name)] + .into_iter() + .collect::>(), + ) } fn bundle_windows(arch: runners::Arch) -> Step { diff --git a/tooling/xtask/src/tasks/workflows/run_tests.rs b/tooling/xtask/src/tasks/workflows/run_tests.rs index 3328d857fb22e174a0e452626e0caf54b58065de..88874754706661939490fc470c58d8a0c867c0d8 100644 --- a/tooling/xtask/src/tasks/workflows/run_tests.rs +++ b/tooling/xtask/src/tasks/workflows/run_tests.rs @@ -302,9 +302,6 @@ pub(crate) fn run_platform_tests(platform: Platform) -> NamedJob { NamedJob { name: format!("run_tests_{platform}"), job: release_job(&[]) - .cond(Expression::new( - "github.repository_owner == 'zed-industries'", - )) .runs_on(runner) .add_step(steps::checkout_repo()) .add_step(steps::setup_cargo_config(platform)) @@ -436,7 +433,7 @@ fn check_docs() -> NamedJob { ) } -fn check_scripts() -> NamedJob { +pub(crate) fn check_scripts() -> NamedJob { fn download_actionlint() -> Step { named::bash( "bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)", diff --git a/tooling/xtask/src/tasks/workflows/steps.rs b/tooling/xtask/src/tasks/workflows/steps.rs index 14ee5cc5b50a464d1fcc54d7497906926f85321e..5a6196b599ec56b68948afc55316175779877a48 100644 --- a/tooling/xtask/src/tasks/workflows/steps.rs +++ b/tooling/xtask/src/tasks/workflows/steps.rs @@ -95,6 +95,7 @@ pub fn upload_artifact(name: &str, path: &str) -> Step { ) .add_with(("name", name)) .add_with(("path", path)) + .add_with(("if-no-files-found", "error")) } pub fn clear_target_dir_if_large(platform: Platform) -> Step { @@ -156,11 +157,15 @@ pub(crate) struct NamedJob { // } pub(crate) fn release_job(deps: &[&NamedJob]) -> Job { - let job = Job::default() + dependant_job(deps) .cond(Expression::new( "github.repository_owner == 'zed-industries'", )) - .timeout_minutes(60u32); + .timeout_minutes(60u32) +} + +pub(crate) fn dependant_job(deps: &[&NamedJob]) -> Job { + let job = Job::default(); if deps.len() > 0 { job.needs(deps.iter().map(|j| j.name.clone()).collect::>()) } else { diff --git a/tooling/xtask/src/tasks/workflows/vars.rs b/tooling/xtask/src/tasks/workflows/vars.rs index 257bf31b5e981cbfccfddfa77939b9a0f2c3f603..b852e12400098c3d49f806c0010458d123ad24fa 100644 --- a/tooling/xtask/src/tasks/workflows/vars.rs +++ b/tooling/xtask/src/tasks/workflows/vars.rs @@ -1,6 +1,6 @@ use std::cell::RefCell; -use gh_workflow::{Env, Expression}; +use gh_workflow::{Concurrency, Env, Expression}; use crate::tasks::workflows::steps::NamedJob; @@ -62,6 +62,12 @@ pub fn windows_bundle_envs() -> Env { .add("TIMESTAMP_SERVER", "http://timestamp.acs.microsoft.com") } +pub(crate) fn one_workflow_per_non_main_branch() -> Concurrency { + Concurrency::default() + .group("${{ github.workflow }}-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }}") + .cancel_in_progress(true) +} + // Represents a pattern to check for changed files and corresponding output variable pub(crate) struct PathCondition { pub name: &'static str,