Clojure Luminus CI/CD#

In this guide, we will show you how to use Semaphore to implement continuous integration and deployment for a Clojure Luminus web application.

Demo project#

Semaphore maintains an example Clojure demo that you can use to get started:

The project is written for the Luminus web application framework, and is based on the guestbook sample app,

Overview of the pipelines#

The example project ships with CI and CD pipelines, which are found in the .semaphore directory:

  • the CI pipeline
    • installs dependencies using the cache for faster builds
    • runs unit tests
    • packages the app as a single standalone jar file
  • the CD pipeline
    • prepares files for deployment

CI+CD

Continuous integration pipeline#

If you are new to Semaphore, be sure to read the guided tour and the related pages for more information before starting with the example project.

version: v1.0
name: Clojure+Semaphore example
agent:
  machine:
    type: e1-standard-2
    os_image: ubuntu1804
blocks:
  - name: "Setup"
    task:
      prologue:
        commands:
          - checkout
          - cache restore lein-deps-$(checksum project.clj)
          - mv home/semaphore/.m2 ~/.m2 2>/dev/null || true
          - cache restore lein-$(checksum `which lein`)
          - mv home/semaphore/.lein ~/.lein 2>/dev/null || true
      jobs:
        - name: Dependencies
          commands:
            - lein with-profile +dev,+test,+uberjar deps
            - cache store lein-deps-$(checksum project.clj) ~/.m2
            - cache store lein-$(checksum `which lein`) ~/.lein
  - name: "Tests"
    task:
      prologue:
        commands:
          - checkout
          - cache restore lein-deps-$(checksum project.clj)
          - mv home/semaphore/.m2 ~/.m2
          - cache restore lein-$(checksum `which lein`)
          - mv home/semaphore/.lein ~/.lein 2>/dev/null || true
      jobs:
        - name: Clojure tests
          commands:
            - lein test
  - name: "Build"
    task:
      prologue:
        commands:
          - checkout
          - cache restore lein-deps-$(checksum project.clj)
          - mv home/semaphore/.m2 ~/.m2
          - cache restore lein-$(checksum `which lein`)
          - mv home/semaphore/.lein ~/.lein 2>/dev/null || true
      jobs:
        - name: Uberjar build
          commands:
            - lein uberjar
            - cache delete uberjar-latest
            - cache store uberjar-latest target/uberjar/guestbook.jar
promotions:
  - name: Production deploy
    pipeline_file: production-deploy.yml
    auto_promote_on:
      - result: passed

Semaphore's Ubuntu 18.04 Virtual Machine comes with leiningen pre-installed. lein automates Clojure projects and manages dependencies.

The CI pipeline is made of 3 blocks:

  • Setup: installs the project dependencies and stores them in the cache to speed up subsequent jobs.
  • Tests: runs the Luminus unit tests.
  • Build: uses Uber-JAR to generate a standalone package.

In order to reduce build times, each block includes a prologue that attempts to retrieve dependencies using Semaphore's cache utility. The prologue is run before each job in the block.

Promotion#

You can create complex workflows with promotions. A promotion can trigger the start of the next pipeline either manually or on user-defined conditions. The auto_promote_on keyword is used to automatically start the deployment pipeline once integration has completed successfully.

Continuous delivery pipeline#

version: v1.0
name: Deploy to production
agent:
  machine:
    type: e1-standard-2
    os_image: ubuntu1804
blocks:
  - name: Deploy
    task:
      prologue:
        commands:
          - cache restore uberjar-latest
      jobs:
        - name: Deploying
          commands:
            - echo 'Deploying to production!'
            - ls -la target/uberjar/

The CD pipeline has only one block. In truth, it doesn't deploy anywhere, but leaves the files set up so developers can quickly pick up and continue with the chosen deployment target.

Luminus automatically generates certain deployment files for your convenience:

  • Dockerfile: for building Docker images.
  • Procfile: for Heroku deployments.
  • Capstanfile: to run the app with the OSv unikernel.

For more details, consult the Luminus deployment manual.

Run the demo yourself#

There is no better way to learn how to use Semaphore than by using it. Here is how you can run the demo:

  1. Fork the repository on GitHub.
  2. Clone the repository to your local machine.
  3. In Semaphore, follow the link in the sidebar to create a new project.
  4. Edit any file and push a commit to the repository, and Semaphore will start the pipeline automatically.

Next steps#

Excellent work! You now have integration and delivery pipelines for your Clojure projects. The next step is implementing a deployment scenario. For further information, consult the following tutorials:

See Also#