API Documentation

webhook module

This module contains the tornado web-application with the webhook listening for gitea events.

class scm_staging.webhook.AppConfig(gitea_user: str, branch_config: list[scm_staging.config.BranchConfig], osc: py_obs.osc.Osc, db_file_name: str = 'submit_requests.db', _conf: py_gitea_opensuse_org.configuration.Configuration = <factory>, _api_client: py_gitea_opensuse_org.api_client.ApiClient = <factory>)
branch_config: list[scm_staging.config.BranchConfig]
db_file_name: str = 'submit_requests.db'
static from_env() AppConfig
gitea_user: str
osc: Osc
class scm_staging.webhook.Label(*, id: int, name: str, color: str, description: str, url: str)
color: str
description: str
id: int
name: str
url: str
class scm_staging.webhook.MainHandler(application: Application, request: HTTPServerRequest, **kwargs: Any)
async check_if_pr_approved(api_client: ApiClient, owner: str, repo_name: str, pr_number: int, pkg_name: str, pr_creator: str) bool

Checks if the pull request $owner/$repo_name/$pr_number has been approved by at least one maintainer of the package pkg_name (and no changes have been requested) or if the pull request has been submitted by one of the maintainers of that package.

initialize(app_config: AppConfig) None
async post() None
async project_from_pull_request(payload: PullRequestPayload, project_prefix: str | None, project_to_copy_repos_from: str | None = None) Project
class scm_staging.webhook.Milestone(*, id: int, title: str, description: str, state: str, open_issues: int, closed_issues: int)
closed_issues: int
description: str
id: int
open_issues: int
state: str
title: str
class scm_staging.webhook.PullRequest(*, id: int, url: str, number: int, user: User, title: str, body: str, labels: list[scm_staging.webhook.Label], milestone: Milestone | None = None, assignee: User | None = None, assignees: list[scm_staging.webhook.User] | None = None, state: str, is_locked: bool, base: Ref, head: Ref, merge_base: str, created_at: str, updated_at: str)
assignee: User | None
assignees: list[scm_staging.webhook.User] | None
base: Ref
body: str
created_at: str
head: Ref
id: int
is_locked: bool
labels: list[scm_staging.webhook.Label]
merge_base: str
milestone: Milestone | None
number: int
state: str
title: str
updated_at: str
url: str
user: User
class scm_staging.webhook.PullRequestPayload(*, action: str, number: int, pull_request: PullRequest, sender: User, repository: Repository, review: Review | None = None)
action: str
number: int
pull_request: PullRequest
repository: Repository
review: Review | None
sender: User
class scm_staging.webhook.PullRequestReviewType(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
APPROVED = 'pull_request_review_approved'
COMMENT = 'pull_request_comment'
REJECTED = 'pull_request_review_rejected'
class scm_staging.webhook.Ref(*, label: str, ref: str, sha: str, repo_id: int, repo: Repository)
label: str
ref: str
repo: Repository
repo_id: int
sha: str
class scm_staging.webhook.Repository(*, id: int, owner: User, name: str, full_name: str, description: str, html_url: str, ssh_url: str, clone_url: str)
clone_url: str
description: str
full_name: str
html_url: str
id: int
name: str
owner: User
ssh_url: str
class scm_staging.webhook.Review(*, type: PullRequestReviewType | str, content: str)
content: str
type: PullRequestReviewType | str
class scm_staging.webhook.User(*, id: int, login: str, full_name: str, email: str)
email: str
full_name: str
id: int
login: str
async scm_staging.webhook.find_devel_project(osc: Osc, project_name: str, package_name: str) DevelProject | None

Retrieve the develproject of the package with the supplied package_name from the project project_name.

Returns:

  • the devel project or None if there is none

scm_staging.webhook.main()
scm_staging.webhook.make_app(app_config: AppConfig) Application
scm_staging.webhook.package_from_pull_request(payload: PullRequestPayload) Package

db module

This module contains the helper functions to store the created submitrequests and the respective pull requests on gitea in a database to keep track of them.

The rabbit listener and the webhook share information via the database.

class scm_staging.db.PullRequestToSubmitRequest(*, submit_request_id: int, obs_project_name: str, obs_package_name: str, gitea_repo_owner: str, gitea_repo_name: str, pull_request_number: int, merge_pr: bool)

pydantic model used to store the submit requests and their corresponding pull requests on gitea.

gitea_repo_name: str

Name of the repository against which the PR has been opened

gitea_repo_owner: str

Owner of the repository against which the PR has been opened

merge_pr: bool

flag whether the pull request should be merged once the submit request is accepted

obs_package_name: str

name of the package on OBS where the pull request is checked out

obs_project_name: str

name of the project on OBS where the package is created

pull_request_number: int

Number of the pull request via which the PR can be found in the web UI. This is not the ID of the pull request!

submit_request_id: int

numeric id of the SubmitRequest on OBS

scm_staging.db.add_db_file_arg(parser: ArgumentParser) ArgumentParser
scm_staging.db.create_db(db_file: str) None

Initializes the database and creates the required table if it does not yet exist. If the database and/or the table already exist, then this function does nothing.

scm_staging.db.find_submitrequests(db_file: str, *, sr_id: int | None = None, obs_project_name: str | None = None, obs_package_name: str | None = None) list[scm_staging.db.PullRequestToSubmitRequest]

Returns all submitrequests from the database when no optional parameters are supplied. If any of the optional parameters is supplied then only submitrequests with that matching parameter are returned. If no submitrequests match, then an empty list is returned.

scm_staging.db.insert_submit_request(db_file: str, pr_to_sr: PullRequestToSubmitRequest) None

Inserts the supplied PullRequestToSubmitRequest into the database.

scm_staging.db.remove_submit_request(db_file: str, sr_id: int) None

Removes the submit request with the supplied id from the database.

rabbit_listener module

This module holds the functions listening to the rabbitmq bus of OBS for package build results and updating the commit status.

class scm_staging.rabbit_listener.ActionPayload(*, action_id: int, type: str, sourceproject: str | None = None, sourcepackage: str | None = None, sourcerevision: str | None = None, targetproject: str, targetpackage: str | None = None, makeoriginolder: bool | None = None, sourceupdate: str | None = None)
action_id: int
makeoriginolder: bool | None
sourcepackage: str | None
sourceproject: str | None
sourcerevision: str | None
sourceupdate: str | None
targetpackage: str | None
targetproject: str
type: str
class scm_staging.rabbit_listener.PackageBuildFailurePayload(*, project: str, package: str, repository: str, arch: str, release: str | None = None, readytime: str, srcmd5: str, rev: str | None = None, reason: str, bcnt: str | None = None, verifymd5: str | None = None, starttime: str, endtime: str, workerid: str, versrel: str | None = None, buildtype: str, previouslyfailed: str)
previouslyfailed: str
class scm_staging.rabbit_listener.PackageBuildSuccessPayload(*, project: str, package: str, repository: str, arch: str, release: str | None = None, readytime: str, srcmd5: str, rev: str | None = None, reason: str, bcnt: str | None = None, verifymd5: str | None = None, starttime: str, endtime: str, workerid: str, versrel: str | None = None, buildtype: str)
arch: str
bcnt: str | None
buildtype: str
endtime: str
package: str
project: str
readytime: str
reason: str
release: str | None
repository: str
rev: str | None
srcmd5: str
starttime: str
verifymd5: str | None
versrel: str | None
workerid: str
class scm_staging.rabbit_listener.PackageBuildUnchangedPayload(*, project: str, package: str, repository: str, arch: str, release: str | None = None, readytime: str, srcmd5: str, rev: str | None = None, reason: str, bcnt: str | None = None, verifymd5: str | None = None, starttime: str, endtime: str, workerid: str, versrel: str | None = None, buildtype: str)
class scm_staging.rabbit_listener.RequestChangedPayload(*, author: str, comment: str | None = None, description: str | None = None, number: int, actions: list[scm_staging.rabbit_listener.ActionPayload], state: RequestStatus, when: str, who: str)
actions: list[scm_staging.rabbit_listener.ActionPayload]
author: str
comment: str | None
description: str | None
number: int
state: RequestStatus
when: str
who: str
class scm_staging.rabbit_listener.RequestCommentPayload(*, author: str, comment: str | None = None, description: str | None = None, number: int, actions: list[scm_staging.rabbit_listener.ActionPayload], state: RequestStatus, when: str, who: str, commenters: list[str], commenter: str, comment_body: str, comment_title: str | None = None, request_number: int | None = None)
comment_body: str
comment_title: str | None
commenter: str
commenters: list[str]
request_number: int | None
class scm_staging.rabbit_listener.RequestReviewChangedPayload(*, reviewers: str | None = None, by_user: str | None = None, by_group: str | None = None, by_project: str | None = None, by_package: str | None = None)
by_group: str | None
by_package: str | None
by_project: str | None
by_user: str | None
reviewers: str | None
class scm_staging.rabbit_listener.RequestReviewsDonePayload(*, reviewers: str | None = None, by_user: str | None = None, by_group: str | None = None, by_project: str | None = None, by_package: str | None = None, author: str, comment: str, description: str | None = None, number: int, actions: list[scm_staging.rabbit_listener.ActionPayload], state: str, when: str, who: str)
actions: list[scm_staging.rabbit_listener.ActionPayload]
author: str
comment: str
description: str | None
number: int
state: str
when: str
who: str
class scm_staging.rabbit_listener.RequestStateChangedPayload(*, author: str, comment: str | None = None, description: str | None = None, number: int, actions: list[scm_staging.rabbit_listener.ActionPayload], state: RequestStatus, when: str, who: str, id: int, oldstate: str, namespace: str, duration: int | None = None)
duration: int | None
id: int
namespace: str
oldstate: str
scm_staging.rabbit_listener.rabbit_listener(db_file: str) None

ci_status module

This module contains helper functions to set the commit status (= CI status) on gitea based on the package build on OBS.

class scm_staging.ci_status.CommitStatusState(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
ERROR = 'error'
FAILURE = 'failure'
PENDING = 'pending'
SUCCESS = 'success'
WARNING = 'warning'
async scm_staging.ci_status.fetch_hash_of_head_of_branch(api_client: ApiClient, repo_owner: str, repo_name: str, branch_name: str = 'main') str
scm_staging.ci_status.main() None
async scm_staging.ci_status.set_commit_status_from_obs(osc: Osc, api_client: ApiClient, repo_owner: str, repo_name: str, commit_sha: str, pkg_name: str, project_name: str) None

config module

The config module contains the Models that are loaded from the webhook json config file.

class scm_staging.config.BranchConfig(*, target_branch_name: str, organization: str, require_approval: bool = False, destination_project: str, submission_style: SubmissionStyle = SubmissionStyle.DIRECT, merge_pr: bool = True, project_prefix: str | None = None)

Configuration entry of the bot for how to treat merge requests for a certain organization.

destination_project: str

project name on OBS against which the package should be submitted

merge_pr: bool

Whether the bot shall merge the pull request once the submitrequest is accepted. Defaults to True.

organization: str

organization (= username) for which pull requests will be monitored

project_prefix: str | None

Project name prefix to be used for creating the projects for submit request. If omitted, the user’s home project will be used.

require_approval: bool

Whether merge requests have to be approved by the package maintainer first, before a submitrequest is created. The default is False.

submission_style: SubmissionStyle

Defines how the bot should submit the packages, defaults to a direct submission (SubmissionStyle.DIRECT)

target_branch_name: str

name of the branch against which the pull requests should be considered

class scm_staging.config.SubmissionStyle(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Options how the bot will submit packages.

DIRECT = 'direct'

the bot submits the package directly to the destination project

FACTORY_DEVEL = 'factory_devel'

the bot sends the project to the develproject defined in the destination project

scm_staging.config.load_config(config_dot_json_path: str) list[scm_staging.config.BranchConfig]

Read the config from the json file with the provided path.

submit_to_pool module

This module has a helper function to automatically create a pull request from src.opensuse.org/rpm/$pkg to src.opensuse.org/pool/$pkg.

async scm_staging.submit_to_pool.create_pr_to_pool(pkg_name: str, gitea_user: str, repo_api: RepositoryApi) None
scm_staging.submit_to_pool.main()