Merge lp:~lifeless/hydrazine/cron into lp:hydrazine

Proposed by Robert Collins on 2010-04-12
Status: Merged
Merge reported by: Martin Pool
Merged at revision: not available
Proposed branch: lp:~lifeless/hydrazine/cron
Merge into: lp:hydrazine
Diff against target: 197 lines (+70/-43)
2 files modified
feed-pqm (+69/-42)
hydrazine/__init__.py (+1/-1)
To merge this branch: bzr merge lp:~lifeless/hydrazine/cron
Reviewer Review Type Date Requested Status
Martin Pool 2010-04-12 Resubmit on 2010-05-13
Review via email: mp+23213@code.launchpad.net

Description of the Change

Use the LP API 'queued' status to record things 'sent' to PQM, and add a cron mode we should run somewhere that will automatically send one (and only one) email to PQM to handle such proposals.

To post a comment you must log in.
lp:~lifeless/hydrazine/cron updated on 2010-04-20
68. By Robert Collins on 2010-04-14

Include the queuer as a prefix and the branch owner as a suffix on commit messages, to automate current practice.

69. By Robert Collins on 2010-04-15

Save the tabs, save the world.

70. By Robert Collins on 2010-04-16

Set queued revision id when queuing.

71. By Robert Collins on 2010-04-18

After sending merge proposals, remove them from the queue if they would not have been found originally.

72. By Robert Collins on 2010-04-19

Handle submitting the last pending proposal.

73. By Robert Collins on 2010-04-20

Remove --cron mode.

74. By Robert Collins on 2010-04-20

Add back manual email submission via 'e'.

75. By Robert Collins on 2010-04-20

Really do it.

Martin Pool (mbp) wrote :

I think this is obsolete until we continue with queue mode? But if you want to separate out some of this, you can.

review: Resubmit
Robert Collins (lifeless) wrote :

No, it should be mergable now, as-is, as a qualititative improvement.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'feed-pqm'
2--- feed-pqm 2010-03-29 05:21:17 +0000
3+++ feed-pqm 2010-04-20 07:20:40 +0000
4@@ -16,12 +16,13 @@
5
6
7 import datetime
8+import optparse
9 import os
10-import subprocess
11 import sys
12
13+from bzrlib.email_message import EmailMessage
14 from bzrlib.config import GlobalConfig
15-from bzrlib.email_message import EmailMessage
16+from bzrlib import gpg
17 from bzrlib.smtp_connection import SMTPConnection
18
19 import hydrazine
20@@ -46,7 +47,12 @@
21 n skip this, go to the next
22 p previous
23 q quit
24- s send it to pqm!
25+ s submit approved merges to the queue (PQM reads from the launchpad
26+ queue) for already queued merges this toggles in and out of queued,
27+ setting a new queuer and putting it at the back of the queue.
28+ Requires membership in the review team for the target branch.
29+ e send in an approved merge via email. Requires GPG and email setup
30+ appropriately in bazaar.conf, and your key in the PQM keyring.
31
32 Please send feedback to mbp@canonical.com
33 """
34@@ -64,6 +70,7 @@
35 print ' %12s: %s' % ('message', mp.commit_message)
36 print ' %12s: %s' % ('source', mp.source_branch.bzr_identity)
37 print ' %12s: %s' % ('target', mp.target_branch.bzr_identity)
38+ print ' %12s: %s' % ('status', mp.queue_status)
39 show_datetime('created', mp.date_created)
40 show_datetime('reviewed', mp.date_reviewed)
41 print ' %12s: %s' % ('registrant', mp.registrant.name)
42@@ -81,71 +88,77 @@
43 mp.lp_save()
44
45
46-def send_mp(launchpad, mp):
47+def queue_mp(launchpad, mp):
48 if not mp.commit_message:
49 print "No message set? Use 'm'."
50 return
51-
52- # suggested subject should match the last comment on the mp so that gmail
53- # doesn't see it as a separate thread;
54- # <https://bugs.edge.launchpad.net/hydrazine/+bug/541586>
55- subject = "Re: [Merge] %s into %s" % (
56- mp.source_branch.bzr_identity,
57- mp.target_branch.bzr_identity)
58-
59+ if mp.queue_status == 'Queued':
60+ mp.setStatus(status='Approved')
61+ mp.setStatus(status='Queued', revid=mp.reviewed_revid)
62+
63+
64+def send_mp(launchpad, mp, send_mail=True):
65+ if not mp.commit_message:
66+ print "No message set - %s queued badly? Set a message first." % mp
67+ return False
68 print "merge command to be signed:"
69- print "Subject: %s" % subject
70 raw_message = (
71 "star-merge %s %s\n"
72 % (mp.source_branch.composePublicURL(scheme='http'),
73 mp.target_branch.composePublicURL(scheme='http')))
74+ print raw_message
75
76+ config = GlobalConfig()
77+ signer = gpg.GPGStrategy(config)
78+ signed_message = signer.sign(raw_message.encode('utf8'))
79 try:
80 my_email = os.environ['EMAIL']
81 except KeyError:
82 my_email = launchpad.me.preferred_email_address.email
83 print "EMAIL environment variable not set, using %s" % my_email
84- child = subprocess.Popen(
85- ['gpg', '--clearsign', '-a'],
86- stdin=subprocess.PIPE,
87- stdout=subprocess.PIPE)
88- signed_message = child.communicate(
89- raw_message)[0]
90- if child.returncode != 0:
91- print "gpg child failed"
92-
93- message = EmailMessage(my_email, PQM_ADDRESS, mp.commit_message,
94+ # TODO: put in bug numbers as well.
95+ commit_message = u"(%s) %s (%s)" % (launchpad.me.name, mp.commit_message,
96+ mp.source_branch.owner.display_name)
97+ message = EmailMessage(my_email, PQM_ADDRESS, commit_message,
98 signed_message)
99- config = GlobalConfig()
100- SMTPConnection(config).send_email(message)
101-
102- print "Sent!"
103-
104- if False:
105- # disabled, because some people think it's too noisy
106- mp.createComment(content="Fed to pqm\n\n" + raw_message,
107- subject=subject)
108-
109+ if send_mail:
110+ SMTPConnection(config).send_email(message)
111+ print "Sent!"
112+ else:
113+ print "Not sending email - disabled."
114+
115+ # suggested subject should match the last comment on the mp so that gmail
116+ # doesn't see it as a separate thread;
117+ # <https://bugs.edge.launchpad.net/hydrazine/+bug/541586>
118+ subject = "Re: [Merge] %s into %s" % (mp.source_branch.bzr_identity,
119+ mp.target_branch.bzr_identity)
120+ print "Recording that the proposal is submitted to PQM."
121+ fed_pqm = "submitted to PQM by hand.\n"
122+ mp.createComment(content=fed_pqm, subject=subject)
123+ return True
124
125
126 def main(argv):
127-
128+ parser = optparse.OptionParser()
129+ parser.add_option('--nomail', help="Do not send email commands", action="store_true", default=False)
130+ parser.add_option('--queued', help="Examine already queued proposals", action="store_true", default=False)
131+ opts, args = parser.parse_args()
132 launchpad = hydrazine.create_session()
133 project = launchpad.projects[argv[1]]
134-
135- print 'Looking for Approved mps in %s' % project
136 i = 0
137- all_mps = list(project.getMergeProposals(status=['Approved']))
138- if all_mps == []:
139- print "Nothing approved to merge?"
140- while True:
141+ find_status = ['Approved']
142+ if opts.queued:
143+ find_status.append('Queued')
144+ print 'Looking for %s mps in %s' % (find_status, project)
145+ all_mps = list(project.getMergeProposals(status=find_status))
146+ while len(all_mps):
147 mp = all_mps[i]
148 show_mp(mp)
149
150 while True:
151 whatnow = read_choice()
152 if whatnow == 'q':
153- return True
154+ return 0
155 elif whatnow in ('h', 'help', '?'):
156 show_help()
157 elif whatnow == 'n':
158@@ -159,11 +172,25 @@
159 elif whatnow == 'm':
160 set_message(mp)
161 elif whatnow == 's':
162- send_mp(launchpad, mp)
163+ queue_mp(launchpad, mp)
164+ if mp.queue_status not in find_status:
165+ del all_mps[i]
166+ if i == len(all_mps):
167+ i -= 1
168+ break
169+ elif whatnow == 'e':
170+ if send_mp(launchpad, mp, send_mail=not opts.nomail):
171+ del all_mps[i]
172+ if i == len(all_mps):
173+ i -= 1
174+ break
175 elif whatnow == '':
176 continue
177 else:
178 print "Sorry, don't understand %r" % whatnow
179+ if not len(all_mps):
180+ print "No remaining merge proposals matching status %r?" % find_status
181+ return 0
182
183
184 if __name__ == '__main__':
185
186=== modified file 'hydrazine/__init__.py'
187--- hydrazine/__init__.py 2010-03-02 05:39:02 +0000
188+++ hydrazine/__init__.py 2010-04-20 07:20:40 +0000
189@@ -11,7 +11,7 @@
190 EDGE_SERVICE_ROOT,
191 )
192
193-service_root = EDGE_SERVICE_ROOT
194+service_root = os.environ.get('LAUNCHPAD_API', EDGE_SERVICE_ROOT)
195
196
197 def trace(s):

Subscribers

People subscribed via source and target branches

to all changes: