DTeam 技术日志

Doer、Delivery、Dream

使用Jenkins对以太坊Dapp应用持续集成

冯宇 Posted at — Jul 8, 2018 阅读

在项目实战开发中,持续集成是一种有效的敏捷开发手段,由自动化流程管控程序从递交代码到最终发布之间的一系列流程,实现高效、可靠的部署过程。

持续集成的准备

要相对项目进行持续集成,需要做一些准备工作,在我看来,主要有以下三点:

所谓项目工程化,并不是说用IDE创建一个工程目录开始写代码,而是指的是项目需要用工程化管理工具,可以脱离IDE环境独立非交互式运行,因为IDE对于自动化持续集成没有任何帮助,所以要求项目必须能脱离IDE环境独立集成。通常这些工具同时包含有依赖管理、自动化测试等一系列自动化托管的功能。基本上所有常见的编程语言都有流行的工程化管理工具。比如常见的有:

等等。这些工程化管理工具几乎都涵盖了从开发到测试的一系列基本功能,比如依赖安装,自动化测试等等。使用工程化管理工具的好处在于大大简化自动化流程的构建,无需用户手写大量的脚本去处理这些过程,并且易于统一化管理。所以要想持续集成,首先必须工程化管理项目

源码版本化这个比较容易理解,就是通过Git/SVN之类的版本控制工具管理源代码,好处就不用多说了,用过版本控制做开发的人都深有体会。

测试自动化这个对于持续集成是最重要的,但反而是最容易被忽视的。这个说起来很简单,就是写自动化测试代码,能通过project manager跑起来即可。但是实际开发的项目又有几个项目有自动化测试呢?自动化测试对开发人员素质的要求会比较高,但是却是持续集成中必不可缺的一环。通过自动化测试反馈项目开发中是否引入了新的问题,是否具备部署条件。

当满足这三点之后,就具备了持续集成的基础,我们就可以继续下一步了。

以太坊项目的持续集成

了解持续集成的一些基本操作和流程之后,进入今天的正题,对以太坊Dapp项目持续集成。首先我们必须将项目工程化。以太坊项目有个很方便的工程化框架Truffle,我们就用它帮助我们工程化项目。

本篇我们使用Truffle官方文档中的quickstart进行演示持续集成,本篇中开发代码不是重点,而quickstart已经包含有构建-测试-发布的代码了,所以我们直接用它讲解持续集成的操作就够了。

NOTE: 以下命令均使用BASH环境,Linux/MacOS直接终端运行即可,对于Windows环境,可以在Cygwin/MingW32模拟环境下运行,Windows 10系统也可以考虑在WSL环境中安装Ubuntu运行。

首先安装NodeJS,这个就不说了。

$ npm install -g truffle
$ mkdir metacoin_ci_example
$ cd metacoin_ci_example/
$ truffle unbox metacoin
Downloading...
Unpacking...
Setting up...
Unbox successful. Sweet!

Commands:

  Compile contracts: truffle compile
  Migrate contracts: truffle migrate
  Test contracts:    truffle test

项目工程和代码都已经就绪,为了管理项目依赖,我们可以考虑使用npm:

$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (metacoin_ci_example)
version: (1.0.0)
description:
entry point: (truffle-config.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to C:\Users\abcfy\projects\metacoin_ci_example\package.json:

{
  "name": "metacoin_ci_example",
  "version": "1.0.0",
  "description": "",
  "main": "truffle-config.js",
  "directories": {
    "test": "test"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}


Is this ok? (yes)

一路回车之后就创建好了npm的依赖管理配置文件package.json,熟悉npm的用户可以自行对这个配置文件进行定制。

目前我们只用了truffle一个依赖,添加这个依赖进入package.json即可:

$ npm install -S truffle
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN metacoin_ci_example@1.0.0 No description
npm WARN metacoin_ci_example@1.0.0 No repository field.

+ truffle@4.1.13
added 81 packages in 16.184s

此时package.json文件中就会多出truffle的依赖项,这样我们就通过配置文件的形式管理了依赖。

接下来是版本化,这里为了演示,我们使用Git管理源码,并且最终会托管到github上供读者参考。

$ git init
$ echo -e '.*\n!.gitignore\nnode_modules\nbuild' > .gitignore
$ git add -A
$ git commit -m 'init'

这样我们就初始化了一个git仓库,并且将隐藏文件以及node_modules/目录和build/目录添加到了.gitignore文件中,提交的时候不会将这些文件提交到版本库。如需添加更多忽略文件可以自行编辑.gitignore

为了后面Jenkins的演示,我已将我的工程代码提交到github中: https://github.com/abcfy2/metacoin_ci_example

此时我们就可以在本地实现自动化测试了(喜欢用npm管理测试步骤的可以自行修改package.json中的test配置项,使用npm test命令运行):

$ node_modules/.bin/truffle test
Using network 'test'.

Compiling .\contracts\ConvertLib.sol...
Compiling .\contracts\MetaCoin.sol...
Compiling .\test\TestMetacoin.sol...
Compiling truffle/Assert.sol...
Compiling truffle/DeployedAddresses.sol...


  TestMetacoin
    √ testInitialBalanceUsingDeployedContract (94ms)
    √ testInitialBalanceWithNewMetaCoin (93ms)

  Contract: MetaCoin
    √ should put 10000 MetaCoin in the first account
    √ should call a function that depends on a linked library (63ms)
    √ should send coin correctly (250ms)


  5 passing (2s)

我们还可以在测试环境下测试一下部署(注: 产品环境部署需要消耗GAS,请务必在测试环境中测试无误方可产品部署)

使用Jenkins自动化持续集成

自动化条件都已经具备,最后我们只需要使用一些工具帮助我们自动触发持续集成即可。这里我们使用Jenkins做示范,如果使用其他ci工具,读者可以自行参考ci工具的文档即可。

我们的Jenkins服务器使用Ubuntu Server 16.04做演示。首先安装Jenkins(安装命令来源于Jenkins官方文档):

$ wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
$ sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
$ sudo apt-get update

# Jenkins运行依赖JRE,但是安装包却不依赖JRE,所以需要自己安装,如果系统环境中已有JRE,则openjdk-8-jre这个包不需要安装,以免和系统已有的包冲突。
$ sudo apt-get install -y openjdk-8-jre git jenkins

Jenkins默认监听8080端口,访问8080端口的http应用即可打开Jenkins页面:

image.png

按照提示打开初始化密码的文件(需root权限),将密码填入,进入下一步:

image.png

为了简便操作我们直接选左边安装推荐的插件,如有定制需求的用户选择右边自定义插件:

image.png

等待插件安装完毕,即可结束安装:

image.png

image.png

我们的项目用了nodejs和npm做底层依赖,所以需要在Jenkins中添加NodeJS插件,减少我们的构建环境维护操作(比如不需要手工在Jenkins服务器安装NodeJS了):

image.png

由于truffle test的终端输出有彩色,为了构建日志中输出好看点,还可以添加Jenkins的AnsiColor插件以支持终端彩色输出:

image.png

目前nodejs的LTS版本是8.x,所以我们再在全局工具配置中,添加一个Node JS 8.11.3的安装管理,并且起名为Node 8.x:

image.png

Jenkins的准备过程就完成了,然后我们得告诉Jenkins应该怎么持续集成我们的项目,接下来我们要在项目中创建Jenkins pipeline配置脚本,该脚本使用Groovy DSL语法,有关Jenkins pipeline script详细使用请参考官方文档

在项目目录中新建一个Jenkinsfile文件,内容如下:

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                nodejs('Node 8.x') {
                    ansiColor {
                        sh 'npm install'
                        sh 'node_modules/.bin/truffle compile'
                    }
                }
            }
        }
        stage('Test') {
            steps {
                nodejs('Node 8.x') {
                    ansiColor {
                        sh 'npm install'
                        sh 'node_modules/.bin/truffle test'
                    }
                }
            }
        }
    }
}

上面的脚本中我们用了两个插件的配置,所以请务必确保NodeJSAnsiColor两个插件安装,并且在全局工具配置中添加有Node 8.x这个NodeJS安装管理。

由于目前没有测试环境,所以并未加Deploy配置,读者可以自行根据需要添加部署配置,并且可以灵活的利用Groovy DSL做各种条件判断,以满足各自复杂的需求,这里就不再展开了。

然后进入Jenkins,在新建项目中选择pipeline:

image.png

pipeline配置如下所示:

image.png

我们的Jenkinsfile来源于SCM,填入github的地址即可: https://github.com/abcfy2/metacoin_ci_example.git

保存之后,点击立即构建看看,构建成功应该看到类似于下面这样的输出:

image.png

在Jenkins的项目界面中也能看到pipeline的示意图:

image.png

手工点击Jenkins的构建按钮完成集成的功能我们已经实现,最后就是实现彻底自动化,在git仓库有变动的时候自动触发Jenkins构建项目,这里需要用到git的webhook功能,由于Jenkins有github这个插件,可以帮助我们简化这个操作,参考github集成文档即可: https://jenkins.io/solutions/github/

我这边的测试环境是内网,github无法利用webhook触发jenkins自动构建,这里我就不做演示了。

觉得有帮助的话,不妨考虑购买付费文章来支持我们 🙂 :

付费文章

友情链接


相关文章