def __init__(self, configuration): self.conf = configuration self.github = Github(configuration) self.pypi = PyPi(configuration) self.fedora = Fedora(configuration) self.logger = configuration.logger self.new_release = {}
def setup_method(self, method): """ setup any state tied to the execution of the given method in a class. setup_method is invoked for every test method of a class. """ configuration.set_logging(level=10) configuration.debug = True self.fedora = Fedora(configuration)
def __init__(self, configuration): self.conf = configuration url = f'https://github.com/{self.conf.repository_owner}/{self.conf.repository_name}.git' self.git = Git(url, self.conf) self.github = Github(configuration, self.git) self.pypi = PyPi(configuration, self.git) self.fedora = Fedora(configuration) self.logger = configuration.logger # FIXME: it's cumbersome to work with these dicts - it's unclear how the content changes; # get rid of them and replace them with individual variables self.new_release = {} self.new_pr = {}
def pypi(self, tmpdir): conf = Configuration() path = str(tmpdir) src = Path(__file__).parent / "src/rlsbot-test" shutil.copy2(str(src / "setup.py"), path) shutil.copy2(str(src / "rlsbot_test.py"), path) self.run_cmd("git init .", work_directory=str(tmpdir)) Fedora.set_git_credentials(str(tmpdir), "Release Bot", "*****@*****.**") self.run_cmd("git add .", work_directory=str(tmpdir)) self.run_cmd("git commit -m 'initial commit'", work_directory=str(tmpdir)) git_repo = Git(str(tmpdir), conf) pypi = PyPi(configuration, git_repo) (flexmock(pypi).should_receive("upload").replace_with(lambda x: None)) return pypi
class ReleaseBot: def __init__(self, configuration): self.conf = configuration url = f'https://github.com/{self.conf.repository_owner}/{self.conf.repository_name}.git' self.git = Git(url, self.conf) self.github = Github(configuration, self.git) self.pypi = PyPi(configuration, self.git) self.fedora = Fedora(configuration) self.logger = configuration.logger # FIXME: it's cumbersome to work with these dicts - it's unclear how the content changes; # get rid of them and replace them with individual variables self.new_release = {} self.new_pr = {} def cleanup(self): if 'tempdir' in self.new_release: self.new_release['tempdir'].cleanup() self.new_release = {} self.new_pr = {} self.github.comment = [] self.fedora.progress_log = [] self.git.cleanup() def load_release_conf(self): """ Updates new_release with latest release-conf.yaml from repository :return: """ # load release configuration from release-conf.yaml in repository conf = self.github.get_configuration() release_conf = self.conf.load_release_conf(conf) self.new_release.update(release_conf) def find_open_release_issues(self): """ Looks for opened release issues on github :return: True on found, False if not found """ cursor = '' release_issues = {} while True: edges = self.github.walk_through_open_issues(start=cursor, direction='before') if not edges: self.logger.debug(f'No more open issues found') break else: for edge in reversed(edges): cursor = edge['cursor'] match = re.match(r'(.+) release', edge['node']['title'].lower()) if match: version = match[1].strip() if validate(version): if edge['node']['authorAssociation'] in [ 'MEMBER', 'OWNER', 'COLLABORATOR' ]: release_issues[version] = edge['node'] self.logger.info( f'Found new release issue with version: {version}' ) else: self.logger.warning( f"Author association {edge['node']['authorAssociation']!r} " f"not in ['MEMBER', 'OWNER', 'COLLABORATOR']" ) else: self.logger.warning( f"{version!r} is not a valid version") if len(release_issues) > 1: msg = f'Multiple release issues are open {release_issues}, please reduce them to one' self.logger.error(msg) return False if len(release_issues) == 1: for version, node in release_issues.items(): self.new_pr = { 'version': version, 'issue_id': node['id'], 'issue_number': node['number'], 'labels': self.new_release.get('labels') } return True else: return False def find_newest_release_pull_request(self): """ Find newest merged release PR :return: bool, whether PR was found """ cursor = '' while True: edges = self.github.walk_through_prs(start=cursor, direction='before', closed=True) if not edges: self.logger.debug(f'No merged release PR found') return False for edge in reversed(edges): cursor = edge['cursor'] match = re.match(r'(.+) release', edge['node']['title'].lower()) if match and validate(match[1]): merge_commit = edge['node']['mergeCommit'] self.logger.info( f"Found merged release PR with version {match[1]}, " f"commit id: {merge_commit['oid']}") new_release = { 'version': match[1], 'commitish': merge_commit['oid'], 'pr_id': edge['node']['id'], 'author_name': merge_commit['author']['name'], 'author_email': merge_commit['author']['email'] } self.new_release.update(new_release) return True def make_release_pull_request(self): """ Makes release pull request and handles outcome :return: whether making PR was successful """ def pr_handler(success): """ Handler for the outcome of making a PR :param success: whether making PR was successful :return: """ result = 'made' if success else 'failed to make' msg = f"I just {result} a PR request for a release version {self.new_pr['version']}" level = logging.INFO if success else logging.ERROR self.logger.log(level, msg) if success: msg += f"\n Here's a [link to the PR]({self.new_pr['pr_url']})" comment_backup = self.github.comment.copy() self.github.comment = [msg] self.github.add_comment(self.new_pr['issue_id']) self.github.comment = comment_backup if success: self.github.close_issue(self.new_pr['issue_number']) latest_gh_str = self.github.latest_release() self.new_pr['previous_version'] = latest_gh_str if Version.coerce(latest_gh_str) >= Version.coerce( self.new_pr['version']): msg = f"Version ({latest_gh_str}) is already released and this issue is ignored." self.logger.warning(msg) return False msg = f"Making a new PR for release of version {self.new_pr['version']} based on an issue." self.logger.info(msg) try: self.new_pr['repo'] = self.git if not self.new_pr['repo']: raise ReleaseException("Couldn't clone repository!") if self.github.make_release_pr(self.new_pr): pr_handler(success=True) return True except ReleaseException: pr_handler(success=False) raise return False def make_new_github_release(self): def release_handler(success): result = "released" if success else "failed to release" msg = f"I just {result} version {self.new_release['version']} on Github" level = logging.INFO if success else logging.ERROR self.logger.log(level, msg) self.github.comment.append(msg) try: latest_release = self.github.latest_release() except ReleaseException as exc: raise ReleaseException( f"Failed getting latest Github release (zip).\n{exc}") if Version.coerce(latest_release) >= Version.coerce( self.new_release['version']): self.logger.info( f"{self.new_release['version']} has already been released on Github" ) else: try: released, self.new_release = self.github.make_new_release( self.new_release) if released: release_handler(success=True) except ReleaseException: release_handler(success=False) raise self.github.update_changelog(self.new_release['version']) return self.new_release def make_new_pypi_release(self): def release_handler(success): result = "released" if success else "failed to release" msg = f"I just {result} version {self.new_release['version']} on PyPI" level = logging.INFO if success else logging.ERROR self.logger.log(level, msg) self.github.comment.append(msg) latest_pypi = self.pypi.latest_version() if Version.coerce(latest_pypi) >= Version.coerce( self.new_release['version']): self.logger.info( f"{self.new_release['version']} has already been released on PyPi" ) return False self.git.fetch_tags() self.git.checkout(self.new_release['version']) try: self.pypi.release() release_handler(success=True) except ReleaseException: release_handler(success=False) raise return True def make_new_fedora_release(self): if not self.new_release.get('fedora'): self.logger.debug('Skipping Fedora release') return self.logger.info("Triggering Fedora release") def release_handler(success): result = "released" if success else "failed to release" msg = f"I just {result} on Fedora" builds = ', '.join(self.fedora.builds) bodhi_update_url = "https://bodhi.fedoraproject.org/updates/new" if builds: msg += f", successfully built for branches: {builds}." msg += f" Follow this link to create bodhi update(s): {bodhi_update_url}" level = logging.INFO if success else logging.ERROR self.logger.log(level, msg) self.github.comment.append(msg) try: name, email = self.github.get_user_contact() self.new_release['commit_name'] = name self.new_release['commit_email'] = email success_ = self.fedora.release(self.new_release) release_handler(success_) except ReleaseException: release_handler(success=False) raise def run(self): self.logger.info( f"release-bot v{configuration.version} reporting for duty!") try: while True: self.git.pull() try: self.load_release_conf() if self.find_newest_release_pull_request(): self.make_new_github_release() # Try to do PyPi release regardless whether we just did github release # for case that in previous iteration (of the 'while True' loop) # we succeeded with github release, but failed with PyPi release if self.make_new_pypi_release(): # There's no way how to tell whether there's already such a fedora 'release' # so try to do it only when we just did PyPi release self.make_new_fedora_release() except ReleaseException as exc: self.logger.error(exc) # Moved out of the previous try-except block, because if it # encounters ReleaseException while checking for PyPi sources # it doesn't check for GitHub issues. try: if self.new_release.get( 'trigger_on_issue' ) and self.find_open_release_issues(): if self.new_release.get('labels') is not None: self.github.put_labels_on_issue( self.new_pr['issue_number'], self.new_release.get('labels')) self.make_release_pull_request() except ReleaseException as exc: self.logger.error(exc) self.github.add_comment(self.new_release.get('pr_id')) self.logger.debug( f"Done. Going to sleep for {self.conf.refresh_interval}s") time.sleep(self.conf.refresh_interval) finally: self.cleanup()
class ReleaseBot: def __init__(self, configuration): self.conf = configuration self.github = Github(configuration) self.pypi = PyPi(configuration) self.fedora = Fedora(configuration) self.logger = configuration.logger self.new_release = {} self.new_pr = {} def cleanup(self): if 'tempdir' in self.new_release: self.new_release['tempdir'].cleanup() self.new_release = {} self.new_pr = {} self.github.comment = [] self.fedora.progress_log = [] def load_release_conf(self): """ Updates new_release with latest release-conf.yaml from repository :return: """ # load release configuration from release-conf.yaml in repository conf = self.github.get_configuration() release_conf = self.conf.load_release_conf(conf) self.new_release.update(release_conf) def find_open_release_issues(self): """ Looks for opened release issues on github :return: True on found, False if not found """ cursor = '' release_issues = {} while True: edges = self.github.walk_through_open_issues(start=cursor, direction='before') if not edges: self.logger.debug(f'No more open issues found') break else: for edge in reversed(edges): cursor = edge['cursor'] match = re.match(r'(.+) release', edge['node']['title'].lower()) if match and validate(match[1]) and \ edge['node']['authorAssociation'] in ['MEMBER', 'OWNER', 'COLLABORATOR']: release_issues[match[1]] = edge['node'] self.logger.info( f'Found new release issue with version: {match[1]}' ) if len(release_issues) > 1: msg = f'Multiple release issues are open {release_issues}, please reduce them to one' self.logger.error(msg) return False if len(release_issues) == 1: for version, node in release_issues.items(): self.new_pr = { 'version': version, 'issue_id': node['id'], 'issue_number': node['number'], 'labels': self.new_release.get('labels') } return True else: return False def find_newest_release_pull_request(self): """ Find newest merged release PR :return: bool, whether PR was found """ cursor = '' while True: edges = self.github.walk_through_prs(start=cursor, direction='before', closed=True) if not edges: self.logger.debug(f'No merged release PR found') return False for edge in reversed(edges): cursor = edge['cursor'] match = re.match(r'(.+) release', edge['node']['title'].lower()) if match and validate(match[1]): merge_commit = edge['node']['mergeCommit'] self.logger.info( f"Found merged release PR with version {match[1]}, " f"commit id: {merge_commit['oid']}") new_release = { 'version': match[1], 'commitish': merge_commit['oid'], 'pr_id': edge['node']['id'], 'author_name': merge_commit['author']['name'], 'author_email': merge_commit['author']['email'] } self.new_release.update(new_release) return True def make_release_pull_request(self): """ Makes release pull request and handles outcome :return: whether making PR was successful """ def pr_handler(success): """ Handler for the outcome of making a PR :param success: whether making PR was successful :return: """ result = 'made' if success else 'failed to make' msg = f"I just {result} a PR request for a release version {self.new_pr['version']}" level = logging.INFO if success else logging.ERROR self.logger.log(level, msg) if success: msg += f"\n Here's a [link to the PR]({self.new_pr['pr_url']})" comment_backup = self.github.comment.copy() self.github.comment = [msg] self.github.add_comment(self.new_pr['issue_id']) self.github.comment = comment_backup if success: self.github.close_issue(self.new_pr['issue_number']) self.new_pr['repo'].cleanup() prev_version = self.github.latest_release() # if there are no previous releases, set version to 0.0.0 prev_version = prev_version if prev_version else '0.0.0' self.new_pr['previous_version'] = prev_version if Version.coerce(prev_version) >= Version.coerce( self.new_pr['version']): msg = f"Version ({prev_version}) is already released and this issue is ignored." self.logger.warning(msg) return False msg = f"Making a new PR for release of version {self.new_pr['version']} based on an issue." self.logger.info(msg) try: self.new_pr['repo'] = self.github.clone_repository() if not self.new_pr['repo']: raise ReleaseException("Couldn't clone repository!") if self.github.make_release_pr(self.new_pr): pr_handler(success=True) return True except ReleaseException: pr_handler(success=False) raise return False def make_new_github_release(self): def release_handler(success): result = "released" if success else "failed to release" msg = f"I just {result} version {self.new_release['version']} on Github" level = logging.INFO if success else logging.ERROR self.logger.log(level, msg) self.github.comment.append(msg) try: latest_github = self.github.latest_release() if Version.coerce(latest_github) >= Version.coerce( self.new_release['version']): self.logger.info( f"{self.new_release['version']} has already been released on Github" ) # to fill in new_release['fs_path'] so that we can continue with PyPi upload self.new_release = self.github.download_extract_zip( self.new_release) return self.new_release except ReleaseException as exc: raise ReleaseException( f"Failed getting latest Github release (zip).\n{exc}") try: released, self.new_release = self.github.make_new_release( self.new_release) if released: release_handler(success=True) except ReleaseException: release_handler(success=False) raise return self.new_release def make_new_pypi_release(self): def release_handler(success): result = "released" if success else "failed to release" msg = f"I just {result} version {self.new_release['version']} on PyPI" level = logging.INFO if success else logging.ERROR self.logger.log(level, msg) self.github.comment.append(msg) latest_pypi = self.pypi.latest_version() # if there are no previous releases, set version to 0.0.0 latest_pypi = latest_pypi if latest_pypi else '0.0.0' if Version.coerce(latest_pypi) >= Version.coerce( self.new_release['version']): self.logger.info( f"{self.new_release['version']} has already been released on PyPi" ) return False try: self.pypi.release(self.new_release) release_handler(success=True) except ReleaseException: release_handler(success=False) raise return True def make_new_fedora_release(self): if not self.new_release.get('fedora'): self.logger.debug('Skipping Fedora release') return self.logger.info("Triggering Fedora release") def release_handler(success): result = "released" if success else "failed to release" msg = f"I just {result} on Fedora" builds = ', '.join(self.fedora.builds) if builds: msg += f", successfully built for branches: {builds}" level = logging.INFO if success else logging.ERROR self.logger.log(level, msg) self.github.comment.append(msg) try: name, email = self.github.get_user_contact() self.new_release['commit_name'] = name self.new_release['commit_email'] = email success_ = self.fedora.release(self.new_release) release_handler(success_) except ReleaseException: release_handler(success=False) raise def run(self): self.logger.info( f"release-bot v{configuration.version} reporting for duty!") while True: try: self.load_release_conf() if self.find_newest_release_pull_request(): self.make_new_github_release() # Try to do PyPi release regardless whether we just did github release # for case that in previous iteration (of the 'while True' loop) # we succeeded with github release, but failed with PyPi release if self.make_new_pypi_release(): # There's no way how to tell whether there's already such a fedora 'release' # so try to do it only when we just did PyPi release self.make_new_fedora_release() if self.new_release.get('trigger_on_issue' ) and self.find_open_release_issues(): if self.new_release.get('labels') is not None: self.github.put_labels_on_issue( self.new_pr['issue_number'], self.new_release.get('labels')) self.make_release_pull_request() except ReleaseException as exc: self.logger.error(exc) self.github.add_comment(self.new_release.get('pr_id')) self.cleanup() self.logger.debug( f"Done. Going to sleep for {self.conf.refresh_interval}s") time.sleep(self.conf.refresh_interval)
class ReleaseBot: def __init__(self, configuration): self.conf = configuration self.github = Github(configuration) self.pypi = PyPi(configuration) self.fedora = Fedora(configuration) self.logger = configuration.logger self.new_release = {} def cleanup(self): if 'tempdir' in self.new_release: self.new_release['tempdir'].cleanup() self.new_release = {} self.github.comment = [] self.fedora.progress_log = [] def load_release_conf(self): # load release configuration from release-conf.yaml in repository release_conf = self.conf.load_release_conf(self.new_release['fs_path']) self.new_release.update(release_conf) def find_newest_release_pull_request(self): """ Find newest merged release PR :return: bool, whether PR was found """ cursor = '' while True: edges = self.github.walk_through_closed_prs(start=cursor, direction='before') if not edges: self.logger.debug(f'No merged release PR found') return False for edge in reversed(edges): cursor = edge['cursor'] match = re.match(r'(.+) release', edge['node']['title'].lower()) if match and validate(match[1]): merge_commit = edge['node']['mergeCommit'] self.logger.info(f"Found merged release PR with version {match[1]}, " f"commit id: {merge_commit['oid']}") self.new_release = {'version': match[1], 'commitish': merge_commit['oid'], 'pr_id': edge['node']['id'], 'author_name': merge_commit['author']['name'], 'author_email': merge_commit['author']['email']} return True def make_new_github_release(self): def release_handler(success): result = "released" if success else "failed to release" msg = f"I just {result} version {self.new_release['version']} on Github" level = logging.INFO if success else logging.ERROR self.logger.log(level, msg) self.github.comment.append(msg) try: released, self.new_release = self.github.make_new_release(self.new_release, self.pypi.latest_version()) if released: release_handler(success=True) except ReleaseException: release_handler(success=False) raise return self.new_release def make_new_pypi_release(self): def release_handler(success): result = "released" if success else "failed to release" msg = f"I just {result} version {self.new_release['version']} on PyPI" level = logging.INFO if success else logging.ERROR self.logger.log(level, msg) self.github.comment.append(msg) latest_pypi = self.pypi.latest_version() if Version.coerce(latest_pypi) >= Version.coerce(self.new_release['version']): self.logger.info(f"{self.new_release['version']} has already been released on PyPi") return False try: self.pypi.release(self.new_release) release_handler(success=True) except ReleaseException: release_handler(success=False) raise return True def make_new_fedora_release(self): if not self.new_release.get('fedora'): self.logger.debug('Skipping Fedora release') return self.logger.info("Triggering Fedora release") def release_handler(success): result = "released" if success else "failed to release" msg = f"I just {result} on Fedora" builds = ', '.join(self.fedora.builds) if builds: msg += f", successfully built for branches: {builds}" level = logging.INFO if success else logging.ERROR self.logger.log(level, msg) self.github.comment.append(msg) try: success_ = self.fedora.release(self.new_release) release_handler(success_) except ReleaseException: release_handler(success=False) raise def run(self): self.logger.info(f"release-bot v{configuration.version} reporting for duty!") while True: try: if self.find_newest_release_pull_request(): self.make_new_github_release() self.load_release_conf() # Try to do PyPi release regardless whether we just did github release # for case that in previous iteration (of the 'while True' loop) # we succeeded with github release, but failed with PyPi release if self.make_new_pypi_release(): # There's no way how to tell whether there's already such a fedora 'release' # so try to do it only when we just did PyPi release self.make_new_fedora_release() except ReleaseException as exc: self.logger.error(exc) self.github.add_comment(self.new_release.get('pr_id')) self.cleanup() self.logger.debug(f"Done. Going to sleep for {self.conf.refresh_interval}s") time.sleep(self.conf.refresh_interval)
class TestFedora: def run_cmd(self, cmd, work_directory): shell = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, cwd=work_directory, universal_newlines=True) return shell def setup_method(self, method): """ setup any state tied to the execution of the given method in a class. setup_method is invoked for every test method of a class. """ configuration.set_logging(level=10) configuration.debug = True self.fedora = Fedora(configuration) def teardown_method(self, method): """ teardown any state that was previously setup with a setup_method call. """ def fake_spectool_func(self, directory, branch, fail=True): source_path = Path(directory) / f"{branch}_source.tar.gz" source_path.touch() return True def fake_clone_func(self, directory, name): directory = Path(directory) if not directory.is_dir(): raise ReleaseException( f"Cannot clone into non-existent directory {directory}:") shell_command(directory, f"fedpkg clone {name!r} --anonymous", "Cloning fedora repository failed:") return str(directory / name) def fake_repository_clone_func(self, directory, name, non_ff=False): self.create_fake_repository(directory, non_ff) return directory def create_fake_repository(self, directory, non_ff=False): self.run_cmd("git init .", directory) self.run_cmd("git checkout -b master", directory) assert self.fedora.set_git_credentials(directory, "Name", "*****@*****.**") spec_content = Path(__file__).parent.joinpath( "src/example.spec").read_text() Path(directory).joinpath("example.spec").write_text(spec_content) self.run_cmd("git add .", directory) self.run_cmd("git commit -m 'Initial commit'", directory) self.run_cmd("git checkout -b f28", directory) if non_ff: spec_content = Path(__file__).parent.joinpath( "src/example_updated.spec").read_text() Path(directory).joinpath("example.spec").write_text(spec_content) self.run_cmd("git add .", directory) self.run_cmd("git commit -m 'Initial commit 2'", directory) else: self.run_cmd("git merge master", directory) self.run_cmd("git checkout master", directory) @pytest.fixture def new_release(self): new_release = { 'version': '9.9.9', 'commitish': '', 'author_name': 'John Doe', 'author_email': '*****@*****.**', 'commit_name': 'Testy McTestFace', 'commit_email': '*****@*****.**', 'python_versions': [3], 'fedora_branches': ["f28"], 'fedora': True, 'changelog': ['Test'], 'fs_path': '', 'tempdir': None } return new_release @pytest.fixture() def no_sources(self): flexmock(self.fedora, fedpkg_sources=True) @pytest.fixture() def no_build(self): flexmock(self.fedora, fedpkg_build=True) @pytest.fixture() def no_push(self): flexmock(self.fedora, fedpkg_push=True) @pytest.fixture() def no_new_sources(self): flexmock(self.fedora, fedpkg_new_sources=True) @pytest.fixture() def no_ticket_init(self): flexmock(self.fedora, init_ticket=True) @pytest.fixture() def fake_spectool(self): (flexmock(self.fedora).should_receive("fedpkg_spectool").replace_with( lambda directory, branch, fail: self.fake_spectool_func( directory, branch, fail))) @pytest.fixture def fake_repository_clone(self, tmpdir): (flexmock(self.fedora).should_receive("fedpkg_clone_repository"). replace_with(lambda directory, name: self.fake_repository_clone_func( tmpdir, name))) return tmpdir @pytest.fixture def fake_repository_clone_no_ff(self, tmpdir): (flexmock(self.fedora).should_receive("fedpkg_clone_repository"). replace_with(lambda directory, name: self.fake_repository_clone_func( tmpdir, name, True))) return tmpdir @pytest.fixture def fake_clone(self): (flexmock(self.fedora).should_receive( "fedpkg_clone_repository").replace_with( lambda directory, name: self.fake_clone_func(directory, name))) @pytest.fixture def no_lint(self): flexmock(self.fedora, fedpkg_lint=True) @pytest.fixture def fake_tmp_clean(self): (flexmock(TemporaryDirectory).should_receive("cleanup").replace_with( lambda: None)) @pytest.fixture def package(self): return 'zip' @pytest.fixture def non_existent_path(self, tmpdir): path = Path(str(tmpdir)) / 'fooo' return str(path) @pytest.fixture def tmp(self, tmpdir): return tmpdir @pytest.fixture def fake_repository(self, tmpdir): self.create_fake_repository(tmpdir) return Path(str(tmpdir)) @pytest.fixture def example_spec(self, tmpdir): spec_content = (Path(__file__).parent / "src/example.spec").read_text() spec = Path(str(tmpdir)) / "example.spec" spec.write_text(spec_content) return str(spec) def test_wrong_dir_clone(self, non_existent_path, package, fake_clone): with pytest.raises(ReleaseException): self.fedora.fedpkg_clone_repository(non_existent_path, package) def test_wrong_dir_switch(self, non_existent_path): with pytest.raises(ReleaseException): self.fedora.fedpkg_switch_branch(non_existent_path, 'master') def test_wrong_dir_build(self, non_existent_path): with pytest.raises(ReleaseException): self.fedora.fedpkg_build(non_existent_path, 'master') def test_wrong_dir_push(self, non_existent_path): with pytest.raises(ReleaseException): self.fedora.fedpkg_push(non_existent_path, 'master') def test_wrong_dir_merge(self, non_existent_path): with pytest.raises(ReleaseException): self.fedora.fedpkg_merge(non_existent_path, 'master') def test_wrong_dir_commit(self, non_existent_path): with pytest.raises(ReleaseException): self.fedora.fedpkg_commit(non_existent_path, 'master', "Some message") def test_wrong_dir_sources(self, non_existent_path): with pytest.raises(ReleaseException): self.fedora.fedpkg_sources(non_existent_path, 'master') def test_wrong_dir_spectool(self, non_existent_path): with pytest.raises(ReleaseException): self.fedora.fedpkg_spectool(non_existent_path, 'master') def test_wrong_dir_lint(self, non_existent_path): with pytest.raises(ReleaseException): self.fedora.fedpkg_lint(non_existent_path, 'master') def test_clone(self, tmp, package, fake_clone): directory = Path(self.fedora.fedpkg_clone_repository(tmp, package)) assert (directory / f"{package}.spec").is_file() assert (directory / ".git").is_dir() def test_switch_branch(self, fake_repository): self.fedora.fedpkg_switch_branch(fake_repository, "f28", False) assert "f28" == self.run_cmd("git rev-parse --abbrev-ref HEAD", fake_repository).stdout.strip() self.fedora.fedpkg_switch_branch(fake_repository, "master", False) assert "master" == self.run_cmd("git rev-parse --abbrev-ref HEAD", fake_repository).stdout.strip() def test_commit(self, fake_repository): spec_path = fake_repository / "example.spec" spec_content = spec_path.read_text() + "\n Test test" spec_path.write_text(spec_content) branch = "master" commit_message = "Test commit" assert self.fedora.fedpkg_commit(fake_repository, "master", commit_message, False) assert commit_message == self.run_cmd( f"git log -1 --pretty=%B {branch}| cat | head -n 1", fake_repository).stdout.strip() def test_lint(self, tmp, package, fake_clone): directory = Path(self.fedora.fedpkg_clone_repository(tmp, package)) assert self.fedora.fedpkg_lint(str(directory), "master", False) spec_path = directory / f"{package}.spec" with spec_path.open('r+') as spec_file: spec = spec_file.read() + "\n Test test" spec_file.write(spec) assert not self.fedora.fedpkg_lint(str(directory), "master", False) def test_sources(self, tmp, package, fake_clone): directory = self.fedora.fedpkg_clone_repository(tmp, package) file_number = len(os.listdir(directory)) assert self.fedora.fedpkg_sources(directory, "master", False) assert file_number != len(os.listdir(directory)) def test_spectool(self, tmp, package, fake_clone): directory = self.fedora.fedpkg_clone_repository(tmp, package) file_number = len(os.listdir(directory)) assert self.fedora.fedpkg_spectool(directory, "master", False) assert file_number != len(os.listdir(directory)) def test_workflow(self, fake_repository): spec_path = fake_repository / "example.spec" spec_content = spec_path.read_text() + "\n Test test" spec_path.write_text(spec_content) commit_message = "Update" assert self.fedora.fedpkg_commit(fake_repository, "master", commit_message, False) assert self.fedora.fedpkg_switch_branch(fake_repository, "f28", False) assert self.fedora.fedpkg_merge(fake_repository, "f28", True, False) assert commit_message == self.run_cmd( f"git log -1 --pretty=%B f28 | cat | head -n 1", fake_repository).stdout.strip() def test_update_package(self, no_build, no_push, no_sources, no_new_sources, fake_spectool, no_lint, new_release, fake_repository): configuration.repository_name = 'example' commit_message = f"Update to {new_release['version']}" assert self.fedora.update_package(fake_repository, "f28", new_release) assert commit_message == self.run_cmd( f"git log -1 --pretty=%B | cat | head -n 1", fake_repository).stdout.strip() def test_release_in_fedora(self, no_build, no_push, no_sources, no_new_sources, fake_spectool, no_lint, fake_repository_clone, new_release, fake_tmp_clean, no_ticket_init): configuration.repository_name = 'example' self.fedora.release(new_release) commit_message = f"Update to {new_release['version']}" assert commit_message == self.run_cmd( f"git log -1 --pretty=%B master| cat | head -n 1", fake_repository_clone).stdout.strip() assert commit_message == self.run_cmd( f"git log -1 --pretty=%B f28 | cat | head -n 1", fake_repository_clone).stdout.strip() def test_release_in_fedora_non_ff(self, no_build, no_push, no_sources, no_new_sources, no_lint, fake_spectool, fake_repository_clone_no_ff, new_release, no_ticket_init, fake_tmp_clean): configuration.repository_name = 'example' self.fedora.release(new_release) commit_message = f"Update to {new_release['version']}" assert commit_message == self.run_cmd( f"git log -1 --pretty=%B master| cat | head -n 1", fake_repository_clone_no_ff).stdout.strip() assert commit_message == self.run_cmd( f"git log -1 --pretty=%B f28 | cat | head -n 1", fake_repository_clone_no_ff).stdout.strip()