场景示例-开发一个带红线卡点的SonarQube扫描步骤

本文将以对接 SonarQube 扫描服务为例,介绍如何使用 Flow-CLI 工具 V2 版本定制开发一个带红线卡点的扫描步骤。

前提条件

本地开发步骤

参考 RedlineSonar 示例代码 https://atomgit.com/flow-step-custom/RedlineSonar ,本地拉取示例代码:

git clone https://atomgit.com/flow-step-custom/RedlineSonar.git

示例代码目录结构如下:

.
├── README.md     # 步骤说明
├── package.json  # typescript 工程包声明
├── src           # 步骤后端执行逻辑
│   ├── index.ts
│   └── params.ts
├── step.yaml     # 步骤前端展示描述信息 yaml
├── tsconfig.eslint.json
└── tsconfig.json

步骤前端展示 step.yaml

step.yaml 文件定义了步骤前端描述,用于定义步骤执行所需的输入参数。参数说明如下:

参数

参数说明

id

步骤唯一标识,全局唯一。(如需发布步骤到企业,请修改 id 为唯一标识后发布)

name

用于定义步骤名称。

items

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

redline

红线信息。

datamap

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

key 红线待校验字段。

本步骤定义以下几个表单,作为步骤执行参数输入:

  • Sonar服务器地址

  • Sonar Token

  • Sonar Project Key

  • 红线信息

---
apiVersion: v2
kind: DefaultJob
id: RedlineSonar
name: RedlineSonar
description: flow redline check with sonar
helpUrl: https://atomgit.com/flow-step-custom/RedlineSonar
execution:
  executor: node
  main: dist/index.js
items:
  - label: Sonar服务器地址
    name: STEP_SONAR_HOST
    type: input
  - label: Sonar Token
    name: STEP_SONAR_TOKEN
    type: password
    rules:
      - require: false
  - label: Sonar Project Key
    name: STEP_SONAR_PROJECT_KEY
    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": "Bugs","type": "LE"},{"key": "Vulnerabilities","type": "LE"},{"key": "Smells","type": "LE"},{"key": "Coverage","type": "GE"}]'
          rules:
            - require: false

红线信息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

指令覆盖率

步骤后端执行逻辑 src/index.ts

src/index.ts 文件定义了步骤后端执行逻辑,主要逻辑说明如下:

  1. 输出基础信息和检验步骤入参

  2. 调用 sonar api 获取指定项目的指标数据(私有项目需要指定 STEP_SONAR_TOKEN)

  3. 将 sonar 返回数据格式化为红线数据

  4. 调用 sdk 进行红线检验和记录报告链接信息

async function runStep(): Promise<void> {
  const params = getParams()
  // 输出基础信息和检验入参
  logAndValidParams(params);

  // 调用 sonar api 获取指定项目的指标数据
  const metrics = await requestSonarMetrics(`${params.sonarHost}/api/measures/search`, params.sonarToken, {
    projectKeys: `${params.sonarProjectKey}`,
    metricKeys: 'alert_status,bugs,reliability_rating,vulnerabilities,security_rating,code_smells,sqale_rating,duplicated_lines_density,coverage,ncloc,ncloc_language_distribution'
  })
  step.infoCyan(`Sonar Metrics: ${JSON.stringify(metrics)}`)

  const bugs = Number(metrics['bugs'])
  const vulnerabilities = Number(metrics['vulnerabilities'])
  const smells = Number(metrics['code_smells'])
  const coverage = Number(metrics['coverage'])

  // 准备红线数据
  const readlineResults = [] as RedlineResult[]
  const bugsRR = generateRedlineResult("Bugs", "缺陷", bugs, redline.Error);
  readlineResults.push(bugsRR)

  const vulnerabilitiesRR = generateRedlineResult("Vulnerabilities", "漏洞", vulnerabilities, redline.Error);
  readlineResults.push(vulnerabilitiesRR)

  const smellsRR = generateRedlineResult("Smells", "坏味道", smells, redline.Error);
  readlineResults.push(smellsRR)

  const coverageRR = generateRedlineResult("Coverage", "覆盖率", coverage, redline.Warning);
  readlineResults.push(coverageRR)

  // 调用 sdk 进行红线检验和记录报告链接信息
  const redlineInfo = {} as RedlineInfo
  redlineInfo.title = 'Redline Sonar'
  redlineInfo.reportUrl = `${params.sonarHost}/component_measures?id=${params.sonarProjectKey}`
  redlineInfo.readlineResults = readlineResults
  const checkResult = step.redline.redlineCheck(redlineInfo, process.env['CHECK_REDLINES'])
  if (!checkResult){
      step.error('Redline check failed')
      process.exit(-1)
  }
}

发布步骤

按需修改上述步骤实现代码后,切换到 step.yaml 文件所在目录,执行以下命令发布步骤到企业:

flow-cli step publish

流水线使用步骤并运行

步骤发布成功后,进入流水线编辑页面,可以在任务编辑页面,指定容器环境 -> 添加步骤 -> 企业步骤,添加 RedlineSonar 这个步骤。

image

编辑后保存并运行流水线,查看步骤运行结果和日志:

image

image

高级用法

在流水线中,推荐使用原子的步骤进行组合支持复杂的使用场景。例如以上的 RedlineSonar 步骤只负责从 sonar 读取某个 projectKey 的 metric 数据,对于 mvn 工程的 sonar 卡点可采取步骤组合如下。

image

其中执行命令对 mvn 工程进行构建和调用 sonar 插件进行扫描:

# mvn 构建
mvn -B clean package -Dmaven.test.skip=true -Dautoconfig.skip

# 通过 mvn sonar 插件执行 sonar 扫描
mvn verify -Dmaven.test.failure.ignore=true org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.token=<your personal access token> -Dsonar.host.url=https://sonarcloud.io -Dsonar.organization=<your organization key> -Dsonar.projectKey=<your project key>

运行效果如下:

image

image

点击「报告」查看sonar扫描结果详情如下:

image

image