# Python package # Create and test a Python package on multiple Python versions. # Add steps that analyze code, save the dist with the build record, publish to a PyPI-compatible index, and # more: # https://docs.microsoft.com/en-us/azure/devops/pipelines/ecosystems/python?view=azure-devops --- trigger: branches: exclude: - v*-doc pr: branches: exclude: - v*-doc paths: exclude: - doc/**/* - galleries/**/* stages: - stage: Check jobs: - job: Skip pool: vmImage: 'ubuntu-latest' variables: DECODE_PERCENTS: 'false' RET: 'true' steps: - bash: | git_log=`git log --max-count=1 --skip=1 --pretty=format:"%B" | tr "\n" " "` echo "##vso[task.setvariable variable=log]$git_log" - bash: echo "##vso[task.setvariable variable=RET]false" condition: >- or(contains(variables.log, '[skip azp]'), contains(variables.log, '[azp skip]'), contains(variables.log, '[skip ci]'), contains(variables.log, '[ci skip]'), contains(variables.log, '[ci doc]')) - bash: echo "##vso[task.setvariable variable=start_main;isOutput=true]$RET" name: result - stage: Main condition: and(succeeded(), eq(dependencies.Check.outputs['Skip.result.start_main'], 'true')) dependsOn: Check jobs: - job: Pytest strategy: matrix: Windows_py311: vmImage: 'windows-2022' # Keep one job pinned to the oldest image python.version: '3.11' Windows_py312: vmImage: 'windows-latest' python.version: '3.12' Windows_py313: vmImage: 'windows-latest' python.version: '3.13' maxParallel: 4 pool: vmImage: '$(vmImage)' steps: - task: UsePythonVersion@0 inputs: versionSpec: '$(python.version)' architecture: 'x64' displayName: 'Use Python $(python.version)' - bash: | choco install ninja displayName: 'Install dependencies' - bash: | python -m pip install --upgrade pip python -m pip install --upgrade --group build python -m pip install --prefer-binary --group test --group test-extra displayName: 'Install dependencies with pip' - bash: | CONFIG='--config-settings=setup-args=--vsenv' CONFIG="$CONFIG --config-settings=setup-args=-Dcpp_link_args=-PROFILE" CONFIG="$CONFIG --config-settings=setup-args=-Dbuildtype=debug" python -m pip install \ --no-build-isolation $CONFIG \ --verbose --editable .[dev] displayName: "Install self" - script: env displayName: 'print env' - script: pip list displayName: 'print pip' - bash: | set -e SESSION_ID=$(python -c "import uuid; print(uuid.uuid4(), end='')") echo "Coverage session ID: ${SESSION_ID}" VS=$(ls -d /c/Program\ Files*/Microsoft\ Visual\ Studio/*/Enterprise) echo "Visual Studio: ${VS}" DIR="$VS/Common7/IDE/Extensions/Microsoft/CodeCoverage.Console" # This is for MSVC 2022 (on windows-latest). TOOL="$DIR/Microsoft.CodeCoverage.Console.exe" for f in build/cp*/src/*.pyd; do echo $f echo "==============================" "$TOOL" instrument $f --session-id $SESSION_ID \ --log-level Verbose --log-file instrument.log cat instrument.log rm instrument.log done echo "Starting $TOOL in server mode" "$TOOL" collect \ --session-id $SESSION_ID --server-mode \ --output-format cobertura --output extensions.xml \ --log-level Verbose --log-file extensions.log & VS_VER=2022 echo "##vso[task.setvariable variable=VS_COVERAGE_TOOL]$TOOL" PYTHONFAULTHANDLER=1 pytest -rfEsXR -n 2 \ --maxfail=50 --timeout=300 --durations=25 \ --junitxml=junit/test-results.xml --cov-report=xml --cov=lib if [[ $VS_VER == 2022 ]]; then "$TOOL" shutdown $SESSION_ID echo "Coverage collection log" echo "=======================" cat extensions.log else "$TOOL" shutdown -session:$SESSION_ID fi displayName: 'pytest' - bash: | if [[ -f extensions.coverage ]]; then # For MSVC 2019. "$VS_COVERAGE_TOOL" analyze -output:extensions.xml \ -include_skipped_functions -include_skipped_modules \ extensions.coverage rm extensions.coverage fi displayName: 'Filter C coverage' condition: succeededOrFailed() - bash: | bash <(curl -s https://codecov.io/bash) \ -n "$PYTHON_VERSION $AGENT_OS" \ -f 'coverage.xml' -f 'extensions.xml' displayName: 'Upload to codecov.io' condition: succeededOrFailed() - task: PublishTestResults@2 inputs: testResultsFiles: '**/test-results.xml' testRunTitle: 'Python $(python.version)' condition: succeededOrFailed() - publish: $(System.DefaultWorkingDirectory)/result_images artifact: $(Agent.JobName)-result_images condition: failed()