Merge lp:~cjwatson/launchpad/snap-auto-build-ui into lp:launchpad
- snap-auto-build-ui
- Merge into devel
Proposed by
Colin Watson
Status: | Merged |
---|---|
Merged at revision: | 18129 |
Proposed branch: | lp:~cjwatson/launchpad/snap-auto-build-ui |
Merge into: | lp:launchpad |
Prerequisite: | lp:~cjwatson/launchpad/snap-auto-build-archive-widget |
Diff against target: |
797 lines (+426/-43) 10 files modified
lib/lp/snappy/browser/snap.py (+58/-5) lib/lp/snappy/browser/tests/test_snap.py (+77/-1) lib/lp/snappy/configure.zcml (+2/-0) lib/lp/snappy/help/snap-build-frequency.html (+42/-0) lib/lp/snappy/javascript/snap.edit.js (+25/-6) lib/lp/snappy/javascript/tests/test_snap.edit.html (+90/-1) lib/lp/snappy/javascript/tests/test_snap.edit.js (+35/-2) lib/lp/snappy/templates/snap-edit.pt (+36/-18) lib/lp/snappy/templates/snap-index.pt (+25/-0) lib/lp/snappy/templates/snap-new.pt (+36/-10) |
To merge this branch: | bzr merge lp:~cjwatson/launchpad/snap-auto-build-ui |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Thomi Richards (community) | Approve | ||
Launchpad code reviewers | Pending | ||
Review via email: mp+297962@code.launchpad.net |
Commit message
Add UI for auto-building snap packages.
Description of the change
Add UI for auto-building snap packages. It's a little basic and could probably use more JS niceties in a few places, but it's functional.
To post a comment you must log in.
Revision history for this message
Thomi Richards (thomir-deactivatedaccount) wrote : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/lp/snappy/browser/snap.py' |
2 | --- lib/lp/snappy/browser/snap.py 2016-07-05 10:20:51 +0000 |
3 | +++ lib/lp/snappy/browser/snap.py 2016-07-12 13:40:07 +0000 |
4 | @@ -179,6 +179,13 @@ |
5 | self.context, field, format_link(self.context.owner), |
6 | header='Change owner', step_title='Select a new owner') |
7 | |
8 | + @property |
9 | + def build_frequency(self): |
10 | + if self.context.auto_build: |
11 | + return 'Built automatically' |
12 | + else: |
13 | + return 'Built on request' |
14 | + |
15 | |
16 | def builds_for_snap(snap): |
17 | """A list of interesting builds. |
18 | @@ -303,6 +310,7 @@ |
19 | 'name', |
20 | 'private', |
21 | 'require_virtualized', |
22 | + 'auto_build', |
23 | 'store_upload', |
24 | ]) |
25 | store_distro_series = Choice( |
26 | @@ -315,8 +323,13 @@ |
27 | branch = copy_field(ISnap['branch'], required=True) |
28 | git_ref = copy_field(ISnap['git_ref'], required=True) |
29 | |
30 | - # These are only required if store_upload is True. Later validation |
31 | - # takes care of adjusting the required attribute. |
32 | + # These are only required if auto_build is True. Later validation takes |
33 | + # care of adjusting the required attribute. |
34 | + auto_build_archive = copy_field(ISnap['auto_build_archive'], required=True) |
35 | + auto_build_pocket = copy_field(ISnap['auto_build_pocket'], required=True) |
36 | + |
37 | + # This is only required if store_upload is True. Later validation takes |
38 | + # care of adjusting the required attribute. |
39 | store_name = copy_field(ISnap['store_name'], required=True) |
40 | |
41 | |
42 | @@ -350,10 +363,14 @@ |
43 | 'owner', |
44 | 'name', |
45 | 'store_distro_series', |
46 | + 'auto_build', |
47 | + 'auto_build_archive', |
48 | + 'auto_build_pocket', |
49 | 'store_upload', |
50 | 'store_name', |
51 | ] |
52 | custom_widget('store_distro_series', LaunchpadRadioWidget) |
53 | + custom_widget('auto_build_archive', SnapArchiveWidget) |
54 | |
55 | def initialize(self): |
56 | """See `LaunchpadView`.""" |
57 | @@ -417,6 +434,8 @@ |
58 | 'processors': [ |
59 | p for p in getUtility(IProcessorSet).getAll() |
60 | if p.build_by_default], |
61 | + 'auto_build_archive': series.main_archive, |
62 | + 'auto_build_pocket': PackagePublishingPocket.UPDATES, |
63 | } |
64 | |
65 | @property |
66 | @@ -425,6 +444,13 @@ |
67 | |
68 | def validate_widgets(self, data, names=None): |
69 | """See `LaunchpadFormView`.""" |
70 | + if self.widgets.get('auto_build') is not None: |
71 | + # Set widgets as required or optional depending on the |
72 | + # auto_build field. |
73 | + super(SnapAddView, self).validate_widgets(data, ['auto_build']) |
74 | + auto_build = data.get('auto_build', False) |
75 | + self.widgets['auto_build_archive'].context.required = auto_build |
76 | + self.widgets['auto_build_pocket'].context.required = auto_build |
77 | if self.widgets.get('store_upload') is not None: |
78 | # Set widgets as required or optional depending on the |
79 | # store_upload field. |
80 | @@ -441,9 +467,15 @@ |
81 | kwargs = {'branch': self.context} |
82 | private = not getUtility( |
83 | ISnapSet).isValidPrivacy(False, data['owner'], **kwargs) |
84 | + if not data.get('auto_build', False): |
85 | + data['auto_build_archive'] = None |
86 | + data['auto_build_pocket'] = None |
87 | snap = getUtility(ISnapSet).new( |
88 | self.user, data['owner'], |
89 | data['store_distro_series'].distro_series, data['name'], |
90 | + auto_build=data['auto_build'], |
91 | + auto_build_archive=data['auto_build_archive'], |
92 | + auto_build_pocket=data['auto_build_pocket'], |
93 | private=private, store_upload=data['store_upload'], |
94 | store_series=data['store_distro_series'].snappy_series, |
95 | store_name=data['store_name'], processors=data['processors'], |
96 | @@ -502,6 +534,14 @@ |
97 | self.widgets['git_ref'].context.required = True |
98 | else: |
99 | raise AssertionError("Unknown branch type %s" % vcs) |
100 | + if self.widgets.get('auto_build') is not None: |
101 | + # Set widgets as required or optional depending on the |
102 | + # auto_build field. |
103 | + super(BaseSnapEditView, self).validate_widgets( |
104 | + data, ['auto_build']) |
105 | + auto_build = data.get('auto_build', False) |
106 | + self.widgets['auto_build_archive'].context.required = auto_build |
107 | + self.widgets['auto_build_pocket'].context.required = auto_build |
108 | if self.widgets.get('store_upload') is not None: |
109 | # Set widgets as required or optional depending on the |
110 | # store_upload field. |
111 | @@ -538,9 +578,15 @@ |
112 | self.context.setProcessors( |
113 | new_processors, check_permissions=True, user=self.user) |
114 | del data['processors'] |
115 | + if not data.get('auto_build', False): |
116 | + if 'auto_build_archive' in data: |
117 | + del data['auto_build_archive'] |
118 | + if 'auto_build_pocket' in data: |
119 | + del data['auto_build_pocket'] |
120 | store_upload = data.get('store_upload', False) |
121 | if not store_upload: |
122 | - data['store_name'] = None |
123 | + if 'store_name' in data: |
124 | + del data['store_name'] |
125 | need_store_reauth = self._needStoreReauth(data) |
126 | self.updateContextFromData(data) |
127 | if need_store_reauth: |
128 | @@ -592,15 +638,19 @@ |
129 | 'owner', |
130 | 'name', |
131 | 'store_distro_series', |
132 | - 'store_upload', |
133 | - 'store_name', |
134 | 'vcs', |
135 | 'branch', |
136 | 'git_ref', |
137 | + 'auto_build', |
138 | + 'auto_build_archive', |
139 | + 'auto_build_pocket', |
140 | + 'store_upload', |
141 | + 'store_name', |
142 | ] |
143 | custom_widget('store_distro_series', LaunchpadRadioWidget) |
144 | custom_widget('vcs', LaunchpadRadioWidget) |
145 | custom_widget('git_ref', GitRefWidget) |
146 | + custom_widget('auto_build_archive', SnapArchiveWidget) |
147 | |
148 | def setUpFields(self): |
149 | """See `LaunchpadFormView`.""" |
150 | @@ -624,6 +674,9 @@ |
151 | initial_values['vcs'] = VCSType.GIT |
152 | else: |
153 | initial_values['vcs'] = VCSType.BZR |
154 | + if self.context.auto_build_pocket is None: |
155 | + initial_values['auto_build_pocket'] = ( |
156 | + PackagePublishingPocket.UPDATES) |
157 | return initial_values |
158 | |
159 | def validate(self, data): |
160 | |
161 | === modified file 'lib/lp/snappy/browser/tests/test_snap.py' |
162 | --- lib/lp/snappy/browser/tests/test_snap.py 2016-07-05 10:20:51 +0000 |
163 | +++ lib/lp/snappy/browser/tests/test_snap.py 2016-07-12 13:40:07 +0000 |
164 | @@ -42,6 +42,7 @@ |
165 | from lp.buildmaster.enums import BuildStatus |
166 | from lp.buildmaster.interfaces.processor import IProcessorSet |
167 | from lp.code.errors import GitRepositoryScanFault |
168 | +from lp.code.interfaces.githosting import IGitHostingClient |
169 | from lp.registry.enums import PersonVisibility |
170 | from lp.registry.interfaces.pocket import PackagePublishingPocket |
171 | from lp.registry.interfaces.series import SeriesStatus |
172 | @@ -72,6 +73,7 @@ |
173 | time_counter, |
174 | ) |
175 | from lp.testing.fakemethod import FakeMethod |
176 | +from lp.testing.fixture import ZopeUtilityFixture |
177 | from lp.testing.layers import ( |
178 | DatabaseFunctionalLayer, |
179 | LaunchpadFunctionalLayer, |
180 | @@ -220,11 +222,23 @@ |
181 | "Source:\n%s\nEdit snap package" % source_display, |
182 | MatchesTagText(content, "source")) |
183 | self.assertThat( |
184 | + "Build schedule:\n(?)\nBuilt on request\nEdit snap package\n", |
185 | + MatchesTagText(content, "auto_build")) |
186 | + self.assertThat( |
187 | + "Source archive for automatic builds:\n\nEdit snap package\n", |
188 | + MatchesTagText(content, "auto_build_archive")) |
189 | + self.assertThat( |
190 | + "Pocket for automatic builds:\n\nEdit snap package", |
191 | + MatchesTagText(content, "auto_build_pocket")) |
192 | + self.assertThat( |
193 | "Builds of this snap package are not automatically uploaded to " |
194 | "the store.\nEdit snap package", |
195 | MatchesTagText(content, "store_upload")) |
196 | |
197 | def test_create_new_snap_git(self): |
198 | + hosting_client = FakeMethod() |
199 | + hosting_client.getBlob = FakeMethod(result="") |
200 | + self.useFixture(ZopeUtilityFixture(hosting_client, IGitHostingClient)) |
201 | [git_ref] = self.factory.makeGitRefs() |
202 | source_display = git_ref.display_name |
203 | browser = self.getViewBrowser( |
204 | @@ -244,6 +258,15 @@ |
205 | "Source:\n%s\nEdit snap package" % source_display, |
206 | MatchesTagText(content, "source")) |
207 | self.assertThat( |
208 | + "Build schedule:\n(?)\nBuilt on request\nEdit snap package\n", |
209 | + MatchesTagText(content, "auto_build")) |
210 | + self.assertThat( |
211 | + "Source archive for automatic builds:\n\nEdit snap package\n", |
212 | + MatchesTagText(content, "auto_build_archive")) |
213 | + self.assertThat( |
214 | + "Pocket for automatic builds:\n\nEdit snap package", |
215 | + MatchesTagText(content, "auto_build_pocket")) |
216 | + self.assertThat( |
217 | "Builds of this snap package are not automatically uploaded to " |
218 | "the store.\nEdit snap package", |
219 | MatchesTagText(content, "store_upload")) |
220 | @@ -309,6 +332,34 @@ |
221 | extract_text(find_tag_by_id(browser.contents, "privacy")) |
222 | ) |
223 | |
224 | + def test_create_new_snap_auto_build(self): |
225 | + # Creating a new snap and asking for it to be automatically built |
226 | + # sets all the appropriate fields. |
227 | + branch = self.factory.makeAnyBranch() |
228 | + archive = self.factory.makeArchive() |
229 | + browser = self.getViewBrowser( |
230 | + branch, view_name="+new-snap", user=self.person) |
231 | + browser.getControl(name="field.name").value = "snap-name" |
232 | + browser.getControl( |
233 | + "Automatically build when branch changes").selected = True |
234 | + browser.getControl("PPA").click() |
235 | + browser.getControl(name="field.auto_build_archive.ppa").value = ( |
236 | + archive.reference) |
237 | + browser.getControl("Pocket for automatic builds").value = ["SECURITY"] |
238 | + browser.getControl("Create snap package").click() |
239 | + |
240 | + content = find_main_content(browser.contents) |
241 | + self.assertThat( |
242 | + "Build schedule:\n(?)\nBuilt automatically\nEdit snap package\n", |
243 | + MatchesTagText(content, "auto_build")) |
244 | + self.assertThat( |
245 | + "Source archive for automatic builds:\n%s\nEdit snap package\n" % |
246 | + archive.displayname, |
247 | + MatchesTagText(content, "auto_build_archive")) |
248 | + self.assertThat( |
249 | + "Pocket for automatic builds:\nSecurity\nEdit snap package", |
250 | + MatchesTagText(content, "auto_build_pocket")) |
251 | + |
252 | def test_create_new_snap_store_upload(self): |
253 | # Creating a new snap and asking for it to be automatically uploaded |
254 | # to the store sets all the appropriate fields and redirects to SSO |
255 | @@ -441,7 +492,7 @@ |
256 | view = create_initialized_view(git_ref, "+new-snap") |
257 | with mock.patch('yaml.load') as unsafe_load: |
258 | with mock.patch('yaml.safe_load') as safe_load: |
259 | - initial_values = view.initial_values |
260 | + view.initial_values |
261 | self.assertEqual(0, unsafe_load.call_count) |
262 | self.assertEqual(1, safe_load.call_count) |
263 | |
264 | @@ -574,6 +625,7 @@ |
265 | new_snappy_series = self.factory.makeSnappySeries( |
266 | usable_distro_series=[new_series]) |
267 | [new_git_ref] = self.factory.makeGitRefs() |
268 | + archive = self.factory.makeArchive() |
269 | |
270 | browser = self.getViewBrowser(snap, user=self.person) |
271 | browser.getLink("Edit snap package").click() |
272 | @@ -585,6 +637,12 @@ |
273 | browser.getControl("Git repository").value = ( |
274 | new_git_ref.repository.identity) |
275 | browser.getControl("Git branch").value = new_git_ref.path |
276 | + browser.getControl( |
277 | + "Automatically build when branch changes").selected = True |
278 | + browser.getControl("PPA").click() |
279 | + browser.getControl(name="field.auto_build_archive.ppa").value = ( |
280 | + archive.reference) |
281 | + browser.getControl("Pocket for automatic builds").value = ["SECURITY"] |
282 | browser.getControl("Update snap package").click() |
283 | |
284 | content = find_main_content(browser.contents) |
285 | @@ -598,6 +656,16 @@ |
286 | "Source:\n%s\nEdit snap package" % new_git_ref.display_name, |
287 | MatchesTagText(content, "source")) |
288 | self.assertThat( |
289 | + "Build schedule:\n(?)\nBuilt automatically\nEdit snap package\n", |
290 | + MatchesTagText(content, "auto_build")) |
291 | + self.assertThat( |
292 | + "Source archive for automatic builds:\n%s\nEdit snap package\n" % |
293 | + archive.displayname, |
294 | + MatchesTagText(content, "auto_build_archive")) |
295 | + self.assertThat( |
296 | + "Pocket for automatic builds:\nSecurity\nEdit snap package", |
297 | + MatchesTagText(content, "auto_build_pocket")) |
298 | + self.assertThat( |
299 | "Builds of this snap package are not automatically uploaded to " |
300 | "the store.\nEdit snap package", |
301 | MatchesTagText(content, "store_upload")) |
302 | @@ -1083,6 +1151,10 @@ |
303 | Owner: Test Person |
304 | Distribution series: Ubuntu Shiny |
305 | Source: lp://dev/~test-person/\\+junk/snap-branch |
306 | + Build schedule: \(\?\) |
307 | + Built on request |
308 | + Source archive for automatic builds: |
309 | + Pocket for automatic builds: |
310 | Builds of this snap package are not automatically uploaded to |
311 | the store. |
312 | Latest builds |
313 | @@ -1106,6 +1178,10 @@ |
314 | Owner: Test Person |
315 | Distribution series: Ubuntu Shiny |
316 | Source: ~test-person/\\+git/snap-repository:master |
317 | + Build schedule: \(\?\) |
318 | + Built on request |
319 | + Source archive for automatic builds: |
320 | + Pocket for automatic builds: |
321 | Builds of this snap package are not automatically uploaded to |
322 | the store. |
323 | Latest builds |
324 | |
325 | === modified file 'lib/lp/snappy/configure.zcml' |
326 | --- lib/lp/snappy/configure.zcml 2016-05-06 16:34:21 +0000 |
327 | +++ lib/lp/snappy/configure.zcml 2016-07-12 13:40:07 +0000 |
328 | @@ -14,6 +14,8 @@ |
329 | <include package=".browser" /> |
330 | <include file="vocabularies.zcml" /> |
331 | |
332 | + <lp:help-folder folder="help" name="+help-snappy" /> |
333 | + |
334 | <!-- Snap --> |
335 | <class class="lp.snappy.model.snap.Snap"> |
336 | <require |
337 | |
338 | === added directory 'lib/lp/snappy/help' |
339 | === added file 'lib/lp/snappy/help/snap-build-frequency.html' |
340 | --- lib/lp/snappy/help/snap-build-frequency.html 1970-01-01 00:00:00 +0000 |
341 | +++ lib/lp/snappy/help/snap-build-frequency.html 2016-07-12 13:40:07 +0000 |
342 | @@ -0,0 +1,42 @@ |
343 | +<html> |
344 | + <head> |
345 | + <title>Snap package build schedule</title> |
346 | + <link rel="stylesheet" type="text/css" |
347 | + href="/+icing/yui/cssreset/reset.css" /> |
348 | + <link rel="stylesheet" type="text/css" |
349 | + href="/+icing/yui/cssfonts/fonts.css" /> |
350 | + <link rel="stylesheet" type="text/css" |
351 | + href="/+icing/yui/cssbase/base.css" /> |
352 | + <style type="text/css"> |
353 | + dt { font-weight: bold } |
354 | + dd p { margin-bottom: 0.5em } |
355 | + </style> |
356 | + </head> |
357 | + <body> |
358 | + <h1>Snap package build schedule</h1> |
359 | + |
360 | + <p>There are two options for when snap packages get built:</p> |
361 | + <dl> |
362 | + <dt>Built automatically</dt> |
363 | + <dd> |
364 | + <p>A build will be scheduled automatically once a change to the |
365 | + top-level source branch for the snap package is detected.</p> |
366 | + <p>If there has been a build of the snap package within the previous |
367 | + hour from the source archive, the build will not be scheduled |
368 | + until an hour since the last build from the source archive.</p> |
369 | + <p>If the snap package has been built within the last hour from a |
370 | + different archive using the "Request builds" action, this will not |
371 | + delay the automatic build.</p> |
372 | + <p>If you really want the build to happen before the one-hour period |
373 | + is up, you can use the "Request builds" action.</p> |
374 | + </dd> |
375 | + <dt>Built on request</dt> |
376 | + <dd> |
377 | + <p>Builds of the snap package have to be manually requested using |
378 | + the "Request builds" action.</p> |
379 | + </dd> |
380 | + </dl> |
381 | + |
382 | + </body> |
383 | +</html> |
384 | + |
385 | |
386 | === modified file 'lib/lp/snappy/javascript/snap.edit.js' |
387 | --- lib/lp/snappy/javascript/snap.edit.js 2015-09-09 14:17:46 +0000 |
388 | +++ lib/lp/snappy/javascript/snap.edit.js 2016-07-12 13:40:07 +0000 |
389 | @@ -1,7 +1,8 @@ |
390 | -/* Copyright 2015 Canonical Ltd. This software is licensed under the |
391 | +/* Copyright 2015-2016 Canonical Ltd. This software is licensed under the |
392 | * GNU Affero General Public License version 3 (see the file LICENSE). |
393 | * |
394 | - * Control enabling/disabling form elements on the Snap:+edit page. |
395 | + * Control enabling/disabling form elements on the {Branch,GitRef}:+new-snap |
396 | + * and Snap:+edit pages. |
397 | * |
398 | * @module Y.lp.snappy.snap.edit |
399 | * @requires node, DOM |
400 | @@ -12,7 +13,9 @@ |
401 | |
402 | module.set_enabled = function(field_id, is_enabled) { |
403 | var field = Y.DOM.byId(field_id); |
404 | - field.disabled = !is_enabled; |
405 | + if (field !== null) { |
406 | + field.disabled = !is_enabled; |
407 | + } |
408 | }; |
409 | |
410 | module.onclick_vcs = function(e) { |
411 | @@ -22,15 +25,31 @@ |
412 | selected_vcs = node.get('value'); |
413 | } |
414 | }); |
415 | - module.set_enabled('field.branch', selected_vcs === 'BZR'); |
416 | - module.set_enabled('field.git_ref.repository', selected_vcs === 'GIT'); |
417 | - module.set_enabled('field.git_ref.path', selected_vcs === 'GIT'); |
418 | + if (selected_vcs !== null) { |
419 | + module.set_enabled('field.branch', selected_vcs === 'BZR'); |
420 | + module.set_enabled( |
421 | + 'field.git_ref.repository', selected_vcs === 'GIT'); |
422 | + module.set_enabled('field.git_ref.path', selected_vcs === 'GIT'); |
423 | + } |
424 | + }; |
425 | + |
426 | + module.onclick_auto_build = function(e) { |
427 | + var auto_build = Y.one( |
428 | + 'input[name="field.auto_build"]').get('checked'); |
429 | + module.set_enabled( |
430 | + 'field.auto_build_archive.option.primary', auto_build); |
431 | + module.set_enabled('field.auto_build_archive.option.ppa', auto_build); |
432 | + module.set_enabled('field.auto_build_archive.ppa', auto_build); |
433 | + module.set_enabled('field.auto_build_pocket', auto_build); |
434 | }; |
435 | |
436 | module.setup = function() { |
437 | Y.all('input[name="field.vcs"]').on('click', module.onclick_vcs); |
438 | + Y.all('input[name="field.auto_build"]').on( |
439 | + 'click', module.onclick_auto_build); |
440 | |
441 | // Set the initial state. |
442 | module.onclick_vcs(); |
443 | + module.onclick_auto_build(); |
444 | }; |
445 | }, '0.1', {'requires': ['node', 'DOM']}); |
446 | |
447 | === modified file 'lib/lp/snappy/javascript/tests/test_snap.edit.html' |
448 | --- lib/lp/snappy/javascript/tests/test_snap.edit.html 2015-09-09 14:17:46 +0000 |
449 | +++ lib/lp/snappy/javascript/tests/test_snap.edit.html 2016-07-12 13:40:07 +0000 |
450 | @@ -1,6 +1,6 @@ |
451 | <!DOCTYPE html> |
452 | <!-- |
453 | -Copyright 2015 Canonical Ltd. This software is licensed under the |
454 | +Copyright 2015-2016 Canonical Ltd. This software is licensed under the |
455 | GNU Affero General Public License version 3 (see the file LICENSE). |
456 | --> |
457 | |
458 | @@ -133,6 +133,95 @@ |
459 | </div> |
460 | </td> |
461 | </tr> |
462 | + <tr> |
463 | + <td colspan="2"> |
464 | + <div> |
465 | + <label for="field.auto_build">Automatically build when branch changes</label> |
466 | + <input class="checkboxType" |
467 | + id="field.auto_build" |
468 | + name="field.auto_build" |
469 | + type="checkbox" |
470 | + value="" /> |
471 | + </div> |
472 | + </td> |
473 | + </tr> |
474 | + <tr> |
475 | + <td> |
476 | + <table class="subordinate"> |
477 | + <tr> |
478 | + <td colspan="2"> |
479 | + <div> |
480 | + <label for="field.auto_build_archive">Source archive for automatic builds:</label> |
481 | + <div> |
482 | + <table> |
483 | + <tr> |
484 | + <td colspan="2"> |
485 | + <label> |
486 | + <input class="radioType" |
487 | + id="field.auto_build_archive.option.primary" |
488 | + name="field.auto_build_archive" |
489 | + type="radio" |
490 | + value="primary" /> |
491 | + Primary Archive for Ubuntu |
492 | + </label> |
493 | + </td> |
494 | + </tr> |
495 | + <tr> |
496 | + <td> |
497 | + <label> |
498 | + <input class="radioType" |
499 | + id="field.auto_build_archive.option.ppa" |
500 | + name="field.auto_build_archive" |
501 | + type="radio" |
502 | + value="ppa" /> |
503 | + PPA |
504 | + </label> |
505 | + </td> |
506 | + <td> |
507 | + <input type="text" |
508 | + value="" |
509 | + id="field.auto_build_archive.ppa" |
510 | + name="field.auto_build_archive.ppa" |
511 | + size="20" |
512 | + maxlength="" |
513 | + onKeyPress="" |
514 | + style="" |
515 | + class="" /> |
516 | + </td> |
517 | + </tr> |
518 | + </table> |
519 | + </div> |
520 | + </div> |
521 | + </td> |
522 | + </tr> |
523 | + <tr> |
524 | + <td colspan="2"> |
525 | + <div> |
526 | + <label for="field.auto_build_pocket">Pocket for automatic builds:</label> |
527 | + <div> |
528 | + <div> |
529 | + <div class="value"> |
530 | + <select id="field.auto_build_pocket" |
531 | + name="field.auto_build_pocket" |
532 | + size="1"> |
533 | + <option value="RELEASE">Release</option> |
534 | + <option value="SECURITY">Security</option> |
535 | + <option selected="selected" value="UPDATES">Updates</option> |
536 | + <option value="PROPOSED">Proposed</option> |
537 | + <option value="BACKPORTS">Backports</option> |
538 | + </select> |
539 | + </div> |
540 | + <input name="field.auto_build_pocket-empty-marker" |
541 | + type="hidden" |
542 | + value="1" /> |
543 | + </div> |
544 | + </div> |
545 | + </div> |
546 | + </td> |
547 | + </tr> |
548 | + </table> |
549 | + </td> |
550 | + </tr> |
551 | </table> |
552 | |
553 | <input type="submit" id="field.actions.update" |
554 | |
555 | === modified file 'lib/lp/snappy/javascript/tests/test_snap.edit.js' |
556 | --- lib/lp/snappy/javascript/tests/test_snap.edit.js 2015-09-09 14:17:46 +0000 |
557 | +++ lib/lp/snappy/javascript/tests/test_snap.edit.js 2016-07-12 13:40:07 +0000 |
558 | @@ -1,4 +1,4 @@ |
559 | -/* Copyright 2015 Canonical Ltd. This software is licensed under the |
560 | +/* Copyright 2015-2016 Canonical Ltd. This software is licensed under the |
561 | * GNU Affero General Public License version 3 (see the file LICENSE). |
562 | * |
563 | * Test driver for snap.edit.js. |
564 | @@ -14,9 +14,10 @@ |
565 | setUp: function() { |
566 | this.tbody = Y.one('#snap.edit'); |
567 | |
568 | - // Get the individual VCS type radio buttons. |
569 | + // Get the widgets with event handlers attached. |
570 | this.vcs_bzr = Y.DOM.byId('field.vcs.Bazaar'); |
571 | this.vcs_git = Y.DOM.byId('field.vcs.Git'); |
572 | + this.auto_build = Y.DOM.byId('field.auto_build'); |
573 | |
574 | // Get the input widgets. |
575 | this.input_branch = Y.DOM.byId('field.branch'); |
576 | @@ -45,6 +46,7 @@ |
577 | |
578 | check_handler(this.vcs_bzr, module.onclick_vcs); |
579 | check_handler(this.vcs_git, module.onclick_vcs); |
580 | + check_handler(this.auto_build, module.onclick_auto_build); |
581 | }, |
582 | |
583 | test_select_vcs_bzr: function() { |
584 | @@ -73,7 +75,38 @@ |
585 | 'git_ref.repository field disabled'); |
586 | Y.Assert.isFalse(this.input_git_path.disabled, |
587 | 'git_ref.path field disabled'); |
588 | + }, |
589 | + |
590 | + test_check_auto_build: function() { |
591 | + var fields = [ |
592 | + 'auto_build_archive.option.primary', |
593 | + 'auto_build_archive.option.ppa', |
594 | + 'auto_build_archive.ppa', |
595 | + 'auto_build_pocket' |
596 | + ]; |
597 | + var field; |
598 | + module.setup(); |
599 | + for (i = 0; i < fields.length; i++) { |
600 | + field = Y.DOM.byId('field.' + fields[i]); |
601 | + Y.Assert.isTrue( |
602 | + field.disabled, fields[i] + ' field not disabled'); |
603 | + } |
604 | + this.auto_build.checked = true; |
605 | + module.onclick_auto_build(); |
606 | + for (i = 0; i < fields.length; i++) { |
607 | + field = Y.DOM.byId('field.' + fields[i]); |
608 | + Y.Assert.isFalse( |
609 | + field.disabled, fields[i] + ' field disabled'); |
610 | + } |
611 | + this.auto_build.checked = false; |
612 | + module.onclick_auto_build(); |
613 | + for (i = 0; i < fields.length; i++) { |
614 | + field = Y.DOM.byId('field.' + fields[i]); |
615 | + Y.Assert.isTrue( |
616 | + field.disabled, fields[i] + ' field not disabled'); |
617 | + } |
618 | } |
619 | + |
620 | })); |
621 | }, '0.1', { |
622 | requires: ['lp.testing.runner', 'test', 'test-console', |
623 | |
624 | === modified file 'lib/lp/snappy/templates/snap-edit.pt' |
625 | --- lib/lp/snappy/templates/snap-edit.pt 2016-05-24 05:15:50 +0000 |
626 | +++ lib/lp/snappy/templates/snap-edit.pt 2016-07-12 13:40:07 +0000 |
627 | @@ -29,24 +29,6 @@ |
628 | <metal:block use-macro="context/@@launchpad_form/widget_row" /> |
629 | </tal:widget> |
630 | |
631 | - <tr tal:condition="view/has_snappy_distro_series"> |
632 | - <td> |
633 | - <tal:widget define="widget nocall:view/widgets/store_upload"> |
634 | - <metal:block use-macro="context/@@launchpad_form/widget_row" /> |
635 | - </tal:widget> |
636 | - <table class="subordinate"> |
637 | - <tal:widget define="widget nocall:view/widgets/store_name"> |
638 | - <metal:block use-macro="context/@@launchpad_form/widget_row" /> |
639 | - </tal:widget> |
640 | - </table> |
641 | - <p class="formHelp"> |
642 | - If you change any settings related to automatically uploading |
643 | - builds of this snap to the store, then the login service will |
644 | - prompt you to authorize this request. |
645 | - </p> |
646 | - </td> |
647 | - </tr> |
648 | - |
649 | <tr> |
650 | <td> |
651 | <div> |
652 | @@ -78,6 +60,42 @@ |
653 | </td> |
654 | </tr> |
655 | |
656 | + <tal:widget define="widget nocall:view/widgets/auto_build"> |
657 | + <metal:block use-macro="context/@@launchpad_form/widget_row" /> |
658 | + </tal:widget> |
659 | + <tr> |
660 | + <td> |
661 | + <table class="subordinate"> |
662 | + <tal:widget define="widget nocall:view/widgets/auto_build_archive"> |
663 | + <metal:block use-macro="context/@@launchpad_form/widget_row" /> |
664 | + </tal:widget> |
665 | + <tal:widget define="widget nocall:view/widgets/auto_build_pocket"> |
666 | + <metal:block use-macro="context/@@launchpad_form/widget_row" /> |
667 | + </tal:widget> |
668 | + </table> |
669 | + </td> |
670 | + </tr> |
671 | + |
672 | + <tal:has-sds tal:condition="view/has_snappy_distro_series"> |
673 | + <tal:widget define="widget nocall:view/widgets/store_upload"> |
674 | + <metal:block use-macro="context/@@launchpad_form/widget_row" /> |
675 | + </tal:widget> |
676 | + <tr> |
677 | + <td> |
678 | + <table class="subordinate"> |
679 | + <tal:widget define="widget nocall:view/widgets/store_name"> |
680 | + <metal:block use-macro="context/@@launchpad_form/widget_row" /> |
681 | + </tal:widget> |
682 | + </table> |
683 | + <p class="formHelp"> |
684 | + If you change any settings related to automatically uploading |
685 | + builds of this snap to the store, then the login service will |
686 | + prompt you to authorize this request. |
687 | + </p> |
688 | + </td> |
689 | + </tr> |
690 | + </tal:has-sds> |
691 | + |
692 | <tal:widget define="widget nocall:view/widgets/processors"> |
693 | <metal:block use-macro="context/@@launchpad_form/widget_row" /> |
694 | </tal:widget> |
695 | |
696 | === modified file 'lib/lp/snappy/templates/snap-index.pt' |
697 | --- lib/lp/snappy/templates/snap-index.pt 2016-05-28 00:21:40 +0000 |
698 | +++ lib/lp/snappy/templates/snap-index.pt 2016-07-12 13:40:07 +0000 |
699 | @@ -61,6 +61,31 @@ |
700 | <a tal:replace="structure view/menu:overview/edit/fmt:icon"/> |
701 | </dd> |
702 | </dl> |
703 | + |
704 | + <dl id="auto_build"> |
705 | + <dt>Build schedule: |
706 | + <a href="/+help-snappy/snap-build-frequency.html" target="help" |
707 | + class="sprite maybe action-icon">(?)</a> |
708 | + </dt> |
709 | + <dd> |
710 | + <span tal:replace="view/build_frequency"/> |
711 | + <a tal:replace="structure view/menu:overview/edit/fmt:icon"/> |
712 | + </dd> |
713 | + </dl> |
714 | + <dl id="auto_build_archive"> |
715 | + <dt>Source archive for automatic builds:</dt> |
716 | + <dd> |
717 | + <a tal:replace="structure context/auto_build_archive/fmt:link"/> |
718 | + <a tal:replace="structure view/menu:overview/edit/fmt:icon"/> |
719 | + </dd> |
720 | + </dl> |
721 | + <dl id="auto_build_pocket"> |
722 | + <dt>Pocket for automatic builds:</dt> |
723 | + <dd> |
724 | + <span tal:replace="context/auto_build_pocket/title|nothing"/> |
725 | + <a tal:replace="structure view/menu:overview/edit/fmt:icon"/> |
726 | + </dd> |
727 | + </dl> |
728 | </div> |
729 | |
730 | <div id="store_upload" class="two-column-list" |
731 | |
732 | === modified file 'lib/lp/snappy/templates/snap-new.pt' |
733 | --- lib/lp/snappy/templates/snap-new.pt 2016-06-30 19:19:20 +0000 |
734 | +++ lib/lp/snappy/templates/snap-new.pt 2016-07-12 13:40:07 +0000 |
735 | @@ -35,26 +35,52 @@ |
736 | <metal:block use-macro="context/@@launchpad_form/widget_row" /> |
737 | </tal:widget> |
738 | |
739 | - <tr tal:condition="view/has_snappy_distro_series"> |
740 | + <tal:widget define="widget nocall:view/widgets/auto_build"> |
741 | + <metal:block use-macro="context/@@launchpad_form/widget_row" /> |
742 | + </tal:widget> |
743 | + <tr> |
744 | <td> |
745 | - <tal:widget define="widget nocall:view/widgets/store_upload"> |
746 | - <metal:block use-macro="context/@@launchpad_form/widget_row" /> |
747 | - </tal:widget> |
748 | <table class="subordinate"> |
749 | - <tal:widget define="widget nocall:view/widgets/store_name"> |
750 | + <tal:widget define="widget nocall:view/widgets/auto_build_archive"> |
751 | + <metal:block use-macro="context/@@launchpad_form/widget_row" /> |
752 | + </tal:widget> |
753 | + <tal:widget define="widget nocall:view/widgets/auto_build_pocket"> |
754 | <metal:block use-macro="context/@@launchpad_form/widget_row" /> |
755 | </tal:widget> |
756 | </table> |
757 | - <p class="formHelp"> |
758 | - If you ask Launchpad to automatically upload builds of this |
759 | - snap to the store on your behalf, then the login service |
760 | - will prompt you to authorize this request. |
761 | - </p> |
762 | </td> |
763 | </tr> |
764 | + |
765 | + <tal:has-sds condition="view/has_snappy_distro_series"> |
766 | + <tal:widget define="widget nocall:view/widgets/store_upload"> |
767 | + <metal:block use-macro="context/@@launchpad_form/widget_row" /> |
768 | + </tal:widget> |
769 | + <tr> |
770 | + <td> |
771 | + <table class="subordinate"> |
772 | + <tal:widget define="widget nocall:view/widgets/store_name"> |
773 | + <metal:block use-macro="context/@@launchpad_form/widget_row" /> |
774 | + </tal:widget> |
775 | + </table> |
776 | + <p class="formHelp"> |
777 | + If you ask Launchpad to automatically upload builds of this |
778 | + snap to the store on your behalf, then the login service |
779 | + will prompt you to authorize this request. |
780 | + </p> |
781 | + </td> |
782 | + </tr> |
783 | + </tal:has-sds> |
784 | </table> |
785 | </metal:formbody> |
786 | </div> |
787 | + |
788 | + <script type="text/javascript"> |
789 | + LPJS.use('lp.snappy.snap.edit', function(Y) { |
790 | + Y.on('domready', function(e) { |
791 | + Y.lp.snappy.snap.edit.setup(); |
792 | + }, window); |
793 | + }); |
794 | + </script> |
795 | </div> |
796 | |
797 | </body> |
LGTM, but it might be worth asking someone with more LP UI experience to take a look.