03 February 2014

Tags: github jbake gradle asciidoctor blog

A few weeks ago, I started this new blog and decided to host it on GitHub. I already explained how I migrated contents from JRoller, but I didn’t really the tool behind publishing. In this post, I will show you how easy it is, now that I have improved my toolchain with Gradle!

JBake

JBake is a static site generator. When I chose this tool for my blog, what attracted me is actually that it runs on the JVM, so I already had the idea of automating stuff with Gradle.

Since then, I have submitted several pull requests to the project, and we’re actually thinking of using it to build the next Groovy website. JBake has good chances to become the "Jekyll of the JVM" and already supports multiple markup languages (markdown, asciidoc) as well as multiple template engines (FreeMarker in 2.2.1, Groovy and Thymeleaf in 2.3.0).

The idea behind JBake is very simple: contents is written using a markup language and "baked" with template engines into actual HTML. Everything is generated statically and you can upload the generated site wherever you want.

On the other side, GitHub offers a nice tool to publish pages: GitHub Pages, so we can have both the sources of our blog and the output of bakery in the same repository. So the initial process looked like this:

  1. create a new page in content directory

  2. run jbake command, check the result, eventually make changes

  3. git add page.adoc to add the new page to the sources

  4. git commit -a to commit the page to the master branch, corresponding to the sources of the blog

  5. git checkout gh-pages to switch to the GitHub pages branch

  6. cp -R output/* . to copy the contents of the output directory at the root of the GitHub pages

  7. git add page.html to add the new page to the GitHub pages branch

  8. git commit -a to commit the contents to GitHub pages

  9. git push origin master to push the sources to GitHub

  10. git push origin gh-pages to push the generated pages to GitHub pages

I published my first blog posts like this, and it’s not that complicated, but it involves a lot of manual steps, so I came up with a Gradle plugin to make this much easier, that is, focusing on contents, period!

Gradle to the rescue!

Prerequisites

We’re going to setup a project that will allow you to publish to GitHub pages in one step, using Gradle. For that, we will need:

Building JBake

This step will become optional when JBake 2.3.0 will be out (or a snapshot of JBake will be published). Meanwhile, you need to install a local version of JBake into your local Maven repository. Don’t worry, this will be easy, you will only need Maven (hey, too bad JBake doesn’t use Gradle ;)):

git clone https://github.com/jbake-org/jbake.git
cd jbake
mvn install

That’s all!

Setting up a project

First step consists in creating the initial project layout:

git init                                                            (1)
git remote add origin <your github remote url>                      (2)
mkdir -p src/jbake                                                  (3)
gradle init                                                         (4)
git add build.gradle gradle gradlew gradlew.bat settings.gradle src (5)
cd src/jbake
jbake -i                                                            (6)
1 initializes the git repository
2 add your remote
3 we will put JBake sources into that directory
4 installs the Gradle wrapper into the repository
5 adds Gradle wrapper and initial structure into Git
6 initializes the default JBake directory layout

Using Gradle to render pages

At this point, your src/jbake directory contains the classic JBake folder contents:

src
 |-- jbake
       |-- assets    : static assets (images, css, ...)
       |-- content   : blog posts, ...
       |-- templates : HTML templates (by default, uses FreeMarker)

Replace the contents of build.gradle with the following:

build.gradle
buildscript {
  repositories {
      mavenLocal() // needed to use the local JBake 2.3.0 build
      jcenter()
  }

  dependencies {
    classpath 'me.champeau.gradle:jbake-gradle-plugin:0.1-SNAPSHOT' (1)
    classpath 'org.asciidoctor:asciidoctor-java-integration:0.1.4'  (2)
    classpath 'org.freemarker:freemarker:2.3.19'                    (3)
  }
}

apply plugin: 'jbake'                                               (4)
1 import the JBake plugin
2 if you write pages using the Asciidoctor format, this is necessary
3 if you use the Freemarker template engine, this is necessary
4 then apply the plugin

By default, the plugin will look for JBake sources in src/jbake and generate the site into build/jbake.

Generating the output

Now that this is applied, you can generate the site by running the following command:

./gradlew -i jbake

after the rendering step, you should now have a new directory:

build
  |-- jbake

into which you will find the generated HTML contents. At this point, you could choose to upload those files to an FTP server, for example, but since we want to host our pages on GitHub, we need to add some configuration to our build.

Publishing to GitHub Pages

Create a new file named publish.gradle with the following contents:

publish.gradle
buildscript {
  repositories {
      jcenter()
  }

  dependencies {
    classpath 'org.ajoberstar:gradle-git:0.6.3'     (1)
  }
}

apply plugin: 'github-pages'                        (2)

githubPages {
  repoUri = 'git@github.com:youtname/blog.git'      (3)
  pages {
     from(file('build/jbake')) {
     	into '.'                                    (4)
     }
  }
}
1 use the gradle-git plugin
2 apply the plugin
3 configure your GitHub repository URL
4 tells the plugin to upload the contents of the build/jbake directory

Then modify the main build.gradle file by adding the following task:

task publish(type: GradleBuild) {           (1)
    buildFile = 'publish.gradle'
    tasks = ['publishGhPages']
}
1 we’re using a separate, sub-build to avoid a classpath issue with JNA

Now if you do:

./gradlew publish

Gradle will pick the contents of the output/jbake directory, add it to the gh-pages branch and push it to GitHub, all in one step! A few seconds later, you should see the result on github.io!

One last thing: this configuration does not add the sources to your git repository. It only deals with the output, so you still need to add the source files, commit them and push them to GitHub. This is of course optional if you don’t want to publish the sources…​ If you decide to make them public, then you can also use the git plugin to do it automatically!

Conclusion

In this post, we’ve shown you how you can leverage JBake and Gradle to publish a blog on GitHub. The setup is really easy, so I hope more people will follow that way and contribute to Open Source too!

Of course, this post has been published using the procedure described on this page, so I used JBake and Gradle to blog about how to publish a blog on GitHub using JBake and Gradle! Like my friend Andres Almiray would say, that’s a toolception!