|
a/Allura/push_re.py |
|
b/Allura/push_re.py |
|
... |
|
... |
13 |
|
13 |
|
14 |
DEBUG=1
|
14 |
DEBUG=1
|
15 |
CP = ConfigParser()
|
15 |
CP = ConfigParser()
|
16 |
|
16 |
|
17 |
re_ticket_ref = re.compile(r'\[#(\d+)\]')
|
17 |
re_ticket_ref = re.compile(r'\[#(\d+)\]')
|
|
|
18 |
re_allura_ref = re.compile(r'\nreference: ')
|
|
|
19 |
re_git_dir = re.compile(r'.*\.git/?\Z')
|
18 |
|
20 |
|
19 |
CRED={}
|
21 |
CRED={}
|
20 |
|
22 |
|
21 |
def main():
|
23 |
def main():
|
22 |
CP.read(os.path.join(os.environ['HOME'], '.forgepushrc'))
|
24 |
CP.read(os.path.join(os.environ['HOME'], '.forgepushrc'))
|
23 |
engineer = option('re', 'engineer', 'Name of engineer pushing: ')
|
25 |
engineer = option('re', 'engineer', 'Name of engineer pushing: ')
|
24 |
api_key = option('re', 'api_key', 'Forge API Key:')
|
26 |
api_key = option('re', 'api_key', 'Forge API Key:')
|
25 |
secret_key = option('re', 'secret_key', 'Forge Secret Key:')
|
27 |
secret_key = option('re', 'secret_key', 'Forge Secret Key:')
|
|
|
28 |
classic_path = option('re', 'classic_path', 'The path to your forge-classic repo:')
|
|
|
29 |
if not re_git_dir.match(classic_path):
|
|
|
30 |
classic_path += '/.git/'
|
26 |
CRED['api_key'] = api_key
|
31 |
CRED['api_key'] = api_key
|
27 |
CRED['secret_key'] = secret_key
|
32 |
CRED['secret_key'] = secret_key
|
28 |
text, tag = make_ticket_text(engineer)
|
33 |
text, tag = make_ticket_text(engineer, classic_path)
|
29 |
raw_input("Verify that there are no new dependencies, or RPM's are built for all deps...")
|
34 |
raw_input("Verify that there are no new dependencies, or RPM's are built for all deps...")
|
30 |
raw_input("Verify that a new sandbox builds starts without engr help...")
|
35 |
raw_input("Verify that a new sandbox builds starts without engr help...")
|
31 |
print '*** Create a ticket on SourceForge (https://sourceforge.net/p/allura/tickets/new/) with the following contents:'
|
36 |
print '*** Create a ticket on SourceForge (https://sourceforge.net/p/allura/tickets/new/) with the following contents:'
|
32 |
print '*** Summary: Production Push (R:%s, D:%s) - allura' % (
|
37 |
print '*** Summary: Production Push (R:%s, D:%s) - allura' % (
|
33 |
tag, date.today().strftime('%Y%m%d'))
|
38 |
tag, date.today().strftime('%Y%m%d'))
|
|
... |
|
... |
35 |
print text
|
40 |
print text
|
36 |
print '---END---'
|
41 |
print '---END---'
|
37 |
newforge_num = raw_input('What is the newforge ticket number? ')
|
42 |
newforge_num = raw_input('What is the newforge ticket number? ')
|
38 |
print '*** Create a SOG Trac ticket (https://control.sog.geek.net/sog/trac/newticket?keywords=LIAISON) with the same summary...'
|
43 |
print '*** Create a SOG Trac ticket (https://control.sog.geek.net/sog/trac/newticket?keywords=LIAISON) with the same summary...'
|
39 |
print '---BEGIN---'
|
44 |
print '---BEGIN---'
|
40 |
print re_ticket_ref.sub('FO:\g<1>', text)
|
45 |
sog_text = re_ticket_ref.sub('FO:\g<1>', text)
|
|
|
46 |
print re_allura_ref.sub('\nreference: https://sourceforge.net/p/allura/tickets/%s/' % newforge_num, sog_text)
|
41 |
print '---END---'
|
47 |
print '---END---'
|
42 |
raw_input('Now link the two tickets...')
|
48 |
raw_input('Now link the two tickets...')
|
|
|
49 |
print "Let's tag the forge repo:"
|
43 |
command('git', 'tag', '-a', '-m', '[#%s] - Push to RE' % newforge_num, tag, 'master')
|
50 |
command('git', 'tag', '-a', '-m', '[#%s] - Push to RE' % newforge_num, tag, 'master')
|
|
|
51 |
print "Let's make a matching tag in the forge-classic repo:"
|
|
|
52 |
command('git', '--git-dir=%s' % classic_path, 'tag', '-a', '-m', '[#%s] - Push to RE' % newforge_num, tag, 'master')
|
44 |
command('git', 'push', 'origin', 'master')
|
53 |
command('git', 'push', 'origin', 'master')
|
|
|
54 |
command('git', 'push', '--tags', 'origin')
|
45 |
command('git', 'push', 'live', 'master')
|
55 |
command('git', 'push', 'live', 'master')
|
46 |
command('git', 'push', '--tags', 'origin')
|
|
|
47 |
command('git', 'push', '--tags', 'live')
|
56 |
command('git', 'push', '--tags', 'live')
|
|
|
57 |
|
|
|
58 |
command('git', '--git-dir=%s' % classic_path, 'push', 'origin', 'master')
|
|
|
59 |
command('git', '--git-dir=%s' % classic_path, 'push', '--tags', 'origin')
|
|
|
60 |
command('git', '--git-dir=%s' % classic_path, 'push', 'live', 'master')
|
|
|
61 |
command('git', '--git-dir=%s' % classic_path, 'push', '--tags', 'live')
|
48 |
raw_input('Now go to the sog-engr channel and let them know that %s is ready'
|
62 |
raw_input('Now go to the sog-engr channel and let them know that %s is ready'
|
49 |
' for pushing (include the JIRA ticket #' % tag)
|
63 |
' for pushing (include the JIRA ticket #' % tag)
|
50 |
raw_input('Make sure SOG restarted reactors and web services.')
|
64 |
raw_input('Make sure SOG restarted reactors and web services.')
|
51 |
CP.write(open(os.path.join(os.environ['HOME'], '.forgepushrc'), 'w'))
|
65 |
CP.write(open(os.path.join(os.environ['HOME'], '.forgepushrc'), 'w'))
|
52 |
print "You're done!"
|
66 |
print "You're done!"
|
53 |
|
67 |
|
54 |
def make_ticket_text(engineer):
|
68 |
def make_ticket_text(engineer, classic_path):
|
55 |
tag_prefix = date.today().strftime('release_%Y%m%d')
|
69 |
tag_prefix = date.today().strftime('release_%Y%m%d')
|
56 |
# get release tag
|
70 |
# get release tag
|
57 |
existing_tags_today = command('git tag -l %s*' % tag_prefix)
|
71 |
existing_tags_today = command('git tag -l %s*' % tag_prefix)
|
58 |
if existing_tags_today:
|
72 |
if existing_tags_today:
|
59 |
tag = '%s.%.2d' % (tag_prefix, len(existing_tags_today))
|
73 |
tag = '%s.%.2d' % (tag_prefix, len(existing_tags_today))
|
|
... |
|
... |
62 |
last_release = command('git tag -l release_*')
|
76 |
last_release = command('git tag -l release_*')
|
63 |
if last_release: last_release = last_release[-1]
|
77 |
if last_release: last_release = last_release[-1]
|
64 |
else: last_release = ''
|
78 |
else: last_release = ''
|
65 |
changes = command(
|
79 |
changes = command(
|
66 |
'git', 'log', "--format=* %h %s", last_release.strip() + '..')
|
80 |
'git', 'log', "--format=* %h %s", last_release.strip() + '..')
|
|
|
81 |
changes += command(
|
|
|
82 |
'git', '--git-dir=%s' % classic_path, 'log', "--format=* %h %s", last_release.strip() + '..')
|
|
|
83 |
if not changes:
|
67 |
assert changes, 'There were no commits found; maybe you forgot to merge dev->master?'
|
84 |
print 'There were no commits found; maybe you forgot to merge dev->master? (Ctrl-C to abort)'
|
68 |
changelog = ''.join(changes)
|
85 |
changelog = ''.join(changes or [])
|
69 |
changes = ''.join(format_changes(changes))
|
86 |
changes = ''.join(format_changes(changes))
|
70 |
print 'Changelog:\n%s' % changelog
|
87 |
print 'Changelog:\n%s' % changelog
|
71 |
print 'Tickets:\n%s' % changes
|
88 |
print 'Tickets:\n%s' % changes
|
72 |
prelaunch = []
|
89 |
prelaunch = []
|
73 |
postlaunch = []
|
90 |
postlaunch = []
|
74 |
needs_reactor_setup = raw_input('Does this release require a reactor_setup? [n]')
|
|
|
75 |
needs_flyway = raw_input('Does this release require a migration? [y]')
|
91 |
needs_flyway = raw_input('Does this release require a migration? [y]')
|
76 |
if needs_reactor_setup[:1].lower() in ('y', '1'):
|
92 |
needs_ensure_index = raw_input('Does this release require ensure_index? [y]')
|
77 |
postlaunch.append('* service reactor stop')
|
|
|
78 |
postlaunch.append('* allurapaste reactor_setup /var/local/config/production.ini')
|
|
|
79 |
postlaunch.append('* service reactor start')
|
|
|
80 |
if needs_flyway[:1].lower() in ('', 'y', '1'):
|
93 |
if needs_flyway[:1].lower() in ('', 'y', '1'):
|
81 |
prelaunch.append('* dump the database in case we need to roll back')
|
94 |
prelaunch.append('* dump the database in case we need to roll back')
|
82 |
postlaunch.append('* allurapaste flyway --url mongo://sfn-mongo:27017/')
|
95 |
postlaunch.append('* allurapaste flyway --url mongo://sfn-mongo:27017/')
|
|
|
96 |
if needs_ensure_index[:1].lower() in ('', 'y', '1'):
|
83 |
postlaunch.append('* allurapaste ensure_index /var/local/config/production.ini')
|
97 |
postlaunch.append('* allurapaste ensure_index /var/local/config/production.ini')
|
84 |
if postlaunch:
|
98 |
if postlaunch:
|
85 |
postlaunch = [ 'From sfu-scmprocess-1 do the following:\n' ] + postlaunch
|
99 |
postlaunch = [ 'From sfu-scmprocess-1 do the following:\n' ] + postlaunch
|
86 |
postlaunch = '\n'.join(postlaunch)
|
100 |
postlaunch = '\n'.join(postlaunch)
|
87 |
else:
|
101 |
else:
|
88 |
postlaunch = '-none-'
|
102 |
postlaunch = '-none-'
|
|
... |
|
... |
92 |
else:
|
106 |
else:
|
93 |
prelaunch = '-none-'
|
107 |
prelaunch = '-none-'
|
94 |
return TICKET_TEMPLATE.substitute(locals()), tag
|
108 |
return TICKET_TEMPLATE.substitute(locals()), tag
|
95 |
|
109 |
|
96 |
def format_changes(changes):
|
110 |
def format_changes(changes):
|
|
|
111 |
if not changes:
|
|
|
112 |
yield '-none-'
|
97 |
ticket_groups = defaultdict(list)
|
113 |
ticket_groups = defaultdict(list)
|
98 |
for change in changes:
|
114 |
for change in changes:
|
99 |
for m in re_ticket_ref.finditer(change):
|
115 |
for m in re_ticket_ref.finditer(change):
|
100 |
ticket_groups[m.group(0)].append(change)
|
116 |
ticket_groups[m.group(0)].append(change)
|
101 |
try:
|
117 |
try:
|
|
... |
|
... |
144 |
|
160 |
|
145 |
TICKET_TEMPLATE=string.Template('''{{{
|
161 |
TICKET_TEMPLATE=string.Template('''{{{
|
146 |
#!push
|
162 |
#!push
|
147 |
|
163 |
|
148 |
(engr) Name of Engineer pushing: $engineer
|
164 |
(engr) Name of Engineer pushing: $engineer
|
149 |
(engr) Which code tree(s): allura
|
165 |
(engr) Which code tree(s): allura, forge-classic
|
150 |
(engr) Is configtree to be pushed?: no
|
166 |
(engr) Is configtree to be pushed?: no
|
151 |
(engr) Which release/revision is going to be synced?: $tag
|
167 |
(engr) Which release/revision is going to be synced?: $tag
|
152 |
(engr) Itemized list of changes to be launched with sync:
|
168 |
(engr) Itemized list of changes to be launched with sync:
|
153 |
|
169 |
|
154 |
$changes
|
170 |
$changes
|
|
... |
|
... |
161 |
|
177 |
|
162 |
$postlaunch
|
178 |
$postlaunch
|
163 |
|
179 |
|
164 |
(engr) Approved for release (Dean/Dave/John): None
|
180 |
(engr) Approved for release (Dean/Dave/John): None
|
165 |
(sog) Outcome of sync:
|
181 |
(sog) Outcome of sync:
|
|
|
182 |
|
|
|
183 |
reference:
|
166 |
}}}''')
|
184 |
}}}''')
|
167 |
|
185 |
|
168 |
if __name__ == '__main__':
|
186 |
if __name__ == '__main__':
|
169 |
main()
|
187 |
main()
|