Deploying deb artifacts to Gemfury

In a previous post I explained how to package a service up into a deb package. Once your service is packaged up, it can be installed by provisioners like puppet. However we still need to publish the package. For open-source project there are plenty of PPA providers out there that will host your package for free, however occasionally it’s desirable to keep the debian artifacts private. Open-source PPA providers do not (by definition) allow private artifacts to be hosted with them, so typically you have to pay for such hosting.

For my own projects I have been using Gemfury to host the packages for about $5 per month. Gemfury provides a nice realtime dashboard (probably implemented with websockets) that enables you to manage deb packages. However as part of continuous integration, I needed a way to get my debian artifacts into Gemfury’s repository without manual intervention.

To this end I build a maven plugin ‘gemfury-maven-plugin’ which can be used as shown below to automatically deploy the debian artifacts to your repository.

<profiles>
    <profile>
        <id>release</id>
        <build>
            <!-- include sources -->
            <plugins>
                <plugin>
                    <groupId>uk.co.solong</groupId>
                    <artifactId>gemfury-maven-plugin</artifactId>
                    <version>0.0.7</version>
                    <executions>
                        <execution>
                            <id>execution1</id>
                            <phase>deploy</phase>
                            <configuration>
                                <gemfuryUrl>https://${secrettoken}@repo.fury.io/username/</gemfuryUrl>
                                <ignoreHttpsCertificateWarnings>true</ignoreHttpsCertificateWarnings>
                            </configuration>
                            <goals>
                                <goal>gemfury</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

We can see the maven plugin binds to the deploy phase while in release mode, which allows us to place the secrettoken in a separate document which we do not commit to source control.

Note that Gemfury use a cheap and nasty ssl provider and so the https certificates are not in the java certificate repository. To get around this, you can use the ignoreHttpsCertificateWarnings parameter, however we strongly recommend you install Gemfury’s certificate for production systems.

The plugin will retry 99 times in the event that Gemfury servers are unavailable - a situation which at the time of writing was quite frequent (1 in 5 deployment attempts required a retry).

You can then use puppet to provision your servers with that package by writing a manifest similar to this:

#services
apt::source { 'fury':
  location => 'https://sEcReTkEy@apt.fury.io/username/',
  release => ' ',
  repos => '/',
  allow_unsigned => true,
}

package { 'yourpackage':
  name     => 'yourpackage',
  ensure   => latest,
  require  => Apt::Source['fury'],
}