# Migration tool for migrating issues from Apache Maven Jira to GitHub

**CAUTION:** The migration has finished, therefore this repository is archived.

This tool is based on the migration tool, that is written by the Spring Team, originally.

Some Key Features:

* Performs basic conversion from JIRA markup to GitHub markup
* Uses GitHub's experimental https://gist.github.com/jonmagic/5282384165e0f86ef105[import issue API] for increased speed and to keep dates accurate
* Links related issues
* Since GitHub issues does not allow for multiple fix versions, the migration creates a separate issue (called a backport issue) for each additional fix version and links to the original issue.
Each backport issue has a label named "Backport" on it so they can easily be found/filtered out.
* Each migrated issue has a Jira label added to it, so that if necessary the migration can be removed and performed again.
* Each issue has a link to the original JIRA issue
* Each comment has a link to the JIRA user profile of the original author

The code adjustments, that was needed for the Apache Maven Project:

* create repository in organization is another REST API than create
repository in a user space
* Apache Jira has a path prefix in the URL
(https://issues.apache.org/jira). Currently, this fact has to be hardcoded.
* Add a `JiraIssueFilter` that allows to set filter rules which Jira issues should be migrated. This feature is needed, if you want to split a Jira project to several repositories
* Jire Remote Links are supported. They are added as text into the issue body (similar to Jira Links).
* Add Label mapping for Jira field `priority`
* Pending issues are collected in a separate properties file, so that PR mapping can be done in a second run.

Sample `application.properties` is prepared for Maven Clean Plugin and for the Maven Shared Component Jira project (Component `maven-verifier`).

## Migration Status Reporting

see https://cwiki.apache.org/confluence/display/MAVEN/JIRA+to+GitHub+Issues+switching[Apache Maven CWiki - JIRA to GitHub Issues switching]

## How to Guide

### Create a service account in Github

see xref:docs/how-to-create-gh-service-account.adoc[Guide: Service Accounts in GitHub]

### Common Configuration

1. Adjust `application.properties` with the metadata of the Jira project that should migrate
2. Configure the author mapping in `src/main/resources/jira-to-github-users.properties` (for jire author exporting see xref:docs/how-to-export-jira-author.adoc[Guide: How to export Jira Author])
3. Create a Application context Configuration
[source, java]
----
@Configuration
@ConditionalOnProperty(name = "jira.projectId", havingValue = "yourProjectId")
public class MigrationConfig {


}
----

### Label Mapping

Add to your `MigrationConfig` class following beans:

[source, java]
----
	@Bean
	public LabelHandler labelHandler() {
		FieldValueLabelHandler fieldValueHandler = new FieldValueLabelHandler();
		fieldValueHandler.addMapping(FieldValueLabelHandler.FieldType.ISSUE_TYPE, "Bug", "bug");

		CompositeLabelHandler handler = new CompositeLabelHandler();
		handler.addLabelHandler(fieldValueHandler);


		return handler;
	}
----

`labelHandler` can be used for simple mapping logic.
If you need a mechanism where you can add more context information, you can implement an `IssuePorcessor`

[source, java]
----
	@Bean
	public IssueProcessor issueProcessor() {
		return new CompositeIssueProcessor(new FixDependencyIssueProcessor());
	}


	private static class FixDependencyIssueProcessor implements IssueProcessor {

		@Override
		public void beforeImport(JiraIssue jiraIssue, ImportGithubIssue githubIssue) {
			if (jiraIssue.getFields().getIssuetype().getName().equals("Task") ||
			jiraIssue.getFields().getIssuetype().getName().equals("Improvement")) {
				if(jiraIssue.getFields().getSummary().contains("Bump") || jiraIssue.getFields().getSummary().contains("Upgrade")) {
					githubIssue.getIssue().setLabels(List.of("dependencies"));
				}

			}
        }
    }
----
If you want to configure the design of the Github Labels, you have to adjust the `LabelFactories` class.


### Filtering Jira Issue for migration

If not all Jira issues should be migrated, you can configure/implement an `JiraIssueFilter` in your `MigrationConfig` class.

For example, you want to migration only Jira issues that have a specific component:

[source, java]
----
	@Bean
	public JiraIssueFilter jiraIssueFilter(@Value("${jira.component}") String componentName) {
		return new CompositeJiraIssueFilter(new JiraIssueComponentFiler(componentName));
	}

	private static class JiraIssueComponentFiler implements JiraIssueFilter {

        private final String componentName;

        public JiraIssueComponentFiler(String componentName) {
            this.componentName = componentName;
        }

		@Override
		public boolean test(JiraIssue jiraIssue) {
			return jiraIssue.getFields().getComponents().stream().anyMatch(jiraComponent -> jiraComponent.getName().contains(componentName));
		}
	}
----

### Filtering Jira Versions for migration

The migration tool creates as one of the first steps GitHub milestones based on the Jira Versions. If you don't need all Jira versions, you can implement a `MilestoneFilter` in your `MigrationConfig` class.

[source, java]
----
	@Bean
	public MilestoneFilter milestoneFilter(@Value("${jira.component}") String componentName) {
		return fixVersion -> fixVersion.getName().startsWith(componentName);
	}

----

### Manual clean up of migrated issues

If you want to delete migrated issues, you should be careful that the GitHub REST API `issues` also get pull requests.
Therefore, you should filter the issues also by author.

### What can I do if the Jira project has to many issues for one migration run?

Using the GitHub API has two limitations.
One limitation is the rate limits of the API and the validation time of the API token.
When the Jira project has too many issues (more than 1000 issues), then you have to split the migration in several runs.
Therefore, you can limit the number of issues for migration with the property `jira.migrate-jql` in `application.properties`.

For example, you can set `jira.migrate-jql=project\=${jira.projectId} AND created < 2010-01-01 and created >=2007-01-01`, so that only issues are migrated that are created in this specific time slot.
So if your Jira project has to many issues for one migration run, you make several migrations run with adjusted time slot for each run.

### Add comment with link to GH issue in the Jira

Once the migration has been done, the current directory will have a new file `github-issue-mappings.properties` containing the mapping between
the Jira issue and the created GH issue.
You can run the tool to add a commnent with link to the GH issue for all Jira issues:
```
java -Djira.projectId=MJAVADOC -Dgithub.repository-slug=apache/maven-javadoc-plugin -Djira.user=xxx -Djira.password=xxx
    -jar target/jira-to-gh-issues-0.0.1-SNAPSHOT.jar
    jiralink
    /home/ubuntu/dev/sources/open-elements/jira-to-gh-issues/github-issue-mappings.properties
```

The first argument `jiralink` will run the tool which add the links, the second optional argument is a path to the mapping file
(default value `./github-issue-mappings.properties`)

### Generate Jira issue GH issue mapping file
If the repository has already been migrated and you don't have the mapping file, you can generate the file `github-issue-mappings.properties`
with the following command
```
java -Djira.projectId=MCLEAN -Dgithub.repository-slug=apache/maven-clean-plugin -Dgithub.access-token=
-jar target/jira-to-gh-issues-0.0.1-SNAPSHOT.jar
jiraghmapping /home/olamy/dev/sources/open-elements/jira-to-gh-issues/github-issue-mappings.properties

```

The first argument `jiraghmapping` will run the tool which add the links, the second optional argument is a path to the mapping file
(default value `./github-issue-mappings.properties`)
