前言

最近几个星期整理了自己的服务器,把大部分服务都迁移到了Docker上,有些正在开发或者经常需要更新的项目也在Docker Hub配置了发Release自动构建镜像。然后过了几天以后突发奇想打算给一些正在维护的项目加上CI。刚开始因为Travis-CI比较有名,就打算用Travis-CI持续构建,结果折腾了一天以后发现Travis-CI过一段时间就要收费了,只好在shields.io支持的CI里面看了一圈,最后决定采用Circle-CI。

步骤

一般来说,持续构建的步骤里面有包括跑测试,不过因为我的项目都比较小,没有专门写过测试,构建步骤里面就直接编译了。

Travis-CI和Circle-CI虽然一个采用虚拟机,一个主推Docker,但是基本上默认系统都是Ubuntu,所以虽然配置文件不大一样,但是里面包含的步骤都基本如下:

  • 通过apt安装依赖,如gcc, cmake, libboost-all-dev
  • 编译安装依赖(如果apt没有)
  • 编译
  • 后续操作,如部署,发布等

如果在apt安装依赖时出现问题,可能需要加上sudo apt update

Travis-CI V.S Circle-CI

由于前期采用了Travis-CI进行构建,在这里可以通过配置文件对两个CI进行相同工作进行对比。
Travis-CI:

.travis.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
language: cpp
sudo: required
dist: bionic
addons:
ssh_known_hosts: example.com
apt:
packages:
- cmake
- gcc
- g++
- libjsoncpp-dev
- uuid-dev
- zlib1g-dev
- openssl
- libssl-dev
- mariadb-client
- mariadb-server
- build-essential
- libboost-all-dev
before_install:
- openssl aes-256-cbc -K $encrypted_5c5e58b15b48_key -iv $encrypted_5c5e58b15b48_iv
-in id_rsa.enc -out ~/.ssh/id_rsa -d
- chmod 600 ~/.ssh/id_rsa
- wget https://github.com/google/googletest/archive/release-1.10.0.tar.gz
- tar xf release-1.10.0.tar.gz
- cd googletest-release-1.10.0
- cmake .
- make
- sudo make install
- cd -
script:
- git submodule update --init --recursive
- mkdir build
- cd build
- cmake ..
- make
after_success:
- mkdir shorturl
- mv etc/ static/ ShortURL shorturl
- tar Jcvf shorturl.tar.xz shorturl/
- scp shorturl.tar.xz ubuntu@example.com:~

Circle-CI:

.circleci/config.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
version: 2.1
jobs:
build:
docker:
- image: circleci/buildpack-deps:focal

steps:
- checkout
- add_ssh_keys:
fingerprints:
- "aa:bb:cc:dd:ee:ff:gg:hh:c1:d4:f3:88:d4:26:8f:95"
- run: |
sudo apt install cmake gcc g++ libjsoncpp-dev uuid-dev zlib1g-dev openssl \
libssl-dev mariadb-client mariadb-server build-essential libboost-all-dev
- run: |
wget https://github.com/google/googletest/archive/release-1.10.0.tar.gz
tar xf release-1.10.0.tar.gz -C ~/
cd ~/googletest-release-1.10.0
cmake .
make
sudo make install
cd -
- run: |
git submodule update --init --recursive
mkdir build
cd build
cmake ..
make
mkdir shorturl
mv etc/ static/ ShortURL shorturl
tar Jcvf shorturl.tar.xz shorturl/
- run: |
ssh-keyscan -t rsa example.com >> ~/.ssh/known_hosts
scp build/shorturl.tar.xz ubuntu@example.com:~

workflows:
version: 2
master_build:
jobs:
- build:
filters:
branches:
only: master

配置文件

Travis-CI和Circle-CI都采用yaml作为配置文件,Travis-CI的配置文件一般都是自己编写,然后push到github上面来触发构建,而Circle-CI则更为先进。Circle-CI在线上有专门的编辑器,在初次设置项目的时候会自动开一个新的分支并给出示例配置文件。在编辑配置文件时有自动检查功能,如果构建失败了还可以直接在线上编辑配置文件。这样的话相对于新手会有更好的体验。

工作流程

Travis-CI 把工作流程分成before_install, install, before_script, script, after_success等阶段。其中install系列与安装依赖阶段有关,script系列与构建阶段有关。而Circle-CI则是全部用run来代替。如果需要同时构建多个平台的Release,Travis-CI可以通过matrix来进行,而Circle-CI则是在workflow中包含多个jobs来代替。在构建流程中,Travis-CI 一般会直接到代码根目录,而Circle-CI一般需要在第一步用- checkout来定位到代码根目录。后面每次新开一个run都会自动切回代码根目录。

运行环境

Travis-CI一般采用预装好运行环境的虚拟机来运行,而Circle-CI则是主推docker运行。虽然看起来不同,但是即使在Circle-CI里面也可以把Docker直接当成一个虚拟机来看待。Circle-CI的docker镜像和一般的docker镜像不太一样。一般的docker镜像都是默认root用户,但是Circle-CI自己构建的docker镜像如果需要进行root操作,需要在命令之前加上sudo。Circle-CI的sudo默认不需要密码,而不是像Travis-CI一样需要提前指定需要sudo权限来避免输密码导致构建停止。

自带功能

Travis-CI似乎自带功能多一些,比如可以加密文件并自动把解密步骤放到配置文件里面,在Circle-CI里面的解决办法一般就是把密码写在Project Settings的环境变量里面,然后自己写命令来解密。如果涉及到把编译好的文件放到自己的服务器上或者一些git操作,Circle-CI支持上传SSH Key,就不需要像Travis-CI一样把SSH Key加密然后放到repo里面。

虽然Circle-CI在配置文件上自带功能少一些,但是通过像写bash脚本一样把Linux命令加上去也可以实现一样的效果。