feat(workflows): upload coverage / JUnit results in workflows #510
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Tests with PyDebug | |
on: | |
push: | |
branches: | |
- main | |
pull_request: | |
paths: | |
- setup.py | |
- setup.cfg | |
- pyproject.toml | |
- MANIFEST.in | |
- CMakeLists.txt | |
- include/** | |
- src/** | |
- tests/** | |
- optree/** | |
- .github/workflows/tests-with-pydebug.yml | |
# Allow to trigger the workflow manually | |
workflow_dispatch: | |
permissions: | |
contents: read | |
concurrency: | |
group: "${{ github.workflow }}-${{ github.ref }}" | |
cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
env: | |
CMAKE_BUILD_TYPE: "Debug" | |
OPTREE_CXX_WERROR: "ON" | |
PYTHON: "python" # to be updated | |
PYTHON_TAG: "py3" # to be updated | |
PYTHON_VERSION: "3" # to be updated | |
PYENV_ROOT: "~/.pyenv" # to be updated | |
COLUMNS: "128" | |
jobs: | |
test: | |
name: Test for CPython ${{ matrix.python-version }}${{ matrix.python-abiflags }} on ${{ matrix.runner }} | |
runs-on: ${{ matrix.runner }} | |
strategy: | |
matrix: | |
runner: [windows-latest] | |
python-version: | |
- "3.7" | |
- "3.8" | |
- "3.9" | |
- "3.10" | |
- "3.11" | |
- "3.12" | |
- "3.13" | |
python-abiflags: ["d", "td"] | |
exclude: | |
- python-version: "3.7" | |
python-abiflags: "td" | |
- python-version: "3.8" | |
python-abiflags: "td" | |
- python-version: "3.9" | |
python-abiflags: "td" | |
- python-version: "3.10" | |
python-abiflags: "td" | |
- python-version: "3.11" | |
python-abiflags: "td" | |
- python-version: "3.12" | |
python-abiflags: "td" | |
fail-fast: false | |
timeout-minutes: 120 | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Set up pyenv | |
if: runner.os != 'Windows' | |
run: | | |
export PYENV_ROOT="${HOME}/.pyenv" | |
git clone https://github.com/pyenv/pyenv.git "${PYENV_ROOT}" | |
echo "PYENV_ROOT=${PYENV_ROOT}" >> "${GITHUB_ENV}" | |
echo "PATH=${PYENV_ROOT}/bin:${PYENV_ROOT}/shims:${PATH}" >> "${GITHUB_ENV}" | |
- name: Set up pyenv | |
if: runner.os == 'Windows' | |
shell: pwsh | |
run: | | |
$Env:PYENV_ROOT = "$Env:USERPROFILE\.pyenv" | |
$Env:PATH = "$Env:PYENV_ROOT\pyenv-win\bin;$Env:PYENV_ROOT\pyenv-win\shims;$Env:PATH" | |
$Env:PATH = "$(Get-Location)\venv\Scripts;$Env:PATH" | |
git clone https://github.com/pyenv-win/pyenv-win.git "$Env:PYENV_ROOT" | |
Write-Output "PYENV_ROOT=$Env:PYENV_ROOT" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append | |
Write-Output "PATH=$Env:PATH" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append | |
- name: Determine Python version | |
shell: bash | |
run: | | |
if [[ "${{ runner.os }}" == 'Windows' ]]; then | |
pyenv update | |
fi | |
echo "::group::pyenv install --list" | |
pyenv install --list | |
echo "::endgroup::" | |
if [[ "${{ matrix.python-abiflags }}" == *t* ]]; then | |
echo "PYTHON_GIL=0" >> "${GITHUB_ENV}" | |
fi | |
if [[ "${{ runner.os }}" != 'Windows' && "${{ matrix.python-abiflags }}" == *t* ]]; then | |
PYTHON_VERSION="$( | |
pyenv install --list | tr -d ' ' | grep -E "^${{ matrix.python-version }}" | | |
grep -vF '-' | grep -E '[0-9]t$' | sort -rV | head -n 1 | |
)" | |
elif ! PYTHON_VERSION="$(pyenv latest --known "${{ matrix.python-version }}")"; then | |
PYTHON_VERSION="$( | |
pyenv install --list | tr -d ' ' | grep -E "^${{ matrix.python-version }}" | | |
grep -vF '-' | grep -E '[0-9]$' | sort -rV | head -n 1 | |
)" | |
fi | |
echo "PYTHON_VERSION=${PYTHON_VERSION}" | tee -a "${GITHUB_ENV}" | |
- uses: actions/cache@v4 | |
id: python-cache | |
with: | |
path: ${{ env.PYENV_ROOT }} | |
key: ${{ runner.os }}-${{ matrix.python-version }}${{ matrix.python-abiflags }}-${{ env.PYTHON_VERSION }} | |
- name: Set up Python | |
if: steps.python-cache.outputs.cache-hit != 'true' | |
shell: bash | |
run: | | |
set -x | |
PYENV_INSTALL_ARGS=() | |
if [[ "${{ runner.os }}" != 'Windows' ]]; then | |
if [[ "${{ matrix.python-abiflags }}" == *d* ]]; then | |
PYENV_INSTALL_ARGS+=("--debug") | |
fi | |
else | |
pyenv update | |
fi | |
pyenv install ${{ env.PYTHON_VERSION }} "${PYENV_INSTALL_ARGS[@]}" | |
if [[ "${{ runner.os }}" == 'Windows' ]]; then | |
INSTALL_ARGS=( | |
"/quiet" | |
"SimpleInstall=1" | |
"InstallAllUsers=0" | |
"Include_dev=1" | |
"Include_lib=1" | |
"Include_exe=1" | |
"Include_pip=1" | |
"Include_tools=1" | |
"Include_launcher=1" | |
"Include_test=0" | |
) | |
if [[ "${{ matrix.python-abiflags }}" == *d* ]]; then | |
INSTALL_ARGS+=( | |
"Include_debug=1" | |
"Include_symbols=1" | |
) | |
fi | |
if [[ "${{ matrix.python-abiflags }}" == *t* ]]; then | |
INSTALL_ARGS+=( | |
"Include_freethreaded=1" | |
) | |
fi | |
INSTALL_ARGS+=( | |
'TargetDir="${{ env.PYENV_ROOT }}\pyenv-win\versions\${{ env.PYTHON_VERSION }}"' | |
) | |
INSTALLER='${{ env.PYENV_ROOT }}\pyenv-win\install_cache\'"$( | |
cd '${{ env.PYENV_ROOT }}\pyenv-win\install_cache' && | |
find . -name "*-${{ env.PYTHON_VERSION }}-*.exe" | | |
head -n 1 | cut -c3- | |
)" | |
pyenv uninstall ${{ env.PYTHON_VERSION }} | |
pwsh -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command \ | |
"${INSTALLER} ${INSTALL_ARGS[*]} 2>&1 | Out-Default" | |
fi | |
pyenv versions | |
pyenv global "$(pyenv versions | grep -F '${{ env.PYTHON_VERSION }}' | tr -d ' ')" | |
pyenv rehash | |
- name: Set up Environment | |
shell: bash | |
run: | | |
set -x | |
echo "::group::Python shims" | |
pyenv shims | |
echo "::endgroup::" | |
if [[ "${{ runner.os }}" == 'Windows' ]]; then | |
if [[ "${{ matrix.python-abiflags }}" == *t* ]]; then | |
PYTHON="${PYTHON}${{ matrix.python-version }}t" | |
fi | |
if [[ "${{ matrix.python-abiflags }}" == *d* ]]; then | |
PYTHON="${PYTHON}_d" | |
fi | |
"${PYTHON}" -m venv venv | |
ls -alh venv/Scripts | |
export PYTHON="${PYTHON}.exe" | |
echo "PYTHON=${PYTHON}" | tee -a "${GITHUB_ENV}" | |
fi | |
"${PYTHON}" --version | |
echo "::group::Upgrade pip" | |
"${PYTHON}" -m pip install --upgrade pip setuptools wheel rich | |
echo "::endgroup::" | |
echo "::group::Python sysconfig" | |
"${PYTHON}" -c 'import rich, sysconfig; rich.print(sysconfig.get_config_vars())' | |
echo "::endgroup::" | |
export PYTHON_TAG="$( | |
echo 'import sys; print( | |
"{0.name[0]}p{1.major}{1.minor}".format( | |
sys.implementation, | |
sys.version_info, | |
).lower(), | |
)' | "${PYTHON}" - | |
)${{ matrix.python-abiflags }}" | |
echo "PYTHON_TAG=${PYTHON_TAG}" | tee -a "${GITHUB_ENV}" | |
if [[ "${{ runner.os }}" == 'Linux' ]]; then | |
sudo sysctl -w kernel.core_pattern="core.${PYTHON_TAG}.%P" | |
sudo sysctl -w kernel.core_uses_pid=0 | |
sudo sysctl -w fs.suid_dumpable=1 | |
sysctl kernel.core_pattern kernel.core_uses_pid fs.suid_dumpable | |
elif [[ "${{ runner.os }}" == 'macOS' ]]; then | |
sudo sysctl -w kern.corefile="core.${PYTHON_TAG}.%P" | |
sudo sysctl -w kern.coredump=1 | |
sudo sysctl -w kern.sugid_coredump=1 | |
sysctl kern.corefile kern.coredump kern.sugid_coredump | |
fi | |
- name: Install OpTree | |
run: | | |
${{ env.PYTHON }} -m pip install -vv --editable '.[test]' | |
- name: Test with pytest | |
shell: bash | |
run: | | |
set -x | |
ulimit -c unlimited | |
ulimit -a | |
PYTESTOPTS=( | |
"--exitfirst" | |
"--cov-report=xml:coverage-${{ env.PYTHON_TAG }}.xml" | |
"--junit-xml=junit-${{ env.PYTHON_TAG }}.xml" | |
) | |
make test PYTESTOPTS="${PYTESTOPTS[*]}" | |
- name: List generated files | |
if: ${{ !cancelled() }} | |
shell: bash | |
run: | | |
find . -type f -name '*.py[co]' -delete | |
find . -depth -type d -name "__pycache__" -exec rm -r "{}" + | |
git status --ignored --porcelain | |
- name: Collect backtraces from coredumps (if any) | |
if: ${{ !cancelled() }} | |
shell: bash | |
run: | | |
if [[ -n "$(find . -iname "core.*.[1-9]*")" ]]; then | |
if [[ "${{ runner.os }}" == 'Linux' ]]; then | |
( | |
export DEBIAN_FRONTEND=noninteractive | |
sudo apt-get update -qq && sudo apt-get install -yqq gdb | |
) | |
echo "Found core dumps:" | |
ls -alh $(find . -iname "core.*.[1-9]*") | |
echo "Collecting backtraces:" | |
find . -iname "core.*.[1-9]*" -exec bash -xc " | |
echo '::group::backtrace from: {}'; | |
gdb ${{ env.PYTHON }} '{}' -ex 'backtrace' -ex 'quit'; | |
echo '::endgroup::'; | |
" ';' | |
fi | |
fi | |
- name: Upload JUnit results to Codecov | |
if: ${{ !cancelled() }} | |
uses: codecov/test-results-action@v1 | |
with: | |
token: ${{ secrets.CODECOV_TOKEN }} | |
file: tests/junit-${{ env.PYTHON_TAG }}.xml | |
flags: junit-${{ env.PYTHON_TAG }} | |
name: junit-umbrella | |
verbose: true | |
fail_ci_if_error: false | |
- name: Upload core dump file | |
if: ${{ !cancelled() }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: coredump-${{ env.PYTHON_TAG }}-${{ runner.os }} | |
path: tests/core.* | |
if-no-files-found: ignore |