This plugin collects Jira data through Jira Cloud REST API. It then computes and visualizes various engineering metrics from the Jira data.
| Metric Name | Description |
|---|---|
| Requirement Count | Number of issues with type “Requirement” |
| Requirement Lead Time | Lead time of issues with type “Requirement” |
| Requirement Delivery Rate | Ratio of delivered requirements to all requirements |
| Requirement Granularity | Number of story points associated with an issue |
| Bug Count | Number of issues with type “Bug” bugs are found during testing |
| Bug Age | Lead time of issues with type “Bug” both new and deleted lines count |
| Bugs Count per 1k Lines of Code | Amount of bugs per 1000 lines of code |
| Incident Count | Number of issues with type “Incident” incidents are found when running in production |
| Incident Age | Lead time of issues with type “Incident” |
| Incident Count per 1k Lines of Code | Amount of incidents per 1000 lines of code |
In order to fully use this plugin, you will need to set various configurations via Dev Lake's config-ui service. Open config-ui on browser, by default the URL is http://localhost:4000, then go to Data Integrations / JIRA page. JIRA plugin currently supports multiple data connections, Here you can add new connection to your JIRA connection or update the settings if needed.
For each connection, you will need to set up following items first:
https://<mydomain>.atlassian.net/rest. DevLake officially supports JIRA Cloud Service on atlassian.net, but may or may not work for JIRA Server Instance.config-ui click the KEY icon on the right side of the input to generate a full HTTP BASIC AUTH token for you.If you want to add more custom config, you can click “settings” to change these config
custom field, which is vary from instance to instance. Please see Find Out Custom Fields.https://id.atlassian.com/manage-profile/security/api-tokens
Devlake supports 3 standard types, all metrics are computed based on these types:
Bug: Problems found during the test phase, before they can reach the production environment.Incident: Problems that went through the test phase, got deployed into production environment.Requirement: Normally, it would be Story on your instance if you adopted SCRUM.You can map arbitrary YOUR OWN ISSUE TYPE to a single STANDARD ISSUE TYPE. Normally, one would map Story to Requirement, but you could map both Story and Task to Requirement if that was your case. Unspecified types are copied directly for your convenience, so you don't need to map your Bug to standard Bug.
Type mapping is critical for some metrics, like Requirement Count, make sure to map your custom type correctly.
Please follow this guide: How to find the custom field ID in Jira?
To collect data, select Advanced Mode on the Create Pipeline Run page and paste a JSON config like the following:
Warning: Data collection only supports single-task execution, and the results of concurrent multi-task execution may not meet expectations.
[
[
{
"plugin": "jira",
"options": {
"connectionId": 1,
"boardId": 8,
"since": "2006-01-02T15:04:05Z"
}
}
]
]
connectionId: The ID field from JIRA Integration page.boardId: JIRA board id, see “Find Board Id” for details.since: optional, download data since a specified date only.?rapidView=Example:
https://{your_jira_endpoint}/secure/RapidBoard.jspa?rapidView=51

Your board id is used in all REST requests to Apache DevLake. You do not need to configure this at the data connection level.
[ { "ID": 14, "CreatedAt": "2021-10-11T11:49:19.029Z", "UpdatedAt": "2021-10-11T11:49:19.029Z", "name": "test-jira-connection", "endpoint": "https://merico.atlassian.net/rest", "basicAuthEncoded": "basicAuth", "epicKeyField": "epicKeyField", "storyPointField": "storyPointField" } ]
{ "name": "jira data connection name", "endpoint": "jira api endpoint, i.e. https://merico.atlassian.net/rest", "basicAuthEncoded": "generated by `echo -n {jira login email}:{jira token} | base64`", "epicKeyField": "name of customfield of epic key", "storyPointField": "name of customfield of story point", "typeMappings": { // optional, send empty object to delete all typeMappings of the data connection "userType": { "standardType": "devlake standard type" } } }
{ "name": "jira data connection name", "endpoint": "jira api endpoint, i.e. https://merico.atlassian.net/rest", "basicAuthEncoded": "generated by `echo -n {jira login email}:{jira token} | base64`", "epicKeyField": "name of customfield of epic key", "storyPointField": "name of customfield of story point", "typeMappings": { // optional, send empty object to delete all typeMappings of the data connection "userType": { "standardType": "devlake standard type", } } }
{ "name": "jira data connection name", "endpoint": "jira api endpoint, i.e. https://merico.atlassian.net/rest", "basicAuthEncoded": "generated by `echo -n {jira login email}:{jira token} | base64`", "epicKeyField": "name of customfield of epic key", "storyPointField": "name of customfield of story point", "typeMappings": { // optional, send empty object to delete all typeMappings of the data connection "userType": { "standardType": "devlake standard type", } } }
[ { "jiraConnectionId": 16, "userType": "userType", "standardType": "standardType" } ]
{ "userType": "userType", "standardType": "standardType" }
{ "standardType": "standardTypeUpdated" }
http://your_devlake_host/plugins/jira/connections/1/proxy/rest/agile/1.0/board/8/sprint would be forwarded to https://your_jira_host/rest/agile/1.0/board/8/sprint{ "maxResults": 1, "startAt": 0, "isLast": false, "values": [ { "id": 7, "self": "https://merico.atlassian.net/rest/agile/1.0/sprint/7", "state": "closed", "name": "EE Sprint 7", "startDate": "2020-06-12T00:38:51.882Z", "endDate": "2020-06-26T00:38:00.000Z", "completeDate": "2020-06-22T05:59:58.980Z", "originBoardId": 8, "goal": "" } ] }