diff --git a/.github/actions/codecov-report/action.yml b/.github/actions/codecov-report/action.yml index f0a31e2716..890d5a4059 100644 --- a/.github/actions/codecov-report/action.yml +++ b/.github/actions/codecov-report/action.yml @@ -21,29 +21,38 @@ runs: steps: - name: Download base commit SHA artifact if: ${{ github.event_name == 'pull_request' && inputs.php-version == '8.3' && inputs.dependencies == 'locked' }} - uses: dawidd6/action-download-artifact@v11 + uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21 with: workflow: test-suite.yml name: codecov-base-commit-sha-${{ inputs.base-branch }} search_artifacts: true - name: Read base commit SHA + id: base-commit if: ${{ github.event_name == 'pull_request' && inputs.php-version == '8.3' && inputs.dependencies == 'locked' }} shell: bash + env: + BASE_BRANCH: ${{ inputs.base-branch }} run: | - ARTIFACT_CONTENT=$(cat codecov-base-commit-sha-${{ inputs.base-branch }}.txt) - echo "codecov_base_commit_sha=$ARTIFACT_CONTENT" >> $GITHUB_ENV + artifact_content=$(cat "codecov-base-commit-sha-${BASE_BRANCH}.txt") + # The artifact crosses from an untrusted PR context, so never forward it unvalidated. + if [[ ! "$artifact_content" =~ ^[0-9a-f]{40}$ ]]; then + echo "Expected a 40-character commit SHA, got: '${artifact_content}'" >&2 + exit 1 + fi + echo "sha=$artifact_content" >> "$GITHUB_OUTPUT" - name: Upload test results (baseline) if: ${{ github.event_name == 'push' && !cancelled() && inputs.php-version == '8.3' && inputs.dependencies == 'locked' }} - uses: codecov/test-results-action@v1 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7 with: token: ${{ inputs.token }} directory: ./var/phpunit/logs + report_type: test_results - name: Upload code coverage (baseline) if: ${{ github.event_name == 'push' && !cancelled() && inputs.php-version == '8.3' && inputs.dependencies == 'locked' }} - uses: codecov/codecov-action@v6 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7 with: token: ${{ inputs.token }} directory: ./var/phpunit/coverage/clover @@ -51,45 +60,52 @@ runs: - name: Upload code coverage (pull request) if: ${{ github.event_name == 'pull_request' && !cancelled() && inputs.dependencies == 'locked' && inputs.php-version == '8.3' }} - uses: codecov/codecov-action@v6 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7 with: token: ${{ inputs.token }} directory: ./var/phpunit/coverage/clover - commit_parent: ${{ env.codecov_base_commit_sha }} + commit_parent: ${{ steps.base-commit.outputs.sha }} flags: tests - name: Upload test results (pull request) if: ${{ github.event_name == 'pull_request' && !cancelled() && inputs.dependencies == 'locked' }} - uses: codecov/test-results-action@v1 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7 with: token: ${{ inputs.token }} directory: ./var/phpunit/logs - commit_parent: ${{ env.codecov_base_commit_sha }} + commit_parent: ${{ steps.base-commit.outputs.sha }} + report_type: test_results - name: Get branch name and commit SHA + id: baseline if: ${{ github.event_name == 'push' && inputs.php-version == '8.3' && inputs.dependencies == 'locked' }} shell: bash run: | - branch_name=${GITHUB_REF#refs/heads/} - commit_sha=$(git rev-parse HEAD) - echo "codecov_branch_name=$branch_name" >> $GITHUB_ENV - echo "codecov_commit_sha=$commit_sha" >> $GITHUB_ENV + { + echo "branch_name=${GITHUB_REF#refs/heads/}" + echo "commit_sha=$(git rev-parse HEAD)" + } >> "$GITHUB_OUTPUT" - name: Save commit SHA to file if: ${{ github.event_name == 'push' && inputs.php-version == '8.3' && inputs.dependencies == 'locked' }} shell: bash - run: echo -n "${{ env.codecov_commit_sha }}" > codecov-base-commit-sha-${{ env.codecov_branch_name }}.txt + env: + COMMIT_SHA: ${{ steps.baseline.outputs.commit_sha }} + BRANCH_NAME: ${{ steps.baseline.outputs.branch_name }} + run: echo -n "$COMMIT_SHA" > "codecov-base-commit-sha-${BRANCH_NAME}.txt" - name: Upload commit SHA as artifact if: ${{ github.event_name == 'push' && inputs.php-version == '8.3' && inputs.dependencies == 'locked' }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: - name: codecov-base-commit-sha-${{ env.codecov_branch_name }} - path: codecov-base-commit-sha-${{ env.codecov_branch_name }}.txt + name: codecov-base-commit-sha-${{ steps.baseline.outputs.branch_name }} + path: codecov-base-commit-sha-${{ steps.baseline.outputs.branch_name }}.txt overwrite: true - name: Add SHA to step summary if: ${{ github.event_name == 'push' && inputs.php-version == '8.3' && inputs.dependencies == 'locked' }} shell: bash + env: + COMMIT_SHA: ${{ steps.baseline.outputs.commit_sha }} run: | - echo "Baseline commit SHA for Codecov: ${{ env.codecov_commit_sha }}" >> $GITHUB_STEP_SUMMARY + echo "Baseline commit SHA for Codecov: $COMMIT_SHA" >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/actions/composer-install/action.yml b/.github/actions/composer-install/action.yml index 1a67525831..595a2fcf45 100644 --- a/.github/actions/composer-install/action.yml +++ b/.github/actions/composer-install/action.yml @@ -32,7 +32,7 @@ runs: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - name: "Cache Composer dependencies" - uses: "actions/cache@v4" + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: "${{ steps.composer-cache.outputs.dir }}" key: "php-${{ inputs.php-version }}-${{ inputs.dependencies }}-composer${{ inputs.cache-key-suffix }}-${{ hashFiles(inputs.composer-file) }}" diff --git a/.github/actions/setup-php-env/action.yml b/.github/actions/setup-php-env/action.yml index 0f5452c080..66a63695b9 100644 --- a/.github/actions/setup-php-env/action.yml +++ b/.github/actions/setup-php-env/action.yml @@ -70,10 +70,13 @@ runs: - name: "Install apt packages" if: ${{ inputs.apt-packages != '' }} shell: bash - run: sudo apt-get update && sudo apt-get install -y ${{ inputs.apt-packages }} + env: + APT_PACKAGES: ${{ inputs.apt-packages }} + # Deliberately unquoted: apt-packages is a space-separated list that must word-split. + run: sudo apt-get update && sudo apt-get install -y $APT_PACKAGES - name: "Install PHP" - uses: "shivammathur/setup-php@v2" + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2 with: tools: ${{ inputs.tools }} php-version: ${{ inputs.php-version }} @@ -87,7 +90,7 @@ runs: env: ${{ inputs.php-env != '' && fromJSON(inputs.php-env) || fromJSON('{}') }} - name: "Install just" - uses: extractions/setup-just@v3 + uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 - name: "Install PIE" if: ${{ inputs.pie-extensions != '' }} @@ -100,8 +103,11 @@ runs: - name: "Install PIE extensions" if: ${{ inputs.pie-extensions != '' }} shell: bash + env: + PIE_EXTENSIONS: ${{ inputs.pie-extensions }} run: | - for ext in ${{ inputs.pie-extensions }}; do + # Deliberately unquoted: pie-extensions is a space-separated list that must word-split. + for ext in $PIE_EXTENSIONS; do echo "Installing extension: $ext" sudo pie install "$ext" done diff --git a/.github/workflows/job-arrow-extension.yml b/.github/workflows/job-arrow-extension.yml index 49897170e8..6d71aab7fd 100644 --- a/.github/workflows/job-arrow-extension.yml +++ b/.github/workflows/job-arrow-extension.yml @@ -37,7 +37,7 @@ jobs: toolchain: stable - name: Cache cargo registry and build - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v5 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: | ~/.cargo/registry @@ -107,7 +107,7 @@ jobs: - name: Upload to Codecov if: ${{ !cancelled() && matrix.php == '8.3' && matrix.os == 'ubuntu-latest' }} - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v6 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7 with: token: ${{ secrets.CODECOV_TOKEN }} directory: ./var/phpunit/coverage/clover diff --git a/.github/workflows/job-extension-tests.yml b/.github/workflows/job-extension-tests.yml index bd9caf3a50..5d2ef0d6a9 100644 --- a/.github/workflows/job-extension-tests.yml +++ b/.github/workflows/job-extension-tests.yml @@ -53,7 +53,7 @@ jobs: - name: Upload to Codecov if: ${{ !cancelled() && matrix.php-version == '8.3' }} - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v6 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7 with: token: ${{ secrets.CODECOV_TOKEN }} directory: ./var/phpunit/coverage/clover diff --git a/.github/workflows/job-flow-php-extension.yml b/.github/workflows/job-flow-php-extension.yml index 374eb4cb9e..15d70cd6fe 100644 --- a/.github/workflows/job-flow-php-extension.yml +++ b/.github/workflows/job-flow-php-extension.yml @@ -37,7 +37,7 @@ jobs: toolchain: stable - name: Cache cargo registry and build - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v5 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: | ~/.cargo/registry @@ -104,7 +104,7 @@ jobs: - name: Upload to Codecov if: ${{ !cancelled() && matrix.php == '8.3' && matrix.os == 'ubuntu-latest' }} - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v6 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7 with: token: ${{ secrets.CODECOV_TOKEN }} directory: ./var/phpunit/coverage/clover diff --git a/.github/workflows/job-mutation-tests.yml b/.github/workflows/job-mutation-tests.yml index ac2fcb397f..88a840eac0 100644 --- a/.github/workflows/job-mutation-tests.yml +++ b/.github/workflows/job-mutation-tests.yml @@ -35,7 +35,7 @@ jobs: run: "mkdir -p var/infection/cache" - name: "Cache infection results" - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v5 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: "var/infection/cache" key: "php-${{ matrix.php-version }}-infection-cache-${{ hashFiles('infection.json', 'tools/infection/phpunit.xml', 'composer.lock') }}" diff --git a/.github/workflows/job-phpunit-telemetry-tests.yml b/.github/workflows/job-phpunit-telemetry-tests.yml index d7aa641dc9..a32ca0a4c0 100644 --- a/.github/workflows/job-phpunit-telemetry-tests.yml +++ b/.github/workflows/job-phpunit-telemetry-tests.yml @@ -72,7 +72,7 @@ jobs: - name: Upload to Codecov if: ${{ !cancelled() && matrix.php-version == '8.3' && matrix.phpunit-version == '11' }} - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v6 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7 with: token: ${{ secrets.CODECOV_TOKEN }} directory: ./var/phpunit/coverage/clover diff --git a/Justfile b/Justfile index e23a362fac..98ad374efd 100644 --- a/Justfile +++ b/Justfile @@ -68,6 +68,8 @@ lint-links: # - every per-package subtree-split readonly.yaml (added by hand per package, so all # are audited to catch drift; dangerous-triggers is exempted for them in # .github/zizmor.yml — they only run `gh pr close`, never check out PR code). +# .github/actions holds the composite actions every workflow depends on; auditing them is +# what catches unpinned or deprecated `uses:` that never appear in a workflow file. lint-actions: #!/usr/bin/env bash set -uo pipefail @@ -78,7 +80,7 @@ lint-actions: done < <(find src -path '*/.github/workflows/readonly.yaml' | sort) actionlint "${extra_workflows[@]}" || rc=$? actionlint || rc=$? - zizmor --offline .github/workflows "${extra_workflows[@]}" || rc=$? + zizmor --offline .github/workflows .github/actions "${extra_workflows[@]}" || rc=$? exit $rc # Run static analysis (Mago). The monorepo and web/landing are analyzed in separate runs because diff --git a/tools/phpunit/composer.lock b/tools/phpunit/composer.lock index 299c6d6281..e160fe911e 100644 --- a/tools/phpunit/composer.lock +++ b/tools/phpunit/composer.lock @@ -589,16 +589,16 @@ }, { "name": "phpunit/phpunit", - "version": "12.5.31", + "version": "12.5.32", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "0608d157a284f15cc73b99a3327eff06b66a176d" + "reference": "c02591dd7840ed124a98d7770753329ad28e9f8f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0608d157a284f15cc73b99a3327eff06b66a176d", - "reference": "0608d157a284f15cc73b99a3327eff06b66a176d", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c02591dd7840ed124a98d7770753329ad28e9f8f", + "reference": "c02591dd7840ed124a98d7770753329ad28e9f8f", "shasum": "" }, "require": { @@ -667,7 +667,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.31" + "source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.32" }, "funding": [ { @@ -675,7 +675,7 @@ "type": "other" } ], - "time": "2026-07-06T14:54:16+00:00" + "time": "2026-07-25T06:54:13+00:00" }, { "name": "sebastian/cli-parser",