C++项目 GitHub Actions操作实例

2023-11-15

在这里插入图片描述

GitHub Actions 是帮助开发者和管理者实现工作流的一种有效方式,如更改存储库中的代码和事件等。这些事件可以是 push 事件(例如编写新的 C++ 代码)、打开或改变拉取请求(以合并更新的 C++ 代码)、创建新的分支、打开或修复问题、cron 计划任务等等。

工作流的步骤使用 YAML 代码定义,并存储在目录 .github/workflows 中。

这些操作在运行程序上执行,运行程序检查可用作业,每次只执行一个作业,直至作业完成。根据设计,运行程序安装在 GitHub 虚拟环境托管的容器中,或者由管理员自行托管。

为什么要在 C++ 项目中使用 GitHub Actions?

GitHub Actions 提供了一个非常方便有效的工具,可让所有与代码相关的工作规范化和自动化,覆盖从编译 C++ 代码,到执行依赖检查、测试等等流程。通过为实施可重复、可迁移的进程,让企业对代码部署将更有自信。此外,GitHub Actions 还可以显著提高开发速度,帮助缩短测试、报告以及提前隔离问题代码的时间,消除手动 CI/CD 活动,如安全分析、启动测试等。

对于那些已经在使用其他 DevOps 工具(如 Jenkins 或 Codeship)的人来说,GitHub Actions可能与这些工具的部分功能有一些重叠。这类团队可以使用下面两种方式的任意一种,发挥 GitHub Actions 的优势:

1、迁移——许多 CI/CD 框架已经实现了类似于 GitHub Actions 的工作流,如 Codeship Steps and Services。此外,已经使用此类框架的团队,可能会发现,与 GitHub 整合的优势很多,因此,将现有流程转化为 GitHub Actions 相当值得。这些优势包括:
1)减少 CI/CD 工具的种类,整合供应商
2)节省费用
3)更好地集成到 GitOps 流程中
将测试和验证C++代码步骤左移,提高代码可靠性
2、功能—— GitHub Actions 与其他现有的工作流不一定冲突;一些团队发现,当添加功能时,例如测试新代码库或自动更新依赖项,GitHub Actions 可以更快更好地帮助实现代码。

点击了解 Incredibuild 加速 CI 构建的解决方案!

下面,我们通过一个实例去理解 GitHub Actions 的作用。

GitHub Actions C++——结合使用,效果更佳

在本例中,我们将:

1、创建一个简单的 C++ 程序来打印“Hello,World!”
2、编写代码以支持编译程序,如配置脚本和 Makefile 文件
3、添加测试,以验证代码
4、使用 GitHub Actions 编译和测试所有 C++ 代码,这些代码为发送至主分支的推拉请求代码。

本例中的代码非常简单,但是,如果你不希望通过键入或复制本文中的代码来创建示例,你可以在 GitHub 中找到示例代码。

使用 GitHub Actions
选中 “Allow all actions” (允许所有操作) 选项:
在这里插入图片描述

编写代码

下面这个简单的 Hello World 程序是本示例的基础(Hello.cpp):

#include <iostream>

int main()
{
   std::cout << "Hello, World!" << std::endl;
}

编写一个名为 configure 的配置脚本:

XX=g++          # The C++ compiler
CXXFLAGS=-g       # C++ complilation flags
NATIVE=on        # compiles code targeted to current hardware
TUNE=generic     # performance-tuning switch

以及一个 Makefile:

/all:
    g++ -std=c++17 hello.cpp -o hello

clean:/
    $(RM) hello

手动测试代码:

$ ./configure && make && ./hello
g++ -std=c++17 hello.cpp -o hello
g++ -std=c++17 helloTest.cpp -lcppunit -o helloTest
Hello, World!

编写一个测试

在代码运行时,编写一个 CppUnit 测试 (helloTest.cpp):

#include <iostream>
#include <cppunit/TestRunner.h>
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/BriefTestProgressListener.h>
#include <cppunit/extensions/TestFactoryRegistry.h>

class Test : public CPPUNIT_NS::TestCase
{
  CPPUNIT_TEST_SUITE(Test);
  CPPUNIT_TEST(testHelloWorld);
  CPPUNIT_TEST_SUITE_END();

public:
 void setUp(void) {}
 void tearDown(void) {}
protected:
 void testHelloWorld(void) {
 system("./hello >nul 2>nul");
 }
};
CPPUNIT_TEST_SUITE_REGISTRATION(Test);

int main()

{
  CPPUNIT_NS::TestResult controller;

  CPPUNIT_NS::TestResultCollector result;
  controller.addListener(&result);
  
  CPPUNIT_NS::BriefTestProgressListener progress;
  controller.addListener(&progress);

  CPPUNIT_NS::TestRunner runner;
  runner.addTest(CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest());
  runner.run(controller);

  return result.wasSuccessful() ? 0 : 1;
}

升级 Makefile 文件,将测试代码和规则添加到原有文件中:

all:
    g++ -std=c++17 hello.cpp -o hello
    g++ -std=c++17 helloTest.cpp -lcppunit -o helloTest

test:
    chmod +x hello
    ./helloTest

clean:
     $(RM) hello helloTest
Again, manually test the code:
$ ./configure && make && make test
g++ -std=c++17 hello.cpp -o hello
g++ -std=c++17 helloTest.cpp -lcppunit -o helloTest
chmod +x hello
./helloTest
Test::testHelloWorld : OK 

编写 GitHub Actions

编写代码和测试后,接下来就应该添加 GitHub Actions 了。默认情况下,GitHub Actions 以 YAML 文件的形式存储在 .github/workflows/ 目录中,例如 .github/workflows/helloAction.yml

Name 指令配置一个字符串,该字符串将显示在 GitHub 的 Actions 对话框中。

On 指令管理 GitHub Actions 何时运行,它可以是通用的指令,也可以特定于事件(如 push),并限制在特定的分支(如 main 分支)中。

GitHub Actions 工作流由一个或多个默认并行运行的作业组成。Jobs 定义运行步骤(以下步骤)的位置,以及在该步骤中要执行的操作,例如命令、设置任务,或存储库中的其他操作。Actions 将主要使用命令,如 make 和 configure 命令,但也将从上游导入操作签出。

/name: C/C++ CI

on:
 push:
  branches: [ main ]
 pull_request:
  branches: [ main ]

jobs:
 build-and-test:
   runs-on: ubuntu-latest
   steps:
   - uses: actions/checkout@v2
   - name: install cppunit
   run: sudo apt install -y libcppunit-dev
   - name: configure
   run: ./configure
   - name: make
   run: make
   - name: make test
   run: make test

执行代码

将代码添加至代码存储库中:

$ git add hello.cpp helloTest.cpp Makefile configure .github/workflows/helloAction.yml
$ git commit -m "initial commit" -a
$ git push origin main

检查 GitHub

观察 GitHub Actions 的结果:
GitHub Actions 的界面也可以扩展,我们可以看到所有的步骤细节:

故障测试

当然,测试成功是我们的目标,但是在第一次使用一个工具时,用一个失败的案例进行测试总是更加稳妥。因此,我们修改 helloTest.cpp 代码,让测试失败:

#include <iostream>
#include <cppunit/TestRunner.h>
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/BriefTestProgressListener.h>
#include <cppunit/extensions/TestFactoryRegistry.h>

class Test : public CPPUNIT_NS::TestCase
{
CPPUNIT_TEST_SUITE(Test);
CPPUNIT_TEST(testHelloWorld);
CPPUNIT_TEST(failHelloWorld);
CPPUNIT_TEST_SUITE_END();

public:
 void setUp(void) {}
 void tearDown(void) {}

protected:
 void testHelloWorld(void)
{
 system("./hello >nul 2>nul");
}

 void failHelloWorld(void)
{
system("./hello >nul 2>nul");
}


void failHelloWorld(void)
{
exit(1);
}

};

CPPUNIT_TEST_SUITE_REGISTRATION(Test);
int main(int ac, char **av)
{
CPPUNIT_NS::TestResult controller;

CPPUNIT_NS::TestResultCollector result;
controller.addListener(&result);

CPPUNIT_NS::BriefTestProgressListener progress;
controller.addListener(&progress);

CPPUNIT_NS::TestRunner runner;
runner.addTest(CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest());
runner.run(controller);

return result.wasSuccessful() ? 0 : 1;
}

提交,推送更改代码:

/$ git commit -m "test failure" helloTest.cpp && git push origin main
[main 8b39841] test failure
1 file changed, 3 insertions(+), 3 deletions(-)
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 311 bytes | 155.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To github.com:jonathanmhurley/demo.git
3828a97..8b39841  main -> main/

在 GitHub 中观察结果:

当然,我们大概率会得到一个失败的测试,在许多实际操作中,我们也会这样做。改变被测代码单元(即测试代码),让测试失败。因此,我们不用去模拟测试失败,而是直接临时对 hello.cpp 代码进行更改,让它打印其他内容,并查看测试是否能顺利捕获这个缺陷。
在这里插入图片描述
在这里插入图片描述

GitHub Actions C++ —— 结论

尽管这个示例是在 C++ 和 Make 中使用 GitHub Actions,但实际上,GitHub Actions 也适用于其他语言和项目。其他的相关用例可在 GitHub 指南中找到,例如 python 用例,Java 用例。在 AWS 云中部署代码,使用 GitHub Actions 可参考 GitHub 指南。

点击了解 Incredibuild 优化 AWS 的解决方案,在加速 AWS 开发速度的同时,优化云成本!

GitHub Actions 适用于所有人,但不一定适用于所有进程,部分进程仍需要手动处理,设置为自动触发的成本太高。通常,如果你有希望进行自动触发的进程,在建立并稳定之后,编写一个 Actions 将是最有效的。不过,在急着为所有的触发进程编写GitHub Actions 之前,请确保时间的均衡分配,有效管理这些工作与其他任务,以最高效的方式使用这个功能。但是,当你看到某个操作可以重复进行时,根据你重复进程的具体情况,考虑使用 GitHub Actions 进行自动化。
在这里插入图片描述
《C++编译加速指南》下载连接

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++项目 GitHub Actions操作实例 的相关文章

随机推荐

  • 非极大值抑制(non-maximum suppression)的理解

    最近在学习RCNN时看到了非极大值抑制 一开始有点不明白 在网上学习了之后记录一下 非极大值抑制就是一个寻找局部最大值的过程 在进行目标检测时一般会采取窗口滑动的方式 在图像上生成很多的候选框 然后把这些候选框进行特征提取后送入分类器 一般
  • MySQL执行update时的[ERROR 1093]处理方法

    版权声明 声明 本文档可以转载 须署名原作者 作者 无为 qq 490073687 周祥兴 zhou xiangxing210 163 com gt update TEST NOIDX set CREATETIME now where ID
  • 使用QFileInfo查看文件相关信息----大小,创建时间,属性

    QString file E workspace Data ColorTransfer txt QFileInfo info file qint64 size info size 文件大小 单位byte QDateTime created
  • [Cocos Creator] Cocos Creator 下拉框(Dropdown)组件的实现

    模仿Unity写了一个Dropdown的组件 使用方法可以见工程 链接见底下 https github com ETRick CocosCreator Dropdown tree master Dropdown
  • opencv-python学习教程【持续更新】

    Opencv python学习系列教程 一 图片的读取 代码 实验结果 二 视频的读取 代码 实验结果 三 颜色通道的读取 代码 实验结果 四 图像边界填充 代码 实验结果 五 图像融合 代码 运行效果 六 图像阈值 代码 实验结果 存疑
  • 《Spring cloud Alibaba全解》阅读笔记

    技术 2022 05 Spring cloud Alibaba全解 创建时间 2022 5 22 15 21 更新时间 2023 2 17 8 52 作者 HelloXF 第一章 微服务的介绍 1 1系统架构的演变 1 1 1单体应用架构
  • ospf综合实验v1

    实验题目 搭建拓扑图 部分配置 r3r4r5r6r7之间的mgre r3中心站点的配置 r5的配置 r6r7的配置以此类推 于r5相似 各个区域之间的ospf 解释 为了方便对不规则区域之间的联络 我采用多进程双点双向重发布来实现其中区域1
  • Swift 之 继承、构造过程与析构过程

    Swift 继承 继承我们可以理解为一个类获取了另外一个类的方法和属性 当一个类继承其它类时 继承类叫子类 被继承类叫超类 或父类 在 Swift 中 类可以调用和访问超类的方法 属性和下标脚本 并且可以重写它们 我们也可以为类中继承来的属
  • STC15单片机实战项目 - PCB打样

    PCB打样 一 设计文件链接 1 PADS9 5格式PCB设计文件 gt Project STC15 V1 0 pcb 2 AltiumDesigner格式PCB设计文件 gt Project STC15 V1 0 PcbDoc 二 获取开
  • Vue 实现商品分类、列表、详情、购物车、搜索(vant)

    商品分类Classify
  • MySQL 1130错误原因及解决方案

    相信大家在使用MySQL数据库的过程中肯定都遇到过报错 其中MySQl 1130就是一个我们在远程登陆是经常遇到的错误 本文树懒君就给大家介绍一下MySQL 1130报错的原因以及解决的思路 并给大家三种具体的解决方案供大家参考 错误概述
  • 简单理解DLL文件是什么,如何使用?

    DLL文件是什么 DLL文件是动态链接库的缩写 可以在多种程序中使用 如何编写DLL文件 可以使用C C VB之类的语言编写 其中包含了一个或者多个函数 以供其他程序调用 例如 如何在Python中使用DLL文件 使用ctypes模块 在P
  • 虚幻引擎(UE4)场景漫游交互项目制作

    1 模型导出 3dmax模型准备 导出FBX格式 导入UE4引擎等 2 模型导入UE4 项目创建 导入注意 模型查看 3 场景搭建 创建关卡 模型材质 搭建场景 4 地形制作 创建地形 资源导入 地形制作 5 场景漫游 碰撞 第一人称控制
  • 6. 整合Spring

    6 整合Spring MyBatis Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中 它将允许 MyBatis 参与到 Spring 的事务管理之中 创建映射器 mapper 和 SqlSession 并注入到
  • Oracle RAC原理

    单点数据库VS RAC 单节点数据库 如果实例宕机了 如果一个业务链接在实例上面 那么这个业务就中断了 这个时候系统就不具有可用性了 那么这个时候单节点的可用性是很差的 对于RAC来说 和单实例一样 还是一份数据文件 都是相同的存储上面放着
  • C#连接SQLServer数据库并通过Button实现增删改查

    C 连接SQLServer数据库并通过Button实现增删改查 数据库课程实验 要求写程序实现数据库的增删改查 不限语言类型 前面实验已经使用VC实现了对数据内容的读取 今天想用C 实现 本文主要写了我过程中遇到的几个问题以及我的解决方法
  • 【限时免费】20天拿下华为OD笔试之【BFS】2023B-最长广播响应-200分【闭着眼睛学数理化】全网注释最详细分类最全的华为OD真题题解

    BFS 2023B 最长广播响应 题目描述与示例 题目描述 某通信网络中有N个网络节点 用1到N进行标识 网络中的节点互联互通 且节点之间的消息传递有时延 相连节点的时延均为一个时间单位 现给定网络节点的连接关系link i u v 其中u
  • rippled节点配置文件详解

    文章目录 一 简介 二 配置文件示例 三 配置项说明 server port rpc admin local port peer port ws admin local node size node db ledger history da
  • java的序列化注解Serial、序列化版本号serialVersionUID、eclipse中自动生成serialVersionUID

    说明 例如 jdk源码NTLMException类的定义 其中涉及到了序列化注解Serial和序列化版本号字段serialVersionUID 序列化注解java io Serial 序列化注解java io Serial是在javaSE
  • C++项目 GitHub Actions操作实例

    GitHub Actions 是帮助开发者和管理者实现工作流的一种有效方式 如更改存储库中的代码和事件等 这些事件可以是 push 事件 例如编写新的 C 代码 打开或改变拉取请求 以合并更新的 C 代码 创建新的分支 打开或修复问题 cr