Skip to content

Commit

Permalink
rework release_merge_info script to handle releases in branches
Browse files Browse the repository at this point in the history
  • Loading branch information
javierggt committed Aug 25, 2023
1 parent 45e3647 commit 286e060
Showing 1 changed file with 90 additions and 53 deletions.
143 changes: 90 additions & 53 deletions skare3_tools/github/scripts/release_merge_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,54 +11,38 @@
import argparse
import re
import sys
import numpy as np

from packaging.version import Version
from skare3_tools import github, packages


def parser():
def get_parser():
parse = argparse.ArgumentParser(description=__doc__)
parse.add_argument(
"--repository", required=True, help="repository name. Example: sot/chandra_aca"
)
parse.add_argument("--sha", help="sha of the release")
parse.add_argument("--tag", help="tag of the release")
parse.add_argument(
"--token", "-t", help="Github token, or name of file that contains token"
)
parse.add_argument(
"--stdout",
action="store_true",
help="print to stdout instead of editing release description",
)
return parse


def main():
args = parser().parse_args()
github.init(token=args.token)
repository = github.Repository(args.repository)

# get all releases and find the one we are working on
releases = repository.releases()
releases = [r for r in releases if not r["draft"] and not r["prerelease"]]
releases = sorted(releases, key=lambda r: Version(r["tag_name"]), reverse=True)
release_commits = [
packages._get_release_commit(repository, r["tag_name"]) for r in releases
]
release_shas = [c["sha"] for c in release_commits]
i_1 = None
for i, sha in enumerate(release_shas):
if sha == args.sha:
i_1 = i
if i_1 is None:
raise Exception(f"Release with sha {args.sha} was not found")

# get all commits between this release and the previous one, if any.
kwargs = {
"until": repository.commits(ref=release_shas[i_1])["commit"]["author"]["date"]
}
if i_1 + 1 < len(releases):
kwargs["since"] = repository.commits(ref=release_shas[i_1 + 1])["commit"][
"author"
]["date"]
commits = repository.commits(sha="master", **kwargs)[
:-1
] # remove the last one, the release
def merges_in_range(repo, sha_1, sha_2):
commits_1 = repo.commits(sha=sha_1)
commits_2 = repo.commits(sha=sha_2)
sha_1 = [c["sha"] for c in commits_1]
sha_2 = [c["sha"] for c in commits_2]
i = np.argwhere(np.in1d(sha_2, sha_1)).flatten()[0]
commits = commits_2[:i]
assert len(commits) # TODO: shouldn't it be possible with no commits?

# get commit messages matching the standard merge commit
merges = []
Expand All @@ -70,32 +54,85 @@ def main():
)
if match:
msg = match.groupdict()
if msg["pr"][0] == "#":
if msg["description"] is None:
msg["description"] = repo.pull_requests(msg["pr"][1:])[0]['title']
msg["pr"] = (
f'[{msg["pr"]}]'
f'(https://github.com/{args.repository}/pull/{msg["pr"][1:]})'
)
merges.append(f'PR {msg["pr"]}: {msg["description"]}')
if merges:
if msg["description"] is None:
msg["description"] = repo.pull_requests(msg["pr"][1:])[0]["title"]
merges.append(msg)
return merges


def main():
parser = get_parser()
args = parser.parse_args()

if not args.tag and not args.sha:
parser.exit("Need to specify tag or sha")

github.init(token=args.token)

repo = github.Repository(args.repository)

# get all releases and their commit sha
releases = repo.releases()
releases = [r for r in releases if not r["draft"] and not r["prerelease"]]
releases = sorted(releases, key=lambda r: Version(r["tag_name"]), reverse=True)
releases = {r["tag_name"]: r for r in releases}
for tag, rel in releases.items():
releases[tag]["sha"] = packages._get_release_commit(repo, rel["tag_name"])[
"sha"
]

release_shas = [rel["sha"] for rel in releases.values()]
releases_by_sha = {rel["sha"]: rel for rel in releases.values()}

# normalize and check arguments
if args.tag and not args.sha:
args.sha = releases[args.tag]["sha"]
elif args.sha and not args.tag:
args.tag = releases_by_sha[args.sha]["tag_name"]

assert args.sha in release_shas, f"Release with sha {args.sha} was not found"
assert args.tag in releases, f"Release with tag {args.tag} was not found"
assert releases[args.tag]["sha"] == args.sha, f"Inconsistent release sha and tag"

# now find all merges between the previous release and the requested one
# checking for commit messages matching the standard merge commit
merges = merges_in_range(
repo,
release_shas[release_shas.index(args.sha) + 1], # TODO: limit check here?
args.sha,
)

msgs = []
for merge in merges:
if merge["pr"][0] == "#":
merge["pr"] = (
f'[{merge["pr"]}]'
f'(https://github.com/{args.repository}/pull/{merge["pr"][1:]})'
)
msgs.append(f'PR {merge["pr"]}: {merge["description"]}')

if msgs:
# edit the release to include the merge information
release_id = releases[i_1]["id"]
body = releases[i_1]["body"]
release = releases[args.tag]
release_id = release["id"]
body = release["body"]
if body:
body += "\n\n"
body += "Includes the following merges:\n"
for merge in merges:
body += f"- {merge}\n"

r = repository.releases.edit(release_id, body=body)
if not r["response"]["ok"]:
sys.exit(
(
f"Failed to edit release '{releases[i_1]['name']}'"
f" ({release_id}): {r['response']['reason']}"
for msg in msgs:
body += f"- {msg}\n"

if args.stdout:
print(body)
else:
r = repo.releases.edit(release_id, body=body)
if not r["response"]["ok"]:
sys.exit(
(
f"Failed to edit release '{release['name']}'"
f" ({release_id}): {r['response']['reason']}"
)
)
)


if __name__ == "__main__":
Expand Down

0 comments on commit 286e060

Please sign in to comment.