There is a new building automation tool in the neighborhood named Earthly. Its intention is to simplify CI pipelines. Nothing like an image to explain it better:

EarthlyIntegrationDiagram

I would describe it as a docker multistage build with batteries. It actually has a Docker-like syntax.

These are some features right from their repo:

🐳 Build anything via containers - build container images or standalone artifacts (eg binaries, packages, arbitrary files)

🛠 Programming language agnostic - allows use of language-specific build tooling

♻️ Reproducible builds - does not depend on user’s local installation. Runs the same locally, as in CI

Parallelism that just works - builds in parallel without special considerations the user has to make

🏠 Mono-repo friendly - ability to split the build definitions across a vast directory hierarchy

🏘 Multi-repo friendly - ability to import builds or artifacts from other repositories

Building something with Earthly

Some days ago while taking a look at Quarkus I found Funqy, part of Quarkus’s serverless strategy that aims to provide a portable Java API to write functions deployable to various FaaS environments like AWS Lambda, Azure Functions, Knative, and Knative Events (Cloud Events). So I decided to see how easy would it be to build a simple “Hello World” with Funqy and Earthly.

I’m not going to focus on the Funqy part since I simply followed their guide. I wanted to know how complicated it would be to define a build.earth file that allowed me to test and build a native quarkus application. This was the result:

FROM quay.io/quarkus/centos-quarkus-maven:20.1.0-java11

WORKDIR /java-example

deps:
    COPY pom.xml ./
    RUN mvn -B de.qaware.maven:go-offline-maven-plugin:1.2.5:resolve-dependencies
    SAVE IMAGE

build:
    FROM +deps
    COPY src src
    RUN mvn -Pnative clean package
    SAVE ARTIFACT target/ /target AS LOCAL target

With that file, I am creating a reproducible build that will create a target folder with my artifacts.

As said before, it is very similar to Dockerfile syntax. Apart from just a few new intuitive commands, if you know Docker you will get comfortable with Earthly really fast.

Describing build.earth

base

This section initializes the build environment, it is like a base for all other steps, it applies to all “targets”.

(1) Base Docker image

(2) Setting working directory

(1) FROM quay.io/quarkus/centos-quarkus-maven:20.1.0-java11
(2) WORKDIR /java-example

deps

This section gathers all my project’s dependencies.

(3) Target’s name

(4) Copy the pom.xml to allow earthly to create a layer/cache of the dependencies of my application.

(5) Runs maven and download all my application dependencies.

(6) Saves this container as an image. This allows the following steps/targets to use all the hard work done by these commands.

(3) deps:
    (4) COPY pom.xml ./
    (5) RUN mvn -B de.qaware.maven:go-offline-maven-plugin:1.2.5:resolve-dependencies
    (6) SAVE IMAGE

build

This section actually builds my artifact.

(7) Target’s name

(8) Defines that this target is built from deps target. There is a dependency.

(9) Copy all my source code into the container.

(10) Maven command to execute all my tests and build my artifact.

(11) Saves output into my machine on a target folder.

(7) build:
    (8) FROM +deps
    (9) COPY src src
    (10) RUN mvn -Pnative clean package
    (11) SAVE ARTIFACT target/ /target AS LOCAL target

Of course, this is a toy example. You can have earthly files way more complicated (even multi-repo projects). It was also really easy to integrate it into Github Actions. This is the repo for anyone who might want to take a deeper look Earthly Repository.