企业级持续交付系统 CircleCI 是怎么炼成的(三):带你 4 步创建入门级 workflow

为了通过这个demo尽可能多的测试circleci yaml功能,我 定义了5个job ,分别是:

我们来看下yaml,先有一个整体感觉, 最后会详细讲解yaml含义

version: 2
parameters:
  temp-workspace:
    type: string
    default: "/temp/workspace"
jobs:
  build:
    docker:
      - image: circleci/openjdk:8-jdk
    working_directory: ~/circleci-demo

    environment:
      JVM_OPTS: -Xmx3200m
      MVN_ARGS: -Dmaven.repo.local=.repo

    steps:
      - checkout

      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "pom.xml" }}
            # fallback to using the latest cache if no exact match is found
            - v1-dependencies-

      - run: mvn clean install package ${MVN_ARGS}

      - save_cache:
          paths:
            -  .repo
          key: v1-dependencies-{{ checksum "pom.xml" }}

      - store_artifacts:
          path: target/
          destination: circleci-demo-jar

      - persist_to_workspace:
          root: ~/
          paths:
            - circleci-demo
  test:
    docker:
      - image: circleci/openjdk:8-jdk
    working_directory: ~/circleci-demo

    environment:
      JVM_OPTS: -Xmx3200m
      MVN_ARGS: -Dmaven.repo.local=.repo

    steps:
      - attach_workspace:
          at: ~/circleci-demo

      - run: | 
          cd circleci-demo
          mvn clean test ${MVN_ARGS}

      - store_test_results:
          path: circleci-demo/target/surefire-reports


  deploy-site1:
    docker:
      - image: circleci/openjdk:8-jdk 
    steps:
      - run: echo 'deploy sit1'


  deploy-site2:
    docker:
      - image: circleci/openjdk:8-jdk 
    steps:
      - run: echo 'deploy sit2'


workflows:
  version: 2
  circleci-demo-workflow:
    jobs:
      - build:
          filters:
            branches:
              only: master

      - test:
          requires:
            - build

      - approval-deploy:
          type: approval
          requires:
            - test

      - deploy-site1:
          requires:
            - approval-deploy
          filters:
            branches:
              only: master

      - deploy-site2:
          requires:
            - approval-deploy
          filters:
            branches:
              only: master

03

触发workflow

默认通过代码push触发yaml,我们来看下流水线整体效果:

build和test执行成功后,workflow会hold在手工确认job“approval-deploy”中

点击每个job,会进入单独的job界面,这里包含了很多信息,包括 Test summary (测试汇总)、 Artifacts (产物)、 Configuration (配置)、 Parameters (参数)等等,比如这次的build job,执行结束后生成了一堆产物:

这里是test job的测试结果

点击手工确认job,确定将jar发布至2个站点(这里的deploy job仅仅是模拟,执行了一个echo)。

确认后,deploy-site1和deploy-site2会并发执行

04

解读yaml

在上面我们看到了完整的yaml,是不是一头雾水,没关系,我们拆分来看。

(如果想了解更多的yaml语法,可以看下另一篇文章,传送门)

首先将整个yaml拆分为jobs和workflows,jobs和workflows都是yml的根key,根jobs的作用是定义任务的具体执行逻辑,而workflows的作用是编排job,关于workflows的更多介绍可以看下 《每月处理 3000万+ 构建的企业级持续交付系统 CircleCI 是怎么炼成的?(二)超详细Pipeline语法解读》

4.1、jobs

jobs在yaml中结构:

version: 2
jobs:
  build:
    ...
  test:
    ...  

(1)build job

version: 2
jobs:
  build:
    #1.定义运行的环境,这里是包含jdk8的一个image
    docker:
      - image: circleci/openjdk:8-jdk

    #2.设置step共享的工作目录(step脚本相对这个目录执行)
    working_directory: ~/circleci-demo

        #3.定义job级别的环境变量,所有step共享
    environment:
      JVM_OPTS: -Xmx3200m
      MVN_ARGS: -Dmaven.repo.local=.repo

        #4.steps
    steps:
        #4.1 下载代码
      - checkout

      #4.2 拉取maven缓存
      - restore_cache:
          keys:
              # cachae key, 仅当pom.xml文件的校验和和上次一样(也就是没有变更)才会更新
            - v1-dependencies-{{ checksum "pom.xml" }} #
            # 如果上面的key失效用这个key代替
            - v1-dependencies-

            #4.3 打包
      - run: mvn clean install package ${MVN_ARGS}

            #4.4 上传缓存
      - save_cache:
              #缓存目录
          paths:
            -  .repo
          #换粗key,仅当pom.xml发生变更才更新
          key: v1-dependencies-{{ checksum "pom.xml" }}

          #4.5 上传产物(编译jar)
      - store_artifacts:
          path: target/
          destination: circleci-demo-jar

            #4.6 将workspace临时存储下来,供workflow下的其他job复用
      - persist_to_workspace:
          root: ~/
          paths:
            - circleci-demo

(2)test job

一个测试job,执行mvn test测试,并将测试产物上传

version: 2
jobs:
  test:
      #1.定义运行的环境,这里是包含jdk8的一个image
    docker:
      - image: circleci/openjdk:8-jdk
    #2.设置step共享的工作目录(step脚本相对这个目录执行)
    working_directory: ~/circleci-demo

        #3.定义job级别的环境变量,所有step共享
    environment:
      JVM_OPTS: -Xmx3200m
      MVN_ARGS: -Dmaven.repo.local=.repo

        #4.steps
    steps:
      #4.1 将build临时保留的workspace恢复到job中
      - attach_workspace:
          at: ~/circleci-demo

            #4.2执行mvn test测试脚本
      - run: | 
          cd circleci-demo
          mvn clean test ${MVN_ARGS}
            #4.3 上传测试产物
      - store_test_results:
          path: circleci-demo/target/surefire-reports

(3)deploy-site1/2 job

两个deploy job,模拟发布jar到两个站点

version: 2
jobs:       
  deploy-site1:
    docker:
      - image: circleci/openjdk:8-jdk 
    steps:
      - run: echo 'deploy sit1'


  deploy-site2:
    docker:
      - image: circleci/openjdk:8-jdk 
    steps:
      - run: echo 'deploy sit2'

4.2、workflows

workflows的作用就是编排job的先后顺序、指定job的执行条件等等

version: 2
workflows:
    #1. workflow版本
  version: 2
  #2. workflow 名称
  circleci-demo-workflow:
      #2.1 jobs
    jobs:
        #2.1.1 build job,仅在master分支触发
      - build:
          filters:
            branches:
              only: master

      #2.1.2 build job,仅在master分支触发,依赖build job
      - test:
          requires:
            - build

            #2.1.3 手动确认job,依赖test job
      - approval-deploy:
          type: approval
          requires:
            - test
            #2.1.4 发布job,依赖approval-deploy job, 和deploy-site2并发执行
      - deploy-site1:
          requires:
            - approval-deploy
          filters:
            branches:
              only: master

            #2.1.5 发布job,依赖approval-deploy job, 和deploy-site1并发执行
      - deploy-site2:
          requires:
            - approval-deploy
          filters:
            branches:
              only: master

引用

[1]Configuring CircleCI :https://circleci.com/docs/2.0/configuration-reference

[2]Getting Started Introduction:https://circleci.com/docs/2.0/getting-started/#creating-a-repository