Showing tags on posts

|

After adding a Categories page I wanted to add tag-handling to the blog. I wanted to display the tags assigned to each post under the title.

Using the same principles as for categories and adapting some CSS from Codinfox, I have achieved that. Each tag name is a link to the relevant section of the Tags page.

Like categories, tags are specified for a post in the front matter, as for this post:

---
layout: post
title: Showing tags on posts
categories: tech
tags: blog
---

Adding a categories page to this blog

|

I succeeded in adding a Categories page to this blog.

Jekyll supports specification of variables category, categories and tags in the front matter of blog posts but it is left as an Exercise for the Reader™ to do anything with them. The Lanyon theme does not itself include page with category or tag lists (but of course is infinitely expandable).

So I created a contents page by adapting this technique with my own amateur CSS applied. The page is contents.html in the root directory of the site and has front matter:

---
layout: page
title: Categories
---

The Lanyon sidebar automatically creates links to any pages with layout: page in the front matter so the Categories page is easily found.

Welcome (back) to my relative ignorance

|

I have resuscitated a blog after about 10 years’ absence. As in that previous life, it is called Relatively Ignorant and contains bits and pieces of things I have observed at work and elsewhere.

This incarnation is hosted at GitHub and is produced using Jekyll with the Lanyon theme. Thanks to my ThoughtWorks colleague Matt Newman for providing a model of the simple kind of blog I wanted.

It also uses HTTPS exclusively so I feel all grown up now.

Gradle build file organisation and reuse

|

Some ideas on how to organise and reuse Gradle build files in a multi-project build.

Introduction

Our project was to create a set of related microservices in Java using Spring Boot, built as a set of Gradle projects all under a single root project.

We wanted to reuse Gradle build scripts as much as possible and reduce the amount of copy-and-paste between service projects.

General layout

(root)
  |
  +- build.gradle
  +- settings.gradle
  +- gradle/
  |    +- code-standards.gradle
  |    +- idea.gradle
  |    +- package.gradle
  |    +- spring-actuator-info.gradle
  |    +- spring-boot.gradle
  |    +- spring-rest-docs.gradle
  |
  +-- microservice-a/
  |     +- build.gradle
  |     +- gradle.properties
  |     +- src/
  |
  +-- microservice-b/
        +- build.gradle
        +- gradle.properties
        +- src/

Gradle scripts

Project root

The project root contains settings.gradle with:

rootProject.name = 'api-microservices'

include 'microservice-a', 'microservice-b'

There can only be one settings.gradle file and it must be in the root directory.

The root build.gradle contains information in common with all projects:

// Common build versions for Spring Boot, Cloud and Prometheus, and Boot plugin.
buildscript {
    ext {
        springBootVersion = '1.5.4.RELEASE'
        springCloudVersion = 'Dalston.SR1'
        springMetricsVersion = '0.5.1.RELEASE'
        prometheusVersion = '0.0.23'
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

// External plugins cannot be declared in an external build script but will be available to
// all child projects.
plugins {
    id 'org.asciidoctor.convert' version '1.5.3'
    // Plugin to generate git.properties on the classpath that will be included
    // in the Actuator info response.
    id 'com.gorylenko.gradle-git-properties' version '1.4.17'
}

group 'com.example'

// These things are applied to all projects.
allprojects {

    apply plugin: 'java'
    sourceCompatibility = 1.8

    repositories {
        maven {
            // Search local repo first.
            url 'http://repo.example.com/public-remote-virtual'
            mavenCentral()
        }
    }
}

If you don’t want all your services to use the same version of Spring Boot (etc.) you will need a different configuration.

Service projects

The build.gradle for each service project is now simplified to start with:

apply from: '../gradle/spring-boot.gradle'
apply from: '../gradle/idea.gradle'
apply from: '../gradle/code-standards.gradle'
apply from: '../gradle/spring-rest-docs.gradle'
apply from: '../gradle/spring-actuator-info.gradle'
apply from: '../gradle/package.gradle'

Other, project-specific declarations follow. For example, to use Redis:

dependencies {
    compile('org.springframework.boot:spring-boot-starter-data-redis')
}

Each project contains a gradle.properties file containing the current version of the service. It is separate from build.gradle so it can be read and written by the Gradle Release Plugin.

Common, reusable scripts

Here is a brief description of the reusable scripts that we created.

File Description
spring-boot.gradle Apply Spring Boot plugin and specify Spring and other dependencies for all projects.
idea.gradle Apply and configure the IntelliJ IDEA plugin.
code-standards.gradle Apply and configure Checkstyle and Jacoco plugins.
spring-rest-docs.gradle Apply and configure the AsciiDoctor plugin; also include the generated doc in the assembled JAR.
spring-actuator-info.gradle Apply and configure the Gradle Git Properties plugin; Specify that Spring Boot generates build-info.properties that will returned by the Actuator info endpoint.
package.gradle Apply and configure the Gradle Linux Packaging plugin to package the service as an RPM.

Postscript

We also used the Gradle Release Plugin but I was not able (in the time available) to get it to work from an external script using apply from. This meant that each service build script contained the same big block of code (not shown here).

Perhaps I will solve that one in the future.