GitLab流水线间值共享问题:如何获取Checkstyle历史工件?
GitLab流水线获取上一次构建Checkstyle工件的解决方案
问题背景
我正在实现Checkstyle质量门禁,但脚本中if [ -e no_checkstyle_issues.txt ]; then PREVIOUS_ISSUES=$(cat no_checkstyle_issues.txt); else PREVIOUS_ISSUES=99999; fi这一行始终返回99999,显然是无法获取上一次构建生成的no_checkstyle_issues.txt工件导致的。当前的GitLab CI配置如下:
checkstyle: extends: .test-build-template stage: checkstyle artifacts: when: always paths: - "no_checkstyle_issues.txt" expire_in: 3 hrs script: - echo "Running checkstyle stage" - gradle checkstyleMain # no. of Checkstyle issues from previous commit - PREVIOUS_ISSUES=0 - if [ -e no_checkstyle_issues.txt ]; then PREVIOUS_ISSUES=$(cat no_checkstyle_issues.txt); else PREVIOUS_ISSUES=99999; fi - echo "No. of previous checkstyle issues = $PREVIOUS_ISSUES" # no. of Checkstyle issues from current commit - CURRENT_ISSUES=0 - for file in $(find . -type f -name 'main.xml'); do CURRENT_ISSUES=$((CURRENT_ISSUES + $(grep -o '<error' $file | wc -l))); done - echo "No. of current checkstyle issues = $CURRENT_ISSUES" # if CURRENT_ISSUES > PREVIOUS_ISSUES, fail pipeline - if [ $CURRENT_ISSUES -gt $PREVIOUS_ISSUES ]; then echo "Checkstyle issues increased. Failing pipeline!"; exit 1; fi - mkdir -p artifacts/checkstyle - echo $CURRENT_ISSUES > no_checkstyle_issues.txt - exit 0
问题原因
GitLab CI的每个构建都是独立的隔离环境,默认不会自动拉取上一次构建的工件。当前脚本仅检查本地目录是否存在目标文件,自然找不到,所以每次都会进入else分支返回99999。
解决方法
要获取上一次成功构建的工件,需要通过GitLab API手动下载。修改CI脚本如下:
1. 添加工件下载逻辑
在获取PREVIOUS_ISSUES的步骤前,加入以下命令,利用GitLab预定义的CI变量完成API调用,下载上一次构建的工件:
# 下载上一次成功构建的no_checkstyle_issues.txt工件 - | curl --header "JOB-TOKEN: $CI_JOB_TOKEN" \ "$CI_API_V4_URL/projects/$CI_PROJECT_ID/jobs/artifacts/$CI_DEFAULT_BRANCH/download?job=$CI_JOB_NAME" \ --output previous_build_artifacts.zip # 解压目标文件,若没有上一次工件则忽略错误 - unzip -o previous_build_artifacts.zip no_checkstyle_issues.txt || true
2. 保留原有检查逻辑
后续检查文件是否存在的逻辑无需修改:如果下载成功就读取上一次的问题数,否则仍使用99999作为初始值,符合第一次构建时的预期。
修改后的完整CI配置
checkstyle: extends: .test-build-template stage: checkstyle artifacts: when: always paths: - "no_checkstyle_issues.txt" expire_in: 3 hrs script: - echo "Running checkstyle stage" - gradle checkstyleMain # 下载上一次构建的工件 - | curl --header "JOB-TOKEN: $CI_JOB_TOKEN" \ "$CI_API_V4_URL/projects/$CI_PROJECT_ID/jobs/artifacts/$CI_DEFAULT_BRANCH/download?job=$CI_JOB_NAME" \ --output previous_build_artifacts.zip - unzip -o previous_build_artifacts.zip no_checkstyle_issues.txt || true # 获取上一次Checkstyle问题数 - PREVIOUS_ISSUES=0 - if [ -e no_checkstyle_issues.txt ]; then PREVIOUS_ISSUES=$(cat no_checkstyle_issues.txt); else PREVIOUS_ISSUES=99999; fi - echo "No. of previous checkstyle issues = $PREVIOUS_ISSUES" # 获取当前Checkstyle问题数 - CURRENT_ISSUES=0 - for file in $(find . -type f -name 'main.xml'); do CURRENT_ISSUES=$((CURRENT_ISSUES + $(grep -o '<error' $file | wc -l))); done - echo "No. of current checkstyle issues = $CURRENT_ISSUES" # 质量门禁检查 - if [ $CURRENT_ISSUES -gt $PREVIOUS_ISSUES ]; then echo "Checkstyle issues increased. Failing pipeline!"; exit 1; fi - mkdir -p artifacts/checkstyle - echo $CURRENT_ISSUES > no_checkstyle_issues.txt - exit 0
注意事项
- 确保GitLab版本在10.0以上,
CI_JOB_TOKEN才有下载工件的权限。 - 如果流水线运行在非默认分支,需要将
$CI_DEFAULT_BRANCH替换为$CI_COMMIT_BRANCH,以对应目标分支的上一次构建。 - 第一次构建时没有历史工件,
unzip会报错,但|| true会忽略错误,脚本会正常使用99999作为初始值,不影响首次检查。
内容的提问来源于stack exchange,提问作者AndreasInfo
相关产品推荐
相关产品推荐

