将测试结果和构建脚本添加到管道
通过将新的或现有测试和构建脚本的结果添加到 DevSecOps 管道持续集成流程,将现有测试和构建流程连接到持续集成管道。
在管道启动时,DevSecOps 脚本会自动将应用程序和配置存储库克隆到以下目录中:
-
克隆应用程序存储库的路径为
/workspace/app/<APP_REPO_NAME> -
管道配置存储库克隆在路径
/workspace/app/one-pipeline-config-repo
在任何阶段,如果需要运行这些资源库中的脚本,必须首先导航到相应的目录。 您可以使用以下方法之一来实现这一目标:
- 直接使用克隆的版本库路径
-
应用程序存储库:
cd "${WORKSPACE}/$APP_REPO_NAME" -
配置存储库:
cd "${WORKSPACE}/one-pipeline-config-repo/"
- 使用 load_repo 命令
-
应用程序存储库:
cd "${WORKSPACE}/$(load_repo app-repo path)" -
配置存储库:
cd "${WORKSPACE}/$(load_repo one-pipeline-config-repo path)"
$WORKSPACE 指的是根路径 /workspace/app。
您可以在持续集成管道中使用以下阶段来添加测试和构建步骤:
- 设置
- 测试
- 容器化 (构建)
- 发行版
管道设置
使用 Setup 阶段来设置测试和构建环境,并将信息拉入管道。 例如,可以在单个构建中使用多个与应用程序相关的存储库。 您可以克隆所需的所有存储库,并使管道在合规性相关检查和扫描中了解这些存储库。
由管道内部克隆并通过使用具有引用名称 app-repo 的 save_repo pipelinectl 接口添加到管道的缺省应用程序存储库。 如果从工具链模板设置管道,那么缺省存储库由存储库管道 UI 参数提供,或者由其工具链绑定名称选择。
如果要使用更多存储库,请在 setup 阶段中克隆这些存储库,并使用相同的 save_repo 界面将其添加到管道中。
示例
#
# your scripts cloning the repositories
#
# make sure you prepare or export the following data from each cloned repository:
# - repository URL
# - path where it was cloned, relative to the $WORKSPACE path
# - cloned branch
# - latest commit hash
#
your_clone_scripts
#
# when cloning is complete
# use `save_repo` to add these information to the pipeline
# repo-reference-name can be any name, it is used to refer to the stored repo
#
save_repo <repo-reference-name> \
url="${REPO_URL}" \
path="${REPO_PATH}" \
branch="${CLONED_BRANCH}" \
commit="${LATEST_GIT_COMMIT}"
这样,管道的其余部分可以扫描这些存储库以查找合规性违例和漏洞。
使用 save_repo 保存的路径必须相对于工作空间路径。
您无需为脚本或基本映像安装 pipelinectl 工具,参考管道将提供脚本上下文的二进制文件。
测试
此阶段是在代码存储库上运行测试的阶段。 您可以使用 list_repos 和 load_repo pipelinectl 界面来访问在安装阶段中添加的存储库。
示例
exit_code=0
#
# `list_repos` returns the list of the reference names of saved repos
#
list_repos | while IFS= read -r repository ; do
#
# load_repo returns a property of a saved repository
#
# Usage:
# load_repo <repo-reference-name> <property>
#
url="$(load_repo "$repository" url)"
sha="$(load_repo "$repository" commit)"
branch="$(load_repo "$repository" branch)"
path="$(load_repo "$repository" path)"
#
# use your repos to test, etc
#
run_tests
result=$?
if [ $result != 0 ]; then
exit_code=$result
fi
done
exit $exit_code
单元测试一致性控制基于阶段脚本的退出代码。 如果测试通过,请使用 0 退出。 否则,在末尾返回非零退出代码。
保存结果
您的测试可能会生成一些报告工件,例如 JSON 或 XML 中的测试结果。 在此阶段中使用 save_result pipelinectl 接口将测试作为证据工件附加到创建的合规性证据。
#
# run tests with some test suite runner, and save output to results.json
#
test_runner -o results.json
#
# save the result for the pipeline, so it can attach it to the unit test evidence
#
save_result test results.json
save_results 的第一个参数必须是 DevSecOps 管道配置阶段名称,如 test、scan-artifact 或 acceptance-test。 否则,证据收集器将无法找到该证据并将其附加到正确的证据。
使用 save_result pipelinectl 接口可确保管道查找结果工件,将这些工件上载到证据锁定程序并附加到管道创建的合规性证据。
使用 save_result 时为单元测试创建的示例证据:
{
"evidence_type_id": "com.ibm.unit_tests",
"evidence_type_version": "1.0.0",
"date": "2021-03-31T07:41:31.881Z",
"result": "success",
"pipeline_id": "8c2b6750-91db-45fb-98ee-51684843b821",
"pipeline_run_id": "89a04de9-2795-4e8e-be90-52a92ac7f9c1",
"issues": [],
"artifacts": [
{
"url": "https://s3.us-south.cloud-object-storage.appdomain.cloud/cos-bucket-name/ci/89a04de9-2795-4e8e-be90-52a92ac7f9c1/artifacts/compliance-app-COMPACT-20210218231513608/unit-tests-results.json_d9619521e7444fef0ff052e59fd54049",
"hash": "d9619521e7444fef0ff052e59fd54049"
}
],
"toolchain_crn": "crn:v1:bluemix:public:toolchain:us-south:a/40111714589c4f7099032529b26a7a63:39d4f080-55e5-42ee-a787-26d936fb2b97::",
"log": [
{
"url": "https://cloud.ibm.com/devops/pipelines/tekton/8c2b6750-91db-45fb-98ee-51684843b821/runs/89a04de9-2795-4e8e-be90-52a92ac7f9c1/code-unit-tests/run-stage?env_id=ibm:yp:us-south",
"hash": null
},
{
"url": "https://s3.us-south.cloud-object-storage.appdomain.cloud/cos-bucket-name/ci/89a04de9-2795-4e8e-be90-52a92ac7f9c1/artifacts/logs/code-unit-tests/run-stage.log_dae902fb1455b1fc9c565273aa4fe1bc",
"hash": "dae902fb1455b1fc9c565273aa4fe1bc"
}
]
}
构建或容器化
在此阶段中,您可以构建工件。 管道为 Docker 映像类型工件提供了一些缺省功能,但您可以在此处构建任何工件。 为管道保存已创建的工件,以便稍后可以对其运行扫描,或者在发布阶段中使用这些工件。
要提供有关已构建工件的信息,请使用 save_artifact pipelinectl 接口。
示例
#
# your scripts building the artifact
#
# make sure you prepare or export the following data from each built artifact:
# - type (image for docker images, package for rpms, npm tarballs, etc )
# - full artifact URL with version tag
# - artifact digest
#
your_build_scripts
#
# when the build is complete
# use `save_artifact` to add these information to the pipeline
# artifact-reference-name can be any name, it is used to refer to the stored artifact
#
save_artifact <artifact-reference-name> \
type=image" \
name="${IMAGE_URL}" \
digest="${IMAGE_DIGEST}"
图像名称的首选格式是 image-URL:build-tag。
如果构建 Docker 映像,请使用 save_artifact 接口为缺省内置映像签名和 CR IBM Informix 虚拟设备扫描任务发送这些映像。
发行版
在管道结束时,必须将构建的工件添加到库存中,以便可以将其提升到部署。 如果要将其他工件 (例如 Helm 图表) 添加到库存,那么发布阶段将提供灵活性。
在此阶段中,可以使用 CLI cocoa inventory add 命令以及 pipelinectl 命令中的数据来创建库存条目。
如果管道运行中存在问题,那么您可以选择跳过库存更新以避免有问题的库存。 要跳过库存更新,请使用以下环境变量:
skip-inventory-update-on-failure来自管道的选择性加入环境变量,用于指定是否更新库存。one-pipeline-status如果管道运行中存在阶段故障,请设置为1。
在此阶段中调用 cocoa inventory add 之前,请检查这些变量。
示例
# Check the status of pipeline and then release the artifacts to inventory
ONE_PIPELINE_STATUS=$(get_env one-pipeline-status 0)
if [ -n "$(get_env skip-inventory-update-on-failure "")" ]; then
if [ $ONE_PIPELINE_STATUS -eq 1 ]; then
echo "Skipping release stage as some of the pipeline stages are not successful."
exit 1
fi
fi
#
# `list_artifacts` returns the list of the reference names of saved artifacts
#
list_artifacts | while IFS= read -r artifact ; do
#
# Add a new value to the inventory repository. `cocoa inventory add` creates a new file with the name option,
# if does not exist otherwise overwrites it.
#
cocoa inventory add \
--name="${artifact}" \
--artifact="$(load_artifact $artifact name)" \
--repository-url="$(load_repo app-repo url)" \
--commit-sha="$(load_repo app-repo commit)" \
--build-number="${BUILD_NUMBER}" \
--pipeline-run-id="${PIPELINE_RUN_ID}" \
--version="$(get_env version)" \
--app-artifacts="{ \
\"signature\": \"$(load_artifact $artifact signature)\", \
\"provenance\": \"$(load_artifact $artifact name)\"\
}"
done
要使用 CLI,必须将其安装在脚本中,或者使用预先安装了 CLI 的基本映像。