GitHub Action to Setup Common Lisp for CI

This is a Github Action to setup Common Lisp, Roswell and Qlot.

It is useful to call it before running tests or building docs for your Common Lisp libraries. Action encapsulates all steps necessary to make available Roswell and Qlot inside the Github CI.

What this action does for you?

Implementation support

Most implementations are tested on Linux, but for some of them Windows and OSX are also should work.

Note, that for correct execution, your workflow should use lispsh -eo pipefail instead of default bash. This way a workflow will work Linux, OSX and Windows. You you will ignore this advice, you'll see such error when trying to call ros or qlot scripts:

/c/Users/runneradmin/.roswell/lisp/quicklisp/bin/qlot: line 4: exec: ros: not found
  Error: Process completed with exit code 127.

Implementation

Linux

OSX

Windows

abcl-bin

allegro

ccl-bin

clasp

clasp-bin

clisp

clisp-head

cmu-bin

ecl

mkcl

npt

sbcl

sbcl-bin

A typical usage

Here is how a minimal GitHub Workflow might look like:

name: 'CI'

on:
  push:
    branches:
      - 'main'
      - 'master'
  pull_request:

jobs:
  tests:
    runs-on: ubuntu-latest
    
    strategy:
      matrix:
        lisp:
          - sbcl-bin
          - ccl-bin
          
    env:
      LISP: ${{ matrix.lisp }}

    steps:
      - uses: actions/checkout@v4
      - uses: 40ants/setup-lisp@v4
        with:
          asdf-system: cl-info
      - uses: 40ants/run-tests@v2
        with:
          asdf-system: cl-info

The part, corresponding to an action call is:

- uses: 40ants/setup-lisp@v4
  with:
    asdf-system: cl-info

If you remove with part, then action will skip the ASDF system installation.

Also, pay attention to the env section of the workflow. If you don't set up a LISP env variable, action will set default lisp implementation to sbcl:

env:
  LISP: ${{ matrix.lisp }}

The last step in this workflow runs tests for the specified ASDF system. It is documented here.

Overriding Roswell version

By default this action will install the latest version of Roswell known to be working with this action. However, should you need to use a different version instead, you can specify that via the roswell-version argument:

- uses: 40ants/setup-lisp@v4
  with:
    roswell-version: v21.10.14.111

Overriding ASDF version

By default this action will install the latest version of ASDF known to be working with this action. However, should you need to use a different version instead, you can specify that via the asdf-version argument:

- uses: 40ants/setup-lisp@v4
  with:
    asdf-version: 3.3.5.3

Overriding Qlot version

By default this action will install the latest version of Qlot known to be working with this action. However, should you need to use a different version instead, you can specify that via the qlot-version argument:

- uses: 40ants/setup-lisp@v4
  with:
    qlot-version: 0.11.5

Overriding qlfile

Sometimes you might want to generate content of qlfile depending on matrix parameters. For example with matrix like this one:

matrix:
  os:
    - ubuntu-latest
    - macos-latest
    - windows-latest
  quicklisp-dist:
    - quicklisp
    - ultralisp
  lisp:
    - sbcl-bin
    - ccl-bin
    - ecl

you might want to add an ultralisp source to the qlfile. Here is how this can be archived:

env:
  LISP: ${{ matrix.lisp }}
  OS: ${{ matrix.os }}
  QUICKLISP_DIST: ${{ matrix.quicklisp-dist }}

steps:
  - uses: actions/checkout@v4
  - uses: 40ants/setup-lisp@v4
    with:
      asdf-system: cl-info
      qlfile-template: |
        {% ifequal quicklisp_dist "ultralisp" %}
        dist ultralisp http://dist.ultralisp.org
        {% endifequal %}

Here we see a few important things.

  1. We put into the env var the type of the quicklisp distribution we want to our library to test against.

  2. We pass a multiline argument qlfile-template to the action.

  3. Template refers to quicklisp_dist to conditionally include a line into qlfile when quicklisp_dist == "ultralisp".

You can refer any environment variable inside the qlfile templater. Also note, it is using Djula markup, similar to Django and Jinja2.

Caching

Usually installing Roswell, a lisp implementation and dependencies take from 2 to 10 minutes. Multiply this to the number of matrix combinations and you'll get signifficant time.

Starting from version 4.0.0, this action cares about caching itself and you don't need to wrap it with actions/cache. This behaviour of enabled by default. Without cache action could be executed about 4 minutes, and with cache it runs only 20 seconds on Ubuntu or 1 minute on Windows.

A new input variable cache was added to control caching beheviour. It is true by default, but you can switch it to false to turn caching off.

The current month is used as part of the cache key, to refresh caches every month. This way a new Roswell, Qlot and ASDF will be used in a build. Also, you can set env.cache-name variable to some value, to force rebuild with a fresh cache.

Roadmap

Contribution

If you want to contribute to this system, join development at GitHub:

https://github.com/40ants/setup-lisp