Merge lp://staging/~sinzui/launchpad/release-love into lp://staging/launchpad

Proposed by Curtis Hovey
Status: Merged
Approved by: Eleanor Berger
Approved revision: not available
Merged at revision: not available
Proposed branch: lp://staging/~sinzui/launchpad/release-love
Merge into: lp://staging/launchpad
Diff against target: 262 lines (+73/-24)
10 files modified
database/schema/security.cfg (+3/-0)
lib/canonical/launchpad/subscribers/karma.py (+8/-2)
lib/lp/bugs/doc/malone-karma.txt (+32/-1)
lib/lp/registry/browser/productrelease.py (+0/-5)
lib/lp/registry/browser/tests/productrelease-views.txt (+0/-6)
lib/lp/registry/doc/milestone.txt (+23/-0)
lib/lp/registry/model/milestone.py (+6/-2)
lib/lp/registry/stories/productrelease/xx-productrelease-basics.txt (+0/-6)
lib/lp/registry/stories/productrelease/xx-productrelease-view.txt (+0/-1)
lib/lp/registry/templates/milestone-index.pt (+1/-1)
To merge this branch: bzr merge lp://staging/~sinzui/launchpad/release-love
Reviewer Review Type Date Requested Status
Eleanor Berger (community) Approve
Review via email: mp+17864@code.staging.launchpad.net
To post a comment you must log in.
Revision history for this message
Curtis Hovey (sinzui) wrote :
Download full text (3.6 KiB)

This is my branch to improve the release experience.

    lp:~sinzui/launchpad/release-love
    Diff size: 242
    Launchpad bug: https://bugs.launchpad.net/bugs/403554
                   https://bugs.launchpad.net/bugs/510984
                   https://bugs.launchpad.net/bugs/341687
                   https://bugs.launchpad.net/bugs/386584
                   https://bugs.launchpad.net/bugs/386586
    Test command: ./bin/test -vv \
        -t malone-karma \
        -t productrelease-views \
        -t milestone \
        -t xx-productrelease-basics \
        -t xx-productrelease-view
    Pre-implementation: No one. I really wanted to do this.
    Target release: 10.01

Improve the release experience
------------------------------

This branch fixes several small bugs that irk me when I make releases.
    * Project drivers do not get credit for setting a bug to triaged,
but
      users get credit for setting a bug to confirmed.
    * When creating a release, all the fix committed bugs should be set
to
      fix released.
    * The release manager should not get the karma for marking bugs fix
      released when they are assigned to someone.
    * The release manager should not see a warning about a deactivate
      milestone because 1) the form asked him if he wanted to keep it
active
      and 2) the milestone page clearly and prominently show the state,
    * Do not show the date expected when showing the date released. This
      does not mean much for launchpad, but it means a lot for
milestones
      that are not time-boxed.

Rules
-----

    * Treated triaged as confirmed in karma rules.
    * Add a rule to award karma to the assignee of a fix released bug.
    * Set fix committed bugs to fix released when a milestone creates
      a release.
    * Do not show a warning about a deactivated milestone when the user
      can see the status in both for the form and the page.
    * Do not show the date expect when a milestone has a date released.

QA
--

    * Triage a bug.
    * Verify that you are awarded bugaccepted karma on you karma
activity.

    * Mark a bug that is assigned to someone else as fix committed.
    * Verify that you are NOT awarded bugfixed karma on you karma
activity.
    * Verify that the other user is awarded bugfixed karma on his karma
      activity page.

    * Release a milestone with bugs fix committed.
    * Verify that the milestones are fixed released.

    * When creating a release, verify that you do not see an info
      notification that the milestone was deactivated because you told
      Launchpad to deactivate it

    * Visit https://edge.launchpad.net/libcpuinfo/trunk/0.0.1
    * Verify that the Expected field is not displayed.

Lint
----

Linting changed files:
  lib/canonical/launchpad/subscribers/karma.py
  lib/lp/bugs/doc/malone-karma.txt
  lib/lp/registry/browser/productrelease.py
  lib/lp/registry/browser/tests/productrelease-views.txt
  lib/lp/registry/doc/milestone.txt
  lib/lp/registry/model/milestone.py
  lib/lp/registry/stories/productrelease/xx-productrelease-basics.txt
  lib/lp/registry/stories/productrelease/xx-productrelease-view.txt
  lib/lp/registry/templates/milestone-index.pt

T...

Read more...

Revision history for this message
Eleanor Berger (intellectronica) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'database/schema/security.cfg'
2--- database/schema/security.cfg 2010-01-17 09:15:43 +0000
3+++ database/schema/security.cfg 2010-01-22 21:50:26 +0000
4@@ -410,6 +410,8 @@
5 # Dyson release import script
6 type=user
7 groups=script
8+public.bug = SELECT
9+public.bugtask = SELECT, UPDATE
10 public.product = SELECT
11 public.productseries = SELECT
12 public.productrelease = SELECT, INSERT, UPDATE
13@@ -420,6 +422,7 @@
14 public.libraryfilealias = SELECT, INSERT
15 public.libraryfilecontent = SELECT, INSERT
16 public.milestone = SELECT, INSERT
17+public.sourcepackagename = SELECT
18
19 [pofilestats]
20 # Translations POFile statistics verification/update script
21
22=== modified file 'lib/canonical/launchpad/subscribers/karma.py'
23--- lib/canonical/launchpad/subscribers/karma.py 2009-06-25 05:30:52 +0000
24+++ lib/canonical/launchpad/subscribers/karma.py 2010-01-22 21:50:26 +0000
25@@ -100,13 +100,19 @@
26 actionname_status_mapping = {
27 BugTaskStatus.FIXRELEASED: 'bugfixed',
28 BugTaskStatus.INVALID: 'bugrejected',
29- BugTaskStatus.CONFIRMED: 'bugaccepted'}
30+ BugTaskStatus.CONFIRMED: 'bugaccepted',
31+ BugTaskStatus.TRIAGED: 'bugaccepted',
32+ }
33
34 if task_delta.status:
35 new_status = task_delta.status['new']
36 actionname = actionname_status_mapping.get(new_status)
37 if actionname is not None:
38- _assign_karma_using_bugtask_context(user, bugtask, actionname)
39+ if actionname == 'bugfixed' and bugtask.assignee is not None:
40+ _assign_karma_using_bugtask_context(
41+ bugtask.assignee, bugtask, actionname)
42+ else:
43+ _assign_karma_using_bugtask_context(user, bugtask, actionname)
44
45 if task_delta.importance is not None:
46 _assign_karma_using_bugtask_context(
47
48=== modified file 'lib/lp/bugs/doc/malone-karma.txt'
49--- lib/lp/bugs/doc/malone-karma.txt 2009-07-23 17:49:31 +0000
50+++ lib/lp/bugs/doc/malone-karma.txt 2010-01-22 21:50:26 +0000
51@@ -79,6 +79,24 @@
52 >>> notify(ObjectModifiedEvent(bugtask, old_bugtask, ['status']))
53 Karma added: action=bugfixed, distribution=debian
54
55+Mark a bug task as fixed when it is assigned awards the karma to the assignee:
56+
57+ >>> from lp.bugs.interfaces.bugtask import IUpstreamBugTask
58+
59+ >>> ufo_product = factory.makeProduct(name='ufo')
60+ >>> assignee = factory.makePerson(name='assignee')
61+ >>> assigned_bugtask = factory.makeBugTask(bug=bug, target=ufo_product)
62+ >>> assigned_bugtask.transitionToAssignee(assignee)
63+ >>> old_bugtask = Snapshot(assigned_bugtask, providing=IUpstreamBugTask)
64+ >>> assigned_bugtask.transitionToStatus(
65+ ... BugTaskStatus.FIXRELEASED, getUtility(ILaunchBag).user)
66+ >>> notify(ObjectModifiedEvent(assigned_bugtask, old_bugtask, ['status']))
67+ Karma added: action=bugfixed, product=ufo
68+
69+ >>> for karma in assignee.latestKarma():
70+ ... print karma.action.name
71+ bugfixed
72+
73 Reject a bug task:
74
75 >>> old_bugtask = Snapshot(bugtask, providing=IDistroBugTask)
76@@ -87,7 +105,7 @@
77 >>> notify(ObjectModifiedEvent(bugtask, old_bugtask, ['status']))
78 Karma added: action=bugrejected, distribution=debian
79
80-Accept a bug task:
81+User accept a bug task:
82
83 >>> old_bugtask = Snapshot(bugtask, providing=IDistroBugTask)
84 >>> bugtask.transitionToStatus(
85@@ -95,6 +113,17 @@
86 >>> notify(ObjectModifiedEvent(bugtask, old_bugtask, ['status']))
87 Karma added: action=bugaccepted, distribution=debian
88
89+Driver accept a bug task:
90+
91+ >>> login_person(bugtask.target.owner)
92+ >>> old_bugtask = Snapshot(bugtask, providing=IDistroBugTask)
93+ >>> bugtask.transitionToStatus(
94+ ... BugTaskStatus.TRIAGED, getUtility(ILaunchBag).user)
95+ >>> notify(ObjectModifiedEvent(bugtask, old_bugtask, ['status']))
96+ Karma added: action=bugaccepted, distribution=debian
97+
98+ >>> login('admin@canonical.com')
99+
100 Change a bug task's importance:
101
102 >>> from canonical.launchpad.interfaces import BugTaskImportance
103@@ -183,6 +212,7 @@
104 >>> notify(ObjectModifiedEvent(bug, old_bug, ['duplicateof']))
105 Karma added: action=bugmarkedasduplicate, product=evolution
106 Karma added: action=bugmarkedasduplicate, product=evolution
107+ Karma added: action=bugmarkedasduplicate, product=ufo
108 Karma added: action=bugmarkedasduplicate, distribution=debian
109 Karma added: action=bugmarkedasduplicate, distribution=debian
110
111@@ -194,6 +224,7 @@
112 >>> notify(ObjectCreatedEvent(comment))
113 Karma added: action=bugcommentadded, product=evolution
114 Karma added: action=bugcommentadded, product=evolution
115+ Karma added: action=bugcommentadded, product=ufo
116 Karma added: action=bugcommentadded, distribution=debian
117 Karma added: action=bugcommentadded, distribution=debian
118
119
120=== modified file 'lib/lp/registry/browser/productrelease.py'
121--- lib/lp/registry/browser/productrelease.py 2009-12-09 11:47:58 +0000
122+++ lib/lp/registry/browser/productrelease.py 2010-01-22 21:50:26 +0000
123@@ -39,7 +39,6 @@
124 action, canonical_url, ContextMenu, custom_widget,
125 enabled_with_permission, LaunchpadEditFormView, LaunchpadFormView,
126 LaunchpadView, Link, Navigation, stepthrough)
127-from canonical.launchpad.webapp.menu import structured
128 from canonical.widgets import DateTimeWidget
129
130 from lp.registry.browser import MilestoneOverlayMixin, RegistryDeleteViewMixin
131@@ -119,10 +118,6 @@
132 milestone.active = False
133 milestone_link = '<a href="%s">%s milestone</a>' % (
134 canonical_url(milestone), cgi.escape(milestone.name))
135- self.request.response.addWarningNotification(structured(
136- _("The %s for this project release was deactivated "
137- "so that bugs and blueprints cannot be associated with "
138- "this release." % milestone_link)))
139 self.next_url = canonical_url(newrelease.milestone)
140 notify(ObjectCreatedEvent(newrelease))
141
142
143=== modified file 'lib/lp/registry/browser/tests/productrelease-views.txt'
144--- lib/lp/registry/browser/tests/productrelease-views.txt 2009-12-07 17:09:55 +0000
145+++ lib/lp/registry/browser/tests/productrelease-views.txt 2010-01-22 21:50:26 +0000
146@@ -50,12 +50,6 @@
147 >>> print view.widget_errors
148 {}
149
150- >>> for notification in view.request.response.notifications:
151- ... print notification.message
152- The <a href="http://launchpad.dev/app/+milestone/0.1">0.1 milestone</a>
153- for this project release was deactivated so that bugs and blueprints
154- cannot be associated with this release.
155-
156 >>> print milestone.active
157 False
158
159
160=== modified file 'lib/lp/registry/doc/milestone.txt'
161--- lib/lp/registry/doc/milestone.txt 2009-11-06 21:06:38 +0000
162+++ lib/lp/registry/doc/milestone.txt 2010-01-22 21:50:26 +0000
163@@ -506,3 +506,26 @@
164 ...
165 AssertionError: You cannot delete a milestone which has structural
166 subscriptions.
167+
168+
169+Creating a release from a milestone with targeted bugs
170+------------------------------------------------------
171+
172+When a milestone with bug tasks creates a release, those bug tasks in fix
173+committed status are updated to fix released.
174+
175+ >>> from lp.bugs.interfaces.bugtask import BugTaskStatus
176+
177+ >>> milestone = ff_onedotzero.newMilestone('kia')
178+ >>> fixed_bugtask = factory.makeBugTask(target=upstream_firefox)
179+ >>> fixed_bugtask.transitionToMilestone(milestone, owner)
180+ >>> fixed_bugtask.transitionToStatus(BugTaskStatus.FIXCOMMITTED, owner)
181+ >>> triaged_bugtask = factory.makeBugTask(target=upstream_firefox)
182+ >>> triaged_bugtask.transitionToMilestone(milestone, owner)
183+ >>> triaged_bugtask.transitionToStatus(BugTaskStatus.TRIAGED, owner)
184+ >>> release = milestone.createProductRelease(owner, datetime.now(UTC))
185+ >>> fixed_bugtask.status
186+ <DBItem BugTaskStatus.FIXRELEASED, (30) Fix Released>
187+
188+ >>> triaged_bugtask.status
189+ <DBItem BugTaskStatus.TRIAGED, (21) Triaged>
190
191=== modified file 'lib/lp/registry/model/milestone.py'
192--- lib/lp/registry/model/milestone.py 2009-12-05 18:37:28 +0000
193+++ lib/lp/registry/model/milestone.py 2010-01-22 21:50:26 +0000
194@@ -31,7 +31,7 @@
195 from lp.registry.model.structuralsubscription import (
196 StructuralSubscriptionTargetMixin)
197 from lp.bugs.interfaces.bugtask import (
198- BugTaskSearchParams, IBugTaskSet)
199+ BugTaskSearchParams, BugTaskStatus, IBugTaskSet)
200 from lp.bugs.interfaces.bugtarget import IHasBugs
201 from lp.registry.interfaces.milestone import (
202 IHasMilestones, IMilestone, IMilestoneSet, IProjectMilestone)
203@@ -177,12 +177,16 @@
204 if self.product_release is not None:
205 raise AssertionError(
206 'A milestone can only have one ProductRelease.')
207- return ProductRelease(
208+ release = ProductRelease(
209 owner=owner,
210 changelog=changelog,
211 release_notes=release_notes,
212 datereleased=datereleased,
213 milestone=self)
214+ for bugtask in self.open_bugtasks:
215+ if bugtask.status == BugTaskStatus.FIXCOMMITTED:
216+ bugtask.transitionToStatus(BugTaskStatus.FIXRELEASED, owner)
217+ return release
218
219 def destroySelf(self):
220 """See `IMilestone`."""
221
222=== modified file 'lib/lp/registry/stories/productrelease/xx-productrelease-basics.txt'
223--- lib/lp/registry/stories/productrelease/xx-productrelease-basics.txt 2009-11-26 03:06:58 +0000
224+++ lib/lp/registry/stories/productrelease/xx-productrelease-basics.txt 2010-01-22 21:50:26 +0000
225@@ -52,12 +52,6 @@
226 >>> browser.url
227 'http://launchpad.dev/firefox/+milestone/1.0'
228
229-There is a warning that the milestone has been deactivated.
230-
231- >>> print get_feedback_messages(browser.contents)
232- [u'The 1.0 milestone for this project release was deactivated so
233- that bugs and blueprints cannot be associated with this release.']
234-
235 The release's information is displayed in the page.
236
237 >>> print extract_text(find_tag_by_id(browser.contents, 'release-notes'))
238
239=== modified file 'lib/lp/registry/stories/productrelease/xx-productrelease-view.txt'
240--- lib/lp/registry/stories/productrelease/xx-productrelease-view.txt 2009-12-14 13:49:03 +0000
241+++ lib/lp/registry/stories/productrelease/xx-productrelease-view.txt 2010-01-22 21:50:26 +0000
242@@ -11,7 +11,6 @@
243 Series: trunk
244 Version: 0.9.2
245 Code name: One (secure) Tree Hill
246- Expected:
247 Released: 2004-10-15
248 Registrant: Foo Bar
249 Release registered: 2005-06-06
250
251=== modified file 'lib/lp/registry/templates/milestone-index.pt'
252--- lib/lp/registry/templates/milestone-index.pt 2010-01-11 14:26:27 +0000
253+++ lib/lp/registry/templates/milestone-index.pt 2010-01-22 21:50:26 +0000
254@@ -67,7 +67,7 @@
255 </dd>
256 </dl>
257
258- <dl>
259+ <dl tal:condition="not: view/release">
260 <dt>Expected:</dt>
261 <dd><span
262 tal:attributes="title context/dateexpected/fmt:datetime"