def run(self): # rev is a commit # we use branch on purpose so we get the latest thing # TODO: check if rev is HEAD on {branch}, warn then? branch = nested_get(self.event, "msg", "commit", "branch") # self.project is dist-git, we need to get upstream dg = DistGit(self.config, self.package_config) self.package_config.upstream_project_url = ( dg.get_project_url_from_distgit_spec()) if not self.package_config.upstream_project_url: raise PackitException( "URL in specfile is not set. We don't know where the upstream project lives." ) n, r = get_namespace_and_repo_name( self.package_config.upstream_project_url) up = self.upstream_service.get_project(repo=r, namespace=n) lp = LocalProject(git_project=up) api = PackitAPI(self.config, self.package_config, lp) api.sync_from_downstream( dist_git_branch=branch, upstream_branch="master", # TODO: this should be configurable )
def test_get_builds(upstream_n_distgit, expected_results, br_list, number_of_builds): u, d = upstream_n_distgit from bodhi.client.bindings import BodhiClient c = get_test_config() pc = get_local_package_config(str(u)) pc.downstream_project_url = str(d) pc.upstream_project_url = str(u) dg = DistGit(c, pc) pc = get_local_package_config(str(u)) flexmock(BodhiClient).should_receive("latest_builds").and_return( BODHI_LATEST_BUILDS ) status = Status(c, pc, u, dg) flexmock( PagureProject, get_git_urls=lambda: {"git": "foo.git"}, fork_create=lambda: None, get_fork=lambda: PagureProject("", "", PagureService()), get_branches=br_list, ) assert status table = status.get_builds(number_of_builds) assert table assert len(table.keys()) == number_of_builds assert table == expected_results
def sync_pr(self, pr_id, dist_git_branch: str, upstream_version: str = None): up = Upstream(config=self.config, package_config=self.package_config) dg = DistGit(config=self.config, package_config=self.package_config) up.checkout_pr(pr_id=pr_id) local_pr_branch = f"pull-request-{pr_id}-sync" # fetch and reset --hard upstream/$branch? dg.checkout_branch(dist_git_branch) dg.create_branch(local_pr_branch) dg.checkout_branch(local_pr_branch) dg.sync_files(up.local_project) patches = up.create_patches( upstream=upstream_version, destination=dg.local_project.working_dir ) dg.add_patches_to_specfile(patches) description = ( f"Upstream pr: {pr_id}\n" f"Upstream commit: {up.local_project.git_repo.head.commit}\n" ) self.sync( distgit=dg, commit_msg=f"Sync upstream pr: {pr_id}", pr_title=f"Upstream pr: {pr_id}", pr_description=description, dist_git_branch="master", add_new_sources=False, )
def test_update_on_cockpit_ostree_pr_exists(cockpit_ostree): upstream_path, dist_git_path = cockpit_ostree def mocked_new_sources(sources=None): if not Path(sources).is_file(): raise RuntimeError("archive does not exist") flexmock(PkgTool, new_sources=mocked_new_sources) flexmock(PackitAPI, init_kerberos_ticket=lambda: None) flexmock( DistGit, push_to_fork=lambda *args, **kwargs: None, is_archive_in_lookaside_cache=lambda archive_path: False, upload_to_lookaside_cache=lambda archive, pkg_tool: None, download_upstream_archive=lambda: "the-archive", ) pr = flexmock(url="https://example.com/pull/1") flexmock(DistGit).should_receive("existing_pr").and_return(pr) pc = get_local_package_config(str(upstream_path)) up_lp = LocalProject(working_dir=upstream_path) c = get_test_config() api = PackitAPI(c, pc, up_lp) api._dg = DistGit(c, pc) api._dg._local_project = LocalProject(working_dir=dist_git_path) with cwd(upstream_path): assert pr == api.sync_release( dist_git_branch="main", use_local_content=False, version="179", force_new_sources=False, create_pr=True, )
def run(self) -> HandlerResults: # self.project is dist-git, we need to get upstream dg = DistGit(self.config, self.package_config) self.package_config.upstream_project_url = ( dg.get_project_url_from_distgit_spec() ) if not self.package_config.upstream_project_url: return HandlerResults( success=False, details={ "msg": "URL in specfile is not set. " "We don't know where the upstream project lives." }, ) n, r = get_namespace_and_repo_name(self.package_config.upstream_project_url) up = self.project.service.get_project(repo=r, namespace=n) self.local_project = LocalProject( git_project=up, working_dir=self.config.command_handler_work_dir ) self.api = PackitAPI(self.config, self.package_config, self.local_project) self.api.sync_from_downstream( # rev is a commit # we use branch on purpose so we get the latest thing # TODO: check if rev is HEAD on {branch}, warn then? dist_git_branch=self.distgit_event.branch, upstream_branch="master", # TODO: this should be configurable ) return HandlerResults(success=True, details={})
def dg(self): if self._dg is None: self._dg = DistGit( config=self.config, package_config=self.package_config, local_project=self.downstream_local_project, ) return self._dg
def __init__(self, config: Config, package_config: PackageConfig): self.config = config self.package_config = package_config self.up = Upstream(config=self.config, package_config=self.package_config) self.dg = DistGit(config=self.config, package_config=self.package_config)
def distgit_instance(upstream_n_distgit, mock_remote_functionality_upstream): u, d = upstream_n_distgit c = get_test_config() pc = get_local_package_config(str(u)) pc.downstream_project_url = str(d) pc.upstream_project_url = str(u) dg = DistGit(c, pc) return d, dg
def distgit_instance(upstream_and_remote, distgit_and_remote, mock_remote_functionality_upstream): u, _ = upstream_and_remote d, _ = distgit_and_remote c = get_test_config() pc = get_local_package_config(str(u)) pc.dist_git_clone_path = str(d) pc.upstream_project_url = str(u) dg = DistGit(c, pc) return d, dg
def dg(self): if self._dg is None: self.init_kerberos_ticket() self._dg = DistGit( config=self.config, package_config=self.package_config, local_project=self.downstream_local_project, stage=self.stage, ) return self._dg
def distgit_with_actions(): return DistGit( config=flexmock(Config()), package_config=flexmock( PackageConfig( actions={ ActionName.pre_sync: "command --a", ActionName.get_current_version: "command --b", })), )
def test_pr_exists(title, description, branch, prs, exists): local_project = LocalProject( git_project=flexmock(service="something", get_pr_list=lambda: prs), refresh=False, ) distgit = DistGit( config=flexmock(Config()), package_config=flexmock(PackageConfig()), local_project=local_project, ) assert distgit.pr_exists(title, description, branch) == exists
def test_existing_pr(title, description, branch, prs, exists): local_project = LocalProject( git_project=flexmock(service="something", get_pr_list=lambda: prs), refresh=False, ) distgit = DistGit( config=flexmock(Config()), package_config=flexmock(PackageConfig()), local_project=local_project, ) pr = distgit.existing_pr(title, description, branch) if exists: assert pr is not None else: assert pr is None
def distgit_mock(local_project_mock, config_mock, package_config_mock): distgit = DistGit( config=config_mock, package_config=package_config_mock, local_project=local_project_mock, ) flexmock(distgit) distgit.should_receive("is_dirty").and_return(False) distgit.should_receive("downstream_config").and_return(package_config_mock) distgit.should_receive("create_branch") distgit.should_receive("update_branch") distgit.should_receive("checkout_branch") distgit.should_receive("commit") distgit.should_receive("push") distgit.should_receive("absolute_specfile_dir").and_return(Path("/mock_path")) return distgit
def get_distgit_kls_from_repo( repo_path: Path, config: Config ) -> Tuple[DistGit, Optional[str], Optional[str]]: """ :return: DistGit instance, centos package name, fedora package name """ path = Path(repo_path) pc = PackageConfig(downstream_package_name=path.name) lp = LocalProject(working_dir=path) if "fedoraproject.org" in lp.git_url: return DistGit(config, pc, local_project=lp), None, path.name elif "centos.org" in lp.git_url: return CentOSDistGit(config, pc, local_project=lp), path.name, None raise PackitException( f"Dist-git URL {lp.git_url} not recognized, we expected centos.org or fedoraproject.org" )
def test_get_updates(upstream_n_distgit, expected_status, number_of_updates): u, d = upstream_n_distgit from bodhi.client.bindings import BodhiClient c = get_test_config() pc = get_local_package_config(str(u)) pc.downstream_project_url = str(d) pc.upstream_project_url = str(u) dg = DistGit(c, pc) pc = get_local_package_config(str(u)) flexmock(BodhiClient).should_receive("query").and_return(BODHI_UPDATES) status = Status(c, pc, u, dg) assert status table = status.get_updates(number_of_updates=number_of_updates) assert table assert len(table) == number_of_updates assert table == expected_status
def test_existing_pr(title, description, branch, prs, exists): user_mock = flexmock().should_receive("get_username").and_return( "packit").mock() local_project = LocalProject( git_project=flexmock(service="something", get_pr_list=lambda: prs), refresh=False, git_service=flexmock(user=user_mock), ) distgit = DistGit( config=flexmock(Config()), package_config=flexmock(PackageConfig()), local_project=local_project, ) pr = distgit.existing_pr(title, description, branch) if exists: assert pr is not None else: assert pr is None
def get_distgit_kls_from_repo( repo_path: Path, config: Config) -> Tuple[DistGit, Optional[str], Optional[str]]: """ :return: DistGit instance, centos package name, fedora package name """ path = Path(repo_path) pc = PackageConfig(downstream_package_name=path.name) lp = LocalProject(working_dir=path) if FEDORA_DOMAIN in lp.git_url: return DistGit(config, pc, local_project=lp), None, path.name elif CENTOS_DOMAIN in lp.git_url: return CentOS8DistGit(config, pc, local_project=lp), path.name, None elif CENTOS_STREAM_GITLAB in lp.git_url: return CentOS9DistGit(config, pc, local_project=lp), path.name, None raise PackitException( f"Dist-git URL {lp.git_url} not recognized, we expected one of: " f"{FEDORA_DOMAIN}, {CENTOS_DOMAIN} or {CENTOS_STREAM_GITLAB}")
def test_get_dg_versions(upstream_n_distgit, expected_versions): u, d = upstream_n_distgit c = get_test_config() pc = get_local_package_config(str(u)) pc.downstream_project_url = str(d) pc.upstream_project_url = str(u) dg = DistGit(c, pc) flexmock(dg.local_project.git_project).should_receive( "get_branches").and_return(expected_versions.keys()) flexmock(dg.specfile).should_receive("get_version").and_return("0.0.2") flexmock(dg).should_receive("checkout_branch").and_return(None) flexmock(dg).should_receive("create_branch").and_return(None) status = Status(c, pc, u, dg) dg_versions = status.get_dg_versions() assert dg_versions.keys() == expected_versions.keys() assert dg_versions == expected_versions
def sync_release(self, dist_git_branch: str, version: str = None): """ Update given package in Fedora """ up = Upstream(config=self.config, package_config=self.package_config) dg = DistGit(config=self.config, package_config=self.package_config) full_version = version or up.get_upstream_version() current_up_branch = up.active_branch try: # TODO: this is problematic, since we may overwrite stuff in the repo # but the thing is that we need to do it # I feel like the ideal thing to do would be to clone the repo and work in tmpdir # TODO: this is also naive, upstream may use different tagging scheme, e.g. # release = 232, tag = v232 up.checkout_release(full_version) local_pr_branch = f"{full_version}-{dist_git_branch}-update" # fetch and reset --hard upstream/$branch? logger.info(f'using "{dist_git_branch}" dist-git branch') dg.checkout_branch(dist_git_branch) dg.create_branch(local_pr_branch) dg.checkout_branch(local_pr_branch) description = ( f"Upstream tag: {full_version}\n" f"Upstream commit: {up.local_project.git_repo.head.commit}\n" ) dg.sync_files(up.local_project) self.sync( distgit=dg, commit_msg=f"{full_version} upstream release", pr_title=f"Update to upstream release {full_version}", pr_description=description, dist_git_branch=dist_git_branch, commit_msg_description=description, add_new_sources=True, ) finally: current_up_branch.checkout()
def dg(self): if self._dg is None: self.init_kerberos_ticket() if not self.package_config.downstream_package_name and ( self.downstream_local_project and self.downstream_local_project.working_dir): # the path to dist-git was passed but downstream_package_name is not set # we know that package names are equal to repo names self.package_config.downstream_package_name = ( self.downstream_local_project.working_dir.name) logger.info( "Package name was not set, we've got it from dist-git's " f"directory name: {self.package_config.downstream_package_name}" ) self._dg = DistGit( config=self.config, package_config=self.package_config, local_project=self.downstream_local_project, ) return self._dg
def test_downstream_pr(upstream_n_distgit, pr_list, number_prs): u, d = upstream_n_distgit c = get_test_config() pc = get_local_package_config(str(u)) pc.downstream_project_url = str(d) pc.upstream_project_url = str(u) dg = DistGit(c, pc) pc = get_local_package_config(str(u)) status = Status(c, pc, u, dg) flexmock( PagureProject, get_git_urls=lambda: {"git": "foo.git"}, fork_create=lambda: None, get_fork=lambda: PagureProject("", "", PagureService()), get_pr_list=pr_list, ) assert status table = status.get_downstream_prs(number_prs) assert table assert len(table) == number_prs
def test_update_on_cockpit_ostree(cockpit_ostree): upstream_path, dist_git_path = cockpit_ostree def mocked_new_sources(sources=None): if not Path(sources).is_file(): raise RuntimeError("archive does not exist") flexmock(FedPKG, init_ticket=lambda x=None: None, new_sources=mocked_new_sources) flexmock( DistGit, push_to_fork=lambda *args, **kwargs: None, is_archive_in_lookaside_cache=lambda archive_path: False, upload_to_lookaside_cache=lambda path: None, download_upstream_archive=lambda: "the-archive", ) flexmock( PackitAPI, push_and_create_pr=lambda pr_title, pr_description, dist_git_branch: None, ) pc = get_local_package_config(str(upstream_path)) up_lp = LocalProject(working_dir=str(upstream_path)) c = get_test_config() api = PackitAPI(c, pc, up_lp) api._dg = DistGit(c, pc) api._dg._local_project = LocalProject(working_dir=dist_git_path) with cwd(upstream_path): api.sync_release( "master", use_local_content=False, version="179", force_new_sources=False, create_pr=True, )
def dg(self): if self._dg is None: self._dg = DistGit(config=self.config, package_config=self.package_config) return self._dg