diff --git a/.circleci/config.yml b/.circleci/config.yml index 802a09097aac..bb93687c3181 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,6 +9,34 @@ version: 2.1 # commands: + check-skip: + steps: + - run: + name: Check-skip + command: | + export git_log=$(git log --max-count=1 --pretty=format:"%B" | tr "\n" " ") + echo "Got commit message:" + echo "${git_log}" + if [[ -v CIRCLE_PULL_REQUEST ]] && ([[ "$git_log" == *"[skip circle]"* ]] || [[ "$git_log" == *"[circle skip]"* ]]); then + echo "Skip detected, exiting job ${CIRCLE_JOB} for PR ${CIRCLE_PULL_REQUEST}." + circleci-agent step halt; + fi + + merge: + steps: + - run: + name: Merge with upstream + command: | + if ! git remote -v | grep upstream; then + git remote add upstream git://github.com/matplotlib/matplotlib.git + fi + git fetch upstream + export merge=${CI_PULL_REQUEST//*pull\//} + if [[ "$merge" != "" ]]; then + echo "Merging ${merge}"; + git pull --ff-only upstream "refs/pull/${merge}/merge"; + fi + apt-install: steps: - run: @@ -124,6 +152,8 @@ jobs: - image: circleci/python:3.8 steps: - checkout + - check-skip + - merge - apt-install - fonts-install diff --git a/.github/workflows/circleci.yml b/.github/workflows/circleci.yml index 90ed466828ed..75fc40d32e99 100644 --- a/.github/workflows/circleci.yml +++ b/.github/workflows/circleci.yml @@ -10,3 +10,4 @@ jobs: repo-token: ${{ secrets.GITHUB_TOKEN }} artifact-path: 0/doc/build/html/index.html circleci-jobs: docs-python38 + job-title: Check the rendered docs here! diff --git a/azure-pipelines.yml b/azure-pipelines.yml index e35ccf3ebec1..5d51afa86f67 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -3,122 +3,143 @@ # 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 -strategy: - matrix: - Linux_py37: - vmImage: 'ubuntu-18.04' - python.version: '3.7' - Linux_py38: - vmImage: 'ubuntu-18.04' - python.version: '3.8' - Linux_py39: - vmImage: 'ubuntu-18.04' - python.version: '3.9' - macOS_py37: - vmImage: 'macOS-10.15' - python.version: '3.7' - macOS_py38: - vmImage: 'macOS-latest' - python.version: '3.8' - macOS_py39: - vmImage: 'macOS-latest' - python.version: '3.9' - Windows_py37: - vmImage: 'vs2017-win2016' - python.version: '3.7' - Windows_py38: - vmImage: 'windows-latest' - python.version: '3.8' - Windows_py39: - vmImage: 'windows-latest' - python.version: '3.9' - maxParallel: 4 +stages: -pool: - vmImage: '$(vmImage)' - -steps: +- stage: Check + jobs: + - job: Skip + pool: + vmImage: 'ubuntu-18.04' + 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]')) + - bash: echo "##vso[task.setvariable variable=start_main;isOutput=true]$RET" + name: result -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(python.version)' - architecture: 'x64' - displayName: 'Use Python $(python.version)' - condition: and(succeeded(), ne(variables['python.version'], 'Pre')) +- stage: Main + condition: and(succeeded(), eq(dependencies.Check.outputs['Skip.result.start_main'], 'true')) + dependsOn: Check + jobs: + - job: Pytest + strategy: + matrix: + Linux_py37: + vmImage: 'ubuntu-18.04' + python.version: '3.7' + Linux_py38: + vmImage: 'ubuntu-18.04' + python.version: '3.8' + Linux_py39: + vmImage: 'ubuntu-18.04' + python.version: '3.9' + macOS_py37: + vmImage: 'macOS-10.15' + python.version: '3.7' + macOS_py38: + vmImage: 'macOS-latest' + python.version: '3.8' + macOS_py39: + vmImage: 'macOS-latest' + python.version: '3.9' + Windows_py37: + vmImage: 'vs2017-win2016' + python.version: '3.7' + Windows_py38: + vmImage: 'windows-latest' + python.version: '3.8' + Windows_py39: + vmImage: 'windows-latest' + python.version: '3.9' + maxParallel: 4 + pool: + vmImage: '$(vmImage)' + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '$(python.version)' + architecture: 'x64' + displayName: 'Use Python $(python.version)' + condition: and(succeeded(), ne(variables['python.version'], 'Pre')) -- task: stevedower.python.InstallPython.InstallPython@1 - displayName: 'Use prerelease Python' - inputs: - prerelease: true - condition: and(succeeded(), eq(variables['python.version'], 'Pre')) + - task: stevedower.python.InstallPython.InstallPython@1 + displayName: 'Use prerelease Python' + inputs: + prerelease: true + condition: and(succeeded(), eq(variables['python.version'], 'Pre')) -- bash: | - set -e - case "$(python -c 'import sys; print(sys.platform)')" in - linux) - sudo apt update - sudo apt install \ - cm-super \ - dvipng \ - ffmpeg \ - gdb \ - gir1.2-gtk-3.0 \ - graphviz \ - inkscape \ - libcairo2 \ - libgirepository-1.0.1 \ - lmodern \ - fonts-freefont-otf \ - poppler-utils \ - texlive-pictures \ - texlive-fonts-recommended \ - texlive-latex-base \ - texlive-latex-extra \ - texlive-latex-recommended \ - texlive-xetex texlive-luatex \ - ttf-wqy-zenhei - ;; - darwin) - brew install --cask xquartz - brew install pkg-config ffmpeg imagemagick mplayer ccache - ;; - win32) - ;; - *) - exit 1 - ;; - esac - displayName: 'Install dependencies' + - bash: | + set -e + case "$(python -c 'import sys; print(sys.platform)')" in + linux) + sudo apt update + sudo apt install \ + cm-super \ + dvipng \ + ffmpeg \ + gdb \ + gir1.2-gtk-3.0 \ + graphviz \ + inkscape \ + libcairo2 \ + libgirepository-1.0.1 \ + lmodern \ + fonts-freefont-otf \ + poppler-utils \ + texlive-pictures \ + texlive-fonts-recommended \ + texlive-latex-base \ + texlive-latex-extra \ + texlive-latex-recommended \ + texlive-xetex texlive-luatex \ + ttf-wqy-zenhei + ;; + darwin) + brew install --cask xquartz + brew install pkg-config ffmpeg imagemagick mplayer ccache + ;; + win32) + ;; + *) + exit 1 + ;; + esac + displayName: 'Install dependencies' -- bash: | - python -m pip install --upgrade pip - python -m pip install -r requirements/testing/all.txt -r requirements/testing/extra.txt || - [[ "$PYTHON_VERSION" = 'Pre' ]] - displayName: 'Install dependencies with pip' + - bash: | + python -m pip install --upgrade pip + python -m pip install -r requirements/testing/all.txt -r requirements/testing/extra.txt || + [[ "$PYTHON_VERSION" = 'Pre' ]] + displayName: 'Install dependencies with pip' -- bash: | - python -m pip install -ve . || - [[ "$PYTHON_VERSION" = 'Pre' ]] - displayName: "Install self" + - bash: | + python -m pip install -ve . || + [[ "$PYTHON_VERSION" = 'Pre' ]] + displayName: "Install self" -- script: env - displayName: 'print env' + - script: env + displayName: 'print env' -- bash: | - PYTHONFAULTHANDLER=1 python -m pytest --junitxml=junit/test-results.xml -raR --maxfail=50 --timeout=300 --durations=25 --cov-report= --cov=lib -n 2 || - [[ "$PYTHON_VERSION" = 'Pre' ]] - displayName: 'pytest' + - bash: | + PYTHONFAULTHANDLER=1 python -m pytest --junitxml=junit/test-results.xml -raR --maxfail=50 --timeout=300 --durations=25 --cov-report= --cov=lib -n 2 || + [[ "$PYTHON_VERSION" = 'Pre' ]] + displayName: 'pytest' -- bash: | - bash <(curl -s https://codecov.io/bash) -f "!*.gcov" -X gcov - displayName: 'Upload to codecov.io' + - bash: | + bash <(curl -s https://codecov.io/bash) -f "!*.gcov" -X gcov + displayName: 'Upload to codecov.io' -- task: PublishTestResults@2 - inputs: - testResultsFiles: '**/test-results.xml' - testRunTitle: 'Python $(python.version)' - 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: and(failed(), ne(variables['python.version'], 'Pre')) + - publish: $(System.DefaultWorkingDirectory)/result_images + artifact: $(Agent.JobName)-result_images + condition: and(failed(), ne(variables['python.version'], 'Pre')) diff --git a/doc/devel/coding_guide.rst b/doc/devel/coding_guide.rst index f936483dee1e..963845cd4a4b 100644 --- a/doc/devel/coding_guide.rst +++ b/doc/devel/coding_guide.rst @@ -219,6 +219,18 @@ will run on all supported platforms and versions of Python. .. _tox: https://tox.readthedocs.io/ +* If you know your changes do not need to be tested (this is very rare!), all + CIs can be skipped for a given commit by including ``[ci skip]`` or + ``[skip ci]`` in the commit message. If you know only a subset of CIs need + to be run (e.g., if you are changing some block of plain reStructuredText and + want only CircleCI to run to render the result), individual CIs can be + skipped on individual commits as well by using the following substrings + in commit messages: + + - GitHub Actions: ``[skip actions]`` + - AppVeyor: ``[skip appveyor]`` (must be in the first line of the commit) + - Azure Pipelines: ``[skip azp]`` + - CircleCI: ``[skip circle]`` .. _pr-squashing: