Grails – publish a plugin in a self-hosted maven repository

June 10, 2013 at 10:08

Context and motivations

Since a few versions ago, grails includes the possibility of packaging your plugin as an old good JAR file. This can be done by using the –binary option:

grails-timestamped $ grails package-plugin --binary
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8 -Xmx2048m -Xms256m -XX:PermSize=512M -XX:MaxPermSize=2048M
| Packaging Grails application.....
| Plugin packaged grails-plugin-timestamped-0.3.jar
grails-timestamped $ ls target/*.jar
target/grails-plugin-timestamped-0.3.jar

This allows a developer to publish closed plugins (as with the traditional packaging, installing a plugin means that you’ll get the source code in your $HOME/.grails) and to gain some speed in compiling / deployment operations, since the plugin doesn’t need to be compiled. Another benefit that I’ve not seen mentioned anywhere is that this allows a plugin to provide AST transforms that can be used by other plugins (as, for example, the timestamped plugin does). The reason is that an AST transform needs to be available at compile time, so if you compile it in the same “compilation execution” as the classes where it’s been applied, it won’t be able to do its work, and all plugins are compiled in the same “compilation execution” (but not in the same “compilation execution” as the main project, being that the reason why the AST transform will work in the project).

There is a problem with the binary packaging though, and is that right now the grails plugins official portal doesn’t support it. You have then to publish it to a maven repo and add it as a maven dependency. Too much work? Not really!

Grails Plugin Maven Deployer

I created a small scripting tool that can create a maven repo structure from a grails plugin. You can just put that structure in any webserver (or even Github or Github pages), and you are ready to go. The Grails Plugin Maven Deployer can be found in Github, and this is an example of using it to publish the timestamped grails plugin:

Prepare a temp directory with the plugin and the deployer for a demo:

$ mkdir grails-plugin-maven-deployer-demo && cd grails-plugin-maven-deployer-demo
$ mkdir -p  maven/releases/
$ git clone https://github.com/deigote/grails-timestamped
$ git clone https://github.com/deigote/grails-plugin-maven-deployer

Using the deployer:

$ grails-plugin-maven-deployer/deploy.sh grails-timestamped/ com.deigote.grails-plugins timestamped maven/releases/
$ ls -R maven/releases/

If everything goes well (if not, open an issue and I’ll try to help :-D), you’ll see a maven repo in the maven/releases (the destination directory passed as the fourth) for the artifact timestamped (the plugin name, passed as third argument to the script) and the group id com.deigote.grails-plugins (passed as second argument to the script). The first argument is, of course, the path to the plugin to publish 😀 .

Then you just can publish the destination directory in any webserver and include it as a dependency. For example, I published the maven/releases/ in Github Pages, which allows me to reach it by including the following in the project’s BuildConfig.groovy:

dependencies {
   ...
   compile 'com.deigote.grails-plugins:timestamped:0.3'
}

repositories {
   inherits true
   mavenRepo 'http://deigote.github.io/grails-timestamped/maven/releases/'
   ...
}