From 131fecce9d6bc6a4fe462d879f68f2870570b4ed Mon Sep 17 00:00:00 2001 From: Finn Evers Date: Fri, 15 May 2026 10:29:24 +0200 Subject: [PATCH] ci: Prepare for Node.js 20 deprecation (#56812) https://github.com/zed-industries/zed/actions/runs/25881329418 complains about the deprecation of Node.js version 20, which will soon be force-bumped to 24 in the runner contexts. Thus, this PR bumps all the jobs mentioned there to versions that run on Node.js 24 by default. I checked all the release note section for the three actions and this should not change any behaviour according to their release notes and get us ready for the deprecation. Release Notes: - N/A --- .github/workflows/autofix_pr.yml | 6 +- .github/workflows/compare_perf.yml | 4 +- .github/workflows/compliance_check.yml | 4 +- .github/workflows/deploy_docs.yml | 2 +- .github/workflows/extension_bump.yml | 8 +- .../workflows/extension_workflow_rollout.yml | 6 +- .github/workflows/release.yml | 58 ++-- .github/workflows/release_nightly.yml | 50 ++-- .github/workflows/run_bundling.yml | 48 ++-- .../xtask/src/tasks/workflows/autofix_pr.rs | 29 +- .../xtask/src/tasks/workflows/deploy_docs.rs | 17 +- .../src/tasks/workflows/extension_bump.rs | 145 +++++----- .../workflows/extension_workflow_rollout.rs | 81 +++--- tooling/xtask/src/tasks/workflows/release.rs | 16 +- .../xtask/src/tasks/workflows/run_bundling.rs | 19 +- tooling/xtask/src/tasks/workflows/steps.rs | 252 ++++++++++++++++-- 16 files changed, 453 insertions(+), 292 deletions(-) diff --git a/.github/workflows/autofix_pr.yml b/.github/workflows/autofix_pr.yml index 5e4fe70439..72fdcab663 100644 --- a/.github/workflows/autofix_pr.yml +++ b/.github/workflows/autofix_pr.yml @@ -74,8 +74,8 @@ jobs: git diff > autofix.patch echo "has_changes=true" >> "$GITHUB_OUTPUT" fi - - name: upload artifact autofix-patch - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: autofix_pr::upload_patch_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: autofix-patch path: autofix.patch @@ -112,7 +112,7 @@ jobs: PR_NUMBER: ${{ inputs.pr_number }} GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} - name: autofix_pr::download_patch_artifact - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c with: name: autofix-patch - name: autofix_pr::commit_changes::apply_patch diff --git a/.github/workflows/compare_perf.yml b/.github/workflows/compare_perf.yml index 2b2154ce9b..154276a710 100644 --- a/.github/workflows/compare_perf.yml +++ b/.github/workflows/compare_perf.yml @@ -69,8 +69,8 @@ jobs: env: BASE: ${{ inputs.base }} HEAD: ${{ inputs.head }} - - name: '@actions/upload-artifact results.md' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: results.md path: results.md diff --git a/.github/workflows/compliance_check.yml b/.github/workflows/compliance_check.yml index 57b528c94d..2cf27fea8b 100644 --- a/.github/workflows/compliance_check.yml +++ b/.github/workflows/compliance_check.yml @@ -42,9 +42,9 @@ jobs: GITHUB_APP_KEY: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }} LATEST_TAG: ${{ steps.determine-version.outputs.tag }} continue-on-error: true - - name: '@actions/upload-artifact compliance-report-${{ github.ref_name }}.md' + - name: run_bundling::upload_artifact if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: compliance-report-${{ github.ref_name }}.md path: compliance-report-${{ github.ref_name }}.md diff --git a/.github/workflows/deploy_docs.yml b/.github/workflows/deploy_docs.yml index 1739b6b257..c66a56f160 100644 --- a/.github/workflows/deploy_docs.yml +++ b/.github/workflows/deploy_docs.yml @@ -143,7 +143,7 @@ jobs: command: deploy .cloudflare/docs-proxy/src/worker.js - name: deploy_docs::docs_deploy_steps::upload_wrangler_logs if: always() - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: wrangler_logs path: /home/runner/.config/.wrangler/logs/ diff --git a/.github/workflows/extension_bump.yml b/.github/workflows/extension_bump.yml index 083c6a7c9e..4757db4343 100644 --- a/.github/workflows/extension_bump.yml +++ b/.github/workflows/extension_bump.yml @@ -187,10 +187,10 @@ jobs: env: CURRENT_VERSION: ${{ needs.check_version_changed.outputs.current_version }} WORKING_DIR: ${{ inputs.working-directory }} - - name: extension_bump::create_version_tag + - name: steps::create_tag uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b with: - script: |- + script: | github.rest.git.createRef({ owner: context.repo.owner, repo: context.repo.repo, @@ -239,10 +239,9 @@ jobs: tag: ${{ needs.create_version_label.outputs.tag }} env: COMMITTER_TOKEN: ${{ steps.generate-token.outputs.token }} - - name: extension_bump::enable_automerge_if_staff + - name: enable_automerge_if_staff uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b with: - github-token: ${{ steps.generate-token.outputs.token }} script: | const prNumber = process.env.PR_NUMBER; if (!prNumber) { @@ -301,6 +300,7 @@ jobs: `, { pullRequestId: pr.node_id }); console.log(`Automerge enabled for PR #${prNumber} in zed-industries/extensions`); + github-token: ${{ steps.generate-token.outputs.token }} env: PR_NUMBER: ${{ steps.extension-update.outputs.pull-request-number }} defaults: diff --git a/.github/workflows/extension_workflow_rollout.yml b/.github/workflows/extension_workflow_rollout.yml index 03767f48fb..7c1617b229 100644 --- a/.github/workflows/extension_workflow_rollout.yml +++ b/.github/workflows/extension_workflow_rollout.yml @@ -56,7 +56,7 @@ jobs: env: PREV_COMMIT: ${{ steps.prev-tag.outputs.prev_commit }} - id: list-repos - name: extension_workflow_rollout::fetch_extension_repos::get_repositories + name: get_repositories uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b with: script: | @@ -91,7 +91,7 @@ jobs: env: COMMIT_SHA: ${{ github.sha }} - name: extension_workflow_rollout::fetch_extension_repos::upload_workflow_files - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: extension-workflow-files path: extensions/workflows/**/*.yml @@ -132,7 +132,7 @@ jobs: repository: zed-extensions/${{ matrix.repo }} token: ${{ steps.generate-token.outputs.token }} - name: extension_workflow_rollout::rollout_workflows_to_extension::download_workflow_files - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c with: name: extension-workflow-files path: workflow-files diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a2a779dc14..d5934a4838 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -321,9 +321,9 @@ jobs: GITHUB_APP_ID: ${{ secrets.ZED_ZIPPY_APP_ID }} GITHUB_APP_KEY: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }} continue-on-error: true - - name: '@actions/upload-artifact compliance-report-${{ github.ref_name }}.md' + - name: run_bundling::upload_artifact if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: compliance-report-${{ github.ref_name }}.md path: compliance-report-${{ github.ref_name }}.md @@ -377,14 +377,14 @@ jobs: run: ./script/download-wasi-sdk - name: ./script/bundle-linux run: ./script/bundle-linux - - name: '@actions/upload-artifact zed-linux-aarch64.tar.gz' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-linux-aarch64.tar.gz path: target/release/zed-linux-aarch64.tar.gz if-no-files-found: error - - name: '@actions/upload-artifact zed-remote-server-linux-aarch64.gz' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-remote-server-linux-aarch64.gz path: target/zed-remote-server-linux-aarch64.gz @@ -417,14 +417,14 @@ jobs: run: ./script/download-wasi-sdk - name: ./script/bundle-linux run: ./script/bundle-linux - - name: '@actions/upload-artifact zed-linux-x86_64.tar.gz' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-linux-x86_64.tar.gz path: target/release/zed-linux-x86_64.tar.gz if-no-files-found: error - - name: '@actions/upload-artifact zed-remote-server-linux-x86_64.gz' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-remote-server-linux-x86_64.gz path: target/zed-remote-server-linux-x86_64.gz @@ -462,14 +462,14 @@ jobs: run: ./script/clear-target-dir-if-larger-than 350 200 - name: run_bundling::bundle_mac::bundle_mac run: ./script/bundle-mac aarch64-apple-darwin - - name: '@actions/upload-artifact Zed-aarch64.dmg' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: Zed-aarch64.dmg path: target/aarch64-apple-darwin/release/Zed-aarch64.dmg if-no-files-found: error - - name: '@actions/upload-artifact zed-remote-server-macos-aarch64.gz' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-remote-server-macos-aarch64.gz path: target/zed-remote-server-macos-aarch64.gz @@ -507,14 +507,14 @@ jobs: run: ./script/clear-target-dir-if-larger-than 350 200 - name: run_bundling::bundle_mac::bundle_mac run: ./script/bundle-mac x86_64-apple-darwin - - name: '@actions/upload-artifact Zed-x86_64.dmg' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: Zed-x86_64.dmg path: target/x86_64-apple-darwin/release/Zed-x86_64.dmg if-no-files-found: error - - name: '@actions/upload-artifact zed-remote-server-macos-x86_64.gz' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-remote-server-macos-x86_64.gz path: target/zed-remote-server-macos-x86_64.gz @@ -552,14 +552,14 @@ jobs: run: script/bundle-windows.ps1 -Architecture aarch64 shell: pwsh working-directory: ${{ env.ZED_WORKSPACE }} - - name: '@actions/upload-artifact Zed-aarch64.exe' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: Zed-aarch64.exe path: target/Zed-aarch64.exe if-no-files-found: error - - name: '@actions/upload-artifact zed-remote-server-windows-aarch64.zip' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-remote-server-windows-aarch64.zip path: target/zed-remote-server-windows-aarch64.zip @@ -597,14 +597,14 @@ jobs: run: script/bundle-windows.ps1 -Architecture x86_64 shell: pwsh working-directory: ${{ env.ZED_WORKSPACE }} - - name: '@actions/upload-artifact Zed-x86_64.exe' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: Zed-x86_64.exe path: target/Zed-x86_64.exe if-no-files-found: error - - name: '@actions/upload-artifact zed-remote-server-windows-x86_64.zip' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-remote-server-windows-x86_64.zip path: target/zed-remote-server-windows-x86_64.zip @@ -622,7 +622,7 @@ jobs: runs-on: namespace-profile-4x8-ubuntu-2204 steps: - name: release::download_workflow_artifacts - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c with: path: ./artifacts/ - name: ls -lR ./artifacts @@ -694,9 +694,9 @@ jobs: env: GITHUB_APP_ID: ${{ secrets.ZED_ZIPPY_APP_ID }} GITHUB_APP_KEY: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }} - - name: '@actions/upload-artifact compliance-report-${{ github.ref_name }}.md' + - name: run_bundling::upload_artifact if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: compliance-report-${{ github.ref_name }}.md path: compliance-report-${{ github.ref_name }}.md diff --git a/.github/workflows/release_nightly.yml b/.github/workflows/release_nightly.yml index 1adb283cc2..fc1b2c26b4 100644 --- a/.github/workflows/release_nightly.yml +++ b/.github/workflows/release_nightly.yml @@ -126,14 +126,14 @@ jobs: run: ./script/download-wasi-sdk - name: ./script/bundle-linux run: ./script/bundle-linux - - name: '@actions/upload-artifact zed-linux-aarch64.tar.gz' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-linux-aarch64.tar.gz path: target/release/zed-linux-aarch64.tar.gz if-no-files-found: error - - name: '@actions/upload-artifact zed-remote-server-linux-aarch64.gz' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-remote-server-linux-aarch64.gz path: target/zed-remote-server-linux-aarch64.gz @@ -172,14 +172,14 @@ jobs: run: ./script/download-wasi-sdk - name: ./script/bundle-linux run: ./script/bundle-linux - - name: '@actions/upload-artifact zed-linux-x86_64.tar.gz' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-linux-x86_64.tar.gz path: target/release/zed-linux-x86_64.tar.gz if-no-files-found: error - - name: '@actions/upload-artifact zed-remote-server-linux-x86_64.gz' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-remote-server-linux-x86_64.gz path: target/zed-remote-server-linux-x86_64.gz @@ -223,14 +223,14 @@ jobs: run: ./script/clear-target-dir-if-larger-than 350 200 - name: run_bundling::bundle_mac::bundle_mac run: ./script/bundle-mac aarch64-apple-darwin - - name: '@actions/upload-artifact Zed-aarch64.dmg' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: Zed-aarch64.dmg path: target/aarch64-apple-darwin/release/Zed-aarch64.dmg if-no-files-found: error - - name: '@actions/upload-artifact zed-remote-server-macos-aarch64.gz' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-remote-server-macos-aarch64.gz path: target/zed-remote-server-macos-aarch64.gz @@ -274,14 +274,14 @@ jobs: run: ./script/clear-target-dir-if-larger-than 350 200 - name: run_bundling::bundle_mac::bundle_mac run: ./script/bundle-mac x86_64-apple-darwin - - name: '@actions/upload-artifact Zed-x86_64.dmg' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: Zed-x86_64.dmg path: target/x86_64-apple-darwin/release/Zed-x86_64.dmg if-no-files-found: error - - name: '@actions/upload-artifact zed-remote-server-macos-x86_64.gz' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-remote-server-macos-x86_64.gz path: target/zed-remote-server-macos-x86_64.gz @@ -327,14 +327,14 @@ jobs: run: script/bundle-windows.ps1 -Architecture aarch64 shell: pwsh working-directory: ${{ env.ZED_WORKSPACE }} - - name: '@actions/upload-artifact Zed-aarch64.exe' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: Zed-aarch64.exe path: target/Zed-aarch64.exe if-no-files-found: error - - name: '@actions/upload-artifact zed-remote-server-windows-aarch64.zip' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-remote-server-windows-aarch64.zip path: target/zed-remote-server-windows-aarch64.zip @@ -380,14 +380,14 @@ jobs: run: script/bundle-windows.ps1 -Architecture x86_64 shell: pwsh working-directory: ${{ env.ZED_WORKSPACE }} - - name: '@actions/upload-artifact Zed-x86_64.exe' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: Zed-x86_64.exe path: target/Zed-x86_64.exe if-no-files-found: error - - name: '@actions/upload-artifact zed-remote-server-windows-x86_64.zip' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-remote-server-windows-x86_64.zip path: target/zed-remote-server-windows-x86_64.zip @@ -493,7 +493,7 @@ jobs: clean: false fetch-depth: 0 - name: release::download_workflow_artifacts - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c with: path: ./artifacts/ - name: ls -lR ./artifacts diff --git a/.github/workflows/run_bundling.yml b/.github/workflows/run_bundling.yml index 05a951588b..bc7408f3a2 100644 --- a/.github/workflows/run_bundling.yml +++ b/.github/workflows/run_bundling.yml @@ -36,14 +36,14 @@ jobs: run: ./script/download-wasi-sdk - name: ./script/bundle-linux run: ./script/bundle-linux - - name: '@actions/upload-artifact zed-linux-aarch64.tar.gz' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-linux-aarch64.tar.gz path: target/release/zed-linux-aarch64.tar.gz if-no-files-found: error - - name: '@actions/upload-artifact zed-remote-server-linux-aarch64.gz' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-remote-server-linux-aarch64.gz path: target/zed-remote-server-linux-aarch64.gz @@ -75,14 +75,14 @@ jobs: run: ./script/download-wasi-sdk - name: ./script/bundle-linux run: ./script/bundle-linux - - name: '@actions/upload-artifact zed-linux-x86_64.tar.gz' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-linux-x86_64.tar.gz path: target/release/zed-linux-x86_64.tar.gz if-no-files-found: error - - name: '@actions/upload-artifact zed-remote-server-linux-x86_64.gz' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-remote-server-linux-x86_64.gz path: target/zed-remote-server-linux-x86_64.gz @@ -119,14 +119,14 @@ jobs: run: ./script/clear-target-dir-if-larger-than 350 200 - name: run_bundling::bundle_mac::bundle_mac run: ./script/bundle-mac aarch64-apple-darwin - - name: '@actions/upload-artifact Zed-aarch64.dmg' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: Zed-aarch64.dmg path: target/aarch64-apple-darwin/release/Zed-aarch64.dmg if-no-files-found: error - - name: '@actions/upload-artifact zed-remote-server-macos-aarch64.gz' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-remote-server-macos-aarch64.gz path: target/zed-remote-server-macos-aarch64.gz @@ -163,14 +163,14 @@ jobs: run: ./script/clear-target-dir-if-larger-than 350 200 - name: run_bundling::bundle_mac::bundle_mac run: ./script/bundle-mac x86_64-apple-darwin - - name: '@actions/upload-artifact Zed-x86_64.dmg' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: Zed-x86_64.dmg path: target/x86_64-apple-darwin/release/Zed-x86_64.dmg if-no-files-found: error - - name: '@actions/upload-artifact zed-remote-server-macos-x86_64.gz' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-remote-server-macos-x86_64.gz path: target/zed-remote-server-macos-x86_64.gz @@ -207,14 +207,14 @@ jobs: run: script/bundle-windows.ps1 -Architecture aarch64 shell: pwsh working-directory: ${{ env.ZED_WORKSPACE }} - - name: '@actions/upload-artifact Zed-aarch64.exe' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: Zed-aarch64.exe path: target/Zed-aarch64.exe if-no-files-found: error - - name: '@actions/upload-artifact zed-remote-server-windows-aarch64.zip' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-remote-server-windows-aarch64.zip path: target/zed-remote-server-windows-aarch64.zip @@ -251,14 +251,14 @@ jobs: run: script/bundle-windows.ps1 -Architecture x86_64 shell: pwsh working-directory: ${{ env.ZED_WORKSPACE }} - - name: '@actions/upload-artifact Zed-x86_64.exe' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: Zed-x86_64.exe path: target/Zed-x86_64.exe if-no-files-found: error - - name: '@actions/upload-artifact zed-remote-server-windows-x86_64.zip' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + - name: run_bundling::upload_artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: zed-remote-server-windows-x86_64.zip path: target/zed-remote-server-windows-x86_64.zip diff --git a/tooling/xtask/src/tasks/workflows/autofix_pr.rs b/tooling/xtask/src/tasks/workflows/autofix_pr.rs index cc6563b6cb..a409594dfd 100644 --- a/tooling/xtask/src/tasks/workflows/autofix_pr.rs +++ b/tooling/xtask/src/tasks/workflows/autofix_pr.rs @@ -2,7 +2,10 @@ use gh_workflow::*; use crate::tasks::workflows::{ runners, - steps::{self, FluentBuilder, NamedJob, RepositoryTarget, TokenPermissions, named, use_clang}, + steps::{ + self, DownloadArtifactStep, FluentBuilder, IfNoFilesFound, NamedJob, RepositoryTarget, + TokenPermissions, UploadArtifactStep, named, use_clang, + }, vars::{self, StepOutput, WorkflowInput}, }; @@ -31,26 +34,14 @@ pub fn autofix_pr() -> Workflow { const PATCH_ARTIFACT_NAME: &str = "autofix-patch"; const PATCH_FILE_PATH: &str = "autofix.patch"; -fn upload_patch_artifact() -> Step { - Step::new(format!("upload artifact {}", PATCH_ARTIFACT_NAME)) - .uses( - "actions", - "upload-artifact", - "330a01c490aca151604b8cf639adc76d48f6c5d4", // v5 - ) - .add_with(("name", PATCH_ARTIFACT_NAME)) - .add_with(("path", PATCH_FILE_PATH)) - .add_with(("if-no-files-found", "ignore")) - .add_with(("retention-days", "1")) +fn upload_patch_artifact() -> UploadArtifactStep { + steps::upload_artifact(PATCH_ARTIFACT_NAME, PATCH_FILE_PATH) + .if_no_files_found(IfNoFilesFound::Ignore) + .retention_days(1) } -fn download_patch_artifact() -> Step { - named::uses( - "actions", - "download-artifact", - "018cc2cf5baa6db3ef3c5f8a56943fffe632ef53", // v6.0.0 - ) - .add_with(("name", PATCH_ARTIFACT_NAME)) +fn download_patch_artifact() -> DownloadArtifactStep { + steps::download_artifact().artifact_name(PATCH_ARTIFACT_NAME) } fn run_autofix(pr_number: &WorkflowInput, run_clippy: &WorkflowInput) -> NamedJob { diff --git a/tooling/xtask/src/tasks/workflows/deploy_docs.rs b/tooling/xtask/src/tasks/workflows/deploy_docs.rs index c2cb633181..894e485fa9 100644 --- a/tooling/xtask/src/tasks/workflows/deploy_docs.rs +++ b/tooling/xtask/src/tasks/workflows/deploy_docs.rs @@ -5,7 +5,10 @@ use gh_workflow::{ use crate::tasks::workflows::{ runners, - steps::{self, CommonJobConditions, FluentBuilder as _, NamedJob, named, release_job}, + steps::{ + self, CommonJobConditions, FluentBuilder as _, NamedJob, UploadArtifactStep, named, + release_job, + }, vars::{self, StepOutput, WorkflowInput}, }; @@ -143,15 +146,9 @@ fn docs_deploy_steps(job: Job, project_name: &StepOutput) -> Job { .add_with(("command", "deploy .cloudflare/docs-proxy/src/worker.js")) } - fn upload_wrangler_logs() -> Step { - named::uses( - "actions", - "upload-artifact", - "ea165f8d65b6e75b540449e92b4886f43607fa02", - ) // v4 - .if_condition(Expression::new("always()")) - .add_with(("name", "wrangler_logs")) - .add_with(("path", "/home/runner/.config/.wrangler/logs/")) + fn upload_wrangler_logs() -> UploadArtifactStep { + steps::upload_artifact("wrangler_logs", "/home/runner/.config/.wrangler/logs/") + .if_condition(Expression::new("always()")) } job.add_step(deploy_to_cf_pages(project_name)) diff --git a/tooling/xtask/src/tasks/workflows/extension_bump.rs b/tooling/xtask/src/tasks/workflows/extension_bump.rs index 6bb0e0a421..e4efebfe67 100644 --- a/tooling/xtask/src/tasks/workflows/extension_bump.rs +++ b/tooling/xtask/src/tasks/workflows/extension_bump.rs @@ -5,9 +5,9 @@ use crate::tasks::workflows::{ extension_tests::{self}, runners, steps::{ - self, BASH_SHELL, CommonJobConditions, DEFAULT_REPOSITORY_OWNER_GUARD, NamedJob, - RepositoryTarget, cache_rust_dependencies_namespace, checkout_repo, dependant_job, - generate_token, named, + self, BASH_SHELL, CommonJobConditions, DEFAULT_REPOSITORY_OWNER_GUARD, GitHubScriptStep, + GitRef, NamedJob, RefSha, RepositoryTarget, cache_rust_dependencies_namespace, + checkout_repo, create_ref, dependant_job, generate_token, named, }, vars::{ JobOutput, StepOutput, WorkflowInput, WorkflowSecret, @@ -145,26 +145,12 @@ fn create_version_label( } fn create_version_tag(tag: &StepOutput, generated_token: StepOutput) -> Step { - named::uses( - "actions", - "github-script", - "f28e40c7f34bde8b3046d885e986cb6290c5673b", // v7 - ) - .with( - Input::default() - .add( - "script", - formatdoc! {r#" - github.rest.git.createRef({{ - owner: context.repo.owner, - repo: context.repo.repo, - ref: 'refs/tags/{tag}', - sha: context.sha - }})"# - }, - ) - .add("github-token", generated_token.to_string()), + create_ref( + GitRef::Tag(tag.to_string()), + RefSha::Context, + &generated_token, ) + .into() } fn determine_tag(current_version: &JobOutput) -> (Step, StepOutput) { @@ -400,76 +386,69 @@ fn release_action( fn enable_automerge_if_staff( pull_request_number: StepOutput, generated_token: StepOutput, -) -> Step { - named::uses( - "actions", - "github-script", - "f28e40c7f34bde8b3046d885e986cb6290c5673b", // v7 - ) - .add_with(("github-token", generated_token.to_string())) - .add_with(( - "script", - indoc! {r#" - const prNumber = process.env.PR_NUMBER; - if (!prNumber) { - console.log('No pull request number set, skipping automerge.'); - return; - } +) -> GitHubScriptStep { + steps::github_script(indoc! {r#" + const prNumber = process.env.PR_NUMBER; + if (!prNumber) { + console.log('No pull request number set, skipping automerge.'); + return; + } - const author = process.env.GITHUB_ACTOR; - let isStaff = false; - try { - const response = await github.rest.teams.getMembershipForUserInOrg({ - org: 'zed-industries', - team_slug: 'staff', - username: author - }); - isStaff = response.data.state === 'active'; - } catch (error) { - if (error.status !== 404) { - throw error; - } - } + const author = process.env.GITHUB_ACTOR; + let isStaff = false; + try { + const response = await github.rest.teams.getMembershipForUserInOrg({ + org: 'zed-industries', + team_slug: 'staff', + username: author + }); + isStaff = response.data.state === 'active'; + } catch (error) { + if (error.status !== 404) { + throw error; + } + } - if (!isStaff) { - console.log(`Actor ${author} is not a staff member, skipping automerge.`); - return; - } + if (!isStaff) { + console.log(`Actor ${author} is not a staff member, skipping automerge.`); + return; + } - // Assign staff member responsible for the bump - const pullNumber = parseInt(prNumber); + // Assign staff member responsible for the bump + const pullNumber = parseInt(prNumber); - await github.rest.issues.addAssignees({ - owner: 'zed-industries', - repo: 'extensions', - issue_number: pullNumber, - assignees: [author] - }); - console.log(`Assigned ${author} to PR #${prNumber} in zed-industries/extensions`); + await github.rest.issues.addAssignees({ + owner: 'zed-industries', + repo: 'extensions', + issue_number: pullNumber, + assignees: [author] + }); + console.log(`Assigned ${author} to PR #${prNumber} in zed-industries/extensions`); - // Get the GraphQL node ID - const { data: pr } = await github.rest.pulls.get({ - owner: 'zed-industries', - repo: 'extensions', - pull_number: pullNumber - }); + // Get the GraphQL node ID + const { data: pr } = await github.rest.pulls.get({ + owner: 'zed-industries', + repo: 'extensions', + pull_number: pullNumber + }); - await github.graphql(` - mutation($pullRequestId: ID!) { - enablePullRequestAutoMerge(input: { pullRequestId: $pullRequestId, mergeMethod: SQUASH }) { - pullRequest { - autoMergeRequest { - enabledAt - } - } + await github.graphql(` + mutation($pullRequestId: ID!) { + enablePullRequestAutoMerge(input: { pullRequestId: $pullRequestId, mergeMethod: SQUASH }) { + pullRequest { + autoMergeRequest { + enabledAt } } - `, { pullRequestId: pr.node_id }); + } + } + `, { pullRequestId: pr.node_id }); - console.log(`Automerge enabled for PR #${prNumber} in zed-industries/extensions`); - "#}, - )) - .add_env(("PR_NUMBER", pull_request_number.to_string())) + console.log(`Automerge enabled for PR #${prNumber} in zed-industries/extensions`); + "#}) + .custom_name("enable_automerge_if_staff") + .token(generated_token) + .env("PR_NUMBER", pull_request_number.to_string()) } fn extension_workflow_secrets() -> (WorkflowSecret, WorkflowSecret) { diff --git a/tooling/xtask/src/tasks/workflows/extension_workflow_rollout.rs b/tooling/xtask/src/tasks/workflows/extension_workflow_rollout.rs index 2e44a9a698..4dd1f1bb1f 100644 --- a/tooling/xtask/src/tasks/workflows/extension_workflow_rollout.rs +++ b/tooling/xtask/src/tasks/workflows/extension_workflow_rollout.rs @@ -5,9 +5,10 @@ use indoc::formatdoc; use indoc::indoc; use serde_json::json; -use crate::tasks::workflows::steps::CheckoutStep; -use crate::tasks::workflows::steps::TokenPermissions; -use crate::tasks::workflows::steps::cache_rust_dependencies_namespace; +use crate::tasks::workflows::steps::{ + CheckoutStep, DownloadArtifactStep, IfNoFilesFound, ResultEncoding, TokenPermissions, + UploadArtifactStep, cache_rust_dependencies_namespace, +}; use crate::tasks::workflows::vars::JobOutput; use crate::tasks::workflows::{ runners, @@ -52,33 +53,31 @@ pub(crate) fn extension_workflow_rollout() -> Workflow { fn fetch_extension_repos(filter_repos_input: &WorkflowInput) -> (NamedJob, JobOutput, JobOutput) { fn get_repositories(filter_repos_input: &WorkflowInput) -> (Step, StepOutput) { - let step = named::uses("actions", "github-script", "f28e40c7f34bde8b3046d885e986cb6290c5673b") + let step: Step = steps::github_script(formatdoc! {r#" + const repos = await github.paginate(github.rest.repos.listForOrg, {{ + org: 'zed-extensions', + type: 'public', + per_page: 100, + }}); + + let filteredRepos = repos + .filter(repo => !repo.archived) + .map(repo => repo.name); + + const filterInput = `{filter_repos_input}`.trim(); + if (filterInput.length > 0) {{ + const allowedNames = filterInput.split(',').map(s => s.trim()).filter(s => s.length > 0); + filteredRepos = filteredRepos.filter(name => allowedNames.includes(name)); + console.log(`Filter applied. Matched ${{filteredRepos.length}} repos from ${{allowedNames.length}} requested.`); + }} + + console.log(`Found ${{filteredRepos.length}} extension repos`); + return filteredRepos; + "#}) + .result_encoding(ResultEncoding::Json) + .custom_name("get_repositories") .id("list-repos") - .add_with(( - "script", - formatdoc! {r#" - const repos = await github.paginate(github.rest.repos.listForOrg, {{ - org: 'zed-extensions', - type: 'public', - per_page: 100, - }}); - - let filteredRepos = repos - .filter(repo => !repo.archived) - .map(repo => repo.name); - - const filterInput = `{filter_repos_input}`.trim(); - if (filterInput.length > 0) {{ - const allowedNames = filterInput.split(',').map(s => s.trim()).filter(s => s.length > 0); - filteredRepos = filteredRepos.filter(name => allowedNames.includes(name)); - console.log(`Filter applied. Matched ${{filteredRepos.length}} repos from ${{allowedNames.length}} requested.`); - }} - - console.log(`Found ${{filteredRepos.length}} extension repos`); - return filteredRepos; - "#}, - )) - .add_with(("result-encoding", "json")); + .into(); let filtered_repos = StepOutput::new(&step, "result"); @@ -144,15 +143,9 @@ fn fetch_extension_repos(filter_repos_input: &WorkflowInput) -> (NamedJob, JobOu .add_env(("COMMIT_SHA", "${{ github.sha }}")) } - fn upload_workflow_files() -> Step { - named::uses( - "actions", - "upload-artifact", - "330a01c490aca151604b8cf639adc76d48f6c5d4", // v5 - ) - .add_with(("name", WORKFLOW_ARTIFACT_NAME)) - .add_with(("path", "extensions/workflows/**/*.yml")) - .add_with(("if-no-files-found", "error")) + fn upload_workflow_files() -> UploadArtifactStep { + steps::upload_artifact(WORKFLOW_ARTIFACT_NAME, "extensions/workflows/**/*.yml") + .if_no_files_found(IfNoFilesFound::Error) } let (get_org_repositories, list_repos_output) = get_repositories(filter_repos_input); @@ -203,14 +196,10 @@ fn rollout_workflows_to_extension( .with_path("extension") } - fn download_workflow_files() -> Step { - named::uses( - "actions", - "download-artifact", - "018cc2cf5baa6db3ef3c5f8a56943fffe632ef53", // v6.0.0 - ) - .add_with(("name", WORKFLOW_ARTIFACT_NAME)) - .add_with(("path", "workflow-files")) + fn download_workflow_files() -> DownloadArtifactStep { + steps::download_artifact() + .artifact_name(WORKFLOW_ARTIFACT_NAME) + .path("workflow-files") } fn sync_workflow_files(removed_ci: JobOutput, removed_shared: JobOutput) -> Step { diff --git a/tooling/xtask/src/tasks/workflows/release.rs b/tooling/xtask/src/tasks/workflows/release.rs index 94db5508f8..325682389d 100644 --- a/tooling/xtask/src/tasks/workflows/release.rs +++ b/tooling/xtask/src/tasks/workflows/release.rs @@ -5,7 +5,10 @@ use crate::tasks::workflows::{ run_bundling::{bundle_linux, bundle_mac, bundle_windows, upload_artifact}, run_tests, runners::{self, Arch, Platform}, - steps::{self, FluentBuilder, NamedJob, TokenPermissions, dependant_job, named, release_job}, + steps::{ + self, DownloadArtifactStep, FluentBuilder, NamedJob, TokenPermissions, dependant_job, + named, release_job, + }, vars::{self, JobOutput, StepOutput, assets}, }; @@ -217,7 +220,7 @@ pub(crate) fn add_compliance_steps( .if_condition(Expression::new("always()")) .when( matches!(context, ComplianceContext::Release { .. }), - |step| step.add_with(("overwrite", true)), + |step| step.overwrite(true), ); let (success_prefix, failure_prefix) = match context { @@ -428,13 +431,8 @@ fn auto_release_preview(deps: &[&NamedJob]) -> (NamedJob, JobOutput) { (job, release_published) } -pub(crate) fn download_workflow_artifacts() -> Step { - named::uses( - "actions", - "download-artifact", - "018cc2cf5baa6db3ef3c5f8a56943fffe632ef53", // v6.0.0 - ) - .add_with(("path", "./artifacts/")) +pub(crate) fn download_workflow_artifacts() -> DownloadArtifactStep { + steps::download_artifact().path("./artifacts/") } pub(crate) fn prep_release_artifacts() -> Step { diff --git a/tooling/xtask/src/tasks/workflows/run_bundling.rs b/tooling/xtask/src/tasks/workflows/run_bundling.rs index 6b9d3b9e36..5fa6b870b0 100644 --- a/tooling/xtask/src/tasks/workflows/run_bundling.rs +++ b/tooling/xtask/src/tasks/workflows/run_bundling.rs @@ -4,7 +4,10 @@ use crate::tasks::workflows::{ nix_build::build_nix, release::ReleaseBundleJobs, runners::{Arch, Platform, ReleaseChannel}, - steps::{DEFAULT_REPOSITORY_OWNER_GUARD, FluentBuilder, NamedJob, dependant_job, named}, + steps::{ + DEFAULT_REPOSITORY_OWNER_GUARD, FluentBuilder, IfNoFilesFound, NamedJob, + UploadArtifactStep, dependant_job, named, + }, vars::{assets, bundle_envs}, }; @@ -112,19 +115,9 @@ pub(crate) fn bundle_mac( } } -pub fn upload_artifact(path: &str) -> Step { +pub fn upload_artifact(path: &str) -> UploadArtifactStep { let name = Path::new(path).file_name().unwrap().to_str().unwrap(); - Step::new(format!("@actions/upload-artifact {}", name)) - .uses( - "actions", - "upload-artifact", - "330a01c490aca151604b8cf639adc76d48f6c5d4", // v5 - ) - // N.B. "name" is the name for the asset. The uploaded - // file retains its filename. - .add_with(("name", name)) - .add_with(("path", path)) - .add_with(("if-no-files-found", "error")) + steps::upload_artifact(name, path).if_no_files_found(IfNoFilesFound::Error) } pub(crate) fn bundle_linux( diff --git a/tooling/xtask/src/tasks/workflows/steps.rs b/tooling/xtask/src/tasks/workflows/steps.rs index 2e13427d60..aec9f2086b 100644 --- a/tooling/xtask/src/tasks/workflows/steps.rs +++ b/tooling/xtask/src/tasks/workflows/steps.rs @@ -524,6 +524,213 @@ pub mod named { } } +const GITHUB_SCRIPT_SHA: &str = "f28e40c7f34bde8b3046d885e986cb6290c5673b"; // v7 +const UPLOAD_ARTIFACT_SHA: &str = "043fb46d1a93c77aae656e7c1c64a875d1fc6a0a"; // v7.0.1 +const DOWNLOAD_ARTIFACT_SHA: &str = "3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c"; // v8.0.1 + +#[allow(unused)] +pub(crate) enum ResultEncoding { + String, + Json, +} + +impl ResultEncoding { + fn as_str(&self) -> &'static str { + match self { + ResultEncoding::String => "string", + ResultEncoding::Json => "json", + } + } +} + +#[derive(Default)] +pub(crate) struct GitHubScriptStep { + name: String, + id: Option, + script: String, + result_encoding: Option, + token: Option, + env: Vec<(String, String)>, +} + +impl GitHubScriptStep { + pub fn custom_name(mut self, name: &str) -> Self { + self.name = name.to_string(); + self + } + + pub fn id(mut self, id: &str) -> Self { + self.id = Some(id.to_string()); + self + } + + pub fn result_encoding(mut self, encoding: ResultEncoding) -> Self { + self.result_encoding = Some(encoding); + self + } + + pub fn token(mut self, token: impl ToString) -> Self { + self.token = Some(token.to_string()); + self + } + + pub fn env(mut self, key: impl Into, value: impl Into) -> Self { + self.env.push((key.into(), value.into())); + self + } +} + +impl From for Step { + fn from(value: GitHubScriptStep) -> Self { + let mut step = Step::new(value.name) + .uses("actions", "github-script", GITHUB_SCRIPT_SHA) + .add_with(("script", value.script)) + .when_some(value.result_encoding, |step, encoding| { + step.add_with(("result-encoding", encoding.as_str())) + }) + .when_some(value.token, |step, token| { + step.add_with(("github-token", token)) + }) + .when_some(value.id, |step, id| step.id(id)); + for (key, val) in value.env { + step = step.add_env((key, val)); + } + step + } +} + +impl FluentBuilder for GitHubScriptStep {} + +pub fn github_script(script: impl Into) -> GitHubScriptStep { + GitHubScriptStep { + name: function_name(1), + script: script.into(), + ..Default::default() + } +} + +pub(crate) enum IfNoFilesFound { + #[allow(unused)] + Warn, + Error, + Ignore, +} + +impl IfNoFilesFound { + fn as_str(&self) -> &'static str { + match self { + IfNoFilesFound::Warn => "warn", + IfNoFilesFound::Error => "error", + IfNoFilesFound::Ignore => "ignore", + } + } +} + +#[derive(Default)] +pub(crate) struct UploadArtifactStep { + name: String, + artifact_name: String, + path: String, + if_no_files_found: Option, + retention_days: Option, + if_condition: Option, + overwrite: bool, +} + +impl UploadArtifactStep { + pub fn if_no_files_found(mut self, behavior: IfNoFilesFound) -> Self { + self.if_no_files_found = Some(behavior); + self + } + + pub fn retention_days(mut self, days: u32) -> Self { + self.retention_days = Some(days); + self + } + + pub fn if_condition(mut self, condition: Expression) -> Self { + self.if_condition = Some(condition); + self + } + + pub fn overwrite(mut self, overwrite: bool) -> Self { + self.overwrite = overwrite; + self + } +} + +impl From for Step { + fn from(value: UploadArtifactStep) -> Self { + Step::new(value.name) + .uses("actions", "upload-artifact", UPLOAD_ARTIFACT_SHA) + .add_with(("name", value.artifact_name)) + .add_with(("path", value.path)) + .when_some(value.if_no_files_found, |step, behavior| { + step.add_with(("if-no-files-found", behavior.as_str())) + }) + .when_some(value.retention_days, |step, days| { + step.add_with(("retention-days", days.to_string())) + }) + .when_some(value.if_condition, |step, condition| { + step.if_condition(condition) + }) + .when(value.overwrite, |step| step.add_with(("overwrite", true))) + } +} + +impl FluentBuilder for UploadArtifactStep {} + +pub fn upload_artifact( + artifact_name: impl Into, + path: impl Into, +) -> UploadArtifactStep { + UploadArtifactStep { + name: function_name(1), + artifact_name: artifact_name.into(), + path: path.into(), + ..Default::default() + } +} + +#[derive(Default)] +pub(crate) struct DownloadArtifactStep { + name: String, + artifact_name: Option, + path: Option, +} + +impl DownloadArtifactStep { + pub fn artifact_name(mut self, artifact_name: impl Into) -> Self { + self.artifact_name = Some(artifact_name.into()); + self + } + + pub fn path(mut self, path: &str) -> Self { + self.path = Some(path.to_string()); + self + } +} + +impl From for Step { + fn from(value: DownloadArtifactStep) -> Self { + Step::new(value.name) + .uses("actions", "download-artifact", DOWNLOAD_ARTIFACT_SHA) + .when_some(value.artifact_name, |step, artifact_name| { + step.add_with(("name", artifact_name)) + }) + .when_some(value.path, |step, path| step.add_with(("path", path))) + } +} + +impl FluentBuilder for DownloadArtifactStep {} + +pub fn download_artifact() -> DownloadArtifactStep { + DownloadArtifactStep { + name: function_name(1), + ..Default::default() + } +} + pub fn git_checkout(ref_name: &dyn std::fmt::Display) -> Step { named::bash(r#"git fetch origin "$REF_NAME" && git checkout "$REF_NAME""#) .add_env(("REF_NAME", ref_name.to_string())) @@ -742,19 +949,29 @@ impl GitRef { } } -#[allow(unused)] enum RefOperation { Create, Update { force: bool }, } +pub(crate) enum RefSha { + Context, + Custom(String), +} + struct RefOp { git_ref: GitRef, operation: RefOperation, - sha: String, + sha: RefSha, token: String, } +impl From for RefSha { + fn from(sha: T) -> Self { + RefSha::Custom(sha.to_string()) + } +} + impl From for Step { fn from(op: RefOp) -> Self { let (api_method, ref_path, force_line) = match &op.operation { @@ -769,38 +986,35 @@ impl From for Step { RefOperation::Create => format!("steps::create_{}", op.git_ref.kind()), RefOperation::Update { .. } => format!("steps::update_{}", op.git_ref.kind()), }; - let sha = &op.sha; let script = indoc::formatdoc! {r#" github.rest.git.{api_method}({{ owner: context.repo.owner, repo: context.repo.repo, ref: '{ref_path}', - sha: '{sha}'{force_line} + sha: {sha}{force_line} }}) - "#}; - Step::new(step_name) - .uses( - "actions", - "github-script", - "f28e40c7f34bde8b3046d885e986cb6290c5673b", // v7 - ) - .with( - Input::default() - .add("script", script) - .add("github-token", op.token), - ) + "#, + sha = match &op.sha { + RefSha::Context => "context.sha".to_string(), + RefSha::Custom(sha) => format!("'{sha}'"), + } + }; + github_script(script) + .custom_name(&step_name) + .token(op.token) + .into() } } pub(crate) fn create_ref( git_ref: GitRef, - sha: impl ToString, + sha: impl Into, token: &StepOutput, ) -> impl Into> { RefOp { git_ref, operation: RefOperation::Create, - sha: sha.to_string(), + sha: sha.into(), token: token.to_string(), } } @@ -815,7 +1029,7 @@ pub(crate) fn update_ref( RefOp { git_ref, operation: RefOperation::Update { force }, - sha: sha.to_string(), + sha: sha.into(), token: token.to_string(), } }