
# 编写多任务build.yml文件
在编译构建中，构建任务是构建的最小单元，适用于业务比较简单的场景，但是在有些复杂的构建场景下，构建任务可能并不能满足复杂的构建要求。例如：
- 多仓工程需要分布到多个机器上去构建，并且构建工程之间还存在一定的依赖关系。
- 希望更加模块化、更加细粒度的拆分构建任务，并按照依赖顺序进行构建。
对于上述这类比较复杂的构建场景，编译构建支持使用BuildFlow将多个存在依赖关系的构建任务按照有向无环图（DAG）的方式组装起来，BuildFlow将会按照构建的依赖关系并发进行构建。
本视频介绍基于Maven构建执行多任务构建工程的操作。
<video controls="controls" preload="none" id="object12220102454018" class="idp-external-video" src="https://res-video.hc-cdn.com/cloudbu-site/china/zh-cn/support/cloudbuild_video/1750644594695229502.mp4" title="多任务构建工程" poster="https://support.huaweicloud.com/usermanual-codeci/zh-cn_image_0000002327981936.jpg" height="300.0000" width="600.0000"></video>
#### 约束与限制
- BuildFlow父任务不会占用一个并发，子任务在并发数不够时会排队，为了最佳使用效果，建议购买[构建并发包](https://support.huaweicloud.com/usermanual-codeci/codeci_ug_0001.html#codeci_ug_0001__section664115251911)，构建并发包使用规则及方法请参考[如何使用构建并发包](https://support.huaweicloud.com/codeci_faq/codeci_faq_0010.html)。
- 构建并发包为租户级别，一个并发包资源同时只能由一个构建任务使用。
 
#### 多任务YAML文件整体内容示例
```
version: 2.0 # 必须是2.0，该版本号必填且唯一
params: # 定义全局参数，即所有子任务可共享该参数
  - name: p
    value: 1
# env和envs配置为非必填项。当用户需要使用条件判断确定使用的主机规格与类型时，选择配置envs
env: # 如果配置，则优先级最高。即在此处定义了主机规格与类型，则不使用构建环境配置中选择的主机类型和规格
  resource:
    type:docker # 资源池类型：docker或custom，其中docker表示使用默认执行机，custom表示使用自定义执行机
    arch:X86 # 构建环境主机类型：X86或ARM
    class:8U16G # 规格：2U8G、4U8G、8U16G、16U32G或16U64G，当type为custom时无需填写该参数
    pool：Mydocker #资源池名称，当type为custom时需要填写该参数
envs: 
    - condition: p == 1 # 主机规格与类型的判断条件，满足条件会使用以下主机规格与类型
      resource:
        type: docker 
        arch: ARM
    - condition: p == 0 # 主机规格与类型的判断条件，不满足条件则不使用以下主机规格与类型
      resource:
        type: docker
        arch: X86
# buildflow和buildflows配置二选一。当需要使用条件判断执行的jobs时，选择配置buildflows
buildflow:
 strategy: lazy # 定义buildFlow运行的策略，支持lazy和eager。如果没有定义，默认使用eager模式
         # lazy：先触发优先级高的子任务构建，优先级高的子任务执行成功之后，再触发优先级低的子任务。构建时间相对较长，但是可以节省构建资源，推荐在并发数不足时使用。
         # eager：同步触发所有子任务的构建，有依赖其他任务的子任务会先准备好环境和代码，等待所依赖的任务构建成功。可能造成资源空闲等待，但是可以缩短构建时间，推荐在并发数足够大的情况下使用。
    jobs: # 用来定义需要进行编排的子任务，每个子任务都必须要有唯一的名字作为构建任务的唯一标识。且若子任务A依赖子任务B，则构建优先级B > A，优先级相同的子任务会同步触发。本示例中，Job3依赖于Job1和Job2，即构建优先级Job1、Job2 > Job3，且Job1和Job2同步触发。
      - job: Job3 # 子任务的名称，可自定义
        depends_on: # 定义job的依赖,此处表示Job3依赖Job1和Job2
            - Job1
            - Job2
        build_ref: .cloudbuild/build3.yml # 定义Job在构建过程中需要运行的yaml构建脚本
      - job: Job1
        build_ref: .cloudbuild/build1.yml
      - job: Job2
        build_ref: .cloudbuild/build2.yml
buildflows:
  - condition: p == 1 # 执行任务的判断条件，满足条件会执行以下jobs中编排的所有子任务
    jobs: # 定义需要进行编排的任务
      - job: Job1 # 子任务的名称，可自定义
        build_ref: 1.yml # 构建任务在构建过程中需要运行的yaml构建脚本
        params:
          - name: abc
            value: 123
      - condition: p == 1 # 执行子任务的判断条件，满足条件会执行Job2子任务
        job: Job2
        build_ref: 2.yml
        params:
          - name: abc
            value: 123
```
在使用代码化构建时，需注意参数使用的优先级，以上述代码示例为例：
构建任务参数设置中设置的运行时参数 \> 构建任务参数设置中的参数默认值 \> build_ref中定义的参数 \> job下的params中定义的参数 \> BuildFlow下params中定义的全局参数。
**params更多使用方法**：
params可以定义全局参数，即所有子任务共享。编译构建也支持在部分子任务上定义参数使用，如下代码所示，未定义全局参数params，而是将参数"isSubmodule"直接定义在Job1与Job2中。
```
buildflow:
    jobs:
      - job: Job3
        depends_on:
            - Build Job1
            - Build job2
        build_ref: .cloudbuild/build3.yml
      - job: Job1
        params:
          - name: isSubmodule
            value: true
        build_ref: .cloudbuild/build1.yml
      - job: Job2
        params:
          - name: isSubmodule
            value: true
        build_ref: .cloudbuild/build2.yml
```
