1# -*- coding: utf-8 -*- 2""" 3Script used to publish GitHub release notes extracted from CHANGELOG.rst. 4 5This script is meant to be executed after a successful deployment in Travis. 6 7Uses the following environment variables: 8 9* GIT_TAG: the name of the tag of the current commit. 10* GH_RELEASE_NOTES_TOKEN: a personal access token with 'repo' permissions. It should be encrypted using: 11 12 $travis encrypt GH_RELEASE_NOTES_TOKEN=<token> -r pytest-dev/pytest 13 14 And the contents pasted in the ``deploy.env.secure`` section in the ``travis.yml`` file. 15 16The script also requires ``pandoc`` to be previously installed in the system. 17 18Requires Python3.6+. 19""" 20import os 21import re 22import sys 23from pathlib import Path 24 25import github3 26import pypandoc 27 28 29def publish_github_release(slug, token, tag_name, body): 30 github = github3.login(token=token) 31 owner, repo = slug.split("/") 32 repo = github.repository(owner, repo) 33 return repo.create_release(tag_name=tag_name, body=body) 34 35 36def parse_changelog(tag_name): 37 p = Path(__file__).parent.parent / "CHANGELOG.rst" 38 changelog_lines = p.read_text(encoding="UTF-8").splitlines() 39 40 title_regex = re.compile(r"pytest (\d\.\d+\.\d+) \(\d{4}-\d{2}-\d{2}\)") 41 consuming_version = False 42 version_lines = [] 43 for line in changelog_lines: 44 m = title_regex.match(line) 45 if m: 46 # found the version we want: start to consume lines until we find the next version title 47 if m.group(1) == tag_name: 48 consuming_version = True 49 # found a new version title while parsing the version we want: break out 50 elif consuming_version: 51 break 52 if consuming_version: 53 version_lines.append(line) 54 55 return "\n".join(version_lines) 56 57 58def convert_rst_to_md(text): 59 return pypandoc.convert_text(text, "md", format="rst") 60 61 62def main(argv): 63 if len(argv) > 1: 64 tag_name = argv[1] 65 else: 66 tag_name = os.environ.get("TRAVIS_TAG") 67 if not tag_name: 68 print("tag_name not given and $TRAVIS_TAG not set", file=sys.stderr) 69 return 1 70 71 token = os.environ.get("GH_RELEASE_NOTES_TOKEN") 72 if not token: 73 print("GH_RELEASE_NOTES_TOKEN not set", file=sys.stderr) 74 return 1 75 76 slug = os.environ.get("TRAVIS_REPO_SLUG") 77 if not slug: 78 print("TRAVIS_REPO_SLUG not set", file=sys.stderr) 79 return 1 80 81 rst_body = parse_changelog(tag_name) 82 md_body = convert_rst_to_md(rst_body) 83 if not publish_github_release(slug, token, tag_name, md_body): 84 print("Could not publish release notes:", file=sys.stderr) 85 print(md_body, file=sys.stderr) 86 return 5 87 88 print() 89 print(f"Release notes for {tag_name} published successfully:") 90 print(f"https://github.com/{slug}/releases/tag/{tag_name}") 91 print() 92 return 0 93 94 95if __name__ == "__main__": 96 sys.exit(main(sys.argv)) 97