Drone CI模板

warning: 这篇文章距离上次修改已过563天,其中的内容可能已经有所变动。

前言

之前就提到过Jenkins的缺陷之一,也就没有办法脚本模板化,导致脚本代码维护难度高,复用率低。而Drone CI作为新生代的选手,自然也考虑到了这个问题。

使用

Drone CI集成了模板功能,但模板模板只存在于组织级别(UI的界面上只能到这里)。
官方文档中提及了,模板功能是基于 Golang Templating库 进行的模板渲染。

模板语法

官方文档在这,简单介绍一下常用的几个。

变量

变量的使用,需要用两对花括号{{}}括起来。
Go Templating文档中,传入的顶级变量用.表示。但是在Drone CI中,所有的数据传入进去都是在input变量里。也就是上述的示例中,如果想要引用projects,完整的表达式应该是这样的:

{{ .input.projects }}

循环

在本文的示例中就使用了循环,因为projects是一个数组,所以在使用时应该要循环读取,模板语法的为:

  1. 直接循环,此时在循环内部直接使用.来获取内容

    {{ range .input.projects}}
      {{ .name }}
    {{ end }}
  2. 循环变量引用

    {{ range $project := .input.projects}}
      {{ $project.name }}
    {{ end }}
  3. 带下标的引用

    {{ range $index, $project := .input.projects }}
      {{ $index }} 
      {{ $project.name }}
    {{ end }}

模板定义

官方提供了三种格式的模板写法,分别是:JsonnetstarlarkYaml,这里只介绍Yaml(因为暂时只用了这种)。
模板的定义和写普通的脚本没有太大区别,区别主要在两个地方:

  1. 后缀名是.yaml,脚本是.yml
  2. 模板可以使用模板引擎的各种语法,因为这是个模板,通过模板引擎翻译后才会变成脚本的.yml文件内容。

展示一个使用的示例(假设文件名为 vue.yaml),这个示例是构建前端项目到发布整个流程:

 kind: pipeline
 type: docker
 name: default

 steps:
   {{ range $index, $project := .input.projects }}
   - name: 构建{{$project.name}}
     image: {{ $project.build_image }}
     pull: if-not-exists
     depends_on: [clone]
     commands:
       - cd {{ $project.dir }}
       - npm install -g pnpm --registry=https://registry.npm.taobao.org --no-audit
       - pnpm install --registry=https://registry.npm.taobao.org
       - pnpm run build

   - name: 构建{{ $project.name }}镜像
     image: plugins/docker
     pull: if-not-exists
     depends_on: [构建{{$project.name}}]
     settings:
       registry:
         from_secret: registry
       username:
         from_secret: username
       password:
         from_secret: password
       repo: {{ $project.image }}
       context: ./{{ $project.dir }}/dist
       dockerfile: {{ $project.dockerfile }}
       tags:
         - latest
         - ${DRONE_BUILD_NUMBER}
         
   - name: 发布
     image: appleboy/drone-ssh
     pull: if-not-exists
     depends_on: [构建{{ $project.name }}镜像]
     environment:
       WORK_DIR:
         from_secret: work_dir
       PLUGIN_ENVS: WORK_DIR
     settings:
       host:
         from_secret: host
       port:
         from_secret: port
       username:
         from_secret: ssh_user
       key:
         from_secret: key
       ssh_passphrase:
         from_secret: passphrase
       script:
         - cd $${WORK_DIR}
         - docker compose -f {{ $project.compose_file }} pull {{ $project.service }}
         - docker compose -f {{ $project.compose_file }} up -d {{ $project.service }}
   {{ end }}

trigger:
  event:
    - push
---

kind: secret
name: registry
get:
  path: setting/data/docker
  name: registry

---
kind: secret
name: username
get:
  path: setting/data/docker
  name: username

---
kind: secret
name: password
get:
  path: setting/data/docker
  name: token

---
kind: secret
name: host
get:
  path: server/data/dev
  name: host

---
kind: secret
name: ssh_user
get:
  path: server/data/dev
  name: user

---
kind: secret
name: port
get:
  path: server/data/dev
  name: port

---
kind: secret
name: work_dir
get:
  path: server/data/dev
  name: work_dir

---
kind: secret
name: key
get:
  path: server/data/keys
  name: key

---
kind: secret
name: passphrase
get:
  path: server/data/keys
  name: passphrase

脚本引用

在写好模板后,将模板在仓库 -> Orgaization -> Templates 中自行添加(因为编辑器引用的是CDN地址,所以有时候打开会很慢。)
在具体仓库里的脚本只需要引用模板,然后传入变量即可:

kind: template
load: vue.yaml
data:
  projects:
    - name: 测试项目
      build_image: node:18.15.0
      dir: .
      image: test/ui
      dockerfile: Dockerfile
      compose_file: test.yml
      service: test-ui
最后修改于:2023年05月08日 17:29

评论已关闭