Switch to unified view

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()