Skip to content

Commit 94d94bc

Browse files
author
Sylvain MARIE
committed
Project updated to latest build process and badges
1 parent a7e3258 commit 94d94bc

15 files changed

Lines changed: 374 additions & 89 deletions

.travis.yml

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,38 @@ language: python
22

33
cache: pip
44

5-
python:
6-
# - "2.6"
7-
- "2.7"
8-
# - "3.2"
9-
# - "3.3"
10-
# - "3.4"
11-
- "3.5"
12-
# - "3.5-dev" # 3.5 development branch
13-
- "3.6"
14-
# - "3.6-dev" # 3.6 development branch
15-
# - "3.7"
16-
# - "3.7-dev" # 3.7 development branch
17-
# - "nightly" # currently points to 3.7-dev
18-
# PyPy versions
19-
# - "pypy" # PyPy2 2.5.0
20-
# - "pypy3" # Pypy3 2.4.0
21-
# - "pypy-5.3.1"
22-
#
5+
matrix:
6+
fast_finish: true
7+
include:
8+
# - python: 2.6
9+
- python: 2.7
10+
# - python: 3.3
11+
# - python: 3.4
12+
- python: 3.5
13+
- python: 3.6
14+
- python: 3.7
15+
dist: xenial
16+
sudo: true
2317

2418
env:
2519
global:
2620
- GH_REF: git@github.com:smarie/python-yamlable.git
2721

2822
before_install:
23+
# (a) linux dependencies
2924
- sudo apt-get install pandoc
3025
- sudo apt-get install ant
3126
- sudo apt-get install ant-optional
3227

3328
install:
34-
- pip install -r ci_tools/requirements-setup.txt
35-
- pip install -r ci_tools/requirements-test.txt
36-
- pip install -r ci_tools/requirements-report.txt
37-
- pip install -r ci_tools/requirements-doc.txt
38-
- pip install codecov # https://github.com/codecov/example-python. This is specific to travis integration
39-
# - pip install coveralls # this is an alternative to codecov
29+
- pip list
30+
# needs to be installed beforehand
31+
- pip install setuptools_scm
32+
- python ci_tools/py_install.py pip ci_tools/requirements-pip.txt
33+
# travis-specific installs
34+
- pip install PyGithub # for ci_tools/github_release.py
35+
- pip install codecov # See https://github.com/codecov/example-python.
36+
- pip list
4037

4138
script:
4239
# - coverage run tests.py
@@ -48,14 +45,14 @@ script:
4845
# now done in a dedicated script to capture exit code 1 and transform it to 0
4946
- chmod a+x ./ci_tools/run_tests.sh
5047
- sh ./ci_tools/run_tests.sh
48+
- python ci_tools/generate-junit-badge.py 100 # generates the badge for the test results and fail build if less than x%
5149

5250
after_success:
5351
# ***reporting***
5452
# - junit2html junit.xml testrun.html output is really not nice
5553
- ant -f ci_tools/generate-junit-html.xml # generates the html for the test results. Actually we dont use it anymore
56-
- python ci_tools/generate-junit-badge.py # generates the badge for the test results
5754
- codecov
58-
- pylint yamlable # note that at the moment the report is simply lost, we dont transform the result into anything
55+
#- pylint yamlable # note that at the moment the report is simply lost, we dont transform the result into anything
5956
# ***documentation***
6057
- mkdocs build -f docs/mkdocs.yml
6158
- mv reports/junit site/
@@ -67,11 +64,11 @@ after_success:
6764
if [ -s "ci_tools/github_travis_rsa" ]; then
6865
chmod 600 ci_tools/github_travis_rsa
6966
eval `ssh-agent -s` # launch the authentication agent
70-
ssh-add ci_tools/github_travis_rsa # register the key
67+
ssh-add ci_tools/github_travis_rsa # register the decrypted key
7168
git config user.name "Automatic Publish"
7269
git config user.email "sylvain.marie@schneider-electric.com"
7370
git remote add gh-remote "${GH_REF}";
74-
git fetch gh-remote && git fetch gh-remote gh-pages:gh-pages;
71+
git fetch gh-remote && git fetch gh-remote gh-pages:gh-pages; # make sure we have the latest gh-remote
7572
# push but only if this is not a build triggered by a pull request
7673
# note: here we use the --dirty flag so that mkdocs does not clean the additional reports that we copied in the site
7774
if [ "${TRAVIS_PULL_REQUEST}" = "false" ] && [ "${TRAVIS_PYTHON_VERSION}" = "3.5" ]; then echo "Pushing to github"; PYTHONPATH=yamlable/ mkdocs gh-deploy -v --dirty -f docs/mkdocs.yml --remote-name gh-remote; git push gh-remote gh-pages; fi;
@@ -80,18 +77,24 @@ after_success:
8077
fi
8178
8279
deploy:
83-
provider: pypi
84-
user: "smarie"
85-
password:
86-
secure: "TLBvYaFRplEFa8T0AW5b0LnRnz19/k/BEjtiiw4aWWrXTfNiWW1RRREG1iqqsqa6rkv547BVug2zj0SeeLvoncjGYclh92bmKMFhLVOlJtmYCIp8pNXT/3fEtrZosUN2OX4Z6qfOWnnefwjBB19rl18XPq/6zTyZ9dwKjkAfN+PPkHLqPtQ22+TcUe7f9jkDOs1pR0afacHz3HuBE5iaWbcDD2yCteJbfHwpFExfyO/X6LcjtQu63KH2NGvFP9qvwGrtnDIvmc1sWW9zi85H/j9T1TLQovJrY0oS8F+QOXbFlz/mOpORnh2sUj3f/nye0CvutnAqgS2OcRMqEAMIrdWzQOu8aBkKQuTOtiP+YKv7q7+GbWDIHJZK+whCWscS6XORVIaP5yGHc6SNZQqXarYskJFuRyJoClL51SxNsUzN4+yOLsdAqI/lvK2jIx4c2IztxuHEmbNwg1/R5/3YTk8g48U/nqOuIWBTNr0YwRRL/lBCxzGfHSjfcEnxzB0h/ORn0wBXig6tmNRyFAeA3qMHRekUgHjmzdZWw1yty3j1+sxdhOJXge+/AvqnNhSdY06w12WhEi4MV7p2pS5ZMX3Wnxvla/AzkCM4hrXxTYycAgFYjU2WkCCYqJwfV+Noa2hDbKPMHucoYBfB+qYNHUu0f+5uEGY3V5EhxZCmrGE="
87-
on:
88-
tags: true
89-
python: 3.5 #only one of the builds have to be deployed
90-
# server: https://test.pypi.org/legacy/
91-
distributions: "sdist bdist_wheel"
80+
# Deploy on PyPI on tags
81+
- provider: pypi
82+
user: "smarie"
83+
password:
84+
secure: "TLBvYaFRplEFa8T0AW5b0LnRnz19/k/BEjtiiw4aWWrXTfNiWW1RRREG1iqqsqa6rkv547BVug2zj0SeeLvoncjGYclh92bmKMFhLVOlJtmYCIp8pNXT/3fEtrZosUN2OX4Z6qfOWnnefwjBB19rl18XPq/6zTyZ9dwKjkAfN+PPkHLqPtQ22+TcUe7f9jkDOs1pR0afacHz3HuBE5iaWbcDD2yCteJbfHwpFExfyO/X6LcjtQu63KH2NGvFP9qvwGrtnDIvmc1sWW9zi85H/j9T1TLQovJrY0oS8F+QOXbFlz/mOpORnh2sUj3f/nye0CvutnAqgS2OcRMqEAMIrdWzQOu8aBkKQuTOtiP+YKv7q7+GbWDIHJZK+whCWscS6XORVIaP5yGHc6SNZQqXarYskJFuRyJoClL51SxNsUzN4+yOLsdAqI/lvK2jIx4c2IztxuHEmbNwg1/R5/3YTk8g48U/nqOuIWBTNr0YwRRL/lBCxzGfHSjfcEnxzB0h/ORn0wBXig6tmNRyFAeA3qMHRekUgHjmzdZWw1yty3j1+sxdhOJXge+/AvqnNhSdY06w12WhEi4MV7p2pS5ZMX3Wnxvla/AzkCM4hrXxTYycAgFYjU2WkCCYqJwfV+Noa2hDbKPMHucoYBfB+qYNHUu0f+5uEGY3V5EhxZCmrGE="
85+
on:
86+
tags: true
87+
python: 3.5 #only one of the builds have to be deployed
88+
# server: https://test.pypi.org/legacy/
89+
distributions: "sdist bdist_wheel"
9290

93-
matrix:
94-
fast_finish: true
91+
# Create a github release on tags
92+
- provider: script
93+
script: python ci_tools/github_release.py -s $GITHUB_TOKEN --repo-slug smarie/python-yamlable -cf ./docs/changelog.md -d https://smarie.github.io/python-yamlable/changelog/ $TRAVIS_TAG
94+
skip_cleanup: true
95+
on:
96+
tags: true
97+
python: 3.5 #only one of the builds have to be deployed
9598

9699
notifications:
97100
email:

README.md

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
*Convert Python objects to YAML and back.*
44

5-
[![Build Status](https://travis-ci.org/smarie/python-yamlable.svg?branch=master)](https://travis-ci.org/smarie/python-yamlable) [![Tests Status](https://smarie.github.io/python-yamlable/junit/junit-badge.svg?dummy=8484744)](https://smarie.github.io/python-yamlable/junit/report.html) [![codecov](https://codecov.io/gh/smarie/python-yamlable/branch/master/graph/badge.svg)](https://codecov.io/gh/smarie/python-yamlable) [![Documentation](https://img.shields.io/badge/docs-latest-blue.svg)](https://smarie.github.io/python-yamlable/) [![PyPI](https://img.shields.io/badge/PyPI-yamlable-blue.svg)](https://pypi.python.org/pypi/yamlable/)
5+
[![Python versions](https://img.shields.io/pypi/pyversions/yamlable.svg)](https://pypi.python.org/pypi/yamlable/) [![Build Status](https://travis-ci.org/smarie/python-yamlable.svg?branch=master)](https://travis-ci.org/smarie/python-yamlable) [![Tests Status](https://smarie.github.io/python-yamlable/junit/junit-badge.svg?dummy=8484744)](https://smarie.github.io/python-yamlable/junit/report.html) [![codecov](https://codecov.io/gh/smarie/python-yamlable/branch/master/graph/badge.svg)](https://codecov.io/gh/smarie/python-yamlable)
6+
7+
[![Documentation](https://img.shields.io/badge/doc-latest-blue.svg)](https://smarie.github.io/python-yamlable/) [![PyPI](https://img.shields.io/pypi/v/yamlable.svg)](https://pypi.python.org/pypi/yamlable/) [![Downloads](https://pepy.tech/badge/yamlable)](https://pepy.tech/project/yamlable) [![Downloads per week](https://pepy.tech/badge/yamlable/week)](https://pepy.tech/project/yamlable) [![GitHub stars](https://img.shields.io/github/stars/smarie/python-yamlable.svg)](https://github.com/smarie/python-yamlable/stargazers)
68

79
**This is the readme for developers.** The documentation for users is available here: [https://smarie.github.io/python-yamlable/](https://smarie.github.io/python-yamlable/)
810

@@ -34,9 +36,7 @@ This project uses `setuptools_scm` to synchronise the version number. Therefore
3436
python setup.py egg_info bdist_wheel rotate -m.whl -k3
3537
```
3638

37-
You need to [generate code](##building-from-sources--notes-on-this-projects-design-principles) before packaging.
38-
39-
You also may need to install requirements for setup beforehand, using
39+
You may need to install requirements for setup beforehand, using
4040

4141
```bash
4242
pip install -r ci_tools/requirements-setup.txt
@@ -47,7 +47,7 @@ pip install -r ci_tools/requirements-setup.txt
4747
This project uses `mkdocs` to generate its documentation page. Therefore building a local copy of the doc page may be done using:
4848

4949
```bash
50-
mkdocs build
50+
mkdocs build -f docs/mkdocs.yml
5151
```
5252

5353
You may need to install requirements for doc beforehand, using
@@ -74,3 +74,20 @@ This project is now automatically deployed to PyPI when a tag is created. Anyway
7474
twine upload dist/* -r pypitest
7575
twine upload dist/*
7676
```
77+
78+
### Merging pull requests with edits - memo
79+
80+
Ax explained in github ('get commandline instructions'):
81+
82+
```bash
83+
git checkout -b <git_name>-<feature_branch> master
84+
git pull https://github.com/<git_name>/python-yamlable.git <feature_branch> --no-commit --ff-only
85+
```
86+
87+
if the second step does not work, do a normal auto-merge (do not use **rebase**!):
88+
89+
```bash
90+
git pull https://github.com/<git_name>/python-yamlable.git <feature_branch> --no-commit
91+
```
92+
93+
Finally review the changes, possibly perform some modifications, and commit.

ci_tools/generate-junit-badge.py

Lines changed: 67 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,70 @@
1+
import sys
2+
try:
3+
# python 3
4+
from urllib.parse import quote_plus
5+
except ImportError:
6+
# python 2
7+
from urllib import quote_plus
8+
19
import requests
210
import shutil
311
from os import makedirs, path
412
import xunitparser
513

614

7-
def download_badge(junit_xml: str='reports/junit/junit.xml', dest_folder: str='reports/junit'):
15+
class TestStats(object):
16+
def __init__(self, success_percentage, success, runned, skipped):
17+
self.success_percentage = success_percentage
18+
self.success = success
19+
self.runned = runned
20+
self.skipped = skipped
821

9-
makedirs(dest_folder, exist_ok=True)
1022

11-
# read the junit test file
23+
def get_test_stats(junit_xml='reports/junit/junit.xml' # type: str
24+
):
25+
# type: (...) -> TestStats
26+
"""
27+
read the junit test file and extract the success percentage
28+
:param junit_xml: the junit xml file path
29+
:return: the success percentage (an int)
30+
"""
1231
ts, tr = xunitparser.parse(open(junit_xml))
13-
runned = tr.testsRun
32+
skipped = len(tr.skipped)
33+
runned = tr.testsRun - skipped
1434
failed = len(tr.failures)
35+
success = runned - failed
36+
37+
success_percentage = round(success * 100 / runned)
38+
39+
return TestStats(success_percentage, success, runned, skipped)
40+
41+
42+
def download_badge(test_stats, # type: TestStats
43+
dest_folder='reports/junit' # type: str
44+
):
45+
"""
46+
Downloads the badge corresponding to the provided success percentage, from https://img.shields.io.
1547
16-
success_percentage = round((runned - failed) * 100 / runned)
17-
if success_percentage < 50:
48+
:param test_stats:
49+
:param dest_folder:
50+
:return:
51+
"""
52+
if not path.exists(dest_folder):
53+
makedirs(dest_folder) # , exist_ok=True) not python 2 compliant
54+
55+
if test_stats.success_percentage < 50:
1856
color = 'red'
19-
elif success_percentage < 75:
57+
elif test_stats.success_percentage < 75:
2058
color = 'orange'
21-
elif success_percentage < 90:
59+
elif test_stats.success_percentage < 90:
2260
color = 'green'
2361
else:
2462
color = 'brightgreen'
25-
url = 'https://img.shields.io/badge/tests-' + str(success_percentage) + '%25-' + color + '.svg'
63+
64+
left_txt = "tests"
65+
# right_txt = "%s%%" % test_stats.success_percentage
66+
right_txt = "%s/%s" % (test_stats.success, test_stats.runned)
67+
url = 'https://img.shields.io/badge/%s-%s-%s.svg' % (left_txt, quote_plus(right_txt), color)
2668

2769
dest_file = path.join(dest_folder, 'junit-badge.svg')
2870

@@ -35,5 +77,19 @@ def download_badge(junit_xml: str='reports/junit/junit.xml', dest_folder: str='r
3577

3678

3779
if __name__ == "__main__":
38-
# execute only if run as a script
39-
download_badge()
80+
# Execute only if run as a script.
81+
# Check the arguments
82+
assert len(sys.argv[1:]) == 1, "a single mandatory argument is required: <threshold>"
83+
threshold = float(sys.argv[1])
84+
85+
# First retrieve the success percentage from the junit xml
86+
test_stats = get_test_stats()
87+
88+
# Validate against the threshold
89+
print("Success percentage is %s%%. Checking that it is >= %s" % (test_stats.success_percentage, threshold))
90+
if test_stats.success_percentage < threshold:
91+
raise Exception("Success percentage %s%% is strictly lower than required threshold %s%%"
92+
"" % (test_stats.success_percentage, threshold))
93+
94+
# Download the badge
95+
download_badge(test_stats)

0 commit comments

Comments
 (0)