零基础从开发到自动化测试完整创建一个GitHub项目
0. 引言
2022年了,大厂毕业季如火如荼。作为初出茅庐的程序员萌新,我们来一起探索一下如何完完整整创建一个GitHub项目,从开发构建到自动化测试全覆盖。
教程需要:
- GitHub账号
1. 创建项目
既然从零开始,那么我们首先要创建一个项目。
- Repository name: github_tutorial
- gitignore: C++
- README: Add a README to your repository
因为我们最最最简单的demo是基于C/C++的Hello world
所以我们gitignore
就选择忽略相应的C++
相关编译冗余文件。
至此基础设置就配置好啦~
2. 克隆项目到本地
接下来我们就要克隆项目到本地。选择复制项目连接并到本地执行:
➜ WORKSPACE git clone https://github.com/KCNyu/github_tutorial.git
Cloning into 'github_tutorial'...
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), 800 bytes | 800.00 KiB/s, done.
3. 本地创建项目
先让我们来看看我们将创建的总体项目结构:
➜ WORKSPACE tree github_tutorial
github_tutorial
├── CMakeLists.txt
├── inc
│ └── hello.h
├── README.md
└── src
├── hello.cpp
└── main.cpp
2 directories, 5 files
现在让我们一个一个来看
- inc
这里面是我们的头文件,我们可以在这里写一些头文件的声明。
#ifndef HELLO_H
#define HELLO_H
#include <iostream>
#include <string>
namespace hello {
void sayHelloto(const std::string& name);
}
#endif // HELLO_H
- src
这里面是我们的源文件,我们可以在这里写一些源文件的实现。
#include "hello.h"
void hello::sayHelloto(const std::string& name)
{
std::cout << "Hello, " << name << "!" << std::endl;
}
以及我们的main
函数:
#include "hello.h"
int main(int argc, char const *argv[])
{
hello::sayHelloto(argv[1]);
return 0;
}
我们通过CMakeLists.txt
文件来配置我们的项目,我们可以看到我们的项目配置如下:
project(hello)
cmake_minimum_required(VERSION 2.8)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
aux_source_directory(./src SRC)
include_directories(./inc)
add_executable(hello ${SRC})
# set up the test
enable_testing()
macro(test TESTNAME)
ADD_TEST(NAME test_hello_${TESTNAME} COMMAND hello ${TESTNAME})
SET_TESTS_PROPERTIES(test_hello_${TESTNAME}
PROPERTIES PASS_REGULAR_EXPRESSION "Hello, ${TESTNAME}")
endmacro()
test(KCN)
test(CODE)
按照惯例,逐行来分析。
project(hello)
设定了项目名称为hello
。
cmake_minimum_required(VERSION 2.8)
设定了CMake的最低版本为2.8。
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
设定了项目的输出目录为bin
。
aux_source_directory(./src SRC)
设定了源文件的目录为src
。
include_directories(./inc)
设定了头文件的目录为inc
。
add_executable(hello ${SRC})
设定了项目的类型为executable
,并且添加了一个hello
的程序。
# set up the test
enable_testing()
设定了测试的功能。
macro(test TESTNAME)
ADD_TEST(NAME test_hello_${TESTNAME} COMMAND hello ${TESTNAME})
SET_TESTS_PROPERTIES(test_hello_${TESTNAME}
PROPERTIES PASS_REGULAR_EXPRESSION "Hello, ${TESTNAME}")
endmacro()
设定了一个test
的宏,并且添加了一个test
的测试。
test(KCN)
test(CODE)
设定了两个测试,分别为KCN
和CODE
。
现在万事具备,我们可以构建和测试我们的项目了。
首先我们先根据CMakeLists.txt
文件来构建build目录:
➜ github_tutorial git:(master) ✗ cmake -B ./build
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/ubuntu/WORKSPACE/github_tutorial/build
再之后,我们可以通过make
命令来构建我们的项目:
➜ github_tutorial git:(master) ✗ cmake --build ./build
Scanning dependencies of target hello
[ 33%] Building CXX object CMakeFiles/hello.dir/src/hello.cpp.o
[ 66%] Building CXX object CMakeFiles/hello.dir/src/main.cpp.o
[100%] Linking CXX executable bin/hello
[100%] Built target hello
我们可以看到,我们的项目构建完成了。
我们进入到bin
目录下,并且执行hello
程序:
➜ bin git:(master) ✗ ./hello KCNyu
Hello, KCNyu!
看上去很简单,但是我们可以看到,我们的程序没有任何错误,并且输出了我们的名字。我们再使用make test
或ctest
来进行测试:
➜ build git:(master) ✗ ctest
Test project /home/ubuntu/WORKSPACE/github_tutorial/build
Start 1: test_hello_KCN
1/2 Test #1: test_hello_KCN ................... Passed 0.00 sec
Start 2: test_hello_CODE
2/2 Test #2: test_hello_CODE .................. Passed 0.00 sec
100% tests passed, 0 tests failed out of 2
Total Test time (real) = 0.01 sec
我们可以看到,我们的测试通过了。
现在我们可以把我们的项目提交到GitHub了。
3. 提交到GitHub
注意到我们build
目录其实是一个项目的构建目录,我们可以通过在gitignore
添加如下来忽略它。
# CMake
build/
最后我们可以通过git add .
来添加所有的文件,并且通过git commit -m "UDPATE: done the project"
来提交我们的项目。最后使用git push origin master
来推送到GitHub。
4. GitHub Actions的使用
可以看到,我们总是通过手动来构建测试项目,这样太麻烦了,我们应该保证每一次提交都能通过构建和测试。所以我们来使用GitHub Actions
来将这个过程自动化。
我们将看到如下一个配置:
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@v3
- 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}}
由于我们的项目非常非常简单,同时也不存在系统差异,所以我们可以使用默认的config
保存即可。
最后我们每次提交,都会触发一次构建和测试。
5. 总结
我们已经完成了一个简单的CMake项目,我们可以在GitHub上提交一个项目,并且可以通过GitHub Actions来自动化构建和测试。这只是非常基础的例子,目的在于让大家对构建一个完整项目有一个基本的认识。