class PullRequestGithubCheckDownstreamHandler(AbstractGithubJobHandler): type = JobType.check_downstream triggers = [TheJobTriggerType.pull_request] event: PullRequestEvent # https://developer.github.com/v3/activity/events/types/#events-api-payload-28 def __init__(self, config: ServiceConfig, job_config: JobConfig, event: PullRequestEvent): super().__init__(config=config, job_config=job_config, event=event) self.event = event self.project: GitProject = event.get_project() self.package_config: PackageConfig = self.get_package_config_from_repo( self.project, event.base_ref, event.pr_id) self.package_config.upstream_project_url = event.project_url def run(self) -> HandlerResults: self.local_project = LocalProject( git_project=self.project, working_dir=self.config.command_handler_work_dir) self.api = PackitAPI(self.config, self.package_config, self.local_project) self.api.sync_pr( pr_id=self.event.pr_id, dist_git_branch=self.job_config.metadata.get( "dist-git-branch", "master"), # TODO: figure out top upstream commit for source-git here ) return HandlerResults(success=True, details={})
def source_git_status(config: Config, source_git: str, dist_git: str): """Tell the synchronization status of a source-git and a dist-git repo. This command checks the commit history in the provided source-git and dist-git repos and informs about the range of commits to be synchronized from dist-git to source-git or the other way around, or informs that the repositories are in sync. If possible, the status command also provides instructions on how to synchronize the repositories. """ source_git_path = pathlib.Path(source_git).resolve() dist_git_path = pathlib.Path(dist_git).resolve() package_config = get_local_package_config( source_git_path, package_config_path=config.package_config_path) api = PackitAPI( config=config, package_config=package_config, upstream_local_project=LocalProject(working_dir=source_git_path, offline=True), downstream_local_project=LocalProject(working_dir=dist_git_path, offline=True), ) click.echo(api.sync_status_string(source_git=source_git, dist_git=dist_git))
def get_packit_api(config: Config, local_project: LocalProject, dist_git_path: str = None): """ Load the package config, set other options and return the PackitAPI """ package_config = get_local_package_config(local_project.working_dir, try_local_dir_last=True) if dist_git_path: package_config.dist_git_clone_path = dist_git_path if dist_git_path and dist_git_path == local_project.working_dir: PackitAPI( config=config, package_config=package_config, upstream_local_project=None, downstream_local_project=local_project, ) remote_urls: List[str] = [] for remote in local_project.git_repo.remotes: remote_urls += remote.urls upstream_hostname = (get_hostname_or_none( url=package_config.upstream_project_url) if package_config.upstream_project_url else None) lp_upstream = None lp_downstream = None for url in remote_urls: remote_hostname = get_hostname_or_none(url=url) if not remote_hostname: continue if upstream_hostname: if remote_hostname == upstream_hostname: lp_upstream = local_project logger.info("Input directory is an upstream repository.") break if package_config.dist_git_base_url and ( remote_hostname in package_config.dist_git_base_url or remote_hostname in DIST_GIT_HOSTNAME_CANDIDATES): lp_downstream = local_project logger.info("Input directory is a downstream repository.") break else: lp_upstream = local_project # fallback, this is the past behavior logger.info("Input directory is an upstream repository.") api = PackitAPI( config=config, package_config=package_config, upstream_local_project=lp_upstream, downstream_local_project=lp_downstream, ) return api
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 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, )
class GithubPullRequestHandler(AbstractGithubJobHandler): name = JobType.check_downstream triggers = [JobTriggerType.pull_request] # https://developer.github.com/v3/activity/events/types/#events-api-payload-28 def __init__(self, config: ServiceConfig, job: JobConfig, pr_event: PullRequestEvent): super().__init__(config=config, job=job, event=pr_event) self.pr_event = pr_event self.project: GitProject = pr_event.get_project() self.package_config: PackageConfig = get_package_config_from_repo( self.project, pr_event.base_ref) if not self.package_config: raise ValueError( f"No config file found in {self.project.full_repo_name}") self.package_config.upstream_project_url = pr_event.project_url def run(self) -> HandlerResults: self.local_project = LocalProject( git_project=self.project, working_dir=self.config.command_handler_work_dir) self.api = PackitAPI(self.config, self.package_config, self.local_project) self.api.sync_pr( pr_id=self.pr_event.pr_id, dist_git_branch=self.job.metadata.get("dist-git-branch", "master"), # TODO: figure out top upstream commit for source-git here ) return HandlerResults(success=True, details={})
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 )
class ProposeUpdate(PackitUnittestOgr): def setUp(self): super().setUp() self.api = PackitAPI( config=self.conf, package_config=self.pc, upstream_local_project=self.lp ) self.api._up = self.upstream self.api._dg = self.dg # Do not upload package, because no credentials given in CI flexmock(self.api).should_receive("_handle_sources").and_return(None) self.set_git_user() @unittest.skip( "Issue in ogr causing that User is not stored in persistent yaml files for pagure" ) def test_propose_update(self): # change specfile little bit to have there some change specfile_location = os.path.join(self.lp.working_dir, "python-ogr.spec") with open(specfile_location, "a") as myfile: myfile.write("# test text") check_output( f"cd {self.lp.working_dir}; git commit -m 'test change' python-ogr.spec", shell=True, ) self.api.sync_release("master")
def test_update_on_cockpit_ostree(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, ) flexmock( PackitAPI, push_and_create_pr=lambda pr_title, pr_description, dist_git_branch: None, ) pc = get_local_package_config(str(cockpit_ostree)) up_lp = LocalProject(working_dir=str(cockpit_ostree)) c = get_test_config() api = PackitAPI(c, pc, up_lp) with cwd(cockpit_ostree): api.sync_release( "master", use_local_content=False, version="179", force_new_sources=False, create_pr=True, ) assert api.dg.download_upstream_archive().is_file()
def run(self) -> HandlerResults: """ Sync the upstream release to dist-git as a pull request. """ self.local_project = LocalProject( git_project=self.project, working_dir=self.config.command_handler_work_dir) self.api = PackitAPI(self.config, self.package_config, self.local_project) errors = [] for branch in get_branches( self.job.metadata.get("dist-git-branch", "master")): try: self.api.sync_release(dist_git_branch=branch, version=self.event.tag_name) except Exception as ex: sentry_integration.send_to_sentry(ex) errors.append( f"Propose update for branch {branch} failed: {ex}") if errors: return HandlerResults( success=False, details={ "msg": "Propose update failed.", "errors": errors }, ) return HandlerResults(success=True, details={})
def test_basic_local_update_direct_push(upstream_distgit_remote, mock_remote_functionality_upstream): """ basic propose-update test: mock remote API, use local upstream and dist-git """ upstream, distgit, remote_dir = upstream_distgit_remote with cwd(upstream): c = get_test_config() pc = get_local_package_config(str(upstream)) pc.upstream_project_url = str(upstream) pc.dist_git_clone_path = str(distgit) up_lp = LocalProject(working_dir=str(upstream)) api = PackitAPI(c, pc, up_lp) api.sync_release("master", "0.1.0", create_pr=False) remote_dir_clone = Path(f"{remote_dir}-clone") subprocess.check_call( ["git", "clone", remote_dir, str(remote_dir_clone)], cwd=str(remote_dir_clone.parent), ) spec = get_specfile(str(remote_dir_clone / "beer.spec")) assert spec.get_version() == "0.1.0" assert (remote_dir_clone / "README.packit").is_file()
class ProposeDownstreamHandler(JobHandler): type = JobType.propose_downstream triggers = [TheJobTriggerType.release] task_name = TaskName.propose_downstream def run(self) -> TaskResults: """ Sync the upstream release to dist-git as a pull request. """ self.local_project = LocalProject( git_project=self.project, working_dir=self.service_config.command_handler_work_dir, ) self.api = PackitAPI(self.service_config, self.job_config, self.local_project) errors = {} for branch in get_branches(*self.job_config.metadata.dist_git_branches, default="master"): try: self.api.sync_release(dist_git_branch=branch, version=self.data.tag_name) except Exception as ex: sentry_integration.send_to_sentry(ex) errors[branch] = str(ex) if errors: branch_errors = "" for branch, err in sorted( errors.items(), key=lambda branch_error: branch_error[0]): err_without_new_lines = err.replace("\n", " ") branch_errors += f"| `{branch}` | `{err_without_new_lines}` |\n" body_msg = ( f"Packit failed on creating pull-requests in dist-git:\n\n" f"| dist-git branch | error |\n" f"| --------------- | ----- |\n" f"{branch_errors}\n\n" "You can re-trigger the update by adding `/packit propose-update`" " to the issue comment.\n") self.project.create_issue( title= f"[packit] Propose update failed for release {self.data.tag_name}", body=body_msg, ) return TaskResults( success=False, details={ "msg": "Propose update failed.", "errors": errors }, ) return TaskResults(success=True, details={})
def test_srpm_snapd(snapd): pc = get_local_package_config(str(snapd)) up_lp = LocalProject(working_dir=str(snapd)) c = get_test_config() api = PackitAPI(c, pc, up_lp) with cwd(snapd): path = api.create_srpm() assert path.exists() build_srpm(path)
def setUp(self): self._feature_id() super().setUp() self.api = PackitAPI(config=self.conf, package_config=self.pc, upstream_local_project=self.lp) self.api._up = self.upstream self.api._dg = self.dg self.set_git_user()
def update(config, dist_git_path, upstream_git_path, dist_git_branch, repo): """ Release current upstream release into Fedora """ package_config = get_local_package_config(directory=repo.working_dir) package_config.downstream_project_url = dist_git_path package_config.upstream_project_url = upstream_git_path api = PackitAPI(config=config, package_config=package_config) api.sync_release(dist_git_branch)
def run(self) -> TaskResults: local_project = LocalProject( git_project=self.project, working_dir=self.service_config.command_handler_work_dir, ) api = PackitAPI( config=self.service_config, # job_config and package_config are the same for PackitAPI # and we want to use job_config since people can override things in there package_config=self.job_config, upstream_local_project=local_project, ) user_can_merge_pr = self.project.can_merge_pr(self.data.user_login) if not (user_can_merge_pr or self.data.user_login in self.service_config.admins): self.project.issue_comment(self.db_trigger.issue_id, PERMISSIONS_ERROR_WRITE_OR_ADMIN) return TaskResults( success=True, details={"msg": PERMISSIONS_ERROR_WRITE_OR_ADMIN}) if not self.data.tag_name: msg = ( "There was an error while proposing a new update for the Fedora package: " "no upstream release found.") self.project.issue_comment(self.db_trigger.issue_id, msg) return TaskResults(success=False, details={"msg": "Propose update failed"}) sync_failed = False for branch in self.dist_git_branches_to_sync: msg = ( f"for the Fedora package `{self.job_config.downstream_package_name}`" f"with the tag `{self.data.tag_name}` in the `{branch}` branch.\n" ) try: new_pr = api.sync_release(dist_git_branch=branch, version=self.data.tag_name, create_pr=True) msg = f"Packit-as-a-Service proposed [a new update]({new_pr.url}) {msg}" self.project.issue_comment(self.db_trigger.issue_id, msg) except PackitException as ex: msg = f"There was an error while proposing a new update {msg} Traceback is: `{ex}`" self.project.issue_comment(self.db_trigger.issue_id, msg) logger.error(f"Error while running a build: {ex}") sync_failed = True if sync_failed: return TaskResults(success=False, details={"msg": "Propose update failed"}) # Close issue if propose-update was successful in all branches self.project.issue_close(self.db_trigger.issue_id) return TaskResults(success=True, details={})
def update_source_git( config: Config, source_git: str, dist_git: str, revision_range: str ): """Update a source-git repository based on a dist-git repository. Update a source-git repository with the selected checkout of a spec file and additional packaging files from a dist-git repository. Revision range represents part of dist-git history which is supposed to be synchronized. Use `HEAD~..` if you want to synchronize the last commit from dist-git. For more information on possible revision range formats, see gitrevisions(7). If patches or the sources file in the spec file changed, the command exits with return code 2. Such changes are not supported by this command, code changes should happen in the source-git repo. Inapplicable changes to the .gitignore file are ignored since the file may not be synchronized between dist-git and source-git. This command, by default, performs only local operations and uses the content of the source-git and dist-git repositories as it is, no checkout or fetch is performed. After the synchronization is done, packit will inform about the changes it has performed and about differences between source-git and dist-git prior to the synchronization process. Dist-git commit messages are preserved and used when creating new source-git commits. Examples Take the last commit (HEAD) of systemd dist-git repo and copy the spec file and other packaging files into the source-git repo: \b $ packit source-git update-source-git rpms/systemd src/systemd HEAD~.. Synchronize changes from the last three dist-git commits: \b $ packit source-git update-source-git rpms/systemd src/systemd HEAD~3.. """ source_git_path = pathlib.Path(source_git).resolve() dist_git_path = pathlib.Path(dist_git).resolve() package_config = get_local_package_config( source_git_path, package_config_path=config.package_config_path ) api = PackitAPI( config=config, package_config=package_config, upstream_local_project=LocalProject(working_dir=source_git_path, offline=True), downstream_local_project=LocalProject(working_dir=dist_git_path, offline=True), ) api.update_source_git(revision_range=revision_range)
def source_git_init( config, dist_git: git.Repo, source_git: git.Repo, upstream_ref: str, upstream_url: Optional[str], upstream_remote, pkg_tool: Optional[str], pkg_name: Optional[str], ignore_missing_autosetup: bool, ): """Initialize SOURCE_GIT as a source-git repo by applying downstream patches from DIST_GIT as Git commits on top of UPSTREAM_REF. SOURCE_GIT needs to be an existing clone of the upstream repository. UPSTREAM_REF is a tag, branch or commit from SOURCE_GIT. SOURCE_GIT and DIST_GIT are paths to the source-git and dist-git repos. Branch names can be specified, separated by colons. If a branch name is specified for SOURCE_GIT, the branch is checked out and reset to UPSTREAM_REF. If a branch name is specified for DIST_GIT, the branch is checked out before setting up the source-git repo. This branch is expected to exist. Each Git commit created in SOURCE_GIT will have a 'From-dist-git-commit' trailer to mark the hash of the dist-git commit from which it is created. To learn more about source-git, please check https://packit.dev/docs/source-git/ Examples: \b $ packit source-git init v2.3.1 src/acl:rawhide rpms/acl:rawhide $ packit source-git init --pkg-tool centpkg v2.3.1 src/acl rpms/acl """ logger.warning( "Generating source-git repositories is experimental, " "please give us feedback if it does things differently than you expect." ) api = PackitAPI(config=config, package_config=None) api.init_source_git( dist_git=dist_git, source_git=source_git, upstream_ref=upstream_ref, upstream_url=upstream_url, upstream_remote=upstream_remote, pkg_tool=pkg_tool or config.pkg_tool, pkg_name=pkg_name, ignore_missing_autosetup=ignore_missing_autosetup, )
def setUp(self): super().setUp() self.api = PackitAPI( config=self.conf, package_config=self.pc, upstream_local_project=self.lp ) self.api._up = self.upstream self.api._dg = self.dg # Do not upload package, because no credentials given in CI flexmock(self.api).should_receive("_handle_sources").and_return(None) self.set_git_user()
def test_srpm_on_cockpit_ostree(cockpit_ostree): upstream_path, dist_git_path = cockpit_ostree 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) with cwd(upstream_path): api.create_srpm()
def run(self): pr_id = self.event["pull_request"]["number"] local_project = LocalProject(git_project=self.project) api = PackitAPI(self.config, self.package_config, local_project) api.sync_pr( pr_id=pr_id, dist_git_branch=self.job.metadata.get("dist-git-branch", "master"), # TODO: figure out top upstream commit for source-git here )
class NewDistGitCommitHandler(FedmsgHandler): """Sync new changes to upstream after a new git push in the dist-git.""" topic = "org.fedoraproject.prod.git.receive" triggers = [TheJobTriggerType.commit] task_name = TaskName.distgit_commit def __init__( self, package_config: PackageConfig, job_config: JobConfig, data: EventData, ): super().__init__( package_config=package_config, job_config=job_config, data=data, ) self.branch = data.event_dict.get("branch") def run(self) -> TaskResults: # self.project is dist-git, we need to get upstream dg = DistGit(self.service_config, self.job_config) self.job_config.upstream_project_url = dg.get_project_url_from_distgit_spec( ) if not self.job_config.upstream_project_url: return TaskResults( 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.job_config.upstream_project_url) up = self.project.service.get_project(repo=r, namespace=n) self.local_project = LocalProject( git_project=up, working_dir=self.service_config.command_handler_work_dir) self.api = PackitAPI(self.service_config, self.job_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.branch, upstream_branch="master", # TODO: this should be configurable ) return TaskResults(success=True, details={})
def test_basic_build(upstream_n_distgit, mock_remote_functionality_upstream): u, d = upstream_n_distgit with cwd(u): c = get_test_config() pc = get_local_package_config(str(u)) pc.upstream_project_url = str(u) pc.downstream_project_url = str(d) up_lp = LocalProject(path_or_url=u) api = PackitAPI(c, pc, up_lp) api.build("master")
def run(self) -> HandlerResults: self.local_project = LocalProject( git_project=self.project, working_dir=self.config.command_handler_work_dir ) self.api = PackitAPI(self.config, self.package_config, self.local_project) self.api.sync_pr( pr_id=self.pr_event.pr_id, dist_git_branch=self.job.metadata.get("dist-git-branch", "master"), # TODO: figure out top upstream commit for source-git here ) return HandlerResults(success=True, details={})
def run(self): """ Sync the upstream release to dist-git as a pull request. """ version = self.event["release"]["tag_name"] local_project = LocalProject(git_project=self.project) api = PackitAPI(self.config, self.package_config, local_project) api.sync_release( dist_git_branch=self.job.metadata.get("dist-git-branch", "master"), version=version, )
def sync_upstream_pull_request( self, package_config: PackageConfig, pr_id: int, dist_git_branch: str, upstream_local_project: LocalProject, ): logger.info("syncing the upstream code to downstream") packit_api = PackitAPI( config=self.config, package_config=package_config, upstream_local_project=upstream_local_project, ) packit_api.sync_pr(pr_id=pr_id, dist_git_branch=dist_git_branch)
class GithubReleaseHandler(AbstractGithubJobHandler): name = JobType.propose_downstream triggers = [JobTriggerType.release] event: ReleaseEvent def __init__(self, config: ServiceConfig, job: JobConfig, release_event: ReleaseEvent): super().__init__(config=config, job=job, event=release_event) self.project: GitProject = release_event.get_project() self.package_config: PackageConfig = get_package_config_from_repo( self.project, release_event.tag_name) if not self.package_config: raise ValueError( f"No config file found in {self.project.full_repo_name}") self.package_config.upstream_project_url = release_event.project_url def run(self) -> HandlerResults: """ Sync the upstream release to dist-git as a pull request. """ self.local_project = LocalProject( git_project=self.project, working_dir=self.config.command_handler_work_dir) self.api = PackitAPI(self.config, self.package_config, self.local_project) errors = [] for branch in get_branches( self.job.metadata.get("dist-git-branch", "master")): try: self.api.sync_release(dist_git_branch=branch, version=self.event.tag_name) except Exception as ex: sentry_integration.send_to_sentry(ex) errors.append( f"Propose update for branch {branch} failed: {ex}") if errors: return HandlerResults( success=False, details={ "msg": "Propose update failed.", "errors": errors }, ) return HandlerResults(success=True, details={})
class NewDistGitCommitHandler(FedmsgHandler): """ A new flag was added to a dist-git pull request """ topic = "org.fedoraproject.prod.git.receive" name = JobType.sync_from_downstream triggers = [JobTriggerType.commit] def __init__(self, config: ServiceConfig, job: JobConfig, distgit_event: DistGitEvent): super().__init__(config=config, job=job, event=distgit_event) self.distgit_event = distgit_event self.project = distgit_event.get_project() self.package_config = get_package_config_from_repo( self.project, distgit_event.ref) if not self.package_config: raise ValueError( f"No config file found in {self.project.full_repo_name}") 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 run(self) -> HandlerResults: self.local_project = LocalProject( git_project=self.project, working_dir=self.config.command_handler_work_dir) self.api = PackitAPI(self.config, self.package_config, self.local_project) collaborators = self.project.who_can_merge_pr() if self.event.github_login not in collaborators | self.config.admins: self.project.issue_comment(self.event.issue_id, PERMISSIONS_ERROR_WRITE_OR_ADMIN) return HandlerResults( success=True, details={"msg": PERMISSIONS_ERROR_WRITE_OR_ADMIN}) if not self.event.tag_name: msg = ( "There was an error while proposing a new update for the Fedora package: " "no upstream release found.") self.project.issue_comment(self.event.issue_id, msg) return HandlerResults(success=False, details={"msg": "Propose update failed"}) sync_failed = False for branch in self.dist_git_branches_to_sync: msg = ( f"for the Fedora package `{self.package_config.downstream_package_name}`" f"with the tag `{self.event.tag_name}` in the `{branch}` branch.\n" ) try: new_pr = self.api.sync_release(dist_git_branch=branch, version=self.event.tag_name, create_pr=True) msg = f"Packit-as-a-Service proposed [a new update]({new_pr.url}) {msg}" self.project.issue_comment(self.event.issue_id, msg) except PackitException as ex: msg = f"There was an error while proposing a new update {msg} Traceback is: `{ex}`" self.project.issue_comment(self.event.issue_id, msg) logger.error(f"error while running a build: {ex}") sync_failed = True if sync_failed: return HandlerResults(success=False, details={"msg": "Propose update failed"}) # Close issue if propose-update was successful in all branches self.project.issue_close(self.event.issue_id) return HandlerResults(success=True, details={})
def setUp(self): if (hasattr(rebasehelper, "VERSION") and int(rebasehelper.VERSION.split(".")[1]) >= 19): DataMiner.key = "rebase-helper>=0.19" else: DataMiner.key = "rebase-helper<0.19" DataMiner.data_type = DataTypes.Dict super().setUp() self.api = PackitAPI(config=self.conf, package_config=self.pc, upstream_local_project=self.lp) self.api._up = self.upstream self.api._dg = self.dg self.set_git_user()