- Timestamp:
- 08/05/2026 07:16:57 AM (2 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/.github/workflows/reusable-phpstan-static-analysis-v1.yml
r62742 r63019 33 33 # - Configures caching for PHPStan static analysis scans. 34 34 # - Runs PHPStan static analysis (with Pull Request annotations). 35 # - Checks whether the baselines need regenerating. 35 36 # - Saves the PHPStan result cache. 36 37 # - Ensures version-controlled files are not modified or deleted. … … 94 95 - name: Run PHP static analysis tests 95 96 id: phpstan 96 run: composer run phpstan -- -vvv --error-format=checkstyle | cs2pr --errors-as-warnings --graceful-warnings 97 run: | 98 # The report is written to a file as well as piped to cs2pr, so that the step below 99 # can look at it. 100 # 101 # cs2pr exits successfully so that reported errors annotate the pull request without 102 # failing the run. A pipeline reports only the status of its last command, so that 103 # also discards the status of the analysis itself. Recover it from PIPESTATUS. 104 composer run phpstan -- -vvv --error-format=checkstyle | tee "${RUNNER_TEMP}/phpstan-report.xml" | cs2pr --errors-as-warnings --graceful-warnings 105 status="${PIPESTATUS[0]}" 106 107 # PHPStan exits 1 when it has errors to report, which is the expected case here and 108 # is what the annotations are for. Anything higher means it did not finish at all, 109 # which would otherwise pass silently, since the discarded status was the only sign. 110 if [ "${status}" -gt 1 ]; then 111 echo "::error title=PHPStan did not complete::The analysis exited with status ${status}, so the code was not fully checked. This is a failure of the run itself rather than a problem found in the code." 112 exit "${status}" 113 fi 114 115 # An ignored error that no longer occurs, or occurs a different number of times, is 116 # reported under an `ignore.*` identifier. That is not something to fix in the code: the 117 # usual cause is that the error *was* fixed, leaving a baseline describing a state that 118 # no longer exists. PHPStan does not allow those reports to be ignored or baselined. 119 # 120 # The analysis above is reported as warnings, so this would otherwise surface as a 121 # passing run carrying an annotation that reads like a complaint about a fix. Call it 122 # out on its own, and say what to do about it. 123 # 124 # Detection is on the identifier rather than the message, which is prose and may be 125 # reworded in any release. The checkstyle format carries it in the `source` attribute. 126 - name: Check whether the baselines need regenerating 127 if: ${{ !cancelled() }} 128 env: 129 BASELINES_URL: ${{ github.server_url }}/${{ github.repository }}/tree/${{ github.sha }}/tests/phpstan/baselines 130 README_URL: ${{ github.server_url }}/${{ github.repository }}/blob/${{ github.sha }}/tests/phpstan/README.md 131 run: | 132 # This step runs even when the analysis above it failed, in which case the report may 133 # never have been written. That failure is reported there, so there is nothing to add 134 # here beyond staying quiet about a file that was never going to exist. 135 if [ ! -f "${RUNNER_TEMP}/phpstan-report.xml" ]; then 136 exit 0 137 fi 138 139 # Leave the run alone unless PHPStan reported an ignore error, because everything 140 # below concerns an ignore configuration that no longer describes the code, and 141 # nothing else. Those errors are `ignore.unmatched`, where a pattern matched nothing 142 # at all, and `ignore.count`, where it matched a different number of times than the 143 # entry records. The `ignore.` prefix is matched rather than those two names so that 144 # any later addition to the group is caught as well. 145 if ! grep -q 'source="ignore\.' "${RUNNER_TEMP}/phpstan-report.xml"; then 146 exit 0 147 fi 148 149 # The summary is Markdown, and its code spans and fences are written literally, so the 150 # heredoc is quoted to keep the backticks out of the shell's hands. The links are 151 # written in reference style for the same reason: the URLs are the only part needing 152 # a variable, so defining them afterwards keeps the whole of the prose in here. 153 # 154 # A newline renders as a line break rather than a space, so each paragraph is one 155 # line however long that makes it, and the rendered summary wraps to its own width. 156 cat >> "${GITHUB_STEP_SUMMARY}" <<'SUMMARY' 157 ## PHPStan baselines are out of date 158 159 An ignored error no longer occurs, or occurs a different number of times, so PHPStan reported it under an `ignore.unmatched` or `ignore.count` identifier. 160 161 **If you fixed the error, this is expected.** Each baseline entry records an exact count for a specific file, so that a new occurrence of an already baselined error is reported rather than absorbed. That same exactness means fixing one leaves the baseline describing a state that no longer exists. There is nothing to fix in the code; the baselines just need to catch up. 162 163 Regenerate them and commit the result: 164 165 ```bash 166 npm run typecheck:php:baselines 167 ``` 168 169 or, outside the Docker environment: 170 171 ```bash 172 composer phpstan:baselines 173 ``` 174 175 That rewrites the files under [`tests/phpstan/baselines`][baselines], deletes any whose errors are now all fixed, and updates the list of them in `phpstan.neon.dist`. 176 177 Where the report names an `@phpstan-ignore` annotation in the code rather than a baseline entry, remove that annotation instead; regenerating will not clear it. 178 179 See [`tests/phpstan/README.md`][readme] for details. 180 181 SUMMARY 182 183 { 184 echo "[baselines]: ${BASELINES_URL}" 185 echo "[readme]: ${README_URL}" 186 } >> "${GITHUB_STEP_SUMMARY}" 187 188 echo "::error title=PHPStan baselines are out of date::An ignored error no longer occurs, or occurs a different number of times. If you fixed it, that is expected: run \`npm run typecheck:php:baselines\` or \`composer phpstan:baselines\` and commit the updated baselines. See ${README_URL}" 189 exit 1 97 190 98 191 - name: "Save result cache"
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)