Can now specify a build target for fedora and distgit releasers

Tito only supported the default build target when releasing,
however, in some cases it was necessisary to change it (building
for zstream for example).

By default, the build target is the same as the branch. With this
change, you can specify a build target on a per branch basis by
adding a 'build_targets' property in the releasers.conf file.

This property takes on the following format:
   build_targets = <branch>:<build_target> <branch>:<build_target> ...

An example configuration could be:

[project-x.y.z]
releaser = tito.release.DistGitReleaser
branches = project-x.y
build_targets = project-x.y:project-x.y.z-candidate

Running:
    tito release project-x.y.z

would instruct the build system to build with the target
'project-x.y.z-candidate' when building from the project-x.y
branch (i.e rhpkg build --no-wait --target project-x.y.z-candidate).
This commit is contained in:
Michael Stead 2012-06-19 12:57:25 -03:00
parent 2486ed3327
commit 61c996977b
2 changed files with 147 additions and 4 deletions

View file

@ -10,6 +10,7 @@
# Red Hat trademarks are not licensed under GPLv2. No permission is
# granted to use or replicate Red Hat trademarks that are incorporated
# in this software or its documentation.
from ConfigParser import NoOptionError
"""
Code for submitting builds for release.
@ -362,13 +363,23 @@ class FedoraGitReleaser(Releaser):
self.git_branches = \
self.releaser_config.get(self.target, "branches").split(" ")
self.package_workdir = os.path.join(self.working_dir,
self.project_name)
build_target_parser = BuildTargetParser(self.releaser_config, self.target,
self.git_branches)
self.build_targets = build_target_parser.get_build_targets()
def release(self, dry_run=False):
self.dry_run = dry_run
self._git_release()
def _get_build_target_for_branch(self, branch):
if branch in self.build_targets:
return self.build_targets[branch]
return None
def _git_release(self):
commands.getoutput("mkdir -p %s" % self.working_dir)
@ -475,7 +486,7 @@ class FedoraGitReleaser(Releaser):
print(cmd)
run_command(cmd)
self._build()
self._build(main_branch)
for branch in self.git_branches[1:]:
print("Merging branch: '%s' -> '%s'" % (main_branch, branch))
@ -489,7 +500,7 @@ class FedoraGitReleaser(Releaser):
print(cmd)
run_command(cmd)
self._build()
self._build(branch)
print
def _merge(self, main_branch):
@ -511,9 +522,14 @@ class FedoraGitReleaser(Releaser):
# TODO: maybe prompt y/n here
os.system(os.environ['SHELL'])
def _build(self):
def _build(self, branch):
""" Submit a Fedora build from current directory. """
build_cmd = "%s build --nowait" % self.cli_tool
target_param = ""
build_target = self._get_build_target_for_branch(branch)
if build_target:
target_param = "--target %s" % build_target
build_cmd = "%s build --nowait %s" % (self.cli_tool, target_param)
if self.dry_run:
self.print_dry_run_warning(build_cmd)
@ -956,3 +972,54 @@ class KojiGitReleaser(KojiReleaser):
output = run_command(cmd)
print(output)
class BuildTargetParser(object):
"""
Parses build targets from a string in the format of:
<branch1>:<target> <branch2>:<target> ...
Each target must be associated with a valid branch.
"""
def __init__(self, releaser_config, release_target, valid_branches):
self.releaser_config = releaser_config
self.release_target = release_target
self.valid_branches = valid_branches
def get_build_targets(self):
build_targets = {}
if not self.releaser_config.has_option(self.release_target, "build_targets"):
return build_targets
defined_build_targets = self.releaser_config.get(self.release_target,
"build_targets").split(" ")
for build_target in defined_build_targets:
# Ignore any empty from multiple spaces in the file.
if not build_target:
continue
branch, target = self._parse_build_target(build_target)
build_targets[branch] = target
return build_targets
def _parse_build_target(self, build_target):
""" Parses a string in the format of branch:target """
if not build_target:
raise TitoException("Invalid build_target: %s. Format: <branch>:<target>"
% build_target)
parts = build_target.split(":")
if len(parts) != 2:
raise TitoException("Invalid build_target: %s. Format: <branch>:<target>"
% build_target)
branch = parts[0]
if not branch in self.valid_branches:
raise TitoException("Invalid build_target: %s. Unknown branch reference."
% build_target)
target = parts[1]
if not target:
raise TitoException("Invalid build_target: %s. Empty target" % build_target)
return (branch, target)

View file

@ -0,0 +1,76 @@
import unittest
from tito.release import BuildTargetParser
from ConfigParser import ConfigParser
from tito.exception import TitoException
class BuildTargetParserTests(unittest.TestCase):
def setUp(self):
unittest.TestCase.setUp(self)
self.valid_branches = ["branch1", "branch2"]
self.release_target = "project-x.y.z"
self.releasers_config = ConfigParser()
self.releasers_config.add_section(self.release_target)
self.releasers_config.set(self.release_target, "build_targets",
"branch1:project-x.y.z-candidate")
def test_parser_gets_correct_targets(self):
parser = BuildTargetParser(self.releasers_config, self.release_target,
self.valid_branches)
release_targets = parser.get_build_targets()
self.assertTrue("branch1" in release_targets)
self.assertEqual("project-x.y.z-candidate", release_targets["branch1"])
self.assertFalse("branch2" in release_targets)
def test_invalid_branch_raises_exception(self):
self.releasers_config.set(self.release_target, "build_targets",
"invalid-branch:project-x.y.z-candidate")
parser = BuildTargetParser(self.releasers_config, self.release_target,
self.valid_branches)
self.assertRaises(TitoException, parser.get_build_targets)
def test_missing_semicolon_raises_exception(self):
self.releasers_config.set(self.release_target, "build_targets",
"invalid-branchproject-x.y.z-candidate")
parser = BuildTargetParser(self.releasers_config, self.release_target,
self.valid_branches)
self.assertRaises(TitoException, parser.get_build_targets)
def test_empty_branch_raises_exception(self):
self.releasers_config.set(self.release_target, "build_targets",
":project-x.y.z-candidate")
parser = BuildTargetParser(self.releasers_config, self.release_target,
self.valid_branches)
self.assertRaises(TitoException, parser.get_build_targets)
def test_empty_target_raises_exception(self):
self.releasers_config.set(self.release_target, "build_targets",
"branch1:")
parser = BuildTargetParser(self.releasers_config, self.release_target,
self.valid_branches)
self.assertRaises(TitoException, parser.get_build_targets)
def test_multiple_spaces_ok(self):
self.releasers_config.set(self.release_target, "build_targets",
" branch1:project-x.y.z-candidate ")
parser = BuildTargetParser(self.releasers_config, self.release_target,
self.valid_branches)
release_targets = parser.get_build_targets()
self.assertEqual(1, len(release_targets))
self.assertTrue("branch1" in release_targets)
self.assertEqual("project-x.y.z-candidate", release_targets["branch1"])
def test_multiple_branches_supported(self):
self.releasers_config.set(self.release_target, "build_targets",
"branch1:project-x.y.z-candidate branch2:second-target")
parser = BuildTargetParser(self.releasers_config, self.release_target,
self.valid_branches)
release_targets = parser.get_build_targets()
self.assertEquals(2, len(release_targets))
self.assertTrue("branch1" in release_targets)
self.assertEqual("project-x.y.z-candidate", release_targets["branch1"])
self.assertTrue("branch2" in release_targets)
self.assertEqual("second-target", release_targets['branch2'])