diff --git a/ci/lp_check.py b/ci/lp_check.py new file mode 100755 index 0000000..145affc --- /dev/null +++ b/ci/lp_check.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2019 Simon Quigley +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import argparse +import launchpadlib +from time import sleep +from launchpadlib.launchpad import Launchpad + + +class LaunchpadCheck: + def login(self): + """Log in to Launchpad anonymously""" + lp = Launchpad.login_anonymously("CI Infrastructure", "production", + version="devel") + return lp + + def verify_source_published(self, package, package_version): + """Verify that the source is published""" + # Log in to Launchpad + lp = self.login() + + # Grab the correct PPA object + for ippa in lp.people[self.lp_person].ppas: + if ippa.name == self.ppa_name: + ppa = ippa + + # We're verifying every five minutes; never go to more than two hours + # (60 minutes × 2 hours) ÷ 5 minutes = 24 max iterations + for i in range(0, 24): + print("Verifying if source is published,", (i*5), "minutes in.") + ppa_source = ppa.getPublishedSources(source_name=package, + version=package_version, + order_by_date=True)[0] + status = ppa_source.status + # Error out if the package isn't on the way to becoming published + if status != "Pending" and status != "Published": + raise ValueError("Source package no longer exists") + if status == "Published": + print("Source published.") + return lp, ppa + elif status == "Pending": + # 60 seconds × 5 minutes = 300 seconds + sleep(300) + # If we've timed out, raise an error + raise ValueError("Timed out, contact Launchpad admins") + + def verify_binaries_published(self, package, package_version): + """Verify that all of the binaries are published and have passed""" + # Getting the source is a prerequisite + lp, ppa = self.verify_source_published(package, package_version) + + # We're verifying every five minutes; never go to more than two hours + # (60 minutes × 2 hours) ÷ 5 minutes = 24 max iterations + for i in range(0, 24): + print("Verifying if binaries are published,", (i*5), "minutes in.") + need_sleep = False + try: + # Ensure all of the builds have passed or are in-progress + for binary in ppa.getBuilds(): + if binary.buildstate == "Needs building" or \ + binary.buildstate == "Currently building" or \ + binary.buildstate == "Uploading build": + print(binary.arch_tag, "still building.") + # Raise a one-way flag so the sleep isn't done during + # the iteration of the binaries + need_sleep = True + elif binary.buildstate == "Successfully built": + print(binary.arch_tag, "successfully built.") + else: + raise ValueError("One or more builds have an error") + # Make sure all of the binaries are in a good state if they've + # passed + for binary in ppa.getPublishedBinaries(): + if binary.status == "Pending": + print(binary_package_name, "still publishing.") + need_sleep = True + elif binary.status == "Published": + print(binary_package_name, "published.") + else: + raise ValueError("One or more builds can't publish") + except IndexError: + need_sleep = True + + if need_sleep: + # 60 seconds × 5 minutes = 300 seconds + sleep(300) + else: + print("All builds have successfully published.") + break + # If we've timed out, raise an error + raise ValueError("Timed out, contact Launchpad admins") + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("-p", "--package", help="The source package", + required=True) + parser.add_argument("-v", "--package-version", help="The package version", + required=True) + parser.add_argument("-t", "--lp-team", help="Launchpad user with the PPA", + required=True) + parser.add_argument("-r", "--ppa", help="Name of the Launchpad PPA", + required=True) + args = parser.parse_args() + self.lp_person = args.lp_team + self.ppa_name = args.ppa + + lpcheck = LaunchpadCheck() + lpcheck.verify_binaries_published() diff --git a/templates/package.xml b/templates/package.xml index e03e728..655e70d 100644 --- a/templates/package.xml +++ b/templates/package.xml @@ -55,6 +55,9 @@ export DEBEMAIL="info@lubuntu.me" tar cvf {{ NAME }}_$VERSION.orig.tar upstream; gzip {{ NAME }}_$VERSION.orig.tar; (cd {{ NAME }}; dch --distribution {{ RELEASE }} --package "{{ NAME }}" --newversion "$VERSION-0ubuntu1~ppa1" "CI upload."; debuild -S -d -sa -k234778F3D70C2B9785EB7426E7BE29862BE6F574; dput {{ UPLOAD_TARGET }} ../{{ NAME }}_$VERSION-0ubuntu1~ppa1_source.changes) +sleep 5m; +git clone https://phab.lubuntu.me/source/ci-tooling.git tooling; +./tooling/ci/lp_check -p {{ NAME }} -v $VERSION -t lubuntu-ci -r unstable-ci-proposed;