Skip to content

Commit ec2e3c7

Browse files
committed
Update the release notes in post release workflow
1 parent 11f554b commit ec2e3c7

File tree

3 files changed

+84
-2
lines changed

3 files changed

+84
-2
lines changed

.github/workflows/post-release.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,13 @@ jobs:
4646
--layout scripts/release/release-layout.yml \
4747
--repo "$GITHUB_REPOSITORY" \
4848
--github-token "$GITHUB_REPOSITORY:$GITHUB_TOKEN" "github/codeql-coding-standards-release-engineering:$RELEASE_ENGINEERING_TOKEN" \
49-
--skip-checks
49+
--skip-checks
50+
51+
- name: Update release notes
52+
env:
53+
GITHUB_TOKEN: ${{ github.token }}
54+
run: |
55+
python scripts/release/update-release-notes.py \
56+
--head-sha $HEAD_SHA \
57+
--repo "$GITHUB_REPOSITORY" \
58+
--github-token "$GITHUB_TOKEN"

scripts/release/requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
semantic-version==2.10.0
22
PyGithub==1.59.1
3-
PyYAML==6.0.1
3+
PyYAML==6.0.1
4+
GitPython==3.1.36
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
from __future__ import annotations # This enables postponed evaluation of type annotations. Required for typing.TYPE_CHECKING. See https://peps.python.org/pep-0563/
2+
from typing import TYPE_CHECKING
3+
import subprocess
4+
from pathlib import Path
5+
6+
if TYPE_CHECKING:
7+
from argparse import Namespace
8+
9+
def generate_release_notes() -> str:
10+
script_path = Path(__file__).parent / "generate_release_notes.py"
11+
cp = subprocess.run(["python", str(script_path)], capture_output=True)
12+
13+
if cp.returncode != 0:
14+
raise Exception(f"Error generating release notes: {cp.stderr.decode('utf-8')}")
15+
16+
return cp.stdout.decode("utf-8")
17+
18+
def main(args: Namespace) -> int:
19+
from github import Github, Auth
20+
import semantic_version # type: ignore
21+
import re
22+
import sys
23+
24+
repo = Github(auth=Auth.Token(args.github_token)).get_repo(args.repo)
25+
26+
pull_candidates = [pr for pr in repo.get_pulls(state="open") if pr.head.sha == args.head_sha]
27+
if len(pull_candidates) != 1:
28+
print(f"Error: expected exactly one PR for SHA {args.head_sha}, but found {len(pull_candidates)}", file=sys.stderr)
29+
return 1
30+
31+
pull_request = pull_candidates[0]
32+
33+
if pull_request.state != "open":
34+
print(f"Error: PR for version {args.version} is not open", file=sys.stderr)
35+
return 1
36+
37+
rc_branch_regex = r"^rc/(?P<version>.*)$"
38+
rc_branch_match = re.match(rc_branch_regex, pull_request.base.ref)
39+
if not rc_branch_match:
40+
print(f"Error: PR {pull_request.url} is not based on a release candidate branch", file=sys.stderr)
41+
return 1
42+
43+
release_version = rc_branch_match.group("version")
44+
45+
try:
46+
semantic_version.Version.parse(release_version) # type: ignore
47+
except ValueError as e:
48+
print(f"Error: invalid version {release_version} use by release branch. Reason {e}", file=sys.stderr)
49+
return 1
50+
51+
releases = [release for release in repo.get_releases() if release.title == f"v{release_version}"]
52+
if len(releases) != 1:
53+
print(f"Error: expected exactly one release with title {args.version}, but found {len(releases)}", file=sys.stderr)
54+
return 1
55+
release = releases[0]
56+
57+
release_notes = generate_release_notes()
58+
59+
release.update_release(name=release.title, message=release_notes, draft=release.draft, prerelease=release.prerelease, tag_name=release.tag_name)
60+
61+
return 0
62+
63+
if __name__ == '__main__':
64+
import argparse
65+
from sys import exit
66+
67+
parser = argparse.ArgumentParser()
68+
parser.add_argument('--head-sha', help="The head SHA of the release PR for which we update it's corresponding release", required=True)
69+
parser.add_argument('--repo', help="The owner and repository name. For example, 'octocat/Hello-World'. Used when testing this script on a fork", required=True, default="github/codeql-coding-standards")
70+
parser.add_argument('--github-token', help="The GitHub token to use to update the release", required=True)
71+
args = parser.parse_args()
72+
exit(main(args))

0 commit comments

Comments
 (0)