...
1#!/usr/bin/env python3
2"""Do a sanity check that you're at something that's ready for you to
3cut a GA tag from
4"""
5
6import os.path
7from os import getenv
8import sys
9import time
10from contextlib import contextmanager
11from typing import Generator
12
13from lib import assert_eq, git_check_clean, vX, vY, re_ga, re_ea
14from lib.uiutil import Checker, CheckResult, run
15from lib.uiutil import run_txtcapture as run_capture
16
17
18DEFAULT_REPO = 'git@github.com:emissary-ingress/emissary'
19
20
21def main(next_ver: str, quiet: bool = False) -> int:
22 print(f'Starting work on "v{next_ver}"...')
23 print()
24 remote_repo = getenv('AMBASSADOR_RELEASE_REPO_OVERRIDE')
25 if remote_repo is None or remote_repo == '':
26 remote_repo = DEFAULT_REPO
27
28 checker = Checker()
29
30 @contextmanager
31 def check(name: str) -> Generator[CheckResult, None, None]:
32 with checker.check(name) as subcheck:
33 # time.sleep(1) # it's stupid, but honestly the delay makes the output more readable
34 yield subcheck
35
36 is_private = False
37
38 with check(f"You're in a clone of {remote_repo}"):
39 url = run_capture(['git', 'remote', 'get-url', '--push', 'origin'])
40 if url.endswith("/"):
41 url = url[:-len("/")]
42 if url.endswith(".git"):
43 url = url[:-len(".git")]
44 if url.endswith("-private"):
45 is_private = True
46 url = url[:-len("-private")]
47 assert_eq(url, remote_repo)
48
49 with check("You're in the toplevel of the clone"):
50 toplevel = run_capture(['git', 'rev-parse', '--show-toplevel'])
51 if not os.path.samefile(toplevel, '.'):
52 raise Exception(f"Not in {toplevel}")
53
54 with check("You're in a clean checkout"):
55 git_check_clean()
56
57 # Cache the name of our remote...
58 remote_name = f'{remote_repo}.git' if is_private else 'origin'
59
60 # ...make sure the passed-in version is OK...
61 m = re_ga.match(next_ver)
62 if not m:
63 m = re_ea.match(next_ver)
64 assert m
65
66 if checker.ok:
67 if not quiet:
68 print()
69 print("Yep, looks like you're good to tag GA.")
70 return 0
71 else:
72 print()
73 print("Looks like there's something wrong with your tree that you need to address before continuing.")
74 return 1
75
76
77def branch_exists(remote: str, branch: str) -> None:
78 # Allow exceptions to propagate upward
79 run(['git', 'fetch', remote, f'refs/heads/{branch}'])
80
81
82def branch_up_to_date(remote: str, branch: str, update_cmd: str) -> None:
83 run(['git', 'fetch', remote, f'refs/heads/{branch}'])
84 try:
85 run(['git', 'merge-base', '--is-ancestor', 'FETCH_HEAD', 'HEAD'])
86 except Exception as err:
87 print(f"HEAD is not up-to-date with '{remote}' '{branch}':")
88 print("You need to update it with:")
89 print()
90 print(f" $ {update_cmd}")
91 print()
92 raise
93
94
95subtree_up_to_date = branch_up_to_date
96
97if __name__ == '__main__':
98 args = sys.argv[1:]
99 quiet = False
100
101 if args and (args[0] == '--quiet'):
102 quiet = True
103 args.pop(0)
104
105 if len(args) != 1 or (not re_ga.match(args[0]) and not re_ea.match(args[0])):
106 sys.stderr.write(f"Usage: {os.path.basename(sys.argv[0])} X.Y.Z(-ea)?\n")
107 sys.exit(2)
108
109 sys.exit(main(next_ver=args[0], quiet=quiet))
View as plain text