在CI构建中验证OAS 3规范的技术实践

本文详细介绍了如何在持续集成流程中使用Swagger Validator Badge工具验证OpenAPI 3规范文件。通过Travis CI配置,包括环境变量设置、本地验证器部署和自动化验证步骤,确保API规范在每次拉取请求时保持正确性。

OAS 3 YAML文件是标准的核心。因此,我们必须始终保持其正确性,特别是在每个拉取请求中确保其有效性。不同标准在参考实现的合规性测试方面有不同级别,但有一点是相同的——我们希望作为持续集成的一部分,对每个拉取请求验证规范。本文描述了如何实现这一点。

为了验证规范,我们使用在Travis CI中运行的Swagger Validator Badge工具。因此,整个设置在仓库根目录的.travis.yml文件中指定。

文件以一个相当标准的开头开始:

1
2
3
4
5
language: java
dist: trusty
sudo: false
jdk:
  - openjdk8

我们使用Java,因为需要运行Maven构建来启动Swagger Validator Badge(见下文)。我们构建YAML文件的URL,以针对本地验证器实例进行验证,并将其存储在环境变量中:

1
2
env:
  - GH_URL=https://raw.githubusercontent.com VALIDATOR_URL=http://localhost:8080/validator/debug?url FILE_TO_VALIDATE=openapi.yaml URL_TO_VALIDATE=$GH_URL/${TRAVIS_PULL_REQUEST_SLUG:-$TRAVIS_REPO_SLUG}/${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}/$FILE_TO_VALIDATE

上述代码段假设规范文件名为openapi.yaml(如果使用不同名称,请更改$FILE_TO_VALIDATE的值),并以适用于拉取请求和分支的方式构建文件URL。更多信息请参见“在Travis CI构建中获取GitHub仓库中文件的URL”。

接下来是before_install阶段,我们在此准备本地Swagger Validator Badge实例。通过克隆该工具的仓库并构建v2.0.0标签来实现。在撰写本文时,Swagger Validator Badge尚未完全支持OAS 3.0。v2.0.0是提供部分支持的最新版本,这就是我们需要执行此步骤的原因。该工具正在积极开发中,2.0分支以不向后兼容的方式更改(硬学到的教训),因此在此处使用标签非常重要。

如果您的API使用OAS 2指定,可以跳过整个before_install步骤,直接对托管版本的Swagger Validator Badge执行请求。如果使用OAS 3,一旦托管版本切换到2.0发布线,您将能够移除此步骤。在此之前,我们自行构建该工具,在后台运行,并等待其启动:

1
2
3
4
5
6
7
before_install:
  # 构建并启动validator-badge。一旦在线版本的validator-badge支持OAS 3.0,此设置将不再需要。在此之前,我们需要设置本地版本。
  - git clone --branch=v2.0.0 https://github.com/swagger-api/validator-badge.git
  - cd validator-badge
  - mvn package -q -DskipTests=true -Dmaven.javadoc.skip=true -B -V jetty:run &
  - cd ..
  - sleep 60

实际验证在script部分执行。我们使用curl对验证器执行请求,附带YAML文件的URL。我们使用验证器的/debug端点,该端点以JSON格式返回验证消息。此输出包括指向YAML文件问题的错误,以及验证器工具尚未支持的功能的警告。我们打印验证器的输出以便于分析失败的构建,并使用jq计算错误数,忽略警告。如果错误数不为0,则构建失败:

1
2
3
4
5
6
7
8
9
script:
  # 验证
  - echo "Validating $URL_TO_VALIDATE:"
  - VALIDATION_OUTPUT=`curl -sS "$VALIDATOR_URL=$URL_TO_VALIDATE"`
  # 打印验证错误
  - echo $VALIDATION_OUTPUT
  # 检查忽略警告的验证输出是否为空数组
  - VALIDATION_ERROR_COUNT=`echo "$VALIDATION_OUTPUT" |jq -c '.schemaValidationMessages // [] | map(select(.level != "warning"))' |jq length`
  - test "$VALIDATION_ERROR_COUNT" == 0

将所有内容整合在一起,我们得到以下.travis.yml文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
language: java
dist: trusty
sudo: false
jdk:
  - openjdk8
env:
  - GH_URL=https://raw.githubusercontent.com VALIDATOR_URL=http://localhost:8080/validator/debug?url FILE_TO_VALIDATE=openapi.yaml URL_TO_VALIDATE=$GH_URL/${TRAVIS_PULL_REQUEST_SLUG:-$TRAVIS_REPO_SLUG}/${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}/$FILE_TO_VALIDATE
before_install:
  # 构建并启动validator-badge。一旦在线版本的validator-badge支持OAS 3.0,此设置将不再需要。在此之前,我们需要设置本地版本。
  - git clone --branch=v2.0.0 https://github.com/swagger-api/validator-badge.git
  - cd validator-badge
  - mvn package -q -DskipTests=true -Dmaven.javadoc.skip=true -B -V jetty:run &
  - cd ..
  - sleep 60
script:
  # 验证
  - echo "Validating $URL_TO_VALIDATE:"
  - VALIDATION_OUTPUT=`curl -sS "$VALIDATOR_URL=$URL_TO_VALIDATE"`
  # 打印验证错误
  - echo $VALIDATION_OUTPUT
  # 检查忽略警告的验证输出是否为空数组
  - VALIDATION_ERROR_COUNT=`echo "$VALIDATION_OUTPUT" |jq -c '.schemaValidationMessages // [] | map(select(.level != "warning"))' |jq length`
  - test "$VALIDATION_ERROR_COUNT" == 0

您可以在几个GA4GH标准中看到此方法的实际应用,例如Beacon、Service Registry、Service Info、Consent Codes、ADA-M等。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计