Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ The task needs special configuration in `exportimportconfig.py` (see sample in
* `PORTFOLIO_EPIC_LABEL`: (porfolio epic mode) for an issue to be considered a porfolio epic, this label must be attached to it
* `PORTFOLIO_EPIC_SUB_EPIC_SOURCE_LINK_NAME`: (porfolio epic mode) only issues that are linked to the portfolio epic with this link name are migrated
* `PORTFOLIO_EPIC_SUB_EPIC_TARGET_LINK_NAME`: (porfolio epic mode) the link name to use in target JIRA to link issues to portfolio epics
* `PORTFOLIO_EPIC_SUB_EPIC_SOURCE_LINK_DIRECTION`: 'outwardIssue' or 'inwardIssue'. Choose which direction search is done
* `PORTFOLIO_EPIC_SUB_EPIC_TARGET_LINK_SWAP`: 'True' or 'False' Optionally swap direction to destination, if it is logically opposite.

* `STATUS_TRANSITIONS`: map of source JIRA statuses to list of workflow transition names in target JIRA that result in equivalent status, `None` for no transition
* `STATUS_TRANSITIONS_ISSUETYPE`: issuetype specific map of source JIRA statuses to list of workflow transition names in target JIRA that result in equivalent status, `None` for no transition. If an issuetype is not in this list, the default `STATUS_TRANSITIONS` are used.
* `RESOLUTION_MAP`: map source JIRA resolutions to target resolutions, only used when a `WithResolution` transition is used in `STATUS_TRANSITIONS`
Expand Down
3 changes: 2 additions & 1 deletion exportimportconfig-sample.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@
PORTFOLIO_EPIC_LABEL = 'porfolio-epic'
PORTFOLIO_EPIC_SUB_EPIC_SOURCE_LINK_NAME = 'sub-epic'
PORTFOLIO_EPIC_SUB_EPIC_TARGET_LINK_NAME = 'sub-epic'

PORTFOLIO_EPIC_SUB_EPIC_SOURCE_LINK_DIRECTION = 'outwardIssue' # or inwardIssue
PORTFOLIO_EPIC_SUB_EPIC_TARGET_LINK_SWAP = 'True' # ...or False, swapping direction
CUSTOM_FIELD_FOR_SOURCE_JIRA_ISSUE_KEY = ('Text 1', 'customfield_10132')

CUSTOM_FIELD = ('customfield_11086', {'value': 'Custom value'})
Expand Down
31 changes: 26 additions & 5 deletions lib/export_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,33 @@ def _map_sub_epics(source_jira, dest_jira, source_issue, dest_issue, conf, resul
print('with sub-epics:')
# Get all linked sub-epics and import them recursively.
for linked_issue in source_issue.fields.issuelinks:
if linked_issue.type.name == conf.PORTFOLIO_EPIC_SUB_EPIC_SOURCE_LINK_NAME and hasattr(linked_issue, 'outwardIssue'):
sub_epic = linked_issue.outwardIssue
new_sub_epic = _map_issue(source_jira, dest_jira, sub_epic, conf, result, None, True)
if linked_issue.type.name == conf.PORTFOLIO_EPIC_SUB_EPIC_SOURCE_LINK_NAME and \
hasattr(linked_issue, conf.PORTFOLIO_EPIC_SUB_EPIC_SOURCE_LINK_DIRECTION):
if conf.PORTFOLIO_EPIC_SUB_EPIC_SOURCE_LINK_DIRECTION == "inwardIssue":
sub_epic = linked_issue.inwardIssue
else:
sub_epic = linked_issue.outwardIssue
# Test if sub_epic already exists. Use that or create a new
# Search always returns an iterator, but it may be empty
# It then throws StopIteration, instead of giving us issue
try:
new_sub_epic = next(_already_imported(conf, dest_jira, sub_epic))
print('Issue', sub_epic, 'has already been imported, link only...')
except StopIteration:
new_sub_epic = _map_issue(source_jira, dest_jira, sub_epic, conf, result, None, True)
# Always create link, no matter if it was existing issue or new
# If SWAP, change direction
# If searched outwardIssue, or if searched inward, but SWAP is true
inIssue = dest_issue.key
outIssue = new_sub_epic.key
# If searched inwardIssue and no SWAP, or if searched outward, but SWAP is true
if (conf.PORTFOLIO_EPIC_SUB_EPIC_SOURCE_LINK_DIRECTION == 'inwardIssue' and not conf.PORTFOLIO_EPIC_SUB_EPIC_SOURCE_LINK_SWAP ) or \
(conf.PORTFOLIO_EPIC_SUB_EPIC_SOURCE_LINK_DIRECTION == 'outwardIssue' and conf.PORTFOLIO_EPIC_SUB_EPIC_TARGET_LINK_SWAP):
outIssue = dest_issue.key
inIssue = new_sub_epic.key

dest_jira.create_issue_link(type=conf.PORTFOLIO_EPIC_SUB_EPIC_TARGET_LINK_NAME,
inwardIssue=dest_issue.key,
outwardIssue=new_sub_epic.key)
inwardIssue= inIssue, outwardIssue= outIssue )
# TODO: add portfolio epic label to target
print('Sub-epics of', source_issue.key, 'done.')

Expand Down