Skip to content

Commit

Permalink
update generating release notes
Browse files Browse the repository at this point in the history
  • Loading branch information
radTuti committed May 1, 2024
1 parent bcd6c93 commit 8a61c89
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 41 deletions.
16 changes: 9 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -161,15 +161,17 @@ bin/ocp.tgz: manifests/ocp/ bin/yq

## Generates release notes for the given version.
.PHONY: release-notes
release-notes:
ifndef GITHUB_TOKEN
$(error GITHUB_TOKEN must be set)
endif
ifndef VERSION
$(error VERSION must be set)
release-notes: var-require-all-GITHUB_TOKEN-VERSION
$(eval RELEASE_BRANCH = $(if $(RELEASE_BRANCH),$(RELEASE_BRANCH),release-$(shell echo "$(VERSION)" | awk -F "." '{print $$1"."$$2}')))
$(eval CURRENT_BRANCH = $(call current-branch))
ifeq ($(RELEASE_BRANCH),$(CURRENT_BRANCH))
$(error Cannot generate release notes for $(VERSION) from $(CURRENT_BRANCH) branch, use $(RELEASE_BRANCH) branch)
endif
VERSION=$(VERSION) GITHUB_TOKEN=$(GITHUB_TOKEN) python2 ./hack/release/generate-release-notes.py
@rm -rf release-notes/$(VERSION)-release-notes.md
@python3 -m pip install PyGithub==2.3.0 && \
VERSION=$(VERSION) GITHUB_TOKEN=$(GITHUB_TOKEN) ./hack/release/generate-release-notes.py

## Updat
## Update the AUTHORS.md file.
update-authors:
ifndef GITHUB_TOKEN
Expand Down
84 changes: 50 additions & 34 deletions hack/release/generate-release-notes.py
Original file line number Diff line number Diff line change
@@ -1,75 +1,91 @@
#!/usr/bin/env python
import github
from github import Github # https://github.com/PyGithub/PyGithub
#!/usr/bin/env python3
# pylint: disable=missing-module-docstring
# pylint: disable=missing-class-docstring
# pylint: disable=missing-function-docstring
import os
import re
import io
import string
import datetime
# To install, run python3 -m pip install PyGithub==2.3.0
from github import Github, Auth, UnknownObjectException # https://github.com/PyGithub/PyGithub

# Validate required environment variables
assert os.environ.get("GITHUB_TOKEN"), "GITHUB_TOKEN must be set"
assert os.environ.get("VERSION"), "VERSION must be set"
VERSION = os.environ.get("VERSION")
assert VERSION.startswith("v"), "VERSION must start with 'v'"

# First create a Github instance. Create a token through GitHub website - provide "repo" auth.
g = Github(os.environ.get('GITHUB_TOKEN'))
auth = Auth.Token(os.environ.get("GITHUB_TOKEN"))
g = Github(auth=auth)

# The milestone to generate notes for.
assert os.environ.get('VERSION')
VERSION=os.environ.get('VERSION')
MILESTONE="Calico %s" % VERSION
MILESTONE = f"Calico {VERSION}"
RELEASE_STREAM = ".".join(VERSION.split(".")[:2])

# The file where we'll store the release notes.
FILENAME="release-notes/%s-release-notes.md" % VERSION
FILENAME = f"release-notes/{VERSION}-release-notes.md"

# Repositories we care about. Add repositories here to include them in release
# note generation.
REPOS = [
"calico",
"bird",
"calico",
"bird",
]


# Returns a dictionary where the keys are repositories, and the values are
# a list of issues in the repository which match the milestone and
# have a `release-note-required` label.
def issues_by_repo():
all_issues = {}
all_repos_issues = {}
org = g.get_organization("projectcalico")
for repo in org.get_repos():
if not repo.name in REPOS:
for _repo in org.get_repos():
if not _repo.name in REPOS:
continue
print("Processing repo %s/%s" % (org.login, repo.name))
print(f"Processing repo {org.login}/{_repo.name}")

# Find the milestone. This finds all open milestones.
milestones = repo.get_milestones()
milestones = _repo.get_milestones()
for m in milestones:
if m.title == MILESTONE:
# Found the milestone in this repo - look for issues (but only
# ones that have been closed!)
# TODO: Assert that the PR has been merged somehow?
print(" found milestone %s" % m.title)
print(f" found milestone {m.title}")
try:
label = repo.get_label("release-note-required")
except github.UnknownObjectException:
label = _repo.get_label("release-note-required")
except UnknownObjectException:
# Label doesn't exist, skip this repo.
break
issues = repo.get_issues(milestone=m, labels=[label], state="closed")
for i in issues:
all_issues.setdefault(repo.name, []).append(i)
return all_issues
_issues = _repo.get_issues(milestone=m, labels=[label], state="closed")
for issue in _issues:
pr = issue.as_pull_request()
if pr.merged:
all_repos_issues.setdefault(_repo.name, []).append(issue)
else:
print(f"WARNING: {pr.number} is not merged, skipping")
return all_repos_issues


# Takes an issue and returns the appropriate release notes from that
# issue as a list. If it has a release-note section defined, that is used.
# If not, then it simply returns the title.
def extract_release_notes(issue):
# Look for a release note section in the body.
matches = re.findall(r'```release-note(.*?)```', issue.body, re.DOTALL)
matches = re.findall(r"```release-note(.*?)```", str(issue.body), re.DOTALL)
if matches:
return [m.strip() for m in matches]
else:
print("WARNING: %s has no release-note section" % (issue.number))
print(f"WARNING: {issue.number} has no release-note section")
return [issue.title.strip()]


if __name__ == "__main__":
# Get the list of issues.
all_issues = issues_by_repo()
if len(all_issues) == 0:
print(f"ERROR: No issues found for milestone {MILESTONE}")
exit(1)

# Get date in the right format.
date = datetime.date.today().strftime("%d %b %Y")
Expand All @@ -78,17 +94,17 @@ def extract_release_notes(issue):
os.makedirs("release-notes")

# Write release notes out to a file.
with io.open(FILENAME, "w", encoding='utf-8') as f:
f.write(u"%s\n\n" % date)
f.write(u"#### Headline feature 1\n\n")
f.write(u"#### Headline feature 2\n\n")
f.write(u"#### Bug fixes\n\n")
f.write(u"#### Other changes\n\n")
with io.open(FILENAME, "w", encoding="utf-8") as f:
f.write(f"{date}\n\n")
f.write("#### Headline feature 1\n\n")
f.write("#### Headline feature 2\n\n")
f.write("#### Bug fixes\n\n")
f.write("#### Other changes\n\n")
for repo, issues in all_issues.items():
print("Writing notes for %s" % repo)
print(f"Writing notes for {repo}")
for i in issues:
for note in extract_release_notes(i):
f.write(" - %s [%s #%d](%s) (@%s)\n" % (note, repo, i.number, i.html_url, i.user.login))
f.write(f" - {note} [{repo} #{i.number}]({i.html_url}) (@{i.user.login})\n")

print("")
print("Release notes written to " + FILENAME)
Expand Down

0 comments on commit 8a61c89

Please sign in to comment.