|
12
by Michael Rooney
move some of the lp config to config.py and add the PushTarball function thanks to Quickly |
1 |
#!/usr/bin/env python
|
|
17
by Michael Rooney
some improvements to ezpkg found on a clean vm, also add maverick |
2 |
import launchpadlib, datetime, os, sys |
|
10
by Michael Rooney
add of initial lp.py to handle lp automation, right now it can mark all fix committed tasks for a milestone as fix released |
3 |
from launchpadlib.launchpad import Launchpad |
4 |
||
|
12
by Michael Rooney
move some of the lp config to config.py and add the PushTarball function thanks to Quickly |
5 |
import config |
6 |
cachedir = config.LP_CACHE_DIR |
|
7 |
server = { |
|
8 |
"staging": launchpadlib.launchpad.STAGING_SERVICE_ROOT, |
|
9 |
"production": launchpadlib.launchpad.EDGE_SERVICE_ROOT, |
|
10 |
}[config.LP_SERVER] |
|
|
11
by Michael Rooney
release.py refactored into class, can now create a release from the milestone also |
11 |
|
12 |
class Releaser: |
|
13 |
def __init__(self, lp, projectName, version): |
|
14 |
self.LP = lp |
|
15 |
self.ProjectName = projectName |
|
16 |
self.Version = version |
|
17 |
self._Initialize() |
|
18 |
||
19 |
def _Initialize(self): |
|
20 |
# Grab the project object.
|
|
|
13
by Michael Rooney
make uploading the tarball and installer work, including calling it from Perform |
21 |
self.Project = self.LP.projects[projectName.lower()] |
|
11
by Michael Rooney
release.py refactored into class, can now create a release from the milestone also |
22 |
# Grab the specified milestone.
|
23 |
self.Milestone = self.Project.getMilestone(name=version) |
|
24 |
self.ReleaseNotes = self.Milestone.summary |
|
25 |
self.ReleaseDate = datetime.date.today().strftime('%Y-%m-%d') |
|
26 |
||
|
13
by Michael Rooney
make uploading the tarball and installer work, including calling it from Perform |
27 |
def _LocateArtifacts(self): |
28 |
"""Find the location of the tarball and installer and return them."""
|
|
29 |
artifactDir = config.PKGROOT |
|
30 |
artifacts = os.listdir(artifactDir) |
|
31 |
tarballs = [f for f in artifacts if f.endswith("tar.gz")] |
|
32 |
if len(tarballs) != 1: |
|
33 |
raise Exception("Expected one tarball in %s, found: %s" % (artifactDir, tarballs)) |
|
34 |
debs = [f for f in artifacts if f.endswith(".deb")] |
|
35 |
if len(debs) != 1: |
|
36 |
raise Exception("Expected one deb in %s, found: %s" % (artfactDir, debs)) |
|
37 |
||
38 |
fullpaths = [os.path.join(artifactDir, filename) for filename in (tarballs[0], debs[0])] |
|
39 |
return fullpaths |
|
40 |
||
41 |
def _UploadArtifact(self, release, filepath, changelog_content=None): |
|
42 |
"""Push new tarball to Launchpad with signature if provided."""
|
|
43 |
filename = os.path.split(filepath)[1] |
|
44 |
content_type, file_type, post_descr = { |
|
45 |
".gz": ("application/x-gzip", "Code Release Tarball", "source tarball"), |
|
46 |
".deb": ("application/x-deb", "Installer file", "installer for Ubuntu"), |
|
47 |
}[os.path.splitext(filename)[1]] |
|
48 |
description = "%s %s %s" % (self.ProjectName, self.Version, post_descr) |
|
49 |
||
50 |
# Get the file contents.
|
|
51 |
file_content = open(filepath).read() |
|
52 |
# Get the signature, if available.
|
|
53 |
signature = filepath + '.asc' |
|
54 |
if os.path.exists(signature): |
|
55 |
signature_content = open(signature, 'r').read() |
|
56 |
else: |
|
57 |
#signature_content = None
|
|
58 |
raise Exception("No signature found for artifact: %s" % filepath) |
|
59 |
||
60 |
# Create a new product release file.
|
|
61 |
release.add_file(filename=filename, description=description, |
|
62 |
file_content=file_content, content_type=content_type, |
|
63 |
file_type=file_type, signature_filename=signature, |
|
64 |
signature_content=signature_content) |
|
65 |
||
66 |
if not changelog_content: |
|
67 |
changelog_content = 'New release available: %s' % self.Version |
|
68 |
else: |
|
69 |
changelog_content = "\n".join(changelog_content) |
|
70 |
release.changelog = changelog_content |
|
71 |
try: |
|
72 |
release.lp_save() |
|
73 |
except HTTPError, e: |
|
74 |
raise Exception('An error happened while uploading %s: %s' % (filepath, e.content)) |
|
75 |
||
|
11
by Michael Rooney
release.py refactored into class, can now create a release from the milestone also |
76 |
def Perform(self, assertReady=True): |
77 |
if assertReady: |
|
78 |
self.AssertReady() |
|
79 |
numFixed = self.MarkCommittedAsReleased() |
|
80 |
print "Marked %s bugs Fix Committed -> Fix Released." % numFixed |
|
|
12
by Michael Rooney
move some of the lp config to config.py and add the PushTarball function thanks to Quickly |
81 |
release = self.MakeReleaseFromMilestone() |
|
13
by Michael Rooney
make uploading the tarball and installer work, including calling it from Perform |
82 |
self.UploadArtifacts(release) |
|
11
by Michael Rooney
release.py refactored into class, can now create a release from the milestone also |
83 |
|
84 |
def AssertReady(self): |
|
85 |
"""Raise an exception if there are any open bugs for this milestone."""
|
|
86 |
unfixed = [task for task in self.Milestone.searchTasks() if task.status not in ["Fix Committed", "Fix Released"]] |
|
87 |
if unfixed: |
|
88 |
raise Exception("There are still %s unfixed tasks for %s, cannot release! Please mark them as Fix Committed or move them to another Milestone." % (len(unfixed), self.Milestone.name)) |
|
89 |
||
90 |
def MarkCommittedAsReleased(self): |
|
91 |
"""Mark "Fix Committed" bugs as "Fix Released"."""
|
|
92 |
committedBugs = [task for task in self.Milestone.searchTasks(status="Fix Committed")] |
|
93 |
for committed in committedBugs: |
|
|
17
by Michael Rooney
some improvements to ezpkg found on a clean vm, also add maverick |
94 |
committed.status = "Fix Released" |
95 |
committed.lp_save() |
|
|
11
by Michael Rooney
release.py refactored into class, can now create a release from the milestone also |
96 |
return len(committedBugs) |
97 |
||
98 |
def MakeReleaseFromMilestone(self): |
|
|
12
by Michael Rooney
move some of the lp config to config.py and add the PushTarball function thanks to Quickly |
99 |
return self.Milestone.createProductRelease(date_released=self.ReleaseDate, release_notes=self.ReleaseNotes) |
100 |
||
|
13
by Michael Rooney
make uploading the tarball and installer work, including calling it from Perform |
101 |
def UploadArtifacts(self, release): |
102 |
for filepath in self._LocateArtifacts(): |
|
103 |
self._UploadArtifact(release, filepath) |
|
|
11
by Michael Rooney
release.py refactored into class, can now create a release from the milestone also |
104 |
|
105 |
||
|
20
by Michael Rooney
add copy_package helper |
106 |
def copy_package(name="fabric", version="0.9.2-1"): |
107 |
ppa = lp.people["mrooney"].getPPAByName(name="ppa") |
|
108 |
ubuntu = lp.distributions['ubuntu'].main_archive |
|
109 |
ppa.syncSource(from_archive=ubuntu, include_binaries=True, source_name=name, to_pocket="Release", to_series="maverick", version=version) |
|
110 |
||
|
11
by Michael Rooney
release.py refactored into class, can now create a release from the milestone also |
111 |
def main(server, lpuser, projectName, version): |
112 |
# Log in.
|
|
113 |
lp = Launchpad.login_with(lpuser, server, cachedir) |
|
114 |
releaser = Releaser(lp, projectName, version) |
|
|
13
by Michael Rooney
make uploading the tarball and installer work, including calling it from Perform |
115 |
releaser.Perform(assertReady=True) |
|
11
by Michael Rooney
release.py refactored into class, can now create a release from the milestone also |
116 |
|
117 |
if __name__ == "__main__": |
|
|
17
by Michael Rooney
some improvements to ezpkg found on a clean vm, also add maverick |
118 |
projectName, version = sys.argv[1:] |
|
13
by Michael Rooney
make uploading the tarball and installer work, including calling it from Perform |
119 |
main(server, config.LP_USER, projectName, version) |