Packaging JIRA Maven 1-based plugins for easy upgrades

This is a simple convention for packaging JIRA plugins, which allows conforming plugins can be automatically compiled against new versions of JIRA. Additionally, there is a convention whereby new files required by the plugin can be added to JIRA, and patches specified to modify JIRA for the plugin's needs.

Compiling against later JIRA versions

As Maven 1 does not have transitive dependencies, most plugin packagers mix JIRA's dependencies up with the plugin's dependencies in a single project.xml. This makes upgrading the plugin a manual and rather painful process.

JIRA will eventually move to Maven 2, which has transitive dependencies, which will eliminate this problem and render this page obsolete.

Plugins set up as described here can be compiled against a new release (3.11 here) this easily:

wget -q 'http://repository.atlassian.com/atlassian-jira/poms/atlassian-jira-3.11.pom'
maven -Djiraversion=3.11 jar

project.xml

Your project.xml should contain only dependencies specific to your plugin, and should "extend" the JIRA project.xml. Here is an example:

<?xml version='1.0' encoding='ISO-8859-1'?>
<project>
    <pomVersion>3</pomVersion>
    <extend>atlassian-jira-${jiraversion}.pom</extend>
    <id>atlassian-bulkmoverestorefields-plugin</id>
    <name>Bulk Move Restore Fields</name>
    <currentVersion>1.0</currentVersion>
    <organization>
        <name>Atlassian Software Systems Pty Ltd</name>
        <url>http://www.atlassian.com/</url>
    </organization>
    <package>com.atlassian.jira.web.action.ext.bulkmoverestorefields</package>
    <description>An example plugin that uses both the web UI and the webwork plugin modules</description>

    <developers>
        <developer>
            <name>Jeff Turner</name>
            <id>jefft</id>
            <email>jeff@atlassian.com</email>
            <organization>Atlassian</organization>
            <roles>
                <role>Developer</role>
            </roles>
        </developer>
    </developers>

    <dependencies>
        <dependency>
            <id>atlassian-jira</id>
            <version>${jiraversion}</version>
        </dependency>
    </dependencies>

    <build>
        <sourceDirectory>src/java</sourceDirectory>
        <resources>
            <resource>
                <directory>src/etc/</directory>
                <include>atlassian-plugin.xml</include>
                <include>**/*.vm</include>
            </resource>
        </resources>
        <unitTestSourceDirectory>test/java</unitTestSourceDirectory>
        <unitTest>
            <includes>
                <include>**/*Test.java</include>
                <include>**/Test*.java</include>
            </includes>
            <excludes>
                <exclude>**/Abstract*.java</exclude>
            </excludes>
            <resources>
                <resource>
                    <directory>test/etc</directory>
                </resource>
            </resources>
        </unitTest>
    </build>
</project>

project.properties

In project.properties, define a variable with a default value for jiraversion (used in the project.xml):

jiraversion=3.12.1

atlassian-jira-$version.pom

Now download the atlassian-jira-$version.pom from the version of JIRA you specified above, and place it in the same directory as project.xml. These files can be found at http://repository.atlassian.com/atlassian-jira/poms/

Custom patches

Not everything can be overridden by a plugin, and sometimes a plugin requires modifications to JIRA core files (eg. JSPs) to work.

We handle this by allowing patches (anything processable by the "patch" command) to be placed in the src/patches/ directory. Patches here should be relative to the JIRA webapp; ie. the atlassian-jira directory in JIRA Standalone.

Extra files

As with patches, sometimes plugin require extra files (eg. images) to be installed in JIRA. These should be placed in a src/patches/webapp directory, where they will be copied (with subdirectories preserved) to the JIRA webapp.

Sample conforming plugins

Labels

 
(None)