GitHub Actions is a free tool provided by GitHub for software automation. It enables you to run a command on a virtual machine in response to changes to a repository, like a new commit. It’s an ideal candidate for automated testing, or continuous integration, for your Lua modules or projects.
By setting up automated testing you can ensure that any contributors to your project have their changes verified against your test suite as well. All pull-request will be utilizes your testing workflow.
In this example I'm going to be using busted as my test suite runner, but you can use pretty much anything: it’s easy to run any shell command.
We'll be using the following two GitHub Actions:
Feeling kind? Star the two projects above to help other people find out how to run Lua in their GitHub Actions workflows
Before getting started
Before setting up GitHub Actions you'll want to make sure you have a test suite
that runs successfully on your computer. Additionally, if you're developing a
Lua module for LuaRocks, then you'll want to have a .rockspec
file that lists
all your project’s dependencies and build process.
Even if you aren’t planning on publishing your code as a module, you can still use a rockspec to declare your dependencies to make it easy to install them during testing
Sicne I'm using busted, I use the following command to run my all of my tests:
$ busted
Optional: I have a rockspec file named something like
myproject-dev-1.rockspec
that is checked into my repository. I recommend
checking in a dev rockspec that can install your module by source from the
repository. It might look something like this:
Show rockspec with dependencies example…
package = "myproject"
version = "dev-1"
source = {
url = "git://github.com/leafo/myproject.git",
}
description = {
summary = "Do something fancy",
homepage = "https://leafo.net",
license = "MIT"
}
dependencies = {
"lua >= 5.1",
"lpeg",
"luasocket",
"lua-cjson",
}
build = {
type = "builtin",
modules = {
["myproject"] = "myproject/init.lua"
}
}
Configuring the Actions workflow
A workflow represents a collection of jobs you have created with GitHub Actions. A job is a list of shell commands & actions executed on a virtual machine. You can create a workflow with a specially named file in your repository.
For running a test suite on new commits we'll start by creating a new file in
our repository: .github/workflows/test.yml
The name
test.yml
can be anything you like. Additionally you can create multiple workflows by creating multiple files in that directory
Insert the following into .github/workflows/test.yml
to start out:
name: test
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: leafo/gh-actions-lua@v5
with:
luaVersion: "5.1"
- uses: leafo/gh-actions-luarocks@v2
- name: setup
run: |
luarocks install busted
- name: test
run: |
busted -o utfTerminal
Most of the lines in this file should be relatively self explanatory, but here’s a quick summary:
Detailed documentation for the workflow syntax can be found on GitHub: Workflow syntax for GitHub Actions
on
instructs the workflow to run for every push to the repository- We declare a job called
test
steps
lists everything that will happen to complete the job (each step is executed in order)- The
actions/checkout@master
action is used to checkout the code in our repository (This action is authored by GitHub) - The
leafo/gh-actions-lua@v5
action will build and install Lua into the current environment- In this example we specify ask for Lua 5.1, examples with more Lua versions are shown below
- The
leafo/gh-actions-luarocks@v2
action will build and install LuaRocks, this must come after the Lua installation - We issue a command called
setup
that will installbusted
for use in the rest of our action - We issue a command called
test
that runsbusted
in the working directory (with color enabled!)
In this example we included a version number (eg. @v5) with each action, it may be necessary to update these versions number in the future. Generally you should specify a version number so prevent unexpected failures happening when an action’s source code is updated.
Head to Running the action/workflow to see how to run the workflow (hint: you just commit and push), or scroll down to see some ways to customize the workflow.
Installing dependencies with LuaRocks
The simplest way to install dependencies is to list them in the workflow file
within the test job in a setup step. The gh-actions-luarocks
action will
automatically configure LuaRocks to install for the current version of Lua your
test is running for.
Here’s how you would edit .github/workflows/test.yml
to add a few more
dependencies:
- name: setup
run: |
luarocks install busted
+ luarocks install moonscript
+ luarocks install luaossl
luarocks make
See full YAML example…
name: test
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: leafo/gh-actions-lua@v5
with:
luaVersion: "5.1"
- uses: leafo/gh-actions-luarocks@v2
- name: setup
run: |
luarocks install busted
luarocks install moonscript
luarocks install luaossl
- name: test
run: |
busted -o utfTerminal
If you have a rockspec in your repository’s root folder you can use LuaRocks to
automatically install the dependencies with the make
command. (This has the
side effect of also building your module)
If you have multiple rockspecs you will need to explicitly specify one like this:
luarocks make myrockspec-dev-1.rockspec
In our example rockspec we have the following dependencies declared:
-- myproject-dev-1.rockspec
dependencies = {
"lua >= 5.1",
"lpeg",
"luasocket",
"lua-cjson",
}
Modified the setup
step to look like this:
- name: setup
run: |
+ luarocks make
luarocks install busted
See full YAML example…
name: test
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: leafo/gh-actions-lua@v5
with:
luaVersion: "5.1"
- uses: leafo/gh-actions-luarocks@v2
- name: setup
run: |
luarocks make
luarocks install busted
- name: test
run: |
busted -o utfTerminal
luarocks make
will use the rockspec located in your repository root
directory, and install the dependencies specified. If anything fails to install
then the job will fail.
busted
is still installed manually because it’s not listed in the rockspec since it’s a a test dependency, and not a runtime dependency.
Testing multiple versions of Lua with a matrix
Testing code that is designed to run on multiple versions of Lua is easily accomplished by listing out the versions you want to test in a variable matrix.
Make the following change to .github/workflows/test.yml
:
jobs:
test:
+ strategy:
+ fail-fast: false
+ matrix:
+ luaVersion: ["5.1", "5.2", "5.3", "luajit"]
+
runs-on: ubuntu-latest
steps:
- uses: leafo/gh-actions-lua@v5
with:
- luaVersion: "5.1"
+ luaVersion: ${{ matrix.luaVersion }}
- uses: leafo/gh-actions-luarocks@v2
See full YAML example…
name: test
on: [push]
jobs:
test:
strategy:
fail-fast: false
matrix:
luaVersion: ["5.1", "5.2", "5.3", "luajit"]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: leafo/gh-actions-lua@v5
with:
luaVersion: ${{ matrix.luaVersion }}
- uses: leafo/gh-actions-luarocks@v2
- name: build
run: |
luarocks install busted
- name: test
run: |
busted -o utfTerminal
With this change, on push the workflow will run 4 instances of the test
job
for each version of Lua specified. You can see what versions are available on
the gh-actions-lua
documentation.
Although not necessary, the
fail-fast: false
option will let all versions run to completion, even if one of them fails early. You can see multiple failures and successes for every push, which can make it a lot easier to debug build issues.
Running the action/workflow
Commit .github/workflows/test.yml
and push it to your repository and GitHub
will automatically start running your workflow on every push. If any of the
steps in your job fail, GitHub will report the commit as failed. Any merge
requests will also automatically be passed through the workflow to verify
changes.
If it doesn’t automatically run, check your repository Settings > Actions and enable it there.
Add a status badge to your repository
GitHub provides easy embeddable image to share the status of your build on your site or readme:

You can generate the code for these directory by heading to your repository’s actions page and selecting the workflow you want.
Example from one of my projects:
I hope that helps you get started with GitHub Actions and Lua!