...
1#!/usr/bin/env python3
2"""Creates github release for tag
3"""
4
5import fileinput
6import os.path
7import os
8import sys
9from contextlib import contextmanager
10from typing import Generator
11
12from lib import re_ga, get_gh_repo, re_ea
13from lib.uiutil import Checker, CheckResult, run, run_txtcapture
14
15
16RELEASE_TITLE_FORMAT = "Emissary Ingress {release_version}"
17
18RELEASE_BODY_FORMAT= """
19## :tada: Emissary Ingress {release_version} :tada:
20
21#### Emissary Ingress is an open source, Kubernetes-native microservices API gateway built on the Envoy Proxy.
22
23Upgrade Emissary - https://www.getambassador.io/reference/upgrading.html
24View changelog - https://github.com/emissary-ingress/emissary/blob/{git_tag}/CHANGELOG.md
25Get started with Emissary on Kubernetes - https://www.getambassador.io/user-guide/getting-started
26
27{release_notes}
28"""
29
30
31def main(release_version: str) -> int:
32 # This context manager and check function are pretty much just to produce
33 # a nice list of steps...
34 in_ci = os.getenv('CI') != ''
35 checker = Checker()
36
37 @contextmanager
38 def check(name: str) -> Generator[CheckResult, None, None]:
39 with checker.check(name) as subcheck:
40 # time.sleep(1) # it's stupid, but honestly the delay makes the output more readable
41 yield subcheck
42
43 with check(f"Check that tag v{release_version} exists"):
44
45 if not in_ci:
46 run(['git', 'fetch', '--tags'])
47 run(['git', 'rev-parse', '--verify', f"v{release_version}"])
48 if not checker.ok:
49 return 1
50
51 buf = ""
52 with check(f"Creating release notes for {release_version}"):
53 # TODO: Rewrite this to use `docs/releaseNotes.yml` instead of
54 # `CHANGELOG.md`.
55 in_changelog = False
56 for line in fileinput.FileInput("CHANGELOG.md"):
57 if in_changelog:
58 if line.startswith("## ") or line == "### Ambassador Edge Stack only\n":
59 break
60 if line.startswith(f"[{release_version}]: https://github.com/"):
61 continue
62 if line == "### Emissary-ingress and Ambassador Edge Stack\n":
63 continue
64 buf += line
65 if line.startswith(f"## [{release_version}] "):
66 in_changelog = True
67 buf = buf.strip()
68 if buf == "":
69 raise Exception(f"Changelog entry for {release_version} not found. Are you sure you're trying to release that?")
70
71 print(f"Generated release notes:")
72 print(buf)
73 if not in_ci:
74 ok = input("Does this look correct? (y/n)")
75 if ok != 'y':
76 print('Ok, not generating release')
77 return 1
78 with check(f"Creating release for {release_version}"):
79 run([
80 "gh", "release", "create",
81 f"v{release_version}",
82 "--repo", get_gh_repo(),
83 "--title", RELEASE_TITLE_FORMAT.format(release_version=release_version),
84 "--notes", RELEASE_BODY_FORMAT.format(
85 release_version=release_version,
86 release_notes=buf,
87 git_tag="v"+release_version,
88 )])
89 if not checker.ok:
90 return 1
91
92 url = run_txtcapture([
93 "gh", "release", "view",
94 "--json=url",
95 "--jq=.url",
96 "--repo="+get_gh_repo(),
97 "v"+release_version])
98 print(f'echo "url={url}" >> $GITHUB_OUTPUT')
99 if os.getenv("AMBASSADOR_RELENG_NO_GUI") == '':
100 print('Release info from github:')
101 run(["gh", "release", "view", "--repo="+get_gh_repo(), f"v{release_version}"])
102
103 return 0
104
105
106if __name__ == '__main__':
107 args = sys.argv[1:]
108
109 if len(args) < 1 or (not re_ga.match(args[0]) and not re_ea.match(args[0])):
110 sys.stderr.write(f"Usage: {os.path.basename(sys.argv[0])} X.Y.Z(-ea)?\n")
111 sys.exit(2)
112
113 sys.exit(main(
114 release_version=args[0],
115 ))
View as plain text