diff options
-rw-r--r-- | CHANGES.rst | 3 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | ci/ghrel_template.md.j2 | 5 | ||||
-rw-r--r-- | ci/github_releases.py | 146 | ||||
-rw-r--r-- | doc/changes.rst | 2 | ||||
-rw-r--r-- | doc/requirements.in | 1 | ||||
-rw-r--r-- | pyproject.toml | 8 |
7 files changed, 19 insertions, 150 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index dc05aa19..d845d884 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -22,6 +22,7 @@ Unreleased - Typing: all product and test code has type annotations. +.. scriv-start-here .. _changes_7-0-5: @@ -965,7 +966,7 @@ Version 5.3 — 2020-09-13 .. _issue 1011: https://github.com/nedbat/coveragepy/issues/1011 -.. endchangesinclude +.. scriv-end-here Older changes ------------- @@ -253,8 +253,8 @@ relnotes_json: $(RELNOTES_JSON) ## Convert changelog to JSON for further parsin $(RELNOTES_JSON): $(CHANGES_MD) $(DOCBIN)/python ci/parse_relnotes.py tmp/rst_rst/changes.md $(RELNOTES_JSON) -github_releases: $(RELNOTES_JSON) ## Update GitHub releases. - $(DOCBIN)/python ci/github_releases.py $(RELNOTES_JSON) $(REPO_OWNER) +github_releases: $(DOCBIN) ## Update GitHub releases. + $(DOCBIN)/python -m scriv github-release comment_on_fixes: $(RELNOTES_JSON) ## Add a comment to issues that were fixed. python ci/comment_on_fixes.py $(REPO_OWNER) diff --git a/ci/ghrel_template.md.j2 b/ci/ghrel_template.md.j2 new file mode 100644 index 00000000..9d626bca --- /dev/null +++ b/ci/ghrel_template.md.j2 @@ -0,0 +1,5 @@ +<!-- for use with scriv to create GitHub releases. --> +{{body}} + +:arrow_right: PyPI page: [coverage {{version}}](https://pypi.org/project/coverage/{{version}}). +:arrow_right: To install: `python3 -m pip install coverage=={{version}}` diff --git a/ci/github_releases.py b/ci/github_releases.py deleted file mode 100644 index 5ba3d522..00000000 --- a/ci/github_releases.py +++ /dev/null @@ -1,146 +0,0 @@ -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt - -"""Upload release notes into GitHub releases.""" - -import json -import shlex -import subprocess -import sys - -import pkg_resources -import requests - - -RELEASES_URL = "https://api.github.com/repos/{repo}/releases" - -def run_command(cmd): - """ - Run a command line (with no shell). - - Returns a tuple: - bool: true if the command succeeded. - str: the output of the command. - - """ - proc = subprocess.run( - shlex.split(cmd), - shell=False, - check=False, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - ) - output = proc.stdout.decode("utf-8") - succeeded = proc.returncode == 0 - return succeeded, output - -def does_tag_exist(tag_name): - """ - Does `tag_name` exist as a tag in git? - """ - return run_command(f"git rev-parse --verify {tag_name}")[0] - -def check_ok(resp): - """ - Check that the Requests response object was successful. - - Raise an exception if not. - """ - if not resp: - print(f"text: {resp.text!r}") - resp.raise_for_status() - -def github_paginated(session, url): - """ - Get all the results from a paginated GitHub url. - """ - while True: - resp = session.get(url) - check_ok(resp) - yield from resp.json() - next_link = resp.links.get("next", None) - if not next_link: - break - url = next_link["url"] - -def get_releases(session, repo): - """ - Get all the releases from a name/project repo. - - Returns: - A dict mapping tag names to release dictionaries. - """ - url = RELEASES_URL.format(repo=repo) - releases = { r['tag_name']: r for r in github_paginated(session, url) } - return releases - -RELEASE_BODY_FMT = """\ -{relnote_text} - -:arrow_right:\xa0 PyPI page: [coverage {version}](https://pypi.org/project/coverage/{version}). -:arrow_right:\xa0 To install: `python3 -m pip install coverage=={version}` -""" - -def release_for_relnote(relnote): - """ - Turn a release note dict into the data needed by GitHub for a release. - """ - relnote_text = relnote["text"] - tag = version = relnote["version"] - body = RELEASE_BODY_FMT.format(relnote_text=relnote_text, version=version) - return { - "tag_name": tag, - "name": version, - "body": body, - "draft": False, - "prerelease": relnote["prerelease"], - } - -def create_release(session, repo, release_data): - """ - Create a new GitHub release. - """ - print(f"Creating {release_data['name']}") - resp = session.post(RELEASES_URL.format(repo=repo), json=release_data) - check_ok(resp) - -def update_release(session, url, release_data): - """ - Update an existing GitHub release. - """ - print(f"Updating {release_data['name']}") - resp = session.patch(url, json=release_data) - check_ok(resp) - -def update_github_releases(json_filename, repo): - """ - Read the json file, and create or update releases in GitHub. - """ - gh_session = requests.Session() - releases = get_releases(gh_session, repo) - if 0: # if you need to delete all the releases! - for release in releases.values(): - print(release["tag_name"]) - resp = gh_session.delete(release["url"]) - check_ok(resp) - return - - with open(json_filename) as jf: - relnotes = json.load(jf) - relnotes.sort(key=lambda rel: pkg_resources.parse_version(rel["version"])) - for relnote in relnotes: - tag = relnote["version"] - if not does_tag_exist(tag): - continue - release_data = release_for_relnote(relnote) - exists = tag in releases - if not exists: - create_release(gh_session, repo, release_data) - else: - release = releases[tag] - if release["body"] != release_data["body"]: - url = release["url"] - update_release(gh_session, url, release_data) - -if __name__ == "__main__": - update_github_releases(*sys.argv[1:3]) diff --git a/doc/changes.rst b/doc/changes.rst index da0f45ae..7f2df618 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -6,7 +6,7 @@ .. The recent changes from the top-level file: .. include:: ../CHANGES.rst - :end-before: endchangesinclude + :end-before: scriv-end-here .. Older changes here: diff --git a/doc/requirements.in b/doc/requirements.in index 12aba6cc..42eca405 100644 --- a/doc/requirements.in +++ b/doc/requirements.in @@ -9,6 +9,7 @@ cogapp #doc8 pyenchant +scriv # for writing GitHub releases sphinx sphinx-autobuild sphinx_rtd_theme diff --git a/pyproject.toml b/pyproject.toml index b21ba3b7..e11a5af1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,3 +27,11 @@ exclude = """(?x)( ^coverage/fullcoverage/encodings\\.py$ # can't import things into it. | ^tests/balance_xdist_plugin\\.py$ # not part of our test suite. )""" + +[tool.scriv] +# Changelog management: https://pypi.org/project/scriv/ +format = "rst" +output_file = "CHANGES.rst" +insert_marker = "scriv-start-here" +end_marker = "scriv-end-here" +ghrel_template = "file: ci/ghrel_template.md.j2" |