Skip to content
Open
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,21 @@ Continuous Integration is a practice of validating the features integrated into

For that, you will need to perform at least these steps:

• **Git flow** - Rules to handle branches in a git repository.

• **Automatic compliance**  - Check if the project is still compiling before merging a feature.

• **Code quality** - Check if there are vulnerabilities in the code.
- **Git flow** - Rules to handle branches in a git repository.
- **Automatic compliance**  - Check if the project is still compiling before merging a feature.
- **Code quality** - Check if there are vulnerabilities in the code.

So, to complete these steps, we will use the following tools:

• **GitHub Actions** - It kicks off a compilation and static code analysis on the cloud. It allows us to run build scripts on every commit or pull request to make sure everything still works with the new changes inserted. ([https://docs.github.com/en/actions](https://docs.github.com/en/actions))

• **Docker** - The Linux container will compile the project and run static analysis in the code. ([https://www.docker.com/](https://www.docker.com/))

• **Cpp Check** - Perform the static analysis of the code and generate a log from it. ([https://cppcheck.sourceforge.io/](https://cppcheck.sourceforge.io/))
- **GitHub Actions** - It kicks off a compilation and static code analysis on the cloud. It allows us to run build scripts on every commit or pull request to make sure everything still works with the new changes inserted. ([https://docs.github.com/en/actions](https://docs.github.com/en/actions))
- **Docker** - The Linux container will compile the project and run static analysis in the code. ([https://www.docker.com/](https://www.docker.com/))
- **Cpp Check** - Perform the static analysis of the code and generate a log from it. ([https://cppcheck.sourceforge.io/](https://cppcheck.sourceforge.io/))

# Project creation

## Board and IDE

To give you an example of how to set up a continuous integration pipeline in a firmware project, I will use the [Silicon Labs Thunderboard Sense Board](https://www.silabs.com/development-tools/thunderboard/thunderboard-sense-two-kit?tab=overview) to run a simple project on [Simplicity Studio IDE](https://www.silabs.com/developers/simplicity-studio) that we will use to build and perform static analysis.
This tutorial is specific to the Simplicity Studio build system, but the general approach should apply to other build systems. I will use the [Silicon Labs Thunderboard Sense Board](https://www.silabs.com/development-tools/thunderboard/thunderboard-sense-two-kit?tab=overview) to run a simple project on [Simplicity Studio IDE](https://www.silabs.com/developers/simplicity-studio) that we will use to build and perform static analysis.

![Thunderboard](/img/setup-a-ci-pipeline-using-github-actions-and-docker/0-thunderboard.png)

Expand Down Expand Up @@ -81,33 +77,31 @@ If you are running it on Linux, you can go directly to the terminal, but if you
make -f empty.Makefile
```

You, at this point, can compile the project at your local machine using the terminal.

![Makefiles](/img/setup-a-ci-pipeline-using-github-actions-and-docker/9-compile.png)
Now the project can be built from the terminal, which is necessary for building in CI.

# Test the compilation on a Docker Container

We will use a docker image with Simplicity Studio to build our project on a container. This will allow us to configure GitHub Actions to use the docker image to do the same.
We will use a docker image based on Ubuntu 18.04 with [Simplicity Studio v5](https://www.silabs.com/documents/login/software/SimplicityStudio-5.tgz) and the necessary [SDKs](https://github.com/SiliconLabs/gecko_sdk) installed to build our project on a container. It will allow us to configure GitHub Actions to use the docker image to do the same.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's include the Dockerfile source with an explanation of what goes into the image- that's a crucial part of this setup and deserves a detailed explanation!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. The Docker image is also 6GB. Would love to understand more about what's in there and what we're tell ing people they need to put in their GitHub Action CI image.

Would also be a good chance to update the Docker file to adhere to best practices

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, but I was trying to provide the readers a "ready to build" docker image. So they can run and build the example in minutes. The image consists of a ubuntu image with Simplicity Studio and the SDKs installed. I had to install Simplicity Studio on an Ubuntu Machine and copy the installation contents to the container to generate the image. So this is not the focus of the article. But I can try to create a docker file for it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, Simplicity Studio requires login 😕 always a bit tedious when vendors do that for free toolchains.

I'd still like to have the Dockerfile detailed here; providing a pre-built one is great if someone wants to try it, but the heart of the article is about setting up such a system, rather than the actual result (eg, if someone's not using Simplicity Studio, having the Dockerfile reference is much more valuable than the pre-built image, IMO).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, understood. I will do it.

So let's pull the image to our computer:

```powershell
```bash
docker pull leoribg/simplicity-studio-5:latest
```

Start the container from the image:

```powershell
```bash
docker run -t -d leoribg/simplicity-studio-5
```

Copy the project files to the container:

```powershell
```bash
docker cp C:\Users\leonardo\SimplicityStudio\v5_workspace\empty 1027ffa9c954:/project
```

Compile the project and make a static code analysis:
Compile the project and run the `cppcheck` static code analysis tool:

```bash
cd /project/
Expand All @@ -120,16 +114,15 @@ cppcheck . --output-file=cpplog.txt
Since the project was created, let's create a git repository.

For this tutorial, this is the repository I've used for my project:
[https://github.com/leoribg/memfault-empty-example](https://github.com/leoribg/memfault-empty-example)


To start and add your project to a git repository, run the following commands on your project directory:
[To start and add your project to a git repository](https://docs.github.com/en/get-started/quickstart/create-a-repo), run the following commands on your project directory:

```bash
git init
git add .
git commit -m "first commit"
git remote add origin [email protected]:"user"/"repository".git
git remote add origin [email protected]:leoribg/memfault-empty-example.git
git push -u origin master
```

Expand All @@ -147,15 +140,71 @@ Choose the right template:

This tutorial will use a single workflow to execute our jobs. So, it will only have a single .yml file.

The .yml file starts like this, we will modify it.
The c-cpp.yml file starts like this, we will modify it.

```yaml
name: C/C++ CI

on: #These are the trigger that will run our jobs
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

jobs: #Jobs are set of steps that will execute our tasks
build:

![Cpp Workflow](/img/setup-a-ci-pipeline-using-github-actions-and-docker/12-cpp-workflow.png)
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: configure
run: ./configure
- name: make
run: make
- name: make check
run: make check
- name: make distcheck
run: make distcheck
```

Let's modify the content of our .yml file to execute the build and the static analysis of the project.

We will indicate the Docker Image we use to execute the workflow's steps. After we will build the project, upload the image as an artifact. Finally, we will make a static analysis in the code and upload the artifact with the results.

![Cpp Editing](/img/setup-a-ci-pipeline-using-github-actions-and-docker/13-cpp-editing.png)
```yaml
name: C/C++ CI

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

jobs:
build:

runs-on: ubuntu-latest
container:
image: leoribg/simplicity-studio-5:latest #Docker Image

steps:
- uses: actions/checkout@v3
- name: make #Build
run: make -f empty.Makefile
- name: binary artifact #Upload the image artifact
uses: actions/upload-artifact@v3
with:
name: empty.s37
path: ./build/debug/empty.s37
- name: static analisys #Lint
run: cppcheck . --output-file=cpplog.txt
- name: lint artifact #Upload the lint artifact
uses: actions/upload-artifact@v3
with:
name: lint_output.txt
path: ./cpplog.txt
```

# Trigger our GitHub Action

Expand Down