Paul Sokolovsky | 2e361a1 | 2023-10-31 21:38:32 +0300 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | import argparse |
| 3 | import sys |
| 4 | import os |
| 5 | import re |
| 6 | import subprocess |
| 7 | |
| 8 | |
Paul Sokolovsky | 910fd55 | 2024-02-20 00:26:10 +0700 | [diff] [blame^] | 9 | DEFAULT_URL = "https://review.trustedfirmware.org/TF-A/trusted-firmware-a" |
Paul Sokolovsky | 2e361a1 | 2023-10-31 21:38:32 +0300 | [diff] [blame] | 10 | WORKDIR = "trusted-firmware-a" |
| 11 | |
Paul Sokolovsky | 006f923 | 2024-01-29 17:57:01 +0700 | [diff] [blame] | 12 | SKIP_PATTERNS = [ |
| 13 | r"docs\(changelog\): ", |
| 14 | r"Merge changes from topic ", |
| 15 | r"Merge \".+\" into ", |
| 16 | r"Merge changes .+ into ", |
| 17 | ] |
| 18 | |
Paul Sokolovsky | 2e361a1 | 2023-10-31 21:38:32 +0300 | [diff] [blame] | 19 | |
| 20 | def run(cmd): |
| 21 | return subprocess.check_call(cmd, shell=True) |
| 22 | |
| 23 | |
| 24 | def maybe_int(s): |
| 25 | if s.isdigit(): |
| 26 | return int(s) |
| 27 | return s |
| 28 | |
| 29 | |
| 30 | def main(): |
| 31 | argp = argparse.ArgumentParser(description="Prepare TF-A LTS release email content") |
Paul Sokolovsky | 910fd55 | 2024-02-20 00:26:10 +0700 | [diff] [blame^] | 32 | argp.add_argument("-u", "--url", default=DEFAULT_URL, help="repository URL (default: %(default)s)") |
| 33 | argp.add_argument("-b", "--branch", default="", help="repository branch for --latest option") |
| 34 | argp.add_argument("--latest", action="store_true", help="use latest release tag on --branch") |
Paul Sokolovsky | 2e361a1 | 2023-10-31 21:38:32 +0300 | [diff] [blame] | 35 | argp.add_argument("release_tag", nargs="?", help="release tag") |
| 36 | args = argp.parse_args() |
| 37 | if not args.release_tag and not args.latest: |
| 38 | argp.error("Either release_tag or --latest is required") |
| 39 | |
| 40 | with open(os.path.dirname(__file__) + "/lts-release-mail.txt") as f: |
| 41 | mail_template = f.read() |
| 42 | |
| 43 | if not os.path.exists(WORKDIR): |
Paul Sokolovsky | 910fd55 | 2024-02-20 00:26:10 +0700 | [diff] [blame^] | 44 | run("git clone %s %s" % (args.url, WORKDIR)) |
Paul Sokolovsky | 2e361a1 | 2023-10-31 21:38:32 +0300 | [diff] [blame] | 45 | os.chdir(WORKDIR) |
| 46 | else: |
| 47 | os.chdir(WORKDIR) |
| 48 | run("git pull --quiet") |
| 49 | |
| 50 | if args.latest: |
| 51 | latest = [] |
| 52 | for l in os.popen("git tag"): |
| 53 | if not re.match(r"lts-v\d+\.\d+\.\d+", l): |
| 54 | continue |
Paul Sokolovsky | 910fd55 | 2024-02-20 00:26:10 +0700 | [diff] [blame^] | 55 | if not l.startswith(args.branch): |
| 56 | continue |
Paul Sokolovsky | 2e361a1 | 2023-10-31 21:38:32 +0300 | [diff] [blame] | 57 | l = l.rstrip() |
| 58 | comps = [maybe_int(x) for x in l.split(".")] |
| 59 | comps.append(l) |
| 60 | if comps > latest: |
| 61 | latest = comps |
| 62 | if not latest: |
| 63 | argp.error("Could not find latest LTS tag") |
| 64 | args.release_tag = latest[-1] |
| 65 | |
| 66 | comps = args.release_tag.split(".") |
| 67 | prev_comps = comps[:-1] + [str(int(comps[-1]) - 1)] |
| 68 | prev_release = ".".join(prev_comps) |
| 69 | |
| 70 | subjects = [] |
| 71 | for l in os.popen("git log --oneline --reverse %s..%s" % (prev_release, args.release_tag)): |
Paul Sokolovsky | 006f923 | 2024-01-29 17:57:01 +0700 | [diff] [blame] | 72 | skip = False |
| 73 | for pat in SKIP_PATTERNS: |
| 74 | if re.match(pat, l.split(" ", 1)[1]): |
| 75 | skip = True |
| 76 | if not skip: |
| 77 | subjects.append(l.rstrip()) |
Paul Sokolovsky | 2e361a1 | 2023-10-31 21:38:32 +0300 | [diff] [blame] | 78 | |
| 79 | urls = [] |
| 80 | for s in subjects: |
| 81 | commit_id, _ = s.split(" ", 1) |
| 82 | for l in os.popen("git show %s" % commit_id): |
| 83 | if "Change-Id:" in l: |
| 84 | _, change_id = l.strip().split(None, 1) |
| 85 | urls.append("https://review.trustedfirmware.org/q/" + change_id) |
| 86 | |
| 87 | assert len(subjects) == len(urls) |
| 88 | |
| 89 | commits = "" |
| 90 | for i, s in enumerate(subjects, 1): |
| 91 | commits += "%s [%d]\n" % (s, i) |
| 92 | |
| 93 | references = "" |
| 94 | for i, s in enumerate(urls, 1): |
| 95 | references += "[%d] %s\n" % (i, s) |
| 96 | |
| 97 | # Strip trailing newline, as it's encoded in template. |
| 98 | commits = commits.rstrip() |
| 99 | references = references.rstrip() |
| 100 | |
| 101 | version = args.release_tag[len("lts-v"):] |
| 102 | sys.stdout.write( |
| 103 | mail_template.format( |
| 104 | version=version, |
| 105 | commits=commits, |
| 106 | references=references, |
| 107 | ) |
| 108 | ) |
| 109 | |
| 110 | |
| 111 | if __name__ == "__main__": |
| 112 | main() |