Skip to content

Commit 8db8438

Browse files
authored
Merge pull request #9 from dfodorRH/main
added script to clone feature with child epics
2 parents 9068693 + 35773f1 commit 8db8438

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-0
lines changed

jira-automation/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Installation
2+
3+
```bash
4+
$ python3 -m venv virtualenv
5+
$ source virtualenv/bin/activate
6+
$ pip install jira
7+
$ deactivate
8+
```
9+
10+
# Usage
11+
12+
```bash
13+
$ source virtualenv/bin/activate
14+
# obtain your personal Jira access token here:
15+
# https://issues.redhat.com/secure/ViewProfile.jspa?selectedTab=com.atlassian.pats.pats-plugin:jira-user-personal-access-tokens
16+
$ export JIRA_TOKEN=...
17+
$ python clone-feature-w-epics.py --feature RHTAP-383 --summary "New Team Enablement" --dry-run
18+
$ deactivate
19+
```
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#!/usr/bin/env python
2+
"""
3+
Description: Clone a feature and its child epics.
4+
Author: rbean
5+
"""
6+
7+
import argparse
8+
import os
9+
import pprint
10+
import sys
11+
12+
import jira
13+
14+
15+
def get_args():
16+
"""
17+
Parse args from the command-line.
18+
"""
19+
parser = argparse.ArgumentParser(description=__doc__)
20+
parser.add_argument(
21+
"--feature",
22+
required=True,
23+
help="Key of the feature id the epic should be attached to",
24+
)
25+
parser.add_argument(
26+
"--summary",
27+
required=True,
28+
help="Summary of the new feature",
29+
)
30+
parser.add_argument(
31+
"--dry-run",
32+
action="store_true",
33+
default=False,
34+
help="Whether or not to take action on JIRA",
35+
)
36+
return parser.parse_args()
37+
38+
39+
args = get_args()
40+
41+
url = os.environ.get("JIRA_URL", "https://issues.redhat.com")
42+
token = os.environ.get("JIRA_TOKEN")
43+
if not token:
44+
print("Set JIRA_TOKEN environment variable to your JIRA personal access token")
45+
sys.exit(1)
46+
47+
JIRA = jira.client.JIRA(server=url, token_auth=token)
48+
49+
print("Inspecting JIRA API.")
50+
all_fields = JIRA.fields()
51+
jira_name_map = {field["name"]: field["id"] for field in all_fields}
52+
parent_key = jira_name_map["Parent Link"]
53+
epic_name_key = jira_name_map["Epic Name"]
54+
55+
query = f"key={args.feature} and type=Feature"
56+
print("Confirming the Feature exists:")
57+
print(" > " + query)
58+
results = JIRA.search_issues(query)
59+
if not results:
60+
print(f"Feature not found via query: {query}")
61+
sys.exit(1)
62+
origin_feature = results[0]
63+
64+
65+
query = f"'Parent Link'={args.feature}"
66+
print("Gathering child epics:")
67+
print(" > " + query)
68+
epics = JIRA.search_issues(query)
69+
if not epics:
70+
print(f"No child epics found via query: {query}")
71+
sys.exit(1)
72+
73+
kwargs = {
74+
"project": origin_feature.fields.project.key,
75+
"summary": args.summary,
76+
"issuetype": origin_feature.fields.issuetype.name,
77+
"description": origin_feature.fields.description,
78+
}
79+
if not args.dry_run:
80+
new_feature = JIRA.create_issue(**kwargs)
81+
new_feature_key = new_feature.key
82+
print(f"Created feature {new_feature}, as a copy of {origin_feature}")
83+
print(f"https://issues.redhat.com/browse/{new_feature}")
84+
if origin_feature.fields.labels:
85+
new_feature.update(
86+
{
87+
"labels": origin_feature.fields.labels,
88+
}
89+
)
90+
else:
91+
print(f"Skipped creating clone of {origin_feature}")
92+
print(f" Would have created:")
93+
pprint.pprint(kwargs)
94+
new_feature_key = "<unknown>"
95+
96+
for origin_epic in epics:
97+
kwargs = {
98+
"project": origin_epic.fields.project.key,
99+
"summary": origin_epic.fields.summary,
100+
"issuetype": origin_epic.fields.issuetype.name,
101+
"description": origin_epic.fields.description or "",
102+
epic_name_key: getattr(origin_epic.fields, epic_name_key),
103+
parent_key: new_feature_key,
104+
}
105+
if not args.dry_run:
106+
new_epic = JIRA.create_issue(**kwargs)
107+
print(f"Created epic {new_epic}, as a copy of {origin_epic}")
108+
if origin_epic.fields.labels:
109+
new_epic.update(
110+
{
111+
"labels": origin_epic.fields.labels,
112+
}
113+
)
114+
else:
115+
print(f"Skipped creating clone of {origin_epic}")
116+
print(f" Would have created:")
117+
pprint.pprint(kwargs)
118+
119+
print("Done.")

0 commit comments

Comments
 (0)