持续集成、持续交付、持续部署。听起来就像是在大型软件工程,高端开发项目组里才会应用到的概念。其实不然,通过运用一些开源免费的工具和平台,不管是你的个人博客还是 side-projects 都能够享受到开发任务自动化的便利。

这次我们的教程主要会分为以下几步:

  1. 注册并设置 Travis CI
  2. 在开发服务器(或本地)上生成密匙并与部署服务器互信
  3. 安装 Ruby 2.0 以上版本并安装 travis 的命令行工具
  4. 编写测试并在项目中配置 travis
  5. 编写 travis 自动部署脚本
  6. 提交代码检验运行

本教程以最基础的部署 php 站点为例(其实与部署的应用本身关系不大,不管是 NodeJS 还是 Hexo 一类的静态站点生成全部都大同小异,只需要替换自动执行的命令就可以了)

注册并设置 Travis CI

先打开 Travis CI 官网,点击右上角使用Github登录的按钮(这里假设读者已经注册并掌握 GitHub 的基本使用了)

v2-487060daf3a1875833ce135966526ed8_hd

登录成功后,你应该会看到和下图差不多的页面,按照提示进行操作:

v2-35a0e932cf8db58f535d929f7b3b1b31_hd

你可以打开先看一眼你在 Travis CI 上项目的页面,不过现在肯定是空空如也一片,我们在官网上需要进行的操作暂且到此为止。

在开发服务器(或本地)生成密匙并与部署服务器互信

不管是本地还是开发服务器,这里已经默认了你的开发环境是 Linux/类 Unix 系统,不要问我 Windows 该怎么办,Win10 可以安装 Ubuntu 子系统,当然你要是不觉得蛋疼也可以下载一些类似 ssh key generator 的软件。

这里其实只需要用到两个命令。

首先在本地或开发服务器上生成密匙,在命令行里输入:

ssh-keygen -t rsa

之后只需要按照提示操作,你大概会看到类似下面的内容:

# 来自Digital Ocean
ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/demo/.ssh/id_rsa): 
# 这里的密码一定要留空袄
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/demo/.ssh/id_rsa.
Your public key has been saved in /home/demo/.ssh/id_rsa.pub.
The key fingerprint is:
4a:dd:0a:c6:35:4e:3f:ed:27:38:8c:74:44:4d:93:67 demo@a
The key's randomart image is:
+--[ RSA 2048]----+
|          .oo.   |
|         .  o.E  |
|        + .  o   |
|     . = = .     |
|      = S = .    |
|     o + = +     |
|      . o + o .  |
|           . o   |
|                 |
+-----------------+

接下来你需要将你开发环境生成的密匙拷贝到你的部署服务器上。之所以进行这一步是为了实现免密码登录 ssh,因为 travis-ci 自动执行命令是不支持交互式输入密码的。

同样只需要一个命令:

ssh-copy-id <登录部署服务器用户名>@<部署服务器地址>
# 如果ssh默认端口不是22
ssh-copy-id <登录部署服务器用户名>@<部署服务器地址> -p <部署服务器ssh端口>
# 示例
ssh-copy-id travis@123.123.123.123 -p 12345

接下来也同样按提示操作,第一次输入密码登录完成后,就可以使用密匙测试免密登录啦,当然为了安全起见,记得这里专门为持续部署新建一个权限适宜的用户袄。

安装 Ruby 2.0 以上版本并安装 travis 的命令行工具

简单的 apt-get install ruby 并不能顺利解决问题,travis 命令行工具依赖 ruby2.0 以上的版本。

这个地方其实是一个坑,我想大部分同学和我一样都是使用 Ubuntu 系统,默认使用apt-get install ruby2.0 安装的事实上是 1.9 版本,这特么就很尴尬了。

所以我们不得不下载源码手动编译安装。如果你的开发环境之前安装过ruby记得先删掉:

sudo apt-get -y update
sudo apt-get -y install build-essential zlib1g-dev libssl-dev libreadline6-dev libyaml-dev
cd /tmp
# 由于众所周知的网络原因,此处可能需要使用到http_proxy
wget http://ftp.ruby-lang.org/pub/ruby/2.1/ruby-2.1.5.tar.gz 
tar -xvzf ruby-2.1.5.tar.gz
cd ruby-2.1.5/
./configure --prefix=/usr/local
make
sudo make install

如果嫌麻烦你可以把上述命令保存成一个 .sh 文件一键执行。安装完成后使用 ruby -v 验证一下版本。

之后再运行:

# 由于众所周知的网络原因,此处可能需要使用到http_proxy
gem install travis

如果网络实在太差,可以使用 RubyGems 镜像

gem sources --add https://gems.ruby-china.org/
gem sources --remove https://rubygems.org/
gem sources --remove http://rubygems.org/
gem sources -l

安装完成后,切换到你开发环境的项目目录下,运行:

travis login

根据提示,输入你刚刚用于 travis-ci 网站登录的 GitHub 账户名及密码。

编写测试并在项目中配置 travis

下面我以使用 PHPUnit 对 PHP 进行测试为例对持续部署项目进行配置:

其实你用 mocha 测试 JS 什么的也是一样的。

<?php
//假如你的PHP项目中并没有安装PHPUnit依赖,就像我这么写吧,不要用use关键字引入,否则在travis-ci运行时会报错
class Test extends PHPUnit_Framework_TestCase
{
    public function testAutoPass()
    {
        $this->assertEquals(
            'yubolun',
            'yubolun'
        );
    }
}

之后在你的项目根目录新建一个名为 .travis.yml 的文件:

language: php
php:
- 5.6
before_script: composer require phpunit/phpunit
script: phpunit Test.php

前端项目也很类似:

language: node_js
node_js:
  - '6.9.5'
  - '7.5.0'
before_script: npm install
script: npm run test

以上只是举个例子,更多详细的配置内容请查阅官网文档

编写 travis 自动部署脚本

做好基本的项目配置之后,我们需要配置持续部署的自动运行脚本。

首先使用 travis encrypt-file 命令对你刚刚在开发环境生成的密匙进行加密(这样一来可以放心地将密匙保存在公开的开源项目当中)。

# 此处的--add参数表示自动添加脚本到.travis.yml文件中
travis encrypt-file ~/.ssh/id_rsa --add

之后再打开 .travis.yml 文件,你会看到一段类似如下内容的命令:

before_install:
  - openssl aes-256-cbc -K $encrypted_830d3b21a25d_key -iv $encrypted_830d3b21a25d_iv
    -in id_rsa.enc -out ~/.ssh/id_rsa -d

默认生成的命令可能会在/前面带转义符\,我们不需要这些转义符,手动删掉所有的转义符,否则可能在后面引发莫名的错误。

之后为了保证命令的顺利运行,我们还需要正确地设置权限和认证:

before_install:
  - openssl aes-256-cbc -K $encrypted_830d3b21a25d_key -iv $encrypted_830d3b21a25d_iv
    -in id_rsa.enc -out ~/.ssh/id_rsa -d
# 添加如下两行内容,Host后面的ip替换成你的部署服务器地址
  - chmod 600 ~/.ssh/id_rsa
  - echo -e "Host 123.123.123.123\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config

P.S. 此处的配置文件只是示例啊,不要直接复制,每次生成的加密都是不一样的。

之后,也是最重要的一步,配置你执行持续部署的命令:

language: php
php:
- 5.6
before_install:
- openssl aes-256-cbc -K $encrypted_830d3b21a25d_key -iv $encrypted_830d3b21a25d_iv
  -in id_rsa.enc -out ~/.ssh/id_rsa -d
- chmod 600 ~/.ssh/id_rsa
- echo -e "Host 123.123.123.123\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
before_script: composer require phpunit/phpunit
script: phpunit Test.php
# 添加一个名为after_success的钩子,并写入你需要执行部署操作的命令
after_success:
- ssh travis@123.123.123.123 -p 12345 'cd /var/www && git pull'

在这里你可以运行任意的脚本,比方说我的项目只需要把代码 pull 下来就算部署完成了,其他的例如静态博客可以 hexo g,或者是 node 应用的 pm2 startup,前端项目也可以先 webpack 一下等等,别跑 rm -rf,其他的随意。

提交代码检验运行

上述的步骤全都部署完成后,只需要使用git将你的所有改动提交到 GitHub 上,travis-ci 就会自动运行啦,最后别忘了登录到你的部署服务器检验一下效果袄~

v2-a6160eb4a70cc923e0c9d3f32ab889b1_hd

至此大功告成,接下来你只需要愉快地写代码,提交 Git。剩下的测试、编译、部署工作全部都会自动完成啦。

参考资料