Grails Plugins in S3 Bucket

Amazon S3 bucket could be utilized as a very simple alternative to full-fledged Maven repository managers like Nexus or Artifactory. It is useful for publishing internal plugins or temporary patches waiting for official merge. The following has been tested with Grails 2.3.8, your mileage may vary.

Infrastructure Setup

Start with creating an S3 bucket. If desired, create typical Maven subfolders within, e.g. release, snapshot etc.

Create a dedicated user for publishing plugins and configure bucket access policy. Usually we want read-only public access to obtain artifacts and full privileges for the publisher. Note that the user (i.e. {user-arn} below) needs to be specified using full ARN identifier. Also, replace {bucket-name} accordingly:

Effect Principal Action Resource
Allow {user-arn} s3:* arn:aws:s3:::{bucket-name}/*
Allow * s3:GetObject arn:aws:s3:::{bucket-name}/*
Allow * s3:ListBucket arn:aws:s3:::{bucket-name}

Resolving Dependencies

When populated with artifacts, S3 bucket is no different from any other Maven repository accessible via HTTP. The respective URL is simply added to BuildConfig.groovy. For instance (again, replace {bucket-name} accordingly):

repositories {
    mavenRepo "{bucket-name}/release/"

Publishing Plugins

Start with adding a repository configuration to ~/.grails/settings.groovy. The name (i.e. {repo-name} below) is purely arbitrary. The username and password come from AWS Access Key for the dedicated publishing user.

grails.project.repos.{repo-name}.url = "s3://{bucket-name}/release"
grails.project.repos.{repo-name}.username = "{access-key-id}"
grails.project.repos.{repo-name}.password = "{access-key-password}"

In order for Maven to handle s3:// protocol, it needs corresponding wagon implementation declared as dependency in BuildConfig.groovy. Note that there is a conflict caused by SLF4J binding in both Grails core as well as S3 wagon. The easiest way out is to exclude the library from the wagon.

build ('org.kuali.maven.wagons:maven-s3-wagon:1.1.22') {
    export = false
    exclude 'slf4j-log4j12'

The plugin could be now published with standard release command:

grails maven-deploy --repository={repo-name}

Note that --repository parameter can be omitted if the desired target repository name is specified via grails.project.repos.default setting in BuildConfig.groovy.