Skip to content

Commit

Permalink
Implement issue journal details export feature
Browse files Browse the repository at this point in the history
  • Loading branch information
wandering-tales committed Mar 14, 2018
1 parent 6b8ed04 commit 293c643
Show file tree
Hide file tree
Showing 5 changed files with 843 additions and 30 deletions.
127 changes: 127 additions & 0 deletions docs/appendixes.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
==========
Appendixes
==========

**********************
Jira REST API Handbook
**********************

Here follows a list of Jira REST API's that you might find useful
while working with the ``redmine2jira`` tool. For instance you
may want to retrieve those nasty Jira internal resource ID's used
in the dictionary mappings in the configuration files.

This handbook is organized in sections, each corresponding to a
Jira resource type.

.. note::

Unless noted otherwise the internal ID field is always ``id``.
Should ``id`` not be included in the JSON response, the ``key``
field can be used in its place.

.. note::

Some API's return paginated list of resources, each specifying a
maximum number of fetched resources per single call. In such cases
you may want to call them multiple times properly tweaking the
``startAt`` and ``maxResults`` parameters.

In the URL examples below the ``maxResults`` parameter is set by
default to the maximum number of results each API is able to return
per single call.


Users
-----

- Get a user, either active or inactive, by his username::

/rest/api/2/user?username={username}&includeInactive=True

- Get all users, both active and inactive::

/rest/api/2/user/search?startAt=0&maxResults=1000&username=_&includeInactive=True'

This API returns a paginated list of users. The maximum number of returned
users is limited to 1000 (already set in the URL above).

- Get all users from group, both active and inactive::

/rest/api/2/group/member?groupname={group_name}&startAt={index}&maxResults=50&includeInactiveUsers=True

This API returns a paginated list of users. The maximum number of returned
users is limited to 50 (already set in the URL above).
This API is useful if you configured a special group containing all of
your users.

.. note::

The value of ``key`` field, for the current version of the Jira REST API
(v2), is equal to the value of the ``username`` field, hence you may simply
avoid calling the API's above if you need to retrieve user ID's.


Projects
--------

- Get all projects::

/rest/api/2/project

- Get project::

/rest/api/2/project/{projectIdOrKey}


Issue Types
-----------

- Get all issue types::

/rest/api/2/issuetype


Issue Statuses
--------------

- Get all issue statuses::

/rest/api/2/status

- Get an issue status::

/rest/api/2/status/{idOrName}


Issue Priorities
----------------

- Get all issue priorities::

/rest/api/2/priority


Custom Fields
-------------

- Get all issue fields, both System and Custom::

/rest/api/2/field


Components
----------

- Get project components::

/rest/api/2/project/{projectIdOrKey}/components


Labels
------

Unfortunately currently there are no endpoints in Jira REST API v2
to work with labels, and there is no way to workaround.

See https://jira.atlassian.com/browse/JRASERVER-29409
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Contents:
contributing
authors
history
appendixes

Indices and tables
==================
Expand Down
2 changes: 1 addition & 1 deletion redmine2jira/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def main():
# in order to easily recognize all the issues in the same import batch
def export_issues(output, query_string):
"""Export Redmine issues."""
exporter = IssuesExporter(check_config=True)

if query_string:
issues = _get_issues_by_filter(query_string)
Expand All @@ -50,7 +51,6 @@ def export_issues(output, query_string):
click.echo("{:d} issue{} found!"
.format(len(issues), "s" if len(issues) > 1 else ""))

exporter = IssuesExporter()
exporter.export(issues)

click.echo("Issues exported in '{}'!".format(output.name))
Expand Down
79 changes: 62 additions & 17 deletions redmine2jira/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@
CHECK_ISSUE_ID_FILTER_AVAILABILITY = True
ISSUE_ID_FILTER_AVAILABLE = True

# Flag to include journals in the issues export.
# As the export of the journals of an issue is a complex feature
# and comes with several requirements on configuration settings,
# it needs to be explicitly enabled by the final user.
#
EXPORT_ISSUE_JOURNALS = False


#
# Resource mappings
#
Expand All @@ -60,12 +68,29 @@
# where the two "RESOURCE_TYPE" placeholders respectively refers to the
# Redmine and Jira resource types where the mappings of resources apply.

# These settings are declared as Python dictionaries where the keys and the
# values are both "identifying names" of the instances of the two resource
# types involved in the mappings, respectively for Redmine and Jira.
# By "identifying names", in this context, we mean strings that "uniquely"
# identify each instance of a specific resource type, in addition to its
# internal ID number.
# These settings are declared as Python dictionaries where the keys are the
# "identifying names" of the instances of the related Redmine resource types,
# and the values may be one of:
#
# - "Identifying names" of the mapped Jira resource instances
# - Tuples composed by:
# - Internal ID of the mapped Jira resource instance
# - "Identifying name" of the mapped Jira resource instance
#
# The second form, more complex, that contains Jira resources internal ID's,
# is necessary only if issue journals need to be included in the export,
# as that feature needs those ID's to properly generate Jira history items.
# The most effective (and official) method to retrieve Jira resources
# internal ID's is via Jira REST API. Nonetheless, calling those API's may
# not be feasible for everyone, for several reasons. So we added a short
# handbook in the tool documentation with a list of useful API's to
# retrieve those ID's:
#
# https://redmine2jira.readthedocs.io/en/latest/appendixes.html#jira-rest-api-handbook
#
# For both forms, instead, by "identifying names" we mean strings that
# "uniquely" identify each instance of a specific resource type, in addition
# to its internal ID number.
# As each resource type, either it belongs to Redmine or Jira, has always
# at least one field designated to contain such identifying name, for each
# one of its instances, we will specify, in a comment before each dictionary
Expand All @@ -90,7 +115,7 @@
# Example:
#
# 'my-cool-project': {
# 'My Redmine instance name': 'My Jira instance name',
# 'My Redmine instance name': (10, 'My Jira instance name'),
# ...
# }
# ...
Expand Down Expand Up @@ -123,7 +148,9 @@
#
# Example:
#
# 'alice.cooper': 'dave.grohl',
# 'ozzy.osbourne: 'ronny.james.dio', # 1st form
# ...
# 'alice.cooper': ('dave.grohl', 'dave.grohl'), # 2nd form
# ...
}

Expand All @@ -148,7 +175,9 @@
#
# Example:
#
# 'lead-developers': 'linus.torvalds',
# 'qa-leads': 'johann.sebastian.bach', # 1st form
# ...
# 'lead-developers': ('linus.torvalds', 'linus.torvalds'), # 2nd form
# ...
}

Expand All @@ -159,7 +188,9 @@
#
# Example:
#
# 'my-cool-project': 'MCP',
# 'my-very-cool-project': 'MVCP', # 1st form
# ...
# 'my-cool-project': (123, 'MCP'), # 2nd form
# ...
}

Expand All @@ -170,7 +201,9 @@
#
# Example:
#
# 'Defect': 'Bug',
# 'Nonconformity': 'Incident', # 1st form
# ...
# 'Defect': (8, 'Bug'), # 2nd form
# ...
}

Expand All @@ -181,7 +214,9 @@
#
# Example:
#
# 'Open': 'To Do',
# 'Closed': 'Done', # 1st form
# ...
# 'Open': (19, 'To Do'), # 2nd form
# ...
}

Expand All @@ -192,7 +227,9 @@
#
# Example:
#
# 'High': 'Highest',
# 'Low': 'Lowest', # 1st form
# ...
# 'High': (9, 'Highest'), # 2nd form
# ...
}

Expand All @@ -203,7 +240,9 @@
#
# Example:
#
# 'Severity': 'Severity',
# 'Approval Team': 'Approvers', # 1st form
# ...
# 'Severity': (16, 'Severity'), # 2nd form
# ...
}

Expand All @@ -216,7 +255,9 @@
# Example:
#
# 'my-cool-project': {
# 'Backend': 'Backend',
# 'Frontend': 'Frontend', # 1st form
# ...
# 'Backend': (5, 'Backend'), # 2nd form
# ...
# }
# ...
Expand All @@ -230,7 +271,9 @@
# Example:
#
# 'my-cool-project': {
# 'My Functional Module': 'My Functional Module',
# 'A category': 'A label', # 1st form
# ...
# 'Another category': (13, 'Another label'), # 2nd form
# ...
# }
# ...
Expand All @@ -244,7 +287,9 @@
# Example:
#
# 'my-cool-project': {
# '1.0.0': '1.0.0',
# '1.0.0': '1.0.0', # 1st form
# ...
# '0.0.1': (1, '0.0.1'), # 2nd form
# ...
# }
# ...
Expand Down

0 comments on commit 293c643

Please sign in to comment.