Creating a Custom Release Notes Template Containing Release Comments

Many JIRA users want to expand the generated Release Notes to include release comments for each issue in the report. Thistutorial 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.

Note, this tutorial applies to JIRA Server only.

Step 1: Creating a Custom Field

The first thing to do is add a custom field for your release note comments, as described below. Note, you'll be associating this custom field with a screen; you can use the default screen or create your own beforehand.

  1. In JIRA, click the cog icon > Issues
  2. Click Custom fields in the left menu. 
  3. Click Add custom field to start the add custom field wizard. Create a field with the following details:
    • Type: Text Field (multi-line)
    • Name: Release notes comments
    • Description: This is a comment to include on the generated release notes.
    • Associated screens: Resolve Issue Screen
  4. Click Update to create your custom field.

You have now finished creating a custom field that will be displayed when you resolve or close an issue. We'll use this to 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

Deploying Velocity Templates without a Restart

In a development instance, you can play with picking up velocity file changes without a restart.

From <jira-install>/atlassian-jira/WEB-INF/classes/velocity.properties:

  1. Change class.resource.loader.cache from true to false
  2. Uncomment (remove the # sign from) #velocimacro.library.autoreload=true

Keep in mind that the next time you upgrade JIRA – or need a new installation for any reason – you will have to manually copy any changes you have made to the JSPs or tempates into the new installation of JIRA. If the JSPs or templates have changed in the newer version, you will have to port your customization into them.

This is quite a simple step. Place the two velocity templates into the <jira-application-dir>/WEB-INF/classes/templates/jira/project/releasenotes subdirectory of your JIRA Installation Directory.

Next you need to specify your new template formats by changing the value of the jira.releasenotes.templates property in the jira-config.properties of your JIRA Home Directory.

  • There is no need to modify the jira.releasenotes.templatenames property since:
    • we still want an Html and Text option and
    • we have only changed the templates themselves.
  • The jira.releasenotes.templates property value should changed to look something like the following, representing your new Html and Text Velocity template files, respectively:

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

    (info) See Adding a New Format Template for more information and how to define these properties if they do not already exist in your jira-config.properties file.

Save your modified jira-config.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.

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

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

Was this page helpful?

Have a question about this article?

See questions about this article

Powered by Confluence and Scroll Viewport