Switch template to calendar versioning & automate releases (#3415)

This commit is contained in:
Bruno Alla 2021-11-18 09:36:42 +00:00 committed by GitHub
parent f49141d333
commit 183ca2088a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 100 additions and 82 deletions

View File

@ -1,4 +1,3 @@
## [{{merge_date.strftime('%Y-%m-%d')}}]
{%- for change_type, pulls in grouped_pulls.items() %} {%- for change_type, pulls in grouped_pulls.items() %}
{%- if pulls %} {%- if pulls %}
### {{ change_type }} ### {{ change_type }}

View File

@ -1,29 +0,0 @@
categories:
- title: 'Breaking Changes'
labels:
- 'breaking'
- title: 'Major Changes'
labels:
- 'major'
- title: 'Minor Changes'
labels:
- 'enhancement'
- title: 'Bugfixes'
labels:
- 'bug'
- title: 'Removals'
labels:
- 'removed'
- title: 'Documentation updates'
labels:
- 'docs'
exclude-labels:
- 'skip-changelog'
- 'update'
- 'project infrastructure'
template: |
## Changes
$CHANGES

View File

@ -1,14 +0,0 @@
name: Release Drafter
on:
push:
branches:
- master
jobs:
release_notes:
runs-on: ubuntu-latest
steps:
- uses: release-drafter/release-drafter@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -8,7 +8,10 @@ on:
workflow_dispatch: workflow_dispatch:
jobs: jobs:
build: release:
# Disables this workflow from running in a repository that is not part of the indicated organization/user
if: github.repository_owner == 'cookiecutter'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@ -22,13 +25,11 @@ jobs:
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install -r requirements.txt pip install -r requirements.txt
- name: Set git details
run: |
git config --global user.name "github-actions"
git config --global user.email "action@github.com"
- name: Update list - name: Update list
run: python scripts/update_changelog.py run: python scripts/update_changelog.py
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v4.12.0
with:
commit_message: Update Changelog
file_pattern: CHANGELOG.md

View File

@ -21,5 +21,6 @@ pyyaml==6.0
# Scripting # Scripting
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
PyGithub==1.55 PyGithub==1.55
gitpython==3.1.24
jinja2==3.0.3 jinja2==3.0.3
requests==2.26.0 requests==2.26.0

View File

@ -1,26 +1,31 @@
import datetime as dt import datetime as dt
import os import os
import re
from pathlib import Path from pathlib import Path
from typing import Iterable from typing import Iterable
from github import Github import git
import github.PullRequest import github.PullRequest
import github.Repository
from github import Github
from jinja2 import Template from jinja2 import Template
CURRENT_FILE = Path(__file__) CURRENT_FILE = Path(__file__)
ROOT = CURRENT_FILE.parents[1] ROOT = CURRENT_FILE.parents[1]
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN", None) GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
GITHUB_REPO = os.getenv("GITHUB_REPOSITORY", None) GITHUB_REPO = os.getenv("GITHUB_REPOSITORY")
GIT_BRANCH = os.getenv("GITHUB_REF_NAME")
# Generate changelog for PRs merged yesterday
MERGED_DATE = dt.date.today() - dt.timedelta(days=1)
def main() -> None: def main() -> None:
""" """
Script entry point. Script entry point.
""" """
merged_pulls = list(iter_pulls()) # Generate changelog for PRs merged yesterday
merged_date = dt.date.today() - dt.timedelta(days=1)
repo = Github(login_or_token=GITHUB_TOKEN).get_repo(GITHUB_REPO)
merged_pulls = list(iter_pulls(repo, merged_date))
print(f"Merged pull requests: {merged_pulls}")
if not merged_pulls: if not merged_pulls:
print("Nothing was merged, existing.") print("Nothing was merged, existing.")
return return
@ -29,26 +34,44 @@ def main() -> None:
grouped_pulls = group_pulls_by_change_type(merged_pulls) grouped_pulls = group_pulls_by_change_type(merged_pulls)
# Generate portion of markdown # Generate portion of markdown
rendered_content = generate_md(grouped_pulls) release_changes_summary = generate_md(grouped_pulls)
print(f"Summary of changes: {release_changes_summary}")
# Update CHANGELOG.md file # Update CHANGELOG.md file
file_path = ROOT / "CHANGELOG.md" release = f"{merged_date:%Y.%m.%d}"
old_content = file_path.read_text() changelog_path = ROOT / "CHANGELOG.md"
updated_content = old_content.replace( write_changelog(changelog_path, release, release_changes_summary)
"<!-- GENERATOR_PLACEHOLDER -->", print(f"Wrote {changelog_path}")
f"<!-- GENERATOR_PLACEHOLDER -->\n\n{rendered_content}",
# Update version
setup_py_path = ROOT / "setup.py"
update_version(setup_py_path, release)
print(f"Updated version in {setup_py_path}")
# Commit changes, create tag and push
update_git_repo([changelog_path, setup_py_path], release)
# Create GitHub release
github_release = repo.create_git_release(
tag=release,
name=release,
message=release_changes_summary,
) )
file_path.write_text(updated_content) print(f"Created release on GitHub {github_release}")
def iter_pulls() -> Iterable[github.PullRequest.PullRequest]: def iter_pulls(
repo: github.Repository.Repository,
merged_date: dt.date,
) -> Iterable[github.PullRequest.PullRequest]:
"""Fetch merged pull requests at the date we're interested in.""" """Fetch merged pull requests at the date we're interested in."""
repo = Github(login_or_token=GITHUB_TOKEN).get_repo(GITHUB_REPO)
recent_pulls = repo.get_pulls( recent_pulls = repo.get_pulls(
state="closed", sort="updated", direction="desc" state="closed",
sort="updated",
direction="desc",
).get_page(0) ).get_page(0)
for pull in recent_pulls: for pull in recent_pulls:
if pull.merged and pull.merged_at.date() == MERGED_DATE: if pull.merged and pull.merged_at.date() == merged_date:
yield pull yield pull
@ -77,7 +100,50 @@ def generate_md(grouped_pulls: dict[str, list[github.PullRequest.PullRequest]])
"""Generate markdown file from Jinja template.""" """Generate markdown file from Jinja template."""
changelog_template = ROOT / ".github" / "changelog-template.md" changelog_template = ROOT / ".github" / "changelog-template.md"
template = Template(changelog_template.read_text(), autoescape=True) template = Template(changelog_template.read_text(), autoescape=True)
return template.render(merge_date=MERGED_DATE, grouped_pulls=grouped_pulls) return template.render(grouped_pulls=grouped_pulls)
def write_changelog(file_path: Path, release: str, content: str) -> None:
"""Write Release details to the changelog file."""
content = f"## {release}\n{content}"
old_content = file_path.read_text()
updated_content = old_content.replace(
"<!-- GENERATOR_PLACEHOLDER -->",
f"<!-- GENERATOR_PLACEHOLDER -->\n\n{content}",
)
file_path.write_text(updated_content)
def update_version(file_path: Path, release: str) -> None:
"""Update template version in setup.py."""
old_content = file_path.read_text()
updated_content = re.sub(
r'\nversion = "\d+\.\d+\.\d+"\n',
f'\nversion = "{release}"\n',
old_content,
)
file_path.write_text(updated_content)
def update_git_repo(paths: list[Path], release: str) -> None:
"""Commit, tag changes in git repo and push to origin."""
repo = git.Repo(ROOT)
for path in paths:
repo.git.add(path)
message = f"Release {release}"
user = repo.git.config("--get", "user.name")
email = repo.git.config("--get", "user.email")
repo.git.commit(
m=message,
author=f"{user} <{email}>",
)
repo.git.tag("-a", release, m=message)
server = f"https://{GITHUB_TOKEN}@github.com/{GITHUB_REPO}.git"
print(f"Pushing changes to {GIT_BRANCH} branch of {GITHUB_REPO}")
repo.git.push(server, GIT_BRANCH)
repo.git.push("--tags", server, GIT_BRANCH)
if __name__ == "__main__": if __name__ == "__main__":
@ -85,4 +151,8 @@ if __name__ == "__main__":
raise RuntimeError( raise RuntimeError(
"No github repo, please set the environment variable GITHUB_REPOSITORY" "No github repo, please set the environment variable GITHUB_REPOSITORY"
) )
if GIT_BRANCH is None:
raise RuntimeError(
"No git branch set, please set the GITHUB_REF_NAME environment variable"
)
main() main()

View File

@ -1,21 +1,11 @@
#!/usr/bin/env python #!/usr/bin/env python
import os
import sys
try: try:
from setuptools import setup from setuptools import setup
except ImportError: except ImportError:
from distutils.core import setup from distutils.core import setup
# Our version ALWAYS matches the version of Django we support # We use calendar versioning
# If Django has a new release, we branch, tag, then update this setting after the tag. version = "2021.11.17"
version = "3.1.13-01"
if sys.argv[-1] == "tag":
os.system(f'git tag -a {version} -m "version {version}"')
os.system("git push --tags")
sys.exit()
with open("README.rst") as readme_file: with open("README.rst") as readme_file:
long_description = readme_file.read() long_description = readme_file.read()