编写代码只是开发的一部分,更多的精力往往花在构建 (build)和测试 (test)上,目前构建和测试的自动化工具层出不穷。这里介绍一下GitLab的CI/CD。

持续集成服务/持续部署服务(Continuous Integration, 简称CI / Continuous Delivery, 简称CD)简单理解就是在完成代码书写后自动检测变化并编译测试的过程。市场份额巨大的 Travis CI 和 GitHub 深度整合,是被广泛使用的 CI 工具。我这里使用 GitLab 的 CI/CD 功能,私心在于这项功能可以部署在自己的服务器上,同时也是同时学习一下自己部署 CI/CD 的工具(主要是 Docker )。

主要目标

本博客是由 Hexo 搭建的,完成CI/CD的构建后,博客写作后就可以自动部署在站点上。

基础环境

  • 一个Hexo站点,源码放在GitLab的private repo里
  • VPS一个,之前靠手动rsync站点文件上去
  • 配置好的GitLab runner,绑定在repo上

配置

  1. repo->Settings->CI/CD->Variables设置预设的变量,这样可以避免私密的文本出现在repo的文件中,主要有以下一些变量:
    • 设置VPS别名,对应.ssh/config的内容
    • 将VPS、GitLab的server key加入known_hosts,对应.ssh/known_hosts的内容(原因见踩坑2)
    • SSH私钥,就是ssh-keygen生成的其中那个私钥
  2. repo下编写 .gitlab-ci.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
    42
    43
    44
    45
    46
    47
    # 选用了固定版本的node,主要担心node更新会带来不稳定
    image: node:10.2.0

    before_script:
    ## 测试命令是否存在,否则安装以下软件包
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client git -y )'
    - eval $(ssh-agent -s)
    - 'which rsync || ( apt-get update -y && apt-get install rsync -y)'

    ## 将私钥添加入ssh-agent
    - echo "$ID_RSA" | tr -d '\r' | ssh-add - > /dev/null

    ## 创建ssh的环境
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - echo "$KNOW_HOSTS" > ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts
    - echo "$CONFIG" > ~/.ssh/config
    - chmod 644 ~/.ssh/config

    ## Clone the submodule (theme)
    - git submodule sync --recursive
    - git submodule update --init --recursive

    ## 如果GitLab runner身处天朝,需考虑该部分
    - ping -c 1 registry.npm.taobao.org
    - ping -c 1 npm.taobao.org
    - npm config set registry https://registry.npm.taobao.org
    - npm config ls -l

    build:
    cache:
    paths:
    - node_modules/

    script:
    - npm cache verify
    - npm cache clean --force
    - npm i -g hexo-cli
    - npm i
    - node -v
    - npm -v
    - hexo -v
    - hexo clean && hexo g
    - hexo d
    only:
    - master

踩坑

  1. npm package安装超时

    其实这个问题我并没有找到原因,参考了Node安装node-sass总是下载超时问题解决When I run npm install, it returns with ERR等一系列文章还无果后,某一天突然就解决了。

  2. Git error: “Host Key Verification Failed”

    Git error: “Host Key Verification Failed” when connecting to remote repository 这个问题实际上是因为此时CICD未将目标Host添加进入.ssh/known_hosts中,平时自己操作git会交互式地提问是否信任Host的RSA key。

    在项目设置里配好SSH_PRIVATE_KEY这个variable后,CI始终报错,报错如下。一顿折腾,发现是手贱在配置variable的时候打勾了“protected”,这样会导致variable只对protected branch/tag可见。

    1
    2
    $ echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
    Enter passphrase for (stdin): ERROR: Job failed: exit code 1
  3. Pipeline status对CI/CD的标示,类似这样

    Settings->General->展开 (Expand) Badges,在这里可以设置;但这个不会出现在README里,需要在README里单独书写,Settings->CI / CD->展开 (Expand) General pipelines 向下滑动至 Pipeline status里面有说明各种语言的Badge该如何书写,比如https://examplegitlab.com/namespace/project/badges/branch/build.svg