Day30-1 - GitLab CI 可以怎麽重构及整理 .gitlab-ci.yml 让内容更好了解?

随着专案的演进,当团队导入 GitLab CI 工作流程之後,通常会是陆续的针对专案需要增加更多的流程,而时间一久 .gitlab-ci.yml 的内容就很有可能变得的冗长,工作流程的样貌变的不容易判读。为了避免後续维护上的困扰,通常会建议,当觉得 .gitlab-ci.yml 开始变得冗长了,开始不容易判读了的时候,就是需要针对它重构的时候了。

连续三十篇的最後一篇,就来谈谈该怎麽真对 .gitlab-ci.yml 的内容进行整理,甚至是重构以让内容更好了解。

一、一个简单的例子小谈重构 .gitlab-ci.yml,原貌:

如果现在有一个已经写好的编译工作用 .gitlab-ci.yml,期间因为陆续增加需求,现在的版本是主要可以完成,针对两个作业系统版本分别编译三个不容内容版本的原始码。

其初步的 .gitlab-ci.yml 概略长这样:

build:ubuntu:20.04:v1.0:
  image: ubuntu:20.04
  stage: build
  script:
    - echo "prepare build env"
    - echo "build ubuntu:20.04 v1.0 application"
    - echo "clean up env"

build:ubuntu:18.04:v1.0:
  image: ubuntu:18.04
  stage: build
  script:
    - echo "prepare build env"
    - echo "build ubuntu:18.04 v1.0 application"
    - echo "clean up env"

build:ubuntu:20.04:v2.0:
  image: ubuntu:20.04
  stage: build
  script:
    - echo "prepare build env"
    - echo "build ubuntu:20.04 v2.0 application"
    - echo "clean up env"

...etc

二、重构:萃取出相同的内容 Extract to common section, ex: default

因为是编译相同的内容,所以环境准备的前置作业跟结束的作业很有可能是一样的,因此,可以思考,是不是统一整理让前置作业及结束的整理作业变成统一的内容。GitLab CI 有提供 before_scriptafter_script 刚好前置作业及作业後的结束作业可以使用,再加上 default 关卡的设计,可以把所有工作都需要的内容透过 default 放置。因此上述内容可以改为:

default:
  before_script:
    - echo "prepare build env"
  after_script:
    - echo "clean up env"

build:ubuntu:20.04:v1.0:
  image: ubuntu:20.04
  stage: build
  script:
    - echo "build ubuntu:20.04 v1.0 application"

build:ubuntu:18.04:v1.0:
  image: ubuntu:18.04
  stage: build
  script:
    - echo "build ubuntu:18.04 v1.0 application"

...etc

三、把不一样的地方变成变数

从上一段落最终的内容可以发现,每个工作都长得很像,只差在一些版本及作业系统不同,那这些可以变成变数吗?当然是可以的,在这边把作业系统变为变数 BUILD_OS 版本变为 BUILD_VER

default:
  before_script:
    - echo "prepare build env"
  after_script:
    - echo "clean up env"

build:ubuntu:20.04:v1.0:
  variables:
    BUILD_OS: ubuntu:20.04
    BUILD_VER: v1.0
  image: ${BUILD_OS}
  stage: build
  script:
    - echo "build ${BUILD_OS} ${BUILD_VER} application"

build:ubuntu:18.04:v1.0:
  variables:
    BUILD_OS: ubuntu:18.04
    BUILD_VER: v1.0
  image: ${BUILD_OS}
  stage: build
  script:
    - echo "build ${BUILD_OS} ${BUILD_VER} application"

...etc

四、再次找到相同的内容变成隐藏工作(hide job) 後各工作继承

因为在上一个段落把不一样的内容都变成了变数,因此执行的工作内容再次的变的一样,这时候就可以思考,可以把内容变为共用的隐藏工作,让个工作使用继承的方式套入各自不同的变数。如下调整:

default:
  before_script:
    - echo "prepare build env"
  after_script:
    - echo "clean up env"

.build_template:
  image: ${BUILD_OS}
  stage: build
  script:
    - echo "build ${BUILD_OS} ${BUILD_VER} application"

build:ubuntu:20.04:v1.0:
  extends: .build_template
  variables:
    BUILD_OS: ubuntu:20.04
    BUILD_VER: v1.0

build:ubuntu:18.04:v1.0:
  extends: .build_template
  variables:
    BUILD_OS: ubuntu:18.04
    BUILD_VER: v1.0

...etc

变为隐藏工作後,其实也会发现 default 关卡的两个 script 也可以考虑放入到隐藏工作中,变为如下的样子,这样的好处是在同一个隐藏工作里就可以看到完整的样貌。但这仅是因为这个案例中 before 及 after script 只有 build 关卡使用,如果有其他关卡也同时使用到,则要再多考虑。

.build_template:
  image: ${BUILD_OS}
  stage: build
  before_script:
    - echo "prepare build env"
  script:
    - echo "build ${BUILD_OS} ${BUILD_VER} application"
  after_script:
    - echo "clean up env"

五、套用平行工作矩阵

接着看现行的 Script 可以再次发现,每个工作的内容都只是在更改变数内容,能一起修改吗?在谈对平行工作设置的时候有提到工作并行阵列,套用後,原本需要六个工作才能描述完成的内容,现在在一个工作之中就完成了。

build_application:
  image: ${BUILD_OS}
  stage: build
  before_script:
    - echo "prepare build env"
  script:
    - echo "build ${BUILD_OS} ${BUILD_VER} application"
  after_script:
    - echo "clean up env"
  parallel:
    matrix:
      - BUILD_OS: ["ubuntu:20.04", "ubuntu:18.04"]
        BUILD_VER: [v1.0, v2.0, v3.0]

六、总结

在上面的小型重构中,其可以参考的原始码放在 GitLab 上,这边总共使用了几个小技巧:

这些是实务上可能可以用的方法,接下来的下一篇将谈谈别人怎麽想以及还可以到哪里参考范例,我是墨嗓(陈佑竹),期待这系列的文章能够让人有些帮助。


<<:  见习村30 - A Chain adding function

>>:  完赛日,心得与阶段学习验收

Day 15 - Rancher 与 Infrastructure as Code

本文将於赛後同步刊登於笔者部落格 有兴趣学习更多 Kubernetes/DevOps/Linux 相...

Python入门 Day 6 : # While True的用法

while 是循环结构(while一定要小写),while 後面搭配布林值(boolean)并用,F...

[Day14] - Django Admin 介绍

Django 框架一个强大的特色,就是他自备後台管理系统(拍手)! 虽然说开发者习惯惯用程序去修改和...

学习Python纪录Day29 - 简易版会飞的小鸟

铁人赛学习纪录来到了第28天,今天想来做点轻松的,决定用python做一只会飞的小鸟 首先大概设计一...

AWS资料仓储

当有大量资料需要分析处理时, AWS也提供了云端资料仓储分析Redshift. 在 Redshift...