Skip to content

Commit b563f6a

Browse files
committed
🚨 Improve CI workflow error handling and reporting
Better handle expected failures in CI by marking PyPy and prerelease builds as allowed to fail. Add detailed Pylint exit code parsing for more accurate error reporting. This prevents false "build failed" statuses while maintaining proper error visibility.
1 parent cb952f9 commit b563f6a

1 file changed

Lines changed: 26 additions & 2 deletions

File tree

‎project_name/.github/workflows/ci.yml.jinja‎

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,20 @@ jobs:
110110
os: ubuntu-latest
111111
python-version: "3.{{ python_max + 1 }}"
112112
{%- raw %}
113-
continue-on-error: ${{ matrix.resolution == 'prerelease' || matrix.python-version == 'pypy3.11' }}
114113
name: test-${{ matrix.python-version }}-${{ matrix.resolution }}-${{ matrix.os }}
115114
steps:
116115
- uses: actions/checkout@v4
117116
- uses: astral-sh/setup-uv@v5
118117
with:
119118
python-version: ${{ matrix.python-version }}
120119
cache-suffix: ${{ matrix.resolution }}
120+
- name: Set versions that allow failure
121+
# pypy and prerelease python versions might fail to install dependencies. In this case, we do not fail the job
122+
run: >-
123+
echo "ALLOW_FAILURE=${{ matrix.resolution == 'prerelease' || startsWith(matrix.python-version, 'pypy') }}"
124+
>> "$GITHUB_ENV"
121125
- name: Install packages
126+
id: install_packages
122127
run: >-
123128
uv sync
124129
--all-extras
@@ -131,9 +136,16 @@ jobs:
131136
matrix.resolution == 'prerelease' && '--upgrade --resolution highest --prerelease allow' ||
132137
'--NON_RECOGNIZED_RESOLUTION'
133138
}}
139+
continue-on-error: ${{ env.ALLOW_FAILURE == 'true' }}
140+
- name: Stop job with warning if install fails for specific versions
141+
if: ${{ env.ALLOW_FAILURE == 'true' && steps.install_packages.outcome == 'failure' }}
142+
run: >-
143+
echo "::warning::Stopping job due to installation failure on Python ${{ matrix.python-version }}"
134144
- name: List packages
145+
if: ${{ steps.install_packages.outcome == 'success' }}
135146
run: uv pip list
136147
- name: Run tests
148+
if: ${{ steps.install_packages.outcome == 'success' }}
137149
run: uv run --no-sync pytest
138150
{%- endraw %}
139151

@@ -153,5 +165,17 @@ jobs:
153165
--locked
154166
- name: List packages
155167
run: uv pip list
168+
# use pylint exitcode to fail only on errors.
156169
- name: Run Pylint
157-
run: uv run --no-sync --with pylint pylint src
170+
run: |
171+
set +e
172+
uv run --no-sync --with pylint pylint src
173+
result=$?
174+
set -e
175+
[ $((result & 1)) -ne 0 ] && echo "::error ::Pylest fatal(s) found"
176+
[ $((result & 2)) -ne 0 ] && echo "::error ::Pylest error(s) found"
177+
[ $((result & 4)) -ne 0 ] && echo "::warning ::Pylest warning(s) found"
178+
[ $((result & 8)) -ne 0 ] && echo "::warning ::Pylest refactor(s) found"
179+
[ $((result & 16)) -ne 0 ] && echo "::warning ::Pylest convention(s) found"
180+
[ $((result & 32)) -ne 0 ] && echo "::error ::Pylest usage error"
181+
exit $((result & 35))

0 commit comments

Comments
 (0)