diff --git a/.github/actions/run_tests/action.yml b/.github/actions/run_tests/action.yml index 9448dfebb0..49022915ee 100644 --- a/.github/actions/run_tests/action.yml +++ b/.github/actions/run_tests/action.yml @@ -5,7 +5,9 @@ runs: using: "composite" steps: - name: Install nextest - uses: taiki-e/install-action@921e2c9f7148d7ba14cd819f417db338f63e733c # nextest + uses: taiki-e/install-action@a6b2e2dcd845ddd7f509ce4f3ed3d922b80cc5d9 # 2.84.0 + with: + tool: nextest - name: Install Node uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 diff --git a/.github/actions/run_tests_windows/action.yml b/.github/actions/run_tests_windows/action.yml index 3752cbb50d..d1a5219144 100644 --- a/.github/actions/run_tests_windows/action.yml +++ b/.github/actions/run_tests_windows/action.yml @@ -12,7 +12,9 @@ runs: steps: - name: Install test runner working-directory: ${{ inputs.working-directory }} - uses: taiki-e/install-action@921e2c9f7148d7ba14cd819f417db338f63e733c # nextest + uses: taiki-e/install-action@a6b2e2dcd845ddd7f509ce4f3ed3d922b80cc5d9 # 2.84.0 + with: + tool: nextest - name: Install Node uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 diff --git a/.github/workflows/add_commented_closed_issue_to_project.yml b/.github/workflows/add_commented_closed_issue_to_project.yml index 27315e7160..47877b6b11 100644 --- a/.github/workflows/add_commented_closed_issue_to_project.yml +++ b/.github/workflows/add_commented_closed_issue_to_project.yml @@ -40,6 +40,9 @@ jobs: app-id: ${{ secrets.ZED_COMMUNITY_BOT_APP_ID }} private-key: ${{ secrets.ZED_COMMUNITY_BOT_PRIVATE_KEY }} owner: zed-industries + repositories: zed + permission-members: read + permission-organization-projects: write - if: steps.is-post-close-comment.outputs.result == 'true' id: check-staff diff --git a/.github/workflows/autofix_pr.yml b/.github/workflows/autofix_pr.yml index 2e7c6e8a39..1b05da6085 100644 --- a/.github/workflows/autofix_pr.yml +++ b/.github/workflows/autofix_pr.yml @@ -53,7 +53,7 @@ jobs: version: '9' - name: autofix_pr::run_autofix::install_cargo_machete if: ${{ inputs.run_clippy }} - uses: taiki-e/install-action@02cc5f8ca9f2301050c0c099055816a41ee05507 + uses: taiki-e/install-action@a6b2e2dcd845ddd7f509ce4f3ed3d922b80cc5d9 with: tool: cargo-machete@0.7.0 - name: autofix_pr::run_autofix::run_cargo_fix @@ -104,6 +104,8 @@ jobs: with: app-id: ${{ secrets.ZED_ZIPPY_APP_ID }} private-key: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + repositories: ${{ github.event.repository.name }} permission-contents: write permission-workflows: write - name: steps::checkout_repo diff --git a/.github/workflows/bump_patch_version.yml b/.github/workflows/bump_patch_version.yml index 7be909c907..eef26b5f6f 100644 --- a/.github/workflows/bump_patch_version.yml +++ b/.github/workflows/bump_patch_version.yml @@ -23,6 +23,9 @@ jobs: with: app-id: ${{ secrets.ZED_ZIPPY_APP_ID }} private-key: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + repositories: ${{ github.event.repository.name }} + permission-contents: write - name: steps::checkout_repo uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd with: @@ -55,7 +58,7 @@ jobs: echo "tag_suffix=$tag_suffix" } >> "$GITHUB_OUTPUT" - name: steps::install_cargo_edit - uses: taiki-e/install-action@02cc5f8ca9f2301050c0c099055816a41ee05507 + uses: taiki-e/install-action@a6b2e2dcd845ddd7f509ce4f3ed3d922b80cc5d9 with: tool: cargo-edit - id: bump-version diff --git a/.github/workflows/bump_zed_version.yml b/.github/workflows/bump_zed_version.yml index 07b17aca32..ee007db74d 100644 --- a/.github/workflows/bump_zed_version.yml +++ b/.github/workflows/bump_zed_version.yml @@ -21,6 +21,9 @@ jobs: with: app-id: ${{ secrets.ZED_ZIPPY_APP_ID }} private-key: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + repositories: ${{ github.event.repository.name }} + permission-contents: read - name: steps::checkout_repo uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd with: @@ -98,6 +101,10 @@ jobs: with: app-id: ${{ secrets.ZED_ZIPPY_APP_ID }} private-key: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + repositories: ${{ github.event.repository.name }} + permission-contents: write + permission-pull-requests: write - name: steps::checkout_repo uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd with: @@ -105,7 +112,7 @@ jobs: ref: main token: ${{ steps.generate-token.outputs.token }} - name: steps::install_cargo_edit - uses: taiki-e/install-action@02cc5f8ca9f2301050c0c099055816a41ee05507 + uses: taiki-e/install-action@a6b2e2dcd845ddd7f509ce4f3ed3d922b80cc5d9 with: tool: cargo-edit - name: bump_zed_version::bump_main::bump_version @@ -141,6 +148,9 @@ jobs: with: app-id: ${{ secrets.ZED_ZIPPY_APP_ID }} private-key: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + repositories: ${{ github.event.repository.name }} + permission-contents: write - name: steps::checkout_repo uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd with: @@ -196,6 +206,9 @@ jobs: with: app-id: ${{ secrets.ZED_ZIPPY_APP_ID }} private-key: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + repositories: ${{ github.event.repository.name }} + permission-contents: write - name: steps::checkout_repo uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd with: diff --git a/.github/workflows/catch_blank_issues.yml b/.github/workflows/catch_blank_issues.yml index dbceac5a19..15a61a50cf 100644 --- a/.github/workflows/catch_blank_issues.yml +++ b/.github/workflows/catch_blank_issues.yml @@ -21,6 +21,9 @@ jobs: app-id: ${{ secrets.ZED_COMMUNITY_BOT_APP_ID }} private-key: ${{ secrets.ZED_COMMUNITY_BOT_PRIVATE_KEY }} owner: zed-industries + repositories: zed + permission-members: read + permission-issues: write - id: check-staff uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 diff --git a/.github/workflows/cherry_pick.yml b/.github/workflows/cherry_pick.yml index 48474ac0bd..4ff5b9bcf8 100644 --- a/.github/workflows/cherry_pick.yml +++ b/.github/workflows/cherry_pick.yml @@ -33,6 +33,8 @@ jobs: with: app-id: ${{ secrets.ZED_ZIPPY_APP_ID }} private-key: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + repositories: ${{ github.event.repository.name }} permission-contents: write permission-workflows: write permission-pull-requests: write diff --git a/.github/workflows/comment_on_potential_duplicate_issues.yml b/.github/workflows/comment_on_potential_duplicate_issues.yml index c6e79bff84..498aafb434 100644 --- a/.github/workflows/comment_on_potential_duplicate_issues.yml +++ b/.github/workflows/comment_on_potential_duplicate_issues.yml @@ -41,6 +41,8 @@ jobs: app-id: ${{ secrets.ZED_COMMUNITY_BOT_APP_ID }} private-key: ${{ secrets.ZED_COMMUNITY_BOT_PRIVATE_KEY }} owner: zed-industries + repositories: zed + permission-issues: write - name: Set up Python uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 diff --git a/.github/workflows/community_pr_board.yml b/.github/workflows/community_pr_board.yml index d155cf8275..16d4a4f8f7 100644 --- a/.github/workflows/community_pr_board.yml +++ b/.github/workflows/community_pr_board.yml @@ -12,6 +12,9 @@ name: Community PR Board on: + # zizmor: ignore[dangerous-triggers] + # Fork PRs must be supported, but this workflow only reads event metadata and + # checks out scripts from the trusted default branch; it never executes PR code. pull_request_target: types: [labeled, unlabeled, assigned, review_requested, edited] issue_comment: @@ -50,6 +53,10 @@ jobs: app-id: ${{ secrets.ZED_COMMUNITY_BOT_APP_ID }} private-key: ${{ secrets.ZED_COMMUNITY_BOT_PRIVATE_KEY }} owner: zed-industries + repositories: zed + permission-issues: read + permission-organization-projects: write + permission-pull-requests: read - name: Checkout repository uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 diff --git a/.github/workflows/community_pr_board_refresh.yml b/.github/workflows/community_pr_board_refresh.yml index 1d77638c82..f4b0c293cf 100644 --- a/.github/workflows/community_pr_board_refresh.yml +++ b/.github/workflows/community_pr_board_refresh.yml @@ -32,6 +32,10 @@ jobs: app-id: ${{ secrets.ZED_COMMUNITY_BOT_APP_ID }} private-key: ${{ secrets.ZED_COMMUNITY_BOT_PRIVATE_KEY }} owner: zed-industries + repositories: zed + permission-issues: read + permission-organization-projects: write + permission-pull-requests: read - name: Checkout repository uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml index 0ec9b51f1b..22ffdc6f34 100644 --- a/.github/workflows/danger.yml +++ b/.github/workflows/danger.yml @@ -31,6 +31,7 @@ jobs: with: node-version: '24' check-latest: true + package-manager-cache: false cache: pnpm cache-dependency-path: script/danger/pnpm-lock.yaml - name: danger::danger_job::install_deps diff --git a/.github/workflows/deploy_collab.yml b/.github/workflows/deploy_collab.yml index b40c55afb1..c9624eaa65 100644 --- a/.github/workflows/deploy_collab.yml +++ b/.github/workflows/deploy_collab.yml @@ -68,7 +68,9 @@ jobs: - name: steps::download_wasi_sdk run: ./script/download-wasi-sdk - name: steps::cargo_install_nextest - uses: taiki-e/install-action@921e2c9f7148d7ba14cd819f417db338f63e733c + uses: taiki-e/install-action@a6b2e2dcd845ddd7f509ce4f3ed3d922b80cc5d9 + with: + tool: nextest - name: steps::clear_target_dir_if_large run: ./script/clear-target-dir-if-larger-than 350 200 - name: deploy_collab::tests::run_collab_tests diff --git a/.github/workflows/docs_suggestions.yml b/.github/workflows/docs_suggestions.yml index f0405af5e9..1509e79ad9 100644 --- a/.github/workflows/docs_suggestions.yml +++ b/.github/workflows/docs_suggestions.yml @@ -9,32 +9,25 @@ name: Documentation Suggestions # 5. Keep this workflow focused on suggestions only until that stable workflow is added. on: - # Run when PRs are merged to main + # Analyze merged PRs on main and cherry-picks to release branches. Each job + # further restricts the event actions and target branch that it handles. pull_request: - types: [closed] - branches: [main] - paths: - - 'crates/**/*.rs' - - '!crates/**/*_test.rs' - - '!crates/**/tests/**' - - # Run on cherry-picks to release branches - pull_request_target: - types: [opened, synchronize] + types: [closed, opened, synchronize] branches: - - 'v0.*' + - main + - "v0.*" paths: - - 'crates/**/*.rs' + - "crates/**/*.rs" # Manual trigger for testing workflow_dispatch: inputs: pr_number: - description: 'PR number to analyze' + description: "PR number to analyze" required: true type: string mode: - description: 'Output mode' + description: "Output mode" required: true type: choice options: @@ -89,7 +82,6 @@ jobs: fi sleep $((i * 5)) done - echo "${HOME}/.local/bin" >> "$GITHUB_PATH" env: FACTORY_API_KEY: ${{ secrets.FACTORY_API_KEY }} @@ -125,6 +117,8 @@ jobs: FACTORY_API_KEY: ${{ secrets.FACTORY_API_KEY }} PR_NUMBER: ${{ steps.pr.outputs.number }} run: | + export PATH="${HOME}/.local/bin:${PATH}" + # Ensure gh CLI is authenticated (GH_TOKEN may not be auto-detected) # Unset GH_TOKEN first to allow gh auth login to store credentials echo "$GH_TOKEN" | (unset GH_TOKEN && gh auth login --with-token) @@ -292,8 +286,10 @@ jobs: group: docs-suggestions-${{ github.event.pull_request.number || inputs.pr_number || 'manual' }} cancel-in-progress: true if: | - (github.event_name == 'pull_request_target' && + (github.event_name == 'pull_request' && + contains(fromJSON('["opened","synchronize"]'), github.event.action) && startsWith(github.event.pull_request.base.ref, 'v0.') && + github.event.pull_request.head.repo.full_name == github.repository && contains(fromJSON('["MEMBER","OWNER"]'), github.event.pull_request.author_association)) || (github.event_name == 'workflow_dispatch' && inputs.mode == 'immediate') @@ -303,7 +299,7 @@ jobs: uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: fetch-depth: 0 - ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.base.ref || '' }} + ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.ref || '' }} persist-credentials: false - name: Install Droid CLI @@ -322,7 +318,6 @@ jobs: fi sleep $((i * 5)) done - echo "${HOME}/.local/bin" >> "$GITHUB_PATH" env: FACTORY_API_KEY: ${{ secrets.FACTORY_API_KEY }} @@ -350,6 +345,8 @@ jobs: FACTORY_API_KEY: ${{ secrets.FACTORY_API_KEY }} PR_NUMBER: ${{ steps.pr.outputs.number }} run: | + export PATH="${HOME}/.local/bin:${PATH}" + # Ensure gh CLI is authenticated (GH_TOKEN may not be auto-detected) # Unset GH_TOKEN first to allow gh auth login to store credentials echo "$GH_TOKEN" | (unset GH_TOKEN && gh auth login --with-token) diff --git a/.github/workflows/extension_bump.yml b/.github/workflows/extension_bump.yml index 494a97b097..0b611bfdaf 100644 --- a/.github/workflows/extension_bump.yml +++ b/.github/workflows/extension_bump.yml @@ -81,6 +81,10 @@ jobs: with: app-id: ${{ secrets.app-id }} private-key: ${{ secrets.app-secret }} + owner: ${{ github.repository_owner }} + repositories: ${{ github.event.repository.name }} + permission-contents: write + permission-pull-requests: write - name: steps::checkout_repo uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd with: @@ -170,6 +174,9 @@ jobs: with: app-id: ${{ secrets.app-id }} private-key: ${{ secrets.app-secret }} + owner: ${{ github.repository_owner }} + repositories: ${{ github.event.repository.name }} + permission-contents: write - name: steps::checkout_repo uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd with: @@ -222,6 +229,10 @@ jobs: private-key: ${{ secrets.app-secret }} owner: zed-industries repositories: extensions + permission-contents: write + permission-issues: write + permission-members: read + permission-pull-requests: write - name: steps::checkout_repo uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd with: diff --git a/.github/workflows/extension_tests.yml b/.github/workflows/extension_tests.yml index 9a6f223f38..885ef12b3d 100644 --- a/.github/workflows/extension_tests.yml +++ b/.github/workflows/extension_tests.yml @@ -99,7 +99,9 @@ jobs: env: PACKAGE_NAME: ${{ steps.get-package-name.outputs.package_name }} - name: steps::cargo_install_nextest - uses: taiki-e/install-action@921e2c9f7148d7ba14cd819f417db338f63e733c + uses: taiki-e/install-action@a6b2e2dcd845ddd7f509ce4f3ed3d922b80cc5d9 + with: + tool: nextest - name: extension_tests::run_nextest run: 'cargo nextest run -p "$PACKAGE_NAME" --no-fail-fast --no-tests=warn --target "$(rustc -vV | sed -n ''s|host: ||p'')"' env: diff --git a/.github/workflows/extension_workflow_rollout.yml b/.github/workflows/extension_workflow_rollout.yml index d1a47870e6..a295c20ddb 100644 --- a/.github/workflows/extension_workflow_rollout.yml +++ b/.github/workflows/extension_workflow_rollout.yml @@ -72,7 +72,7 @@ jobs: .filter(repo => !repo.archived) .map(repo => repo.name); - const filterInput = `${{ inputs.filter-repos }}`.trim(); + const filterInput = process.env.FILTER_REPOS.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)); @@ -82,6 +82,8 @@ jobs: console.log(`Found ${filteredRepos.length} extension repos`); return filteredRepos; result-encoding: json + env: + FILTER_REPOS: ${{ inputs.filter-repos }} - name: steps::cache_rust_dependencies_namespace uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 with: @@ -215,6 +217,8 @@ jobs: with: app-id: ${{ secrets.ZED_ZIPPY_APP_ID }} private-key: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + repositories: ${{ github.event.repository.name }} permission-contents: write - name: steps::checkout_repo uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd diff --git a/.github/workflows/guild_assignment_status.yml b/.github/workflows/guild_assignment_status.yml index 77f03168c4..c91c05bb54 100644 --- a/.github/workflows/guild_assignment_status.yml +++ b/.github/workflows/guild_assignment_status.yml @@ -34,6 +34,11 @@ jobs: app-id: ${{ secrets.ZED_COMMUNITY_BOT_APP_ID }} private-key: ${{ secrets.ZED_COMMUNITY_BOT_PRIVATE_KEY }} owner: zed-industries + repositories: zed + permission-issues: write + permission-members: read + permission-organization-projects: write + permission-pull-requests: read - name: Checkout repository uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 diff --git a/.github/workflows/guild_new_pr_notify.yml b/.github/workflows/guild_new_pr_notify.yml index afa9b07d87..52b4107bb2 100644 --- a/.github/workflows/guild_new_pr_notify.yml +++ b/.github/workflows/guild_new_pr_notify.yml @@ -7,6 +7,9 @@ name: Guild New PR Notification on: + # zizmor: ignore[dangerous-triggers] + # Fork PRs must be supported, but this workflow only reads event metadata and + # checks out scripts from the trusted default branch; it never executes PR code. pull_request_target: types: [opened] @@ -31,6 +34,11 @@ jobs: app-id: ${{ secrets.ZED_COMMUNITY_BOT_APP_ID }} private-key: ${{ secrets.ZED_COMMUNITY_BOT_PRIVATE_KEY }} owner: zed-industries + repositories: zed + permission-issues: write + permission-members: read + permission-organization-projects: write + permission-pull-requests: read - name: Checkout repository uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 diff --git a/.github/workflows/guild_stale_assignments.yml b/.github/workflows/guild_stale_assignments.yml index 90b47988c3..81a7f0c0ff 100644 --- a/.github/workflows/guild_stale_assignments.yml +++ b/.github/workflows/guild_stale_assignments.yml @@ -32,6 +32,11 @@ jobs: app-id: ${{ secrets.ZED_COMMUNITY_BOT_APP_ID }} private-key: ${{ secrets.ZED_COMMUNITY_BOT_PRIVATE_KEY }} owner: zed-industries + repositories: zed + permission-issues: write + permission-members: read + permission-organization-projects: write + permission-pull-requests: read - name: Checkout repository uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 diff --git a/.github/workflows/guild_weekly_shipped.yml b/.github/workflows/guild_weekly_shipped.yml index 9f2a7fb4c8..1f3bf71fea 100644 --- a/.github/workflows/guild_weekly_shipped.yml +++ b/.github/workflows/guild_weekly_shipped.yml @@ -30,6 +30,11 @@ jobs: app-id: ${{ secrets.ZED_COMMUNITY_BOT_APP_ID }} private-key: ${{ secrets.ZED_COMMUNITY_BOT_PRIVATE_KEY }} owner: zed-industries + repositories: zed + permission-issues: read + permission-members: read + permission-organization-projects: read + permission-pull-requests: read - name: Checkout repository uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 diff --git a/.github/workflows/pr_issue_labeler.yml b/.github/workflows/pr_issue_labeler.yml index 524d301aec..f783db10c1 100644 --- a/.github/workflows/pr_issue_labeler.yml +++ b/.github/workflows/pr_issue_labeler.yml @@ -12,6 +12,9 @@ name: PR Issue Labeler on: issues: types: [opened] + # zizmor: ignore[dangerous-triggers] + # Fork PRs must be labeled, but this workflow only passes GitHub-provided event + # metadata to a pinned action; it never checks out or executes PR code. pull_request_target: types: [opened] @@ -30,6 +33,10 @@ jobs: app-id: ${{ secrets.ZED_COMMUNITY_BOT_APP_ID }} private-key: ${{ secrets.ZED_COMMUNITY_BOT_PRIVATE_KEY }} owner: zed-industries + repositories: zed + permission-issues: write + permission-members: read + permission-pull-requests: read - id: apply-authorship-label uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 diff --git a/.github/workflows/publish_extension_cli.yml b/.github/workflows/publish_extension_cli.yml index bee3c7c21f..6f14092a66 100644 --- a/.github/workflows/publish_extension_cli.yml +++ b/.github/workflows/publish_extension_cli.yml @@ -42,6 +42,8 @@ jobs: with: app-id: ${{ secrets.ZED_ZIPPY_APP_ID }} private-key: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + repositories: ${{ github.event.repository.name }} permission-contents: write - name: steps::update_tag uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b @@ -67,6 +69,11 @@ jobs: with: app-id: ${{ secrets.ZED_ZIPPY_APP_ID }} private-key: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + repositories: ${{ github.event.repository.name }} + permission-contents: write + permission-pull-requests: write + permission-workflows: write - name: steps::checkout_repo uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd with: @@ -121,6 +128,9 @@ jobs: private-key: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }} owner: zed-industries repositories: extensions + permission-contents: write + permission-pull-requests: write + permission-workflows: write - id: short-sha name: publish_extension_cli::get_short_sha run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5a3808e063..0e59362fdd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,8 +33,11 @@ jobs: with: node-version: '24' check-latest: true + package-manager-cache: false - name: steps::cargo_install_nextest - uses: taiki-e/install-action@921e2c9f7148d7ba14cd819f417db338f63e733c + uses: taiki-e/install-action@a6b2e2dcd845ddd7f509ce4f3ed3d922b80cc5d9 + with: + tool: nextest - name: steps::clear_target_dir_if_large run: ./script/clear-target-dir-if-larger-than 350 200 - name: steps::setup_sccache @@ -82,8 +85,11 @@ jobs: with: node-version: '24' check-latest: true + package-manager-cache: false - name: steps::cargo_install_nextest - uses: taiki-e/install-action@921e2c9f7148d7ba14cd819f417db338f63e733c + uses: taiki-e/install-action@a6b2e2dcd845ddd7f509ce4f3ed3d922b80cc5d9 + with: + tool: nextest - name: steps::clear_target_dir_if_large run: ./script/clear-target-dir-if-larger-than 350 200 - name: steps::setup_sccache @@ -128,6 +134,7 @@ jobs: with: node-version: '24' check-latest: true + package-manager-cache: false - name: steps::clear_target_dir_if_large run: ./script/clear-target-dir-if-larger-than.ps1 350 200 shell: pwsh @@ -254,13 +261,6 @@ jobs: clean: false - name: run_tests::check_scripts::run_shellcheck run: ./script/shellcheck-scripts error - - id: get_actionlint - name: run_tests::check_scripts::download_actionlint - run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) - - name: run_tests::check_scripts::run_actionlint - run: '"$ACTIONLINT_BIN" -color' - env: - ACTIONLINT_BIN: ${{ steps.get_actionlint.outputs.executable }} - name: steps::cache_rust_dependencies_namespace uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 with: @@ -274,6 +274,19 @@ jobs: echo "Please run 'cargo xtask workflows' locally and commit the changes" exit 1 fi + - id: get_actionlint + name: run_tests::check_scripts::download_actionlint + run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) + - name: run_tests::check_scripts::run_actionlint + run: '"$ACTIONLINT_BIN" -color' + env: + ACTIONLINT_BIN: ${{ steps.get_actionlint.outputs.executable }} + - name: run_tests::check_scripts::run_zizmor + uses: zizmorcore/zizmor-action@6599ee8b7a49aef6a770f63d261d214911a7ce02 + with: + advanced-security: false + min-severity: high + version: latest timeout-minutes: 60 create_draft_release: if: (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions') @@ -285,6 +298,8 @@ jobs: with: app-id: ${{ secrets.ZED_ZIPPY_APP_ID }} private-key: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + repositories: ${{ github.event.repository.name }} permission-contents: write - name: steps::checkout_repo uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd @@ -545,6 +560,7 @@ jobs: with: node-version: '24' check-latest: true + package-manager-cache: false - name: steps::setup_sentry uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b with: @@ -596,6 +612,7 @@ jobs: with: node-version: '24' check-latest: true + package-manager-cache: false - name: steps::setup_sentry uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b with: @@ -845,6 +862,9 @@ jobs: with: app-id: ${{ secrets.ZED_ZIPPY_APP_ID }} private-key: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + repositories: ${{ github.event.repository.name }} + permission-contents: write - name: steps::checkout_repo uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd with: diff --git a/.github/workflows/release_nightly.yml b/.github/workflows/release_nightly.yml index cf9f4728aa..75f5708fe1 100644 --- a/.github/workflows/release_nightly.yml +++ b/.github/workflows/release_nightly.yml @@ -64,8 +64,11 @@ jobs: with: node-version: '24' check-latest: true + package-manager-cache: false - name: steps::cargo_install_nextest - uses: taiki-e/install-action@921e2c9f7148d7ba14cd819f417db338f63e733c + uses: taiki-e/install-action@a6b2e2dcd845ddd7f509ce4f3ed3d922b80cc5d9 + with: + tool: nextest - name: steps::clear_target_dir_if_large run: ./script/clear-target-dir-if-larger-than 350 200 - name: steps::setup_sccache @@ -290,6 +293,7 @@ jobs: with: node-version: '24' check-latest: true + package-manager-cache: false - name: steps::setup_sentry uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b with: @@ -345,6 +349,7 @@ jobs: with: node-version: '24' check-latest: true + package-manager-cache: false - name: steps::setup_sentry uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b with: @@ -574,6 +579,8 @@ jobs: with: app-id: ${{ secrets.ZED_ZIPPY_APP_ID }} private-key: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + repositories: ${{ github.event.repository.name }} permission-contents: write - name: steps::checkout_repo uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd diff --git a/.github/workflows/run_bundling.yml b/.github/workflows/run_bundling.yml index 4299bac401..a16651db4b 100644 --- a/.github/workflows/run_bundling.yml +++ b/.github/workflows/run_bundling.yml @@ -197,6 +197,7 @@ jobs: with: node-version: '24' check-latest: true + package-manager-cache: false - name: steps::setup_sentry uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b with: @@ -247,6 +248,7 @@ jobs: with: node-version: '24' check-latest: true + package-manager-cache: false - name: steps::setup_sentry uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b with: diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 0841b4c748..ebe8b57714 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -344,6 +344,7 @@ jobs: with: node-version: '24' check-latest: true + package-manager-cache: false - name: steps::clear_target_dir_if_large run: ./script/clear-target-dir-if-larger-than.ps1 350 200 shell: pwsh @@ -402,8 +403,11 @@ jobs: with: node-version: '24' check-latest: true + package-manager-cache: false - name: steps::cargo_install_nextest - uses: taiki-e/install-action@921e2c9f7148d7ba14cd819f417db338f63e733c + uses: taiki-e/install-action@a6b2e2dcd845ddd7f509ce4f3ed3d922b80cc5d9 + with: + tool: nextest - name: steps::clear_target_dir_if_large run: ./script/clear-target-dir-if-larger-than 350 200 - name: steps::setup_sccache @@ -454,8 +458,11 @@ jobs: with: node-version: '24' check-latest: true + package-manager-cache: false - name: steps::cargo_install_nextest - uses: taiki-e/install-action@921e2c9f7148d7ba14cd819f417db338f63e733c + uses: taiki-e/install-action@a6b2e2dcd845ddd7f509ce4f3ed3d922b80cc5d9 + with: + tool: nextest - name: steps::clear_target_dir_if_large run: ./script/clear-target-dir-if-larger-than 350 200 - name: steps::setup_sccache @@ -694,7 +701,7 @@ jobs: cache: rust path: ~/.rustup - name: run_tests::check_dependencies::install_cargo_machete - uses: taiki-e/install-action@02cc5f8ca9f2301050c0c099055816a41ee05507 + uses: taiki-e/install-action@a6b2e2dcd845ddd7f509ce4f3ed3d922b80cc5d9 with: tool: cargo-machete@0.7.0 - name: run_tests::check_dependencies::run_cargo_machete @@ -804,13 +811,6 @@ jobs: clean: false - name: run_tests::check_scripts::run_shellcheck run: ./script/shellcheck-scripts error - - id: get_actionlint - name: run_tests::check_scripts::download_actionlint - run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) - - name: run_tests::check_scripts::run_actionlint - run: '"$ACTIONLINT_BIN" -color' - env: - ACTIONLINT_BIN: ${{ steps.get_actionlint.outputs.executable }} - name: steps::cache_rust_dependencies_namespace uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 with: @@ -824,6 +824,19 @@ jobs: echo "Please run 'cargo xtask workflows' locally and commit the changes" exit 1 fi + - id: get_actionlint + name: run_tests::check_scripts::download_actionlint + run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) + - name: run_tests::check_scripts::run_actionlint + run: '"$ACTIONLINT_BIN" -color' + env: + ACTIONLINT_BIN: ${{ steps.get_actionlint.outputs.executable }} + - name: run_tests::check_scripts::run_zizmor + uses: zizmorcore/zizmor-action@6599ee8b7a49aef6a770f63d261d214911a7ce02 + with: + advanced-security: false + min-severity: high + version: latest timeout-minutes: 60 check_postgres_and_protobuf_migrations: needs: diff --git a/.github/workflows/slack_notify_community_automation_failure.yml b/.github/workflows/slack_notify_community_automation_failure.yml index d02b3b23c2..71e490cd02 100644 --- a/.github/workflows/slack_notify_community_automation_failure.yml +++ b/.github/workflows/slack_notify_community_automation_failure.yml @@ -5,6 +5,9 @@ name: Notify Slack on community automation failure on: + # zizmor: ignore[dangerous-triggers] + # The job validates that the completed run came from this repository, was + # started by an expected event, and failed before exposing the Slack secret. workflow_run: workflows: - "Comment on potential duplicate bug/crash reports" @@ -24,7 +27,9 @@ permissions: jobs: notify-slack: if: >- - github.repository_owner == 'zed-industries' + github.repository == 'zed-industries/zed' + && github.event.workflow_run.head_repository.full_name == github.repository + && contains(fromJSON('["issues","issue_comment","pull_request","pull_request_target","schedule","workflow_dispatch"]'), github.event.workflow_run.event) && github.event.workflow_run.conclusion == 'failure' runs-on: namespace-profile-2x4-ubuntu-2404 diff --git a/.github/workflows/track_duplicate_bot_effectiveness.yml b/.github/workflows/track_duplicate_bot_effectiveness.yml index bdcf8a5f40..b72f08d47e 100644 --- a/.github/workflows/track_duplicate_bot_effectiveness.yml +++ b/.github/workflows/track_duplicate_bot_effectiveness.yml @@ -35,6 +35,9 @@ jobs: app-id: ${{ secrets.ZED_COMMUNITY_BOT_APP_ID }} private-key: ${{ secrets.ZED_COMMUNITY_BOT_PRIVATE_KEY }} owner: zed-industries + repositories: zed + permission-issues: read + permission-organization-projects: write - name: Set up Python uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 @@ -74,6 +77,9 @@ jobs: app-id: ${{ secrets.ZED_COMMUNITY_BOT_APP_ID }} private-key: ${{ secrets.ZED_COMMUNITY_BOT_PRIVATE_KEY }} owner: zed-industries + repositories: zed + permission-issues: read + permission-organization-projects: write - name: Set up Python uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 diff --git a/.github/workflows/triage_project_sync.yml b/.github/workflows/triage_project_sync.yml index b652e0fb0a..9b8500db98 100644 --- a/.github/workflows/triage_project_sync.yml +++ b/.github/workflows/triage_project_sync.yml @@ -91,6 +91,7 @@ jobs: # mutations. Without `owner:`, the default token is repo-scoped and # cannot write to org projects. owner: zed-industries + repositories: zed # Scope the token down to the minimum needed for this workflow. # Even though the App may have broader permissions for other # automations (e.g., Issues:Write for the dupe-bot), this token diff --git a/.github/zizmor.yml b/.github/zizmor.yml new file mode 100644 index 0000000000..550e33a7cc --- /dev/null +++ b/.github/zizmor.yml @@ -0,0 +1 @@ +rules: {} diff --git a/tooling/xtask/src/tasks/workflows/bump_patch_version.rs b/tooling/xtask/src/tasks/workflows/bump_patch_version.rs index 6b9abab426..afad08d6a1 100644 --- a/tooling/xtask/src/tasks/workflows/bump_patch_version.rs +++ b/tooling/xtask/src/tasks/workflows/bump_patch_version.rs @@ -65,7 +65,10 @@ fn run_bump_patch_version(branch: &WorkflowInput) -> steps::NamedJob { .id("bump-version") } - let (authenticate, token) = steps::authenticate_as_zippy().into(); + let (authenticate, token) = steps::authenticate_as_zippy() + .for_repository(steps::RepositoryTarget::current()) + .with_permissions([(steps::TokenPermissions::Contents, Level::Write)]) + .into(); let channel_step = read_channel(); let tag_suffix = StepOutput::new(&channel_step, "tag_suffix"); let bump_version_step = bump_version(); diff --git a/tooling/xtask/src/tasks/workflows/bump_zed_version.rs b/tooling/xtask/src/tasks/workflows/bump_zed_version.rs index ccbbd19ee0..39635908ff 100644 --- a/tooling/xtask/src/tasks/workflows/bump_zed_version.rs +++ b/tooling/xtask/src/tasks/workflows/bump_zed_version.rs @@ -88,7 +88,10 @@ fn resolve_versions() -> (steps::NamedJob, ResolvedOutputs) { .id("versions") } - let (authenticate, token) = steps::authenticate_as_zippy().into(); + let (authenticate, token) = steps::authenticate_as_zippy() + .for_repository(steps::RepositoryTarget::current()) + .with_permissions([(steps::TokenPermissions::Contents, Level::Read)]) + .into(); let versions_step = extract_versions(); let next_version = StepOutput::new(&versions_step, "next_version"); let pr_branch = StepOutput::new(&versions_step, "pr_branch"); @@ -134,7 +137,13 @@ fn bump_main( named::bash("cargo set-version -p zed --bump minor") } - let (authenticate, token) = steps::authenticate_as_zippy().into(); + let (authenticate, token) = steps::authenticate_as_zippy() + .for_repository(steps::RepositoryTarget::current()) + .with_permissions([ + (steps::TokenPermissions::Contents, Level::Write), + (steps::TokenPermissions::PullRequests, Level::Write), + ]) + .into(); named::job( Job::default() @@ -175,7 +184,10 @@ fn create_preview_branch( named::bash("echo \"main_sha=$(git rev-parse HEAD)\" >> \"$GITHUB_OUTPUT\"").id("main-sha") } - let (authenticate, token) = steps::authenticate_as_zippy().into(); + let (authenticate, token) = steps::authenticate_as_zippy() + .for_repository(steps::RepositoryTarget::current()) + .with_permissions([(steps::TokenPermissions::Contents, Level::Write)]) + .into(); let main_sha_step = get_main_sha(); let main_sha = StepOutput::new(&main_sha_step, "main_sha"); @@ -225,7 +237,10 @@ fn promote_to_stable( versions_job: &steps::NamedJob, outputs: &ResolvedOutputs, ) -> steps::NamedJob { - let (authenticate, token) = steps::authenticate_as_zippy().into(); + let (authenticate, token) = steps::authenticate_as_zippy() + .for_repository(steps::RepositoryTarget::current()) + .with_permissions([(steps::TokenPermissions::Contents, Level::Write)]) + .into(); let read_version_step = named::bash(indoc::indoc! {r#" stable_version=$(script/get-crate-version zed) diff --git a/tooling/xtask/src/tasks/workflows/extension_bump.rs b/tooling/xtask/src/tasks/workflows/extension_bump.rs index 9f6f6462b6..7ec0245b1f 100644 --- a/tooling/xtask/src/tasks/workflows/extension_bump.rs +++ b/tooling/xtask/src/tasks/workflows/extension_bump.rs @@ -7,8 +7,8 @@ use crate::tasks::workflows::{ steps::{ self, BASH_SHELL, CommonJobConditions, CommonPermissionSets, DEFAULT_REPOSITORY_OWNER_GUARD, GitHubScriptStep, GitRef, NamedJob, RefSha, - RepositoryTarget, cache_rust_dependencies_namespace, checkout_repo, create_ref, - dependant_job, generate_token, named, + RepositoryTarget, TokenPermissions, cache_rust_dependencies_namespace, checkout_repo, + create_ref, dependant_job, generate_token, named, }, vars::{ JobOutput, StepOutput, WorkflowInput, WorkflowSecret, @@ -126,7 +126,10 @@ fn create_version_label( app_secret: &WorkflowSecret, ) -> (NamedJob, StepOutput) { let (generate_token, generated_token) = - generate_token(&app_id.to_string(), &app_secret.to_string()).into(); + generate_token(&app_id.to_string(), &app_secret.to_string()) + .for_repository(RepositoryTarget::current()) + .with_permissions([(TokenPermissions::Contents, Level::Write)]) + .into(); let (determine_tag_step, tag) = determine_tag(current_version); let job = steps::dependant_job(dependencies) .defaults(extension_job_defaults()) @@ -215,7 +218,13 @@ fn bump_extension_version( app_secret: &WorkflowSecret, ) -> NamedJob { let (generate_token, generated_token) = - generate_token(&app_id.to_string(), &app_secret.to_string()).into(); + generate_token(&app_id.to_string(), &app_secret.to_string()) + .for_repository(RepositoryTarget::current()) + .with_permissions([ + (TokenPermissions::Contents, Level::Write), + (TokenPermissions::PullRequests, Level::Write), + ]) + .into(); let (bump_version, _new_version, title, body, branch_name) = bump_version(current_version, bump_type); @@ -330,6 +339,12 @@ fn trigger_release( let (generate_token, generated_token) = generate_token(&app_id.to_string(), &app_secret.to_string()) .for_repository(extension_registry) + .with_permissions([ + (TokenPermissions::Contents, Level::Write), + (TokenPermissions::Issues, Level::Write), + (TokenPermissions::Members, Level::Read), + (TokenPermissions::PullRequests, Level::Write), + ]) .into(); let (get_extension_id, extension_id) = get_extension_id(); let (release_action, pull_request_number) = release_action(extension_id, tag, &generated_token); diff --git a/tooling/xtask/src/tasks/workflows/extension_workflow_rollout.rs b/tooling/xtask/src/tasks/workflows/extension_workflow_rollout.rs index 19e2c5e28d..ae3465af48 100644 --- a/tooling/xtask/src/tasks/workflows/extension_workflow_rollout.rs +++ b/tooling/xtask/src/tasks/workflows/extension_workflow_rollout.rs @@ -67,7 +67,7 @@ fn fetch_extension_repos(filter_repos_input: &WorkflowInput) -> (NamedJob, JobOu .filter(repo => !repo.archived) .map(repo => repo.name); - const filterInput = `{filter_repos_input}`.trim(); + const filterInput = process.env.FILTER_REPOS.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)); @@ -80,6 +80,7 @@ fn fetch_extension_repos(filter_repos_input: &WorkflowInput) -> (NamedJob, JobOu .result_encoding(ResultEncoding::Json) .custom_name("get_repositories") .id("list-repos") + .env("FILTER_REPOS", filter_repos_input.to_string()) .into(); let filtered_repos = StepOutput::new(&step, "result"); diff --git a/tooling/xtask/src/tasks/workflows/publish_extension_cli.rs b/tooling/xtask/src/tasks/workflows/publish_extension_cli.rs index d4843cbaf4..567e235dfe 100644 --- a/tooling/xtask/src/tasks/workflows/publish_extension_cli.rs +++ b/tooling/xtask/src/tasks/workflows/publish_extension_cli.rs @@ -86,7 +86,14 @@ fn publish_job() -> NamedJob { fn update_sha_in_zed(publish_job: &NamedJob, message: &WorkflowInput) -> NamedJob { let (generate_token, generated_token) = - generate_token(vars::ZED_ZIPPY_APP_ID, vars::ZED_ZIPPY_APP_PRIVATE_KEY).into(); + generate_token(vars::ZED_ZIPPY_APP_ID, vars::ZED_ZIPPY_APP_PRIVATE_KEY) + .for_repository(RepositoryTarget::current()) + .with_permissions([ + (TokenPermissions::Contents, Level::Write), + (TokenPermissions::PullRequests, Level::Write), + (TokenPermissions::Workflows, Level::Write), + ]) + .into(); fn replace_sha() -> Step { named::bash(indoc! {r#" @@ -150,6 +157,11 @@ fn update_sha_in_extensions(publish_job: &NamedJob, message: &WorkflowInput) -> let (generate_token, generated_token) = generate_token(vars::ZED_ZIPPY_APP_ID, vars::ZED_ZIPPY_APP_PRIVATE_KEY) .for_repository(extensions_repo) + .with_permissions([ + (TokenPermissions::Contents, Level::Write), + (TokenPermissions::PullRequests, Level::Write), + (TokenPermissions::Workflows, Level::Write), + ]) .into(); fn checkout_extensions_repo(token: &StepOutput) -> Step { diff --git a/tooling/xtask/src/tasks/workflows/release.rs b/tooling/xtask/src/tasks/workflows/release.rs index ba6bafb933..0b75268bc9 100644 --- a/tooling/xtask/src/tasks/workflows/release.rs +++ b/tooling/xtask/src/tasks/workflows/release.rs @@ -427,7 +427,10 @@ fn auto_release_preview(deps: &[&NamedJob]) -> (NamedJob, JobOutput) { .add_env(("GITHUB_TOKEN", token)) } - let (authenticate, token) = steps::authenticate_as_zippy().into(); + let (authenticate, token) = steps::authenticate_as_zippy() + .for_repository(steps::RepositoryTarget::current()) + .with_permissions([(steps::TokenPermissions::Contents, Level::Write)]) + .into(); let auto_release_preview_step = auto_release_preview(&token); let release_published = StepOutput::new(&auto_release_preview_step, "release_published"); @@ -498,6 +501,7 @@ fn create_draft_release() -> NamedJob { } let (authenticate_step, token) = steps::authenticate_as_zippy() + .for_repository(steps::RepositoryTarget::current()) .with_permissions([(TokenPermissions::Contents, Level::Write)]) .into(); diff --git a/tooling/xtask/src/tasks/workflows/run_tests.rs b/tooling/xtask/src/tasks/workflows/run_tests.rs index 2707034eee..d7fdf84fe5 100644 --- a/tooling/xtask/src/tasks/workflows/run_tests.rs +++ b/tooling/xtask/src/tasks/workflows/run_tests.rs @@ -801,6 +801,17 @@ pub(crate) fn check_scripts(harden: bool) -> NamedJob { named::bash("./script/shellcheck-scripts error") } + fn run_zizmor() -> Step { + named::uses( + "zizmorcore", + "zizmor-action", + "6599ee8b7a49aef6a770f63d261d214911a7ce02", // v0.6.0 + ) + .add_with(("advanced-security", false)) + .add_with(("min-severity", "high")) + .add_with(("version", "latest")) + } + fn check_xtask_workflows() -> Step { named::bash(indoc::indoc! {r#" cargo xtask workflows @@ -818,10 +829,11 @@ pub(crate) fn check_scripts(harden: bool) -> NamedJob { .when(harden, |this| this.add_step(steps::harden_runner())) .add_step(steps::checkout_repo()) .add_step(run_shellcheck()) + .add_step(cache_rust_dependencies_namespace()) + .add_step(check_xtask_workflows()) .add_step(download_actionlint().id("get_actionlint")) .add_step(run_actionlint()) - .add_step(cache_rust_dependencies_namespace()) - .add_step(check_xtask_workflows()), + .add_step(run_zizmor()), ) } diff --git a/tooling/xtask/src/tasks/workflows/steps.rs b/tooling/xtask/src/tasks/workflows/steps.rs index daf8cb0e40..754995d9cb 100644 --- a/tooling/xtask/src/tasks/workflows/steps.rs +++ b/tooling/xtask/src/tasks/workflows/steps.rs @@ -177,6 +177,7 @@ pub fn setup_node() -> Step { ) .add_with(("node-version", "24")) .add_with(("check-latest", true)) + .add_with(("package-manager-cache", false)) } pub fn setup_sentry() -> Step { @@ -205,17 +206,13 @@ pub fn taiki_install_action(tool: &str) -> Step { .uses( "taiki-e", "install-action", - "02cc5f8ca9f2301050c0c099055816a41ee05507", // v2 + "a6b2e2dcd845ddd7f509ce4f3ed3d922b80cc5d9", // v2.84.0 ) .add_with(("tool", tool)) } pub fn cargo_install_nextest() -> Step { - named::uses( - "taiki-e", - "install-action", - "921e2c9f7148d7ba14cd819f417db338f63e733c", // nextest - ) + taiki_install_action("nextest") } pub fn setup_cargo_config(platform: Platform) -> Step { @@ -784,6 +781,7 @@ pub fn download_artifact() -> DownloadArtifactStep { pub(crate) enum TokenPermissions { Contents, Issues, + Members, PullRequests, Workflows, } @@ -793,38 +791,70 @@ impl TokenPermissions { match self { TokenPermissions::Contents => "permission-contents", TokenPermissions::Issues => "permission-issues", + TokenPermissions::Members => "permission-members", TokenPermissions::PullRequests => "permission-pull-requests", TokenPermissions::Workflows => "permission-workflows", } } } -pub(crate) struct GenerateAppToken<'a> { +pub(crate) struct Unset; + +pub(crate) struct GenerateAppToken<'a, Target = Unset, Permissions = Unset> { job_name: String, app_id: &'a str, app_secret: &'a str, - repository_target: Option, - permissions: Option>, + repository_target: Target, + permissions: Permissions, } -impl<'a> GenerateAppToken<'a> { - pub fn for_repository(self, repository_target: RepositoryTarget) -> Self { - Self { - repository_target: Some(repository_target), - ..self - } - } - - pub fn with_permissions(self, permissions: impl Into>) -> Self { - Self { - permissions: Some(permissions.into()), - ..self +impl<'a, Permissions> GenerateAppToken<'a, Unset, Permissions> { + pub fn for_repository( + self, + repository_target: RepositoryTarget, + ) -> GenerateAppToken<'a, RepositoryTarget, Permissions> { + GenerateAppToken { + job_name: self.job_name, + app_id: self.app_id, + app_secret: self.app_secret, + repository_target, + permissions: self.permissions, } } } -impl<'a> From> for (Step, StepOutput) { - fn from(token: GenerateAppToken<'a>) -> Self { +impl<'a, Target> GenerateAppToken<'a, Target, Unset> { + pub fn with_permissions( + self, + permissions: impl Into>, + ) -> GenerateAppToken<'a, Target, Vec<(TokenPermissions, Level)>> { + GenerateAppToken { + job_name: self.job_name, + app_id: self.app_id, + app_secret: self.app_secret, + repository_target: self.repository_target, + permissions: permissions.into(), + } + } +} + +impl<'a> From>> + for (Step, StepOutput) +{ + fn from(token: GenerateAppToken<'a, RepositoryTarget, Vec<(TokenPermissions, Level)>>) -> Self { + let input = token.permissions.into_iter().fold( + Input::default() + .add("app-id", token.app_id) + .add("private-key", token.app_secret) + .add("owner", token.repository_target.owner) + .add("repositories", token.repository_target.repositories), + |input, (permission, level)| { + input.add( + permission.environment_name(), + serde_json::to_value(&level).unwrap_or_default(), + ) + }, + ); let step = Step::new(token.job_name) .uses( "actions", @@ -832,35 +862,7 @@ impl<'a> From> for (Step, StepOutput) { "f8d387b68d61c58ab83c6c016672934102569859", ) .id("generate-token") - .add_with( - Input::default() - .add("app-id", token.app_id) - .add("private-key", token.app_secret) - .when_some( - token.repository_target, - |input, - RepositoryTarget { - owner, - repositories, - }| { - input - .when_some(owner, |input, owner| input.add("owner", owner)) - .when_some(repositories, |input, repositories| { - input.add("repositories", repositories) - }) - }, - ) - .when_some(token.permissions, |input, permissions| { - permissions - .into_iter() - .fold(input, |input, (permission, level)| { - input.add( - permission.environment_name(), - serde_json::to_value(&level).unwrap_or_default(), - ) - }) - }), - ); + .add_with(input); let generated_token = StepOutput::new(&step, "token"); (step, generated_token) @@ -868,23 +870,23 @@ impl<'a> From> for (Step, StepOutput) { } pub(crate) struct RepositoryTarget { - owner: Option, - repositories: Option, + owner: String, + repositories: String, } impl RepositoryTarget { pub fn new(owner: T, repositories: &[&str]) -> Self { Self { - owner: Some(owner.to_string()), - repositories: Some(repositories.join("\n")), + owner: owner.to_string(), + repositories: repositories.join("\n"), } } pub fn current() -> Self { - Self { - owner: None, - repositories: None, - } + Self::new( + "${{ github.repository_owner }}", + &["${{ github.event.repository.name }}"], + ) } } @@ -907,8 +909,8 @@ fn generate_token_with_job_name<'a>( job_name: function_name(1), app_id: app_id_source, app_secret: app_secret_source, - repository_target: None, - permissions: None, + repository_target: Unset, + permissions: Unset, } }