To create a Github action, we simply need to create a directory in the top-level of the repo called .github/workflows, and place a YAML file there describing our workflow. For this example, we'll be using a workflow called build-flash-and-run-simple.yml which demonstrates how to set up a simple, straightforward CI pipeline.
name:Simple pipeline to build firmware, flash DUT, and run testson:[push]env:LAGER_GATEWAY:helpful-horsejobs:build_flash_and_run:runs-on:ubuntu-lateststeps:-uses:actions/checkout@v2with:submodules:'recursive'-name:Builduses:docker://lagerdata/devenv-cortexm@sha256:2742d3fc1d3794d84afbe5aee79a1854a9079a2468d26d083f5d67c98435db3awith:entrypoint:/usr/local/bin/lagerargs:exec make-name:Connect to debuggeruses:docker://lagerdata/lager-cli:v0.1.51env:LAGER_SECRET_TOKEN:${{ secrets.AKBAR_SECRET_TOKEN }}with:entrypoint:/usr/local/bin/lagerargs:connect --device nrf52 --force-name:Flash and runuses:docker://lagerdata/lager-cli:v0.1.51env:LAGER_SECRET_TOKEN:${{ secrets.AKBAR_SECRET_TOKEN }}with:entrypoint:/usr/local/bin/lagerargs:testrun --serial-device /dev/ttyACM0 --hexfile _build/unit-tests/test-suites/test-example/test-example.hex
Up top we have the name of the workflow which will be displayed in Github's UI, the events that should trigger it (in this example, a push to the repo), and finally some global environment variables we want to set. In this case we set LAGER_GATEWAY to the value helpful-horse. This will be used by the lager-cli tool to determine which of your gateways to talk to. If you only have one you can omit this variable.
Next we have our jobs definition. In this case we have a single job with four steps. More sophisticated workflows can have multiple jobs which run in parallel and/or have ordering dependencies upon each other, but in this case we want to keep it as simple as possible so we just combine everything into one job with four steps that run serially.
The steps:
Check out the code. We use the built-in checkout@v2 action, and recursively check out submodules to make sure we get all dependencies
Build the image. For this step, we are using a public docker image called lagerdata/devenv-cortexm. We specify the exact SHA-256 hash because we want to ensure that whenever this workflow runs, it uses a consistent image. If we'd simply said docker://lagerdata/devenv-cortexm, then we would always get the latest version of the image, which would not necessarily be compatible with this particular commit in the future (imagine if a future version of the image contains an incompatible compiler). In general your CI pipeline should always specify the exact version of each tool to enable consistent repeatable builds..
Connect to the debugger. For this step we're using the lagerdata/lager-cli docker image. This is a minimal image that only contains the lager-cli tool. In this step we're setting an environment variable LAGER_SECRET_TOKEN to the value of secrets.AKBAR_SECRET_TOKEN, which is a repo-level secret. We're using a repo secret since storing secrets directly in your source control is considered a bad practice - it would mean anyone with access to your repo would be able to view your secrets. For help setting up Github repo secrets for use with Lager, see our docs The lager-cli tool will use this secret to authenticate with Lager's API before attempting to talk to the gateway.
Finally, flash the DUT and run it, and read serial output from /dev/ttyACM0, which is the USB serial interface for the dev board. This will flash the board with the output of the build step - _build/unit-tests/test-suites/test-example/test-example.hex - and run it. Assuming everything went well, you'll see output that looks something like this: