Skip to content

Commit f57d7e2

Browse files
authored
CI - better coverage report, pypy on Azure, add codeclimate (#1031)
This now is done. It's a major rewrite and was significantly more troublesome than expected. After all the effort put in, failed to convince either codecov or coveralls to function correctly. So where two does not work, let's use the third option: codeclimate (https://codeclimate.com/github/tox-dev/tox/builds). This one finally gives up on trying to be too smart (e.g. forcing users to merge reports locally during the build), but work correctly what it does offer: - great documentation, - Github App, - great chrome extension to annotate PRs inline, - Github comment support. Does not have branch coverage for now but I don't think we used that much often that feature. With this, we also moved off Travis completely as now ``pypy`` tests are also done on Azure Pipelines. PS. NOTE: we no longer really on a service to report/display code coverage. The CI itself collects all coverage reports, merges them and then displays them as a final step. Codeclimate is just an additional UI to this data, and the coverage gets uploaded to that service too; however, it's also available as part of the CI build log (both full coverage and diff coverage).
1 parent b367a52 commit f57d7e2

File tree

10 files changed

+253
-185
lines changed

10 files changed

+253
-185
lines changed

.codeclimate.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
engines:
2+
duplication:
3+
enabled: true
4+
config:
5+
languages:
6+
python:
7+
python_version: 3
8+
pep8:
9+
enabled: true
10+
radon:
11+
enabled: true
12+
sonar-python:
13+
enabled: true
14+
config:
15+
tests_patterns:
16+
- tests/**
17+
18+
ratings:
19+
paths:
20+
- "**.py"

.codecov.yml

Lines changed: 0 additions & 37 deletions
This file was deleted.

.travis.yml

Lines changed: 0 additions & 40 deletions
This file was deleted.

README.rst

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,10 @@
77
.. image:: https://dev.azure.com/toxdev/tox/_apis/build/status/tox%20ci?branchName=master
88
:target: https://dev.azure.com/toxdev/tox/_build/latest?definitionId=9&branchName=master
99
:alt: Azure Pipelines build status
10-
.. image:: https://travis-ci.org/tox-dev/tox.svg?branch=master
11-
:target: https://travis-ci.org/tox-dev/tox
12-
:alt: Travis-CI build status
13-
.. image:: https://codecov.io/gh/tox-dev/tox/branch/master/graph/badge.svg
14-
:target: https://codecov.io/gh/tox-dev/tox
15-
:alt: Code coverage Status
16-
.. image:: https://readthedocs.org/projects/tox/badge/?version=latest
10+
.. image:: https://api.codeclimate.com/v1/badges/425c19ab2169a35e1c16/test_coverage
11+
:target: https://codeclimate.com/github/tox-dev/tox/test_coverage
12+
:alt: Test Coverage
13+
.. image:: https://readthedocs.org/projects/tox/badge/?version=latest&style=flat-square
1714
:target: https://tox.readthedocs.io/en/latest/?badge=latest
1815
:alt: Documentation status
1916
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg

azure-pipelines.yml

Lines changed: 130 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ name: $(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.rr)
22

33
variables:
44
"System.PreferGit": true
5+
CI_NAME: Azure Pipelines
6+
CI_BUILD_ID: $(Build.BuildId)
7+
CI_BUILD_URL: "https://toxdev.visualstudio.com/tox/_build/results?buildId=$(Build.BuildId)"
8+
GIT_BRANCH: $(Build.SourceBranch)
9+
GIT_COMMIT_SHA: $(Build.SourceVersion)
510

611
trigger:
712
batch: true
@@ -23,63 +28,154 @@ trigger:
2328
- tasks/*
2429

2530
jobs:
31+
- job: notify_build_start
32+
pool: {vmImage: 'Ubuntu 16.04'}
33+
steps:
34+
- script: echo start
35+
- script: |
36+
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter && \
37+
chmod +x ./cc-test-reporter && \
38+
./cc-test-reporter before-build -d
39+
displayName: notify code climate of new build
40+
condition: eq(variables['system.pullrequest.isfork'], false)
41+
42+
- template: azure-run-tox-env.yml
43+
parameters: {tox: fix_lint, python: 3.7}
44+
- template: azure-run-tox-env.yml
45+
parameters: {tox: docs, python: 3.7}
2646
- template: azure-run-tox-env.yml
27-
parameters: {name: check_code_style, tox: "fix-lint", python: '3.7', image: 'Ubuntu 16.04'}
47+
parameters: {tox: package_description, python: 3.7}
48+
2849
- template: azure-run-tox-env.yml
29-
parameters: {name: generate_docs, tox: docs, python: '3.7', image: 'Ubuntu 16.04'}
50+
parameters: {tox: pypy, python: pypy, os: linux}
3051
- template: azure-run-tox-env.yml
31-
parameters: {name: check_package_long_description, tox: "package-description", python: '3.7', image: 'Ubuntu 16.04'}
52+
parameters: {tox: pypy3, python: pypy3, os: linux}
3253

3354
- template: azure-run-tox-env.yml
34-
parameters: {name: windows_37, python: '3.7', image: 'vs2017-win2016'}
55+
parameters: {tox: py37, python: 3.7, os: windows}
3556
- template: azure-run-tox-env.yml
36-
parameters: {name: windows_36, python: '3.6', image: 'vs2017-win2016'}
57+
parameters: {tox: py36, python: 3.6, os: windows}
3758
- template: azure-run-tox-env.yml
38-
parameters: {name: windows_35, python: '3.5', image: 'vs2017-win2016'}
59+
parameters: {tox: py35, python: 3.5, os: windows}
3960
- template: azure-run-tox-env.yml
40-
parameters: {name: windows_34, python: '3.4', image: 'vs2017-win2016'}
61+
parameters: {tox: py34, python: 3.4, os: windows}
4162
- template: azure-run-tox-env.yml
42-
parameters: {name: windows_27, python: '2.7', image: 'vs2017-win2016'}
63+
parameters: {tox: py27, python: 2.7, os: windows}
4364

4465
- template: azure-run-tox-env.yml
45-
parameters: {name: linux_37, python: '3.7', image: 'Ubuntu 16.04'}
66+
parameters: {tox: py37, python: 3.7, os: linux}
4667
- template: azure-run-tox-env.yml
47-
parameters: {name: linux_36, python: '3.6', image: 'Ubuntu 16.04'}
68+
parameters: {tox: py36, python: 3.6, os: linux}
4869
- template: azure-run-tox-env.yml
49-
parameters: {name: linux_35, python: '3.5', image: 'Ubuntu 16.04'}
70+
parameters: {tox: py35, python: 3.5, os: linux}
5071
- template: azure-run-tox-env.yml
51-
parameters: {name: linux_34, python: '3.4', image: 'Ubuntu 16.04'}
72+
parameters: {tox: py34, python: 3.4, os: linux}
5273
- template: azure-run-tox-env.yml
53-
parameters: {name: linux_27, python: '2.7', image: 'Ubuntu 16.04'}
74+
parameters: {tox: py27, python: 2.7, os: linux}
5475

5576
- template: azure-run-tox-env.yml
56-
parameters: {name: macOS_36, python: '3.6', image: 'macOS 10.13'}
77+
parameters: {tox: py36, python: 3.6, os: macOs}
5778

58-
- job: tests_done
79+
- job: report_coverage
5980
pool: {vmImage: 'Ubuntu 16.04'}
60-
condition: always()
81+
condition: eq(variables['system.pullrequest.isfork'], false)
6182
dependsOn:
62-
- windows_37
63-
- windows_36
64-
- windows_35
65-
- windows_34
66-
- windows_27
67-
- linux_37
68-
- linux_36
69-
- linux_35
70-
- linux_34
71-
- linux_27
72-
- macOS_36
83+
- windows_py37
84+
- windows_py36
85+
- windows_py35
86+
- windows_py34
87+
- windows_py27
88+
- linux_py37
89+
- linux_py36
90+
- linux_py35
91+
- linux_py34
92+
- linux_py27
93+
- linux_pypy3
94+
- linux_pypy
95+
- macOS_py36
7396
steps:
74-
- script: echo "done"
75-
displayName: running tests done
97+
- task: DownloadBuildArtifacts@0
98+
displayName: download coverage files for run
99+
inputs:
100+
buildType: current
101+
downloadType: specific
102+
itemPattern: coverage-*/*
103+
downloadPath: $(Build.StagingDirectory)
104+
105+
- task: UsePythonVersion@0
106+
displayName: setup python
107+
inputs:
108+
versionSpec: 3.7
109+
110+
- script: |
111+
python -c '
112+
from pathlib import Path
113+
import shutil
114+
115+
from_folder = Path("$(Build.StagingDirectory)")
116+
destination_folder = Path("$(System.DefaultWorkingDirectory)") / ".tox"
117+
destination_folder.mkdir()
118+
for coverage_file in from_folder.glob("*/.coverage"):
119+
destination = destination_folder / f".coverage.{coverage_file.parent.name[9:]}"
120+
print(f"{coverage_file} copy to {destination}")
121+
shutil.copy(str(coverage_file), str(destination))'
122+
displayName: move coverage files into .tox
123+
124+
- script: 'python -m pip install -U tox --pre'
125+
displayName: install tox
126+
127+
- script: 'python -m tox -e py --sdistonly'
128+
displayName: generate version.py
129+
130+
- script: 'python -m tox -e coverage'
131+
displayName: create coverag report via tox
132+
133+
- task: PublishCodeCoverageResults@1
134+
displayName: publish overall coverage report to Azure
135+
inputs:
136+
codeCoverageTool: 'cobertura'
137+
summaryFileLocation: '$(System.DefaultWorkingDirectory)/.tox/coverage.xml'
138+
reportDirectory: '$(System.DefaultWorkingDirectory)/.tox/htmlcov'
139+
failIfCoverageEmpty: true
140+
141+
- script: |
142+
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter && \
143+
chmod +x ./cc-test-reporter && \
144+
python -c '
145+
from xml.etree import ElementTree as et
146+
from pathlib import Path
147+
import subprocess
148+
149+
from_folder = Path("$(Build.StagingDirectory)")
150+
for counter, coverage_file in enumerate(from_folder.glob("*/coverage.xml")):
151+
key = coverage_file.parent.name[9:]
152+
print(f"{counter}) {coverage_file}")
153+
try:
154+
cmd = ["$(System.DefaultWorkingDirectory)/cc-test-reporter", "format-coverage",
155+
str(coverage_file),
156+
"-d", "-t", "coverage.py",
157+
"-o", f"$(Build.StagingDirectory)/code-climate.{key}.json"]
158+
print(f"\t{cmd}")
159+
log = subprocess.check_output(cmd, stderr=subprocess.STDOUT, universal_newlines=True)
160+
code = 0
161+
except subprocess.CalledProcessError as exception:
162+
log, code = exception.output, exception.returncode
163+
finally:
164+
print(code, log, "\n", sep="\n")' && \
165+
./cc-test-reporter sum-coverage -d --output - \
166+
--parts $(ls -1 $(Build.StagingDirectory)/code-climate.*.json | wc -l) \
167+
$(Build.StagingDirectory)/code-climate.*.json | \
168+
./cc-test-reporter -d -r d24f105984ab5e087773a21b8668acb0b36cb8311fc2637f78a2d9451e531e08 \
169+
upload-coverage --input -
170+
displayName: publish code climate
171+
condition: succeededOrFailed()
76172
77173
- job: publish
78174
dependsOn:
79-
- tests_done
80-
- check_code_style
81-
- generate_docs
82-
- check_package_long_description
175+
- report_coverage
176+
- linux_fix_lint
177+
- linux_docs
178+
- linux_package_description
83179
condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/'))
84180
pool: {vmImage: 'Ubuntu 16.04'}
85181
steps:
@@ -90,5 +186,5 @@ jobs:
90186
displayName: Package and publish to PyPI
91187
inputs:
92188
pypiConnection: pypi-conn
93-
packageDirectory: '$(System.DefaultWorkingDirectory)'
189+
packageDirectory: $(System.DefaultWorkingDirectory)
94190
alsoPublishWheel: true

0 commit comments

Comments
 (0)