创建一个带红线功能的测试步骤

本文作为自定义步骤的进阶,以 Sonar 为例创建一个用于测试/扫描的步骤,并开放给所有企业。

准备

  • 一个公网可访问的 Sonar 服务。

  • 一个用于测试的代码库,以 maven 项目为例,确保 pom 文件中引入了 sonar 插件:

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.sonarsource.scanner.maven</groupId>
                    <artifactId>sonar-maven-plugin</artifactId>
                    <version>3.4.0.905</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

本地开发

参照自定义步骤 Flow CLI 子命令:step搭建好开发环境,初始化一个步骤:

flow step init sonar-qube

sona-qube 目录下会有三个文件

sona-qubeBash 目录

  • Dockerfile 用于构建步骤镜像,Dockerfile 中的基础镜像为云效提供的基础镜像,里面已经内置了一些软件,尽量不要更改基础镜像,如需更改基础镜像,请确保新的基础镜像中安装了jq。

  • step.sh 为在步骤中执行的脚本。

  • step.yaml 用户描述步骤信息。

前端

  1. 编辑sonar-qube文件夹下面的step.yaml

    重要

    image 需要改成用户自己的镜像地址,且必须为公开pull权限。

    ---
    name: SonarQube(预发)
    sign: sonar-qube-staging
    description: SonarQube用于测试公开步骤
    category: 静态扫描
    image: registry.cn-beijing.aliyuncs.com/build-steps/sonar-qube-staging:1.0
    items:
      - label: Sonar服务器地址
        name: STEP_SONAR_HOST
        type: input
      - label: 红线信息
        name: CHECK_REDLINES
        type: addable_group
        rules:
          - require: false
        add_button:
          type: icon
          icon: plus
          text: 增加红线
          tip:
            icon: question-circle
            description: 红线校验失败任务将失败 
        template:
          items:
            - name: redline
              label: 红线
              position: flat
              type: custom_redline_dropdown
              datamap: '[{"key": "Total","type": "LE"},{"key": "Blocker","type": "LE"},{"key": "Critical","type": "LE"},{"key": "Major","type": "LE"}]'
              rules:
                - require: false
    

    参数

    参数说明

    name

    用于定义步骤名称。

    sign

    步骤唯一标识,全局唯一。

    category

    步骤分类。

    image

    步骤镜像地址,image 需要改成用户自己的镜像地址,且必须为公开pull权限。

    items

    步骤语言描述,请参考步骤语言YAML描述。

    redline

    红线信息。

    datamap

    type 枚举字段 LE: 实际值小于等于期望值;GE: 实际值大于等于期望值;EQ 实际值等于期望值

    key 红线待校验字段。

    以下key 支持显示中文描述,自定义key则直接显示key:

    key(不区分大小写)

    中文描述

    passedrate

    测试通过率

    total

    Total 问题数

    blocker

    Blocker 问题数

    high

    High 问题数

    medium

    Medium 问题数

    critical

    Critical 问题数

    major

    Major 问题数

    violation

    Violation 问题数

    information

    Information 问题数

    warning

    Warning 问题数

    error

    Error 问题数

    linecoveragerate

    行覆盖率

    branchcoveragerate

    分支覆盖率

    methodcoveragerate

    方法覆盖率

    classcoveragerate

    类覆盖率

    instructioncoveragerate

    指令覆盖率

  2. 校验 Yaml,在 sonar-qube 文件夹下执行:

    flow step valid

    没有任何输出表示校验通过。

后端

  1. 编辑Dockerfile

    FROM registry.cn-beijing.aliyuncs.com/rdc-builds/oracle-jdk:1.8
    MAINTAINER jintang <yidong.***@alibaba-inc.com>
    COPY .step/*.sh /root/
    COPY sonar-qube/step.sh /root/step.sh
    RUN chmod +x /root/*.sh
    ENTRYPOINT [ "/root/entry.sh"]
  2. 请确保基础镜像中已经安装jq

  3. 编辑sonar-qube文件夹下面的step.sh

    #!/bin/bash
    set -e
    
    export SONAR_INFO=$WORK_SPACE/sonar_info.json
    
    # 系统提供参数,从流水线上下文获取
    echo [INFO] PIPELINE_ID=$PIPELINE_ID       # 流水线ID
    echo [INFO] PIPELINE_NAME=$PIPELINE_NAME   # 流水线名称
    echo [INFO] BUILD_NUMBER=$BUILD_NUMBER     # 流水线运行实例编号
    echo [INFO] EMPLOYEE_ID=$EMPLOYEE_ID       # 触发流水线用户ID
    echo [INFO] WORK_SPACE=$WORK_SPACE         # /root/workspace容器中目录
    echo [INFO] PROJECT_DIR=$PROJECT_DIR       # 代码库根路径,默认为/root/workspace/code
    echo [INFO] PLUGIN_DIR=$PLUGIN_DIR         # 插件路径,默认为/root/workspace/plugins
    echo [INFO] BUILD_JOB_ID=$BUILD_JOB_ID     # build-service 任务ID
    
    cd $PROJECT_DIR
    
    mvn install -DskipTests
    mvn sonar:sonar -Dsonar.host.url=$STEP_SONAR_HOST
    
    STEP_PROJECT_GROUP_ID=`mvn -q -Dexec.executable=echo -Dexec.args='${project.groupId}' --non-recursive exec:exec 2>/dev/null`
    STEP_PROJECT_ARTIFACT_ID=`mvn -q -Dexec.executable=echo -Dexec.args='${project.artifactId}' --non-recursive exec:exec 2>/dev/null`
    
    curl $STEP_SONAR_HOST/api/measures/search\?projectKeys\=$STEP_PROJECT_GROUP_ID%3A$STEP_PROJECT_ARTIFACT_ID\&metricKeys\=alert_status%2Cbugs%2Creliability_rating%2Cvulnerabilities%2Csecurity_rating%2Ccode_smells%2Csqale_rating%2Cduplicated_lines_density%2Ccoverage%2Cncloc%2Cncloc_language_distribution > $SONAR_INFO
    
    STEP_SONAR_BUGS=`jq -r '.measures[] | select(.metric == "bugs") | .value' $SONAR_INFO`
    STEP_SONAR_VULNERABILITIES=`jq -r '.measures[] | select(.metric == "vulnerabilities") | .value' $SONAR_INFO`
    STEP_SONAR_SMELLS=`jq -r '.measures[] | select(.metric == "code_smells") | .value' $SONAR_INFO`
    STEP_SONAR_COVERAGE=`jq -r '.measures[] | select(.metric == "coverage") | .value' $SONAR_INFO`
    
    
    redline Bugs:缺陷:$STEP_SONAR_BUGS:Error Vulnerabilities:漏洞:$STEP_SONAR_VULNERABILITIES:Warning Smells:坏味道:$STEP_SONAR_SMELLS:Warning Coverage:覆盖率:$STEP_SONAR_COVERAGE:Default Report:$STEP_SONAR_HOST/dashboard?id=$STEP_PROJECT_GROUP_ID%3A$STEP_PROJECT_ARTIFACT_ID
    • set -e :表示运行过程中遇到任何错误步骤即错误退出,随机流水线也会中断运行。

    • cd $PROJECT_DIR :表示进入代码库所在路径。

    • mvn install -DskipTests :安装 maven 依赖。

    • mvn sonar:sonar -Dsonar.host.url=$STEP_SONAR_HOST 执行 Sonar 扫描。

    • redline ... :redline 这个方法主要作用是将输入结构简单化,并会自动解析红线。以空格为分隔,每段字符包含<key>:<name>:<value>:<style> ,报告格式为: Report:<url>。key 要和step.yaml中红线定义的key一致。Style 展示的样式 Error: 红色,Warning: 橙色,Default: 灰 。

    影响前端显示,最终会在日志里形成下列输出:

    日志

    左侧每一个元素对应右侧三行输出,分别为:

    • STATE_NAME_xxx: 字段名称。

    • STATE_VALUE_xxx:字段值。

    • STATE_STYLE_xxx:字段样式(Error: 红色,Warning: 橙色,Default: 灰色)。

    STATE_URL___REPORT为报告链接,在前端显示为报告按钮,点击调整到值对应的 Url。

  4. 如果想上传本地文件生成报告链接,可以在自定义步骤后追加“报告上传”步骤。

本地运行

步骤的本质是一个容器镜像,因此可以在本地运行,flow cli 帮助在本地模拟一个和流水线上运行相似的环境,包括挂载代码路径、缓存以及一些流水线上下文环境变量。在sonar-qube文件夹下执行:

flow step run

输入STEP_SONAR_HOSTCHECK_REDLINESworkspace三个变量,步骤即可在本地运行。

CHECK_REDLINES 举例:

[{\"identifier\":\"10_1581409320500__10_1581421770772__CHECK_REDLINES__0\",\"key\":\"Bugs\",\"type\":\"LE\",\"threshold\":0},{\"identifier\":\"10_1581409320500__10_1581421770772__CHECK_REDLINES__1\",\"key\":\"Vulnerabilities\",\"type\":\"GE\",\"threshold\":2}]Bash

identifier 为步骤唯一标识,可以是随机字符串,key 为待校验字段,type 为枚举字段,分别标识:LE: 实际值小于等于期望值;GE: 实际值大于等于期望值;EQ 实际值等于期望值;thredshold 为期望值。

您可以通过日志输出观察运行情况以及在$WORK_SPACE/params里是否得到预期的返回。

  • 这个命令会执行 docker build, docker run 两个命令以在本地运行步骤。

  • 输入的参数会换存到sonar-qube/params.env文件内,无需每次输出。

  • 多次运行 maven 依赖会缓存到本地~/.m2

  • 运行时输入的 workspace 对应到本地的一个绝对路径,会被 mount 到容器中 /root/workspace/code 路径下,这个路径在流水线运行时为可变路径,可以在 step.sh 中使用 $PROJECT_DIR 变量获得

企业内使用

sonar-qube文件夹下执行:

flow step publish

该命令会执行 docker build, docker push 两个命令以发布步骤镜像,同时将步骤信息(yaml)同步到企业下的步骤列表。执行以下命令查看列表:

flow step ls

同时进入企业流水线编辑页面,可以在添加步骤->自定义步骤中看到 SonarQube 这个步骤。

步骤测试

这个步骤可以和系统提供的其他步骤一样使用:

系统

跨企业共享步骤

开放步骤给所有 Flow 的企业,在sonar-cube所在目录下执行:

flow step public sonar-qube
flow step ls

跨企业共享步骤1

可以看到sonar-cube步骤的状态变为了PORCESSING,这个时候需要等待云效的工作人员进行人工审核,一段时间后步骤状态再次变为PRIVATE,使用命令flow step search可以查看到一个sonar-qube-<regionId>的步骤说明步骤被成功公开,如果审核不通过,会在云效页面右上角的通知栏里告知审核未通过原因。

步骤公开成功后得到两个步骤,一个为企业内可见的自定义步骤,sign 为sonar-qube,一个为公开步骤,sign 为sonar-qube-<regionId>,如果想要更新线上步骤,需要再执行一次flow step public,所有步骤历史版本都会保留,通过flow step version <sign>可以查看步骤版本,flow step get <sign> -v <version>可以查看该步骤历史版本详细信息。

sonar-qube显示在步骤编辑页中自定义步骤栏sonar-qube-<regionId>显示类别位置由step.yaml中的 category 字段决定:

跨企业共享步骤2