Last active
February 3, 2024 20:16
-
-
Save rjspies/27e519fafab44a2fc8db778514c578c9 to your computer and use it in GitHub Desktop.
A python script which creates git branches and GitHub pull requests from Jira issues
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
GitPython >= 1.7.0 | |
jira >= 3.6.0 | |
PyGithub >= 2.2.0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!env /usr/bin/python3 | |
import os as OperatingSystem | |
import sys as System | |
import re as RegularExpression | |
from git import Repo as GitRepository | |
from jira import JIRA as Jira | |
from github import Github | |
from github import Auth as GithubAuthentication | |
JIRA_TOKEN_ENVIRONMENT_VARIABLE = "SLAVE_JIRA" | |
JIRA_SERVER_ADDRESS = "https://example.atlassian.net" | |
JIRA_EMAIL_ADDRESS = "[email protected]" | |
JIRA_ISSUE_TYPES_STORY = ["developer story", "user story"] | |
JIRA_ISSUE_TYPE_BUG = "bug" | |
JIRA_ISSUE_TYPE_SPIKE = "spike" | |
GITHUB_TOKEN_ENVIRONMENT_VARIABLE = "SLAVE_GITHUB" | |
GITHUB_REPOSITORY_NAME = "user/Repo" | |
GITHUB_ASSIGNEE_NAME = "user" | |
GITHUB_PULL_REQUEST_BASE_BRANCH = "main" | |
GITHUB_PULL_REQUEST_DRAFT = True | |
GIT_RELATIVE_REPOSITORY_PATH = "/path/to/repo" | |
GIT_BRANCH_PREFIX_STORY = "Feature" | |
GIT_BRANCH_PREFIX_BUG = "Bugfix" | |
GIT_BRANCH_PREFIX_SPIKE = "Experimental" | |
def main(ticket_key: str): | |
jira_token = OperatingSystem.environ[JIRA_TOKEN_ENVIRONMENT_VARIABLE] | |
jira = Jira( | |
server = JIRA_SERVER_ADDRESS, | |
basic_auth = (JIRA_EMAIL_ADDRESS, jira_token) | |
) | |
try: | |
issue = jira.issue(ticket_key, fields ="key,summary,issuetype") | |
except: | |
raise KeyError(f"Issue with key '{ticket_key}' has not been found") | |
branch_name = get_branch_name_from_issue(issue) | |
create_branch(branch_name) | |
create_github_pull_request(issue, branch_name) | |
def create_github_pull_request(issue, branch_name: str): | |
github_authentication_token = OperatingSystem.environ[GITHUB_TOKEN_ENVIRONMENT_VARIABLE] | |
github_authentication = GithubAuthentication.Token(github_authentication_token) | |
github = Github(auth = github_authentication) | |
github_repository = github.get_repo(GITHUB_REPOSITORY_NAME) | |
key = issue.key | |
summary = issue.fields.summary | |
pull_request_title = f"{key} {summary}" | |
pull_request = github_repository.create_pull(base = GITHUB_PULL_REQUEST_BASE_BRANCH, head = branch_name, title = pull_request_title, draft = GITHUB_PULL_REQUEST_DRAFT) | |
pull_request.add_to_assignees(GITHUB_ASSIGNEE_NAME) | |
def create_branch(branch_name): | |
home_directory = OperatingSystem.environ["HOME"] | |
repository = GitRepository(f"{home_directory}{GIT_RELATIVE_REPOSITORY_PATH}") | |
repository.create_head(branch_name) | |
repository.git.push("--set-upstream", "origin", branch_name) | |
def get_branch_name_from_issue(issue): | |
prefix = get_prefix_from_issue_type(issue.fields.issuetype.name) | |
summary = formatted_summary(issue.fields.summary) | |
return f"{prefix}/{issue.key}+{summary}" | |
def formatted_summary(summary: str): | |
cleaned_summary = summary.replace(" ", "_") | |
pattern = r"[^a-zA-Z0-9\.\-_\/]" | |
cleaned_summary = RegularExpression.sub(pattern, "", cleaned_summary) | |
return cleaned_summary | |
def get_prefix_from_issue_type(name: str): | |
internal_name = name.lower() | |
if internal_name in JIRA_ISSUE_TYPES_STORY: | |
return GIT_BRANCH_PREFIX_STORY | |
elif internal_name == JIRA_ISSUE_TYPE_BUG: | |
return GIT_BRANCH_PREFIX_BUG | |
elif internal_name == JIRA_ISSUE_TYPE_SPIKE: | |
return GIT_BRANCH_PREFIX_SPIKE | |
else: | |
raise TypeError(f"Unknown issue type '{internal_name}'") | |
if __name__ == "__main__": | |
try: | |
ticket_key = System.argv[1] | |
except: | |
raise AttributeError("First argument 'ticket_key' has not been set") | |
main(ticket_key) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment