Documentation for JIRA 4.0. Documentation for other versions of JIRA is available too.

Many JIRA users want to expand the generated Release Notes to include release comments for each issue in the report. This tutorial shows how to do this using a custom field and some customized velocity templates. It assumes the reader understands JIRA's custom fields. For more information on custom fields see the JIRA documentation.

Step 1: Creating a Custom Field

The first thing to do is add a custom field for your release note comments. To add the custom field, click the Administration link in the top navigation bar then choose Issue Fields > Custom Fields and on the resulting page choose the Add Custom Field link. You should see this screen:

From this screen choose the Free Text Field (unlimited text) field type and click next. On the next page enter the name, description, search template, applicable issue types, and applicable context of our new custom field. The values should be:

  • name: release notes comments
  • description: This is a comment to include on the generated release notes.
  • search template: Free Text Searcher (the default for this type of custom field)
  • applicable issue typs: Any Issue Type (this can quite easily be changed if you only wish this custom field to apply to a certain issue type)
  • applicable context: Global context. Apply to all issues in JIRA (you can choose here to suit your preference)

The input screen should look like this:

Click the Finish button. You will be taken to the 'Associate field release notes comments to screens' screen. Click the checkbox associated with the 'Resolve Issue Screen'. In this example it only really makes sense to show this custom field when resolving or closing an issue. The screen should look like this:

Click the Update button. You are now finished creating our custom field. When you choose to resolve or close an issue you should now have a text area where you can enter comments to appear on the release notes.

Step 2: Creating Custom Velocity Templates for Release Notes Reports

Velocity is the templating engine used in JIRA. Currently JIRA ships with a text and a html release notes report template. For this tutorial we will modify the existing templates to also display the custom field that we created in the previous step, for each issue in the report. The modified text template looks something like this:

#macro (getReleaseNoteComment $issue $customFieldManager)
#set ($customFields = $customFieldManager.getCustomFieldObjects($issue.project.getLong("id"), $issue.issueType.getString("id")))
#foreach($customField in $customFields)
#if($customField.name.equals("release notes comments"))
#if($customField.getValue($issue)) - Release Comment: $textUtils.htmlEncode($customField.getValue($issue))#end
#end
#end
#end

<title>$action.getText('release.notes.text.title', $project, $version) </title>
<body>
<table>
<tr>
<td>

#foreach ($issueType in $issueTypes)
#if($issueType.issues.size() > 0)
<h2>$textUtils.htmlEncode($issueType.name)</h2>
<ul>
#foreach ($issue in $issueType.issues)
<li>[<a xhref='$!appProps.getString("jira.baseurl")/browse/$issue.key'>$issue.key</a>] -
 $textUtils.htmlEncode($issue.summary)#getReleaseNoteComment($issue $customFieldManager)</li>
#end
</ul>
#end
#end
</td>
</tr>

<tr>
<td>

<hr width="100%">

<a name="editarea"><h2>$action.getText('release.notes.edit.copy')</h2></a>
<p>$action.getText('release.notes.description')<br></p>

<textarea rows="40" cols="120">

$action.getText('release.notes.heading', $project, $version)

#foreach ($issueType in $issueTypes)
#if($issueType.issues.size() > 0)
** $textUtils.htmlEncode($issueType.name)
#foreach ($issue in $issueType.issues)
* [$issue.key] - $textUtils.htmlEncode($issue.summary)#getReleaseNoteComment($issue $customFieldManager)
#end
#end

#end
</textarea>
</td>
</tr>
</table>
</body>

The modified html template looks like this:

#macro (getReleaseNoteComment $issue $customFieldManager)
#set ($customFields = $customFieldManager.getCustomFieldObjects($issue.project.getLong("id"), $issue.issueType.getString("id")))
#foreach($customField in $customFields)
#if($customField.name.equals("release notes comments"))
#if($customField.getValue($issue)) - <b>Release Comment</b>: $textUtils.htmlEncode($customField.getValue($issue))#end
#end
#end
#end
<title>$action.getText('release.notes.html.title', $project, $version) </title>
<body>
<table>
<tr>
<td>

#foreach ($issueType in $issueTypes)
#if($issueType.issues.size() > 0)
<h2>$textUtils.htmlEncode($issueType.name)</h2>
<ul>
#foreach ($issue in $issueType.issues)
<li>[<a xhref='$!appProps.getString("jira.baseurl")/browse/$issue.key'>$issue.key</a>] -
 $textUtils.htmlEncode($issue.summary)#getReleaseNoteComment($issue $customFieldManager)</li>
#end
</ul>
#end
#end
</td>
</tr>

<tr>
<td>

<hr width="100%">

<a name="editarea"><h2>$action.getText('release.notes.edit.copy')</h2></a>
<p>$action.getText('release.notes.description')<br></p>

<textarea rows="40" cols="120">

$action.getText('release.notes.heading', $project, $version)
#foreach ($issueType in $issueTypes)
#if($issueType.issues.size() > 0)

<h2>$textUtils.htmlEncode($issueType.name)</h2>
<ul>
#foreach ($issue in $issueType.issues)
<li>[<a xhref='$!appProps.getString("jira.baseurl")/browse/$issue.key'>$issue.key</a>] -
 $textUtils.htmlEncode($issue.summary)#getReleaseNoteComment($issue $customFieldManager)</li>
#end
</ul>
#end
#end
</textarea>
</td>
</tr>
</table>
</body>

The only difference between the above templates and the originals is the definition of the velocity macro 'getReleaseNoteComment' and its use after the issue summary. In the macro we use the context variable $customFieldManager which is an instance of the com.atlassian.jira.issue.CustomFieldManager interface. We use the CustomFieldManager to get all CustomFieldObjects for the current issue and then iterate through them looking for the field we want. When we find the field named 'release notes comments' we get and display the value if it is not null. NOTE: we do not use the getCustomFieldObjectByName method because it is deprecated and we can not be certain that the custom field name will be unique within the JIRA instance.

These velocity templates will display the 'release notes comments' custom field in our generated Release Notes. Now you need to tell JIRA to use the new templates.

Step 3: Modifying JIRA to Use Custom Velocity Templates

This is quite a simple step. Place the two velocity templates into your JIRA distribution* in the directory: WEB-INF/classes/templates/jira/project/releasenotes . Next you must modify the WEB-INF/classes/jira-application.properties file. There are two variables that are of importance to us:

{{jira.releasenotes.templatenames = Text, Html
jira.releasenotes.templates = releasenotes-text.vm, releasenotes-html.vm}}

We do not need to modify the first property since we still want a Text and Html option and have only changed the templates. We modify the second property to look like this:

jira.releasenotes.templates = releasenotes-with-releasecomment-text.vm, releasenotes-with-releasecomment-html.vm

Save the properties file and restart Jira. Now we can test that what we have done works. You must make sure you can generate some Release Notes that will contain issues:

  • Make sure that you have created a version for the project you are testing this under (release notes can only be generated for a version).
  • Make sure that you have some issues that have the fix versions set to the version you created above.
  • Make sure that you have entered some release comment text on the issues with the fix versions from above(in our example if there is not a release comment for an issue then nothing will display and it will look very much like the original Release Notes).

Browse to the release notes page, click the 'Browse Project' link in the top navigation, click the 'Release Notes' link on the resulting page, choose your 'Version' and 'Style', and click 'Create'. You should see the release note comments text after the summary text for each issue. The screen should look something like this:

Step 4: Filtering Release Notes

As an optional extra, you can filter the release notes based on various issue properties to see if they match your criteria. For example, to print only issues that have a resolution of Fixed and a Status, put an #if statement around the code that creates a bullet point for the issue:

#set ($resolution = $issue.getResolutionObject())
#set ($status = $issue.getStatusObject())
## check for resolved or closed and fixed
#if (($status.getId() == "5" || $status.getId() == "6") && $resolution.getId() == "1")
 <li>[<a href='$!appProps.getString("jira.baseurl")/browse/$issue.getString("key")'>$issue.getString("key")</a>] -
 $textUtils.htmlEncode($issue.getString("summary"))#getReleaseNoteComment($issue $customFieldManager)</li>
#end

* The Jira Distribution is the package that you downloaded and installed from our website. The directory commonly has a name starting with atlassian-jira-<edition>-<version>.

Conclusion

This tutorial shows a very simple modification to the Release Notes reports but the concepts used within should show you how to customize Release Notes to fit many other needs. The use of custom fields and the mechanism for accessing their values through a velocity template can allow a great number of extensions beyond the scope of this example.

Have fun and good luck!

Further Resources

1) Available Fields - Please see the JIRA Remote API for details on what information you can retrieve. For example:

2) Template Syntax - The Velocity User Guide will help you choose the right syntax.

3) Help & Support - Please post to the JIRA Development Forums for get help from the user community with your templates.