diff --git a/src/tito/release/distgit.py b/src/tito/release/distgit.py index 4eef3da7..f882cfea 100644 --- a/src/tito/release/distgit.py +++ b/src/tito/release/distgit.py @@ -11,6 +11,7 @@ # granted to use or replicate Red Hat trademarks that are incorporated # in this software or its documentation. import datetime +import requests import os.path import subprocess import sys @@ -33,6 +34,7 @@ from tito.buildparser import BuildTargetParser from tito.exception import RunCommandException from tito.bugtracker import BugzillaExtractor, MissingBugzillaCredsException +from tito.exception import TitoException import getpass from string import Template @@ -41,8 +43,6 @@ class FedoraGitReleaser(Releaser): - REQUIRED_CONFIG = ['branches'] - def __init__(self, name=None, tag=None, build_dir=None, config=None, user_config=None, target=None, releaser_config=None, no_cleanup=False, @@ -56,8 +56,7 @@ def __init__(self, name=None, tag=None, build_dir=None, else: self.cli_tool = "fedpkg" - self.git_branches = \ - self.releaser_config.get(self.target, "branches").split(" ") + self.git_branches = self._branches(name) # check .tito/releasers.conf if self.releaser_config.has_option(self.target, "remote_git_name"): @@ -86,6 +85,66 @@ def release(self, dry_run=False, no_build=False, scratch=False): self.no_build = no_build self._git_release() + def _branches(self, pkgname): + branches = [] + if self.releaser_config.has_option(self.target, "branches"): + branches = \ + self.releaser_config.get(self.target, "branches").split(" ") + + # This is a bit hacky because our inheritence hierarchy is messed up. + # RHEL, and CentOS releasers inherits from the Fedora releaser instead + # of all of them having a common ancestor. We only want to use the + # current implementation of dynamic branches for the `FedoraGitReleaser` + if self.cli_tool != "fedpkg": + if not branches: + raise TitoException("No branches specified in the config and " + "dynamic branches not supported by '{0}'" + .format(self.__class__.__name__)) + return branches + + excluded = [x.lstrip("!") for x in branches if x.startswith("!")] + if branches and not excluded: + return branches + + branches = set(self._dynamic_branches(pkgname)) - set(excluded) + return list(branches) + + def _dynamic_branches(self, pkgname): + active_branches = set(self._pdc_active_branches()) + package_branches = set(self._fedora_distgit_branches(pkgname)) + return list(active_branches.intersection(package_branches)) + + def _pdc_active_branches(self): + """ + https://pdc.fedoraproject.org/rest_api/v1/product-versions/ + """ + pdc = "https://pdc.fedoraproject.org" + url = "{0}/rest_api/v1/product-versions/?active=true".format(pdc) + response = requests.get(url) + + if not response.ok: + raise TitoException("Failed to get active branches from PDC") + + products = response.json()["results"] + return [self._pdc_product_to_branch(x) for x in products] + + def _pdc_product_to_branch(self, product): + if product["short"] == "fedora": + if product["version"] == "rawhide": + return "rawhide" + abbrev = "f" + elif product["short"] == "epel": + abbrev = "epel" + return "{}{}".format(abbrev, product["version"]) + + def _fedora_distgit_branches(self, pkgname): + url = "https://src.fedoraproject.org/api/0/rpms/copr-cli/git/branches" + response = requests.get(url) + if not response.ok: + msg = "Failed to get DistGit branches for '{}'".format(pkgname) + raise TitoException(msg) + return response.json()["branches"] + def _get_build_target_for_branch(self, branch): if branch in self.build_targets: return self.build_targets[branch] @@ -435,6 +494,9 @@ def _git_sync_files(self, project_checkout): class DistGitReleaser(FedoraGitReleaser): + + REQUIRED_CONFIG = ['branches'] + def __init__(self, name=None, tag=None, build_dir=None, config=None, user_config=None, target=None, releaser_config=None, no_cleanup=False, @@ -461,6 +523,8 @@ class CentosGitReleaser(FedoraGitReleaser): entry in 'branches' in the conf file will be used. """ + REQUIRED_CONFIG = ['branches'] + def __init__(self, name=None, tag=None, build_dir=None, config=None, user_config=None, target=None, releaser_config=None, no_cleanup=False,