c++ - GitHub 持续集成 CMake/C++
问题描述
我正在尝试为托管在 GitHub上的私有存储库上的 cmake/c++ 项目设置 CI。
该项目依赖于许多应该被 git 克隆和构建的第三方库。后者需要一段时间,因此,我创建了一个安装了所有依赖项的 docker 映像,并将其托管在 docker hub 上。(理想情况下,我也希望 docker 映像是私有的,但如果不可能,我可以将其公开。)
我想实现以下目标:
在向主分支提出拉取请求时,应用程序会自动构建在 docker 容器上(因为所有依赖项都在那里),运行所有单元测试(gtest),如果一切正常,则将分支合并到主分支。
理想情况下,我希望查看 gcovr/lcov 生成的日志和统计信息。
操作系统:Ubuntu 18.04
我想知道这是否可以实现,因为我已经搜索了 2 天,但没有运气和十亿个可能的读数。
解决方案
我对使用 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
推荐阅读
- api - 我可以使用 Google API 从实体名称和地址列表中获取餐厅联系人详细信息吗?
- java - AuditorAware 未向 Spring Batch 线程提供最新值
- flow - api 调用错误 403 微软团队消息
- python-3.x - ImportError:无法从“ipywidgets”导入名称“AppLayout”
- python - python中的基本矩阵转置
- mongodb - pymongo 重命名索引键会引发重复键错误
- javascript - 突出显示搜索的关键字
- bash - Go 应用程序作为 systemd 服务运行
- twilio - Twilio Autopilot - 您能否为用户响应配置 LISTEN 超时或重新建立对话上下文?
- go - 删除 gota 系列的重复值