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:

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, found in the .semaphore directory:

  • Continuous Integration
    • Install dependencies, using a cache for faster builds.
    • Run the unit tests.
    • Package the app as a single, standalone jar file.
  • Continuous Deployment
    • Prepare files for deployment.

CI+CD

Continuous Integration Pipeline

If you are new to Semaphore, be sure to read the guided tour and the linked pages for more information.

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 preinstalled. 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 uberjar 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 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 autopromoteon 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 some 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

No better way of learning about Semaphore than by using it. Here is how you can run the demo:

  1. Fork the repository on GitHub.
  2. Clone the repository on your local machine.
  3. In Semaphore, follow the link on the sidebar to create a new project.
  4. Edit any file and push a commit to the repository. 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

Still need help? Contact Us Contact Us