GitHub Actions and Conan

It’s always wise to use continuous integration (CI), even in our hobby projects. When working with C++, it might be painful to install the required dependencies, even for the most essential packages like the googletest for the unit tests or the spdlog for the logger. In those cases, using Conan package manager is a no brainer. But how we can apply a similar approach when we want to use it in CI?

This time we assume that we want to use GitHub Actions. It is actually easy to do it. On your code repository page, there are various tabs, and one of those is called Actions. If it is a C++ project, one of the suggested workflows is the CMake based projects. By accepting that, it creates a cmake.yml inside a hidden folder .github/workflows/ in your repository.

The first vanilla version will look like that:

name: CMake

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

env:
  # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
  BUILD_TYPE: Release

jobs:
  build:
    # The CMake configure and build commands are platform agnostic and should work equally
    # well on Windows or Mac.  You can convert this to a matrix build if you need
    # cross-platform coverage.
    # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2

    - name: Configure CMake
      # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
      # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
      run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}

    - name: Build
      # Build your program with the given configuration
      run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}

    - name: Test
      working-directory: ${{github.workspace}}/build
      # Execute tests defined by the CMake configuration.  
      # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
      run: ctest -C ${{env.BUILD_TYPE}}

Hmm, and now how we are going to use Conan. Well, there are four steps that we need to do, assuming that our repository already using Conan, so there is already the corresponding conanfile.txt, for example, something like that:

[requires]
spdlog/1.9.2

[generators]
cmake

The steps are:

  • Install Conan
  • Create the default profile
  • Update the profile regarding the compiler settings, and
  • Install the libraries as described in the conanfile.txt

Nice, show the new cmake.yml now…

name: CMake

on:
  push:
    branches: [ master ]
  
env:
  # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
  BUILD_TYPE: Debug

jobs:
  build:
    # The CMake configure and build commands are platform agnostic and should work equally
    # well on Windows or Mac.  You can convert this to a matrix build if you need
    # cross-platform coverage.
    # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    
    - name: Get Conan
      uses: turtlebrowser/get-conan@v1.0
      
    - name: Create default profile
      run: conan profile new default --detect
      
    - name: Update profile
      run: conan profile update settings.compiler.libcxx=libstdc++11 default
      
    - name: Install dependencies
      run: conan install . -s build_type=${{env.BUILD_TYPE}} --install-folder=${{github.workspace}}/build

    - name: Configure CMake
      # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
      # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
      run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}

    - name: Build
      # Build your program with the given configuration
      run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}

Have fun!