Merge ~wgrant/launchpad:buildinfo-exposure into launchpad:master

Proposed by William Grant
Status: Merged
Approved by: William Grant
Approved revision: 3a7f749fde4fc03353b8cfd4b4808521b9cf65ec
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~wgrant/launchpad:buildinfo-exposure
Merge into: launchpad:master
Diff against target: 199 lines (+74/-1)
7 files modified
lib/lp/soyuz/doc/build-files.rst (+9/-0)
lib/lp/soyuz/interfaces/binarypackagebuild.py (+11/-1)
lib/lp/soyuz/model/binarypackagebuild.py (+10/-0)
lib/lp/soyuz/stories/soyuz/xx-build-record.rst (+5/-0)
lib/lp/soyuz/stories/webservice/xx-builds.rst (+3/-0)
lib/lp/soyuz/templates/build-index.pt (+7/-0)
lib/lp/soyuz/tests/test_build.py (+29/-0)
Reviewer Review Type Date Requested Status
Clinton Fung Approve
Review via email: mp+459249@code.launchpad.net

Commit message

Expose .buildinfo files in the API and web UI

We've been capturing these for BinaryPackageBuilds for years, and
storing them in the DB and librarian, but they haven't been available to
users.

LP: #1686242

To post a comment you must log in.
Revision history for this message
Clinton Fung (clinton-fung) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/soyuz/doc/build-files.rst b/lib/lp/soyuz/doc/build-files.rst
2index ddca43d..2ba7f52 100644
3--- a/lib/lp/soyuz/doc/build-files.rst
4+++ b/lib/lp/soyuz/doc/build-files.rst
5@@ -28,6 +28,7 @@ following file type in its context.
6 * Binary changesfile: '.changes';
7 * Build logs: '.txt.gz';
8 * Build upload logs: '_log.txt';
9+ * .buildinfo file: '.buildinfo';
10 * Built files: '*deb';
11
12 >>> print(build.title)
13@@ -70,6 +71,14 @@ Adding and retrieving a upload_log.
14 >>> build.upload_log == build.getFileByName(upload_log_name)
15 True
16
17+Adding and retrieving a .buildinfo.
18+
19+ >>> build.addBuildInfo(
20+ ... factory.makeLibraryFileAlias(filename="foo.buildinfo")
21+ ... )
22+ >>> build.buildinfo == build.getFileByName("foo.buildinfo")
23+ True
24+
25 Retrieve a built file:
26
27 >>> deb == build.getFileByName("test_1.0_all.deb")
28diff --git a/lib/lp/soyuz/interfaces/binarypackagebuild.py b/lib/lp/soyuz/interfaces/binarypackagebuild.py
29index 18bc50f..e72b450 100644
30--- a/lib/lp/soyuz/interfaces/binarypackagebuild.py
31+++ b/lib/lp/soyuz/interfaces/binarypackagebuild.py
32@@ -139,8 +139,9 @@ class IBinaryPackageBuildView(IPackageBuildView):
33
34 changesfile_url = exported(
35 TextLine(
36- title=_("Changes File URL"),
37+ title=_("Changes file URL"),
38 required=False,
39+ readonly=True,
40 description=_(
41 "The URL for the changes file for this build. "
42 "Will be None if the build was imported by Gina."
43@@ -153,6 +154,15 @@ class IBinaryPackageBuildView(IPackageBuildView):
44 "this build, if any."
45 )
46
47+ buildinfo_url = exported(
48+ TextLine(
49+ title=_("buildinfo file URL"),
50+ required=False,
51+ readonly=True,
52+ description=_("The URL for the .buildinfo file for this build."),
53+ )
54+ )
55+
56 package_upload = Attribute(
57 "The `PackageUpload` record corresponding to the original upload "
58 "of the binaries resulted from this build. It's 'None' if it is "
59diff --git a/lib/lp/soyuz/model/binarypackagebuild.py b/lib/lp/soyuz/model/binarypackagebuild.py
60index a801a6a..4ac614c 100644
61--- a/lib/lp/soyuz/model/binarypackagebuild.py
62+++ b/lib/lp/soyuz/model/binarypackagebuild.py
63@@ -408,6 +408,14 @@ class BinaryPackageBuild(PackageBuildMixin, StormBase):
64 return ProxiedLibraryFileAlias(self.upload_log, self).http_url
65
66 @property
67+ def buildinfo_url(self):
68+ """See `IBinaryPackageBuild`."""
69+ buildinfo = self.buildinfo
70+ if buildinfo is None:
71+ return None
72+ return ProxiedLibraryFileAlias(buildinfo, self).http_url
73+
74+ @property
75 def distributionsourcepackagerelease(self):
76 """See `IBuild`."""
77 from lp.soyuz.model.distributionsourcepackagerelease import (
78@@ -832,6 +840,8 @@ class BinaryPackageBuild(PackageBuildMixin, StormBase):
79 """See `IBuild`."""
80 if filename.endswith(".changes"):
81 file_object = self.upload_changesfile
82+ elif filename.endswith(".buildinfo"):
83+ file_object = self.buildinfo
84 elif filename.endswith(".txt.gz"):
85 file_object = self.log
86 elif is_upload_log(filename):
87diff --git a/lib/lp/soyuz/stories/soyuz/xx-build-record.rst b/lib/lp/soyuz/stories/soyuz/xx-build-record.rst
88index 9da0cb4..593e1c7 100644
89--- a/lib/lp/soyuz/stories/soyuz/xx-build-record.rst
90+++ b/lib/lp/soyuz/stories/soyuz/xx-build-record.rst
91@@ -310,6 +310,7 @@ appropriate 'Build status' section the user will see 2 new sections,
92 >>> build.buildqueue_record.destroySelf()
93 >>> build.updateStatus(BuildStatus.FULLYBUILT, builder=bob_builder)
94 >>> build.setLog(stp.addMockFile("fake-buildlog"))
95+ >>> build.addBuildInfo(stp.addMockFile("testing_1.0_all.buildinfo"))
96 >>> binaries = stp.uploadBinaryForBuild(build, "testing-bin")
97 >>> upload = stp.distroseries.createQueueEntry(
98 ... PackagePublishingPocket.RELEASE,
99@@ -329,10 +330,14 @@ appropriate 'Build status' section the user will see 2 new sections,
100 Finished on 2008-01-01 (took 5 minutes, 0.0 seconds)
101 buildlog (7 bytes)
102 testing_1.0_all.changes (15 bytes)
103+ testing_1.0_all.buildinfo (7 bytes)
104
105 >>> print(anon_browser.getLink("testing_1.0_all.changes").url)
106 http://.../+build/.../+files/testing_1.0_all.changes
107
108+ >>> print(anon_browser.getLink("testing_1.0_all.buildinfo").url)
109+ http://.../+build/.../+files/testing_1.0_all.buildinfo
110+
111 >>> print(extract_text(find_tag_by_id(anon_browser.contents, "binaries")))
112 Binary packages
113 Binary packages awaiting approval in NEW queue:
114diff --git a/lib/lp/soyuz/stories/webservice/xx-builds.rst b/lib/lp/soyuz/stories/webservice/xx-builds.rst
115index 203e503..93a399a 100644
116--- a/lib/lp/soyuz/stories/webservice/xx-builds.rst
117+++ b/lib/lp/soyuz/stories/webservice/xx-builds.rst
118@@ -53,6 +53,7 @@ of properties:
119 arch_tag: 'i386'
120 archive_link: 'http://.../beta/~cprov/+archive/ubuntu/ppa'
121 builder_link: 'http://.../beta/builders/bob'
122+ buildinfo_url: None
123 can_be_cancelled: False
124 can_be_rescored: False
125 can_be_retried: True
126@@ -89,6 +90,7 @@ Whereas the 1.0 webservice for builds maintains the old property names
127 build_log_url:
128 'http://.../~cprov/+archive/ubuntu/ppa/+build/26/+files/netapplet-1.0.0.tar.gz'
129 builder_link: 'http://.../builders/bob'
130+ buildinfo_url: None
131 buildstate: 'Failed to build'
132 can_be_cancelled: False
133 can_be_rescored: False
134@@ -122,6 +124,7 @@ devel webservice also contains build date_started and duration.
135 build_log_url:
136 'http://.../~cprov/+archive/ubuntu/ppa/+build/26/+files/netapplet-1.0.0.tar.gz'
137 builder_link: 'http://.../builders/bob'
138+ buildinfo_url: None
139 buildstate: 'Failed to build'
140 can_be_cancelled: False
141 can_be_rescored: False
142diff --git a/lib/lp/soyuz/templates/build-index.pt b/lib/lp/soyuz/templates/build-index.pt
143index e00428b..9883dfc 100644
144--- a/lib/lp/soyuz/templates/build-index.pt
145+++ b/lib/lp/soyuz/templates/build-index.pt
146@@ -197,6 +197,13 @@
147 tal:content="changesfile/filename">CHANGESFILE</a>
148 (<span tal:replace="changesfile/content/filesize/fmt:bytes" />)
149 </li>
150+ <li tal:define="buildinfo context/buildinfo;"
151+ tal:condition="buildinfo">
152+ <a class="sprite download"
153+ tal:attributes="href context/buildinfo_url"
154+ tal:content="buildinfo/filename">BUILDINFO</a>
155+ (<span tal:replace="buildinfo/content/filesize/fmt:bytes" />)
156+ </li>
157 </ul>
158 </metal:macro>
159
160diff --git a/lib/lp/soyuz/tests/test_build.py b/lib/lp/soyuz/tests/test_build.py
161index 8ee97c4..e14f26d 100644
162--- a/lib/lp/soyuz/tests/test_build.py
163+++ b/lib/lp/soyuz/tests/test_build.py
164@@ -277,6 +277,35 @@ class TestBuild(TestCaseWithFactory):
165 expected_url = "%s/%s" % (url_start, expected_filename)
166 self.assertEqual(expected_url, build.upload_log_url)
167
168+ def test_buildinfo(self):
169+ # The .buildinfo file can be attached to a build
170+ spph = self.publisher.getPubSource(
171+ sourcename=self.factory.getUniqueString(),
172+ version="%s.1" % self.factory.getUniqueInteger(),
173+ distroseries=self.distroseries,
174+ )
175+ [build] = spph.createMissingBuilds()
176+
177+ self.assertIsNone(build.buildinfo)
178+ self.assertIsNone(build.buildinfo_url)
179+
180+ buildinfo = self.factory.makeLibraryFileAlias()
181+ with person_logged_in(self.admin):
182+ build.addBuildInfo(buildinfo)
183+ self.assertEqual(buildinfo, build.buildinfo)
184+
185+ url_start = (
186+ "http://launchpad.test/%s/+source/%s/%s/+build/%s/+files"
187+ % (
188+ self.distroseries.distribution.name,
189+ spph.source_package_name,
190+ spph.source_package_version,
191+ build.id,
192+ )
193+ )
194+ expected_url = "%s/%s" % (url_start, buildinfo.filename)
195+ self.assertEqual(expected_url, build.buildinfo_url)
196+
197 def test_retry_resets_state(self):
198 # Retrying a build resets most of the state attributes, but does
199 # not modify the first dispatch time.

Subscribers

People subscribed via source and target branches

to status/vote changes: