首页 > 解决方案 > GitHub 持续集成 CMake/C++

问题描述

我正在尝试为托管在 GitHub上的私有存储库上的 cmake/c++ 项目设置 CI。

该项目依赖于许多应该被 git 克隆和构建的第三方库。后者需要一段时间,因此,我创建了一个安装了所有依赖项的 docker 映像,并将其托管在 docker hub 上。(理想情况下,我也希望 docker 映像是私有的,但如果不可能,我可以将其公开。)

我想实现以下目标:

在向主分支提出拉取请求时,应用程序会自动构建在 docker 容器上(因为所有依赖项都在那里),运行所有单元测试(gtest),如果一切正常,则将分支合并到主分支。

理想情况下,我希望查看 gcovr/lcov 生成的日志和统计信息。

操作系统:Ubuntu 18.04

我想知道这是否可以实现,因为我已经搜索了 2 天,但没有运气和十亿个可能的读数。

标签: c++gitdockercmakegithub-actions

解决方案


我对使用 docker 进行受控构建的 2 美分(更多评论)。
对于自动合并,我不知道,因为我会反对它,因为代码审查不能被 CI 替换,恕我直言......

看看https://github.com/Mizux/cmake-cpp

介绍

我使用 Makefile 进行编排(docker 命令可能太长;))和 docker 用于在各种发行版上进行隔离构建。

亲:

  • 能够在本地进行测试(只需要一个带有 Docker 和 Make 的 GNU/Linux 发行版)
  • 可以轻松迁移到各种 CI runner 提供商(Travis-CI、GitHub Workflow、gitlab-runner、bitbucket?)
  • 贡献者可以在发送 PR 之前进行本地测试

缺点:

  • 与 github 的耦合较少 -> 维护起来更复杂。
  • 工作流之间更难缓存

注意:Dockerfile 存储在存储库中,即我在第一步中重建了图像,但如果您的图像位于 docker hub 上(未测试)ci/docker,您应该可以通过简单的步骤替换此步骤docker load

设置

Dockerfile

我将 Dockerfile 分成几个阶段(主要用于调试)。

注意:您可以ubuntu:rolling用自己的图像替换...

ci/docker/ubuntu/Dockerfile:

# Create a virtual environment with all tools installed
# ref: https://hub.docker.com/_/ubuntu
FROM ubuntu:rolling AS env
LABEL maintainer="mizux.dev@gmail.com"
# Install system build dependencies
# note: here we use the CMake package provided by Ubuntu
# see: https://repology.org/project/cmake/versions
ENV PATH=/usr/local/bin:$PATH
RUN apt-get update -q && \
apt-get install -yq git build-essential cmake && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

CMD [ "/bin/sh" ]

# Add the library src to our build env
FROM env AS devel
# Create lib directory
WORKDIR /home/lib
# Bundle lib source
COPY . .

# Build in an other stage
FROM devel AS build
# CMake configure
RUN cmake -H. -Bbuild
# CMake build
RUN cmake --build build --target all
# CMake install
RUN cmake --build build --target install

# Create an install image to check cmake install config
FROM env AS install
# Copy lib from build to install
COPY --from=build /usr/local /usr/local/
# Copy  sample
WORKDIR /home/sample
COPY ci/sample .

跑步者职位

Github action runners 安装了 docker。

注意:每个 yml 文件可以有一个徽章。例如,您可以每个发行版使用一项作业,例如每个发行版有一项作业或一个文件Release和一个文件Debug...

.github/workflows/docker.yml:

name: C++ CI

on: [push, pull_request]

jobs:
  build-docker:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Build env image
      run: docker build --target=env --tag project:env -f ci/docker/ubuntu/Dockerfile . 
    - name: Build devel image
      run: docker build --target=devel --tag project:devel -f ci/docker/ubuntu/Dockerfile .
    - name: Build build image
      run: docker build --target=build --tag project:build -f ci/docker/ubuntu/Dockerfile .

对于测试,您可以添加其他阶段或使用project:build图像运行它:

docker run --rm --init -t --name test project:build cmake --build build --target test

附件

更快的构建

您可以添加一个.dockerignore文件来删除不需要的文件(例如,许可证、文档、本地构建目录,如果在本地测试...)以减少 docker 上下文和COPY . .

.dockerignore:

# Project Files unneeded by docker
ci/cache
ci/docker
ci/Makefile
.git
.gitignore
.github
.dockerignore
.travis.yml
.appveyor.yml
.clang-format
AUTHORS
CONTRIBUTING.md
CONTRIBUTHORS
INSTALL
LICENSE
README.md
doc

# Native CMake build
build/

# Editor directories and files
*.user
*.swp

自定义 CMake 版本安装

您可以使用以下内容代替apt install -y cmake

重建 CMake 后可能需要一些时间...

# Install CMake 3.16.4
RUN wget "https://cmake.org/files/v3.16/cmake-3.16.4.tar.gz" \
&& tar xzf cmake-3.16.4.tar.gz \
&& rm cmake-3.16.4.tar.gz \
&& cd cmake-3.16.4 \
&& ./bootstrap --prefix=/usr/local/ \
&& make \
&& make install \
&& cd .. \
&& rm -rf cmake-3.16.4

因此您可以使用预构建版本,而不是使用:

# Install CMake 3.16.4
RUN wget "https://cmake.org/files/v3.16/cmake-3.16.4-Linux-x86_64.sh" \
&& chmod a+x cmake-3.16.4-Linux-x86_64.sh \
&& ./cmake-3.16.4-Linux-x86_64.sh --prefix=/usr/local/ --skip-license \
&& rm cmake-3.16.4-Linux-x86_64.sh

推荐阅读