如何在GitHub Actions工作流中保存ZAP双扫描任务的产物
问题描述
尝试通过GitHub Actions工作流同时执行ZAP API扫描与ZAP全量扫描,期望生成两个可下载至本地目录的产物“artifact1”和“artifact2”,但当前编写的YAML脚本无法实现该功能。原脚本分为三部分:Full_scans job执行全量扫描并尝试存储结果,API_scan job执行API扫描并存储结果,Upload_Artifacts job尝试上传两个扫描的结果。
原脚本片段如下:
name: ZAP Security Scans on: push: branches: - main jobs: Full_scans: runs-on: ubuntu-latest outputs: full_scan_result: ${{ steps.store_full_scan_result.outputs.full_scan_result }} steps: - name: Checkout uses: actions/checkout@v4 with: ref: main - name: ZAP Full Scan id: full_scan uses: zaproxy/action-full-scan@v0.9.0 with: token: ${{ secrets.GITHUB_TOKEN }} docker_name: 'ghcr.io/zaproxy/zaproxy:stable' target: 'www.targeturl.com' - name: Store Full Scan Result id: store_full_scan_result run: | mkdir -p full_scan_results mv *.html full_scan_results/ || true FULL_RESULT_FILE=$(find full_scan_results -name "*.html" -type f) echo "::set-output name=full_scan_result::$FULL_RESULT_FILE" API_scan: runs-on: ubuntu-latest outputs: api_scan_result: ${{ steps.store_api_scan_result.outputs.api_scan_result }} steps: - name: Checkout uses: actions/checkout@v4 with: ref: main - name: ZAP API Scan id: api_scan uses: zaproxy/action-api-scan@v0.6.0 with: token: ${{ secrets.GITHUB_TOKEN }} docker_name: 'ghcr.io/zaproxy/zaproxy:stable' format: openapi target: 'www.targeturl.com' - name: Store API Scan Result id: store_api_scan_result run: | mkdir -p api_scan_results mv *.html api_scan_results/ || true API_RESULT_FILE=$(find api_scan_results -name "*.html" -type f) echo "::set-output name=api_scan_result::$API_RESULT_FILE" Upload_Artifacts: needs: - Full_scans - API_scan runs-on: ubuntu-latest steps: - name: Upload Full Scan Artifact uses: actions/upload-artifact@v2 with: name: artifact1 path: ${{ needs.Full_scans.outputs.full_scan_result }} - name: Upload API Scan Artifact uses: actions/upload-artifact@v2 with: name: artifact2 path: ${{ needs.API_scan.outputs.api_scan_result }}
问题原因
- Runner环境隔离:GitHub Actions中每个job运行在独立的runner实例上,
Full_scans和API_scan生成的结果文件仅存在于各自的runner环境中,Upload_Artifactsjob无法直接访问这些路径下的文件。 - 过时的输出命令:使用了已废弃的
::set-output命令,当前GitHub Actions推荐使用$GITHUB_OUTPUT环境变量来设置job输出。 - 产物传递逻辑错误:试图通过job输出传递文件路径,但路径仅在原runner有效,跨job无法直接引用。
修正后的完整脚本
最直接的解决方案是在每个扫描job中直接上传产物,无需额外的Upload_Artifacts job,这样既简化流程又避免跨job文件访问问题:
name: ZAP Security Scans on: push: branches: - main jobs: Full_scans: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 with: ref: main - name: ZAP Full Scan id: full_scan uses: zaproxy/action-full-scan@v0.9.0 with: token: ${{ secrets.GITHUB_TOKEN }} docker_name: 'ghcr.io/zaproxy/zaproxy:stable' target: 'www.targeturl.com' - name: Upload Full Scan Artifact uses: actions/upload-artifact@v4 with: name: artifact1 path: | *.html if-no-files-found: warn API_scan: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 with: ref: main - name: ZAP API Scan id: api_scan uses: zaproxy/action-api-scan@v0.6.0 with: token: ${{ secrets.GITHUB_TOKEN }} docker_name: 'ghcr.io/zaproxy/zaproxy:stable' format: openapi target: 'www.targeturl.com' - name: Upload API Scan Artifact uses: actions/upload-artifact@v4 with: name: artifact2 path: | *.html if-no-files-found: warn
修改说明
- 移除冗余的输出和存储步骤:直接在扫描完成后上传所有HTML结果文件,无需额外创建目录和传递路径。
- 使用最新版上传artifact动作:将
actions/upload-artifact@v2升级为v4,兼容最新GitHub Actions特性。 - 简化产物匹配逻辑:通过
*.html直接匹配扫描生成的结果文件,无需查找具体文件名。 - 添加文件缺失警告:设置
if-no-files-found: warn,避免因无结果文件导致工作流失败,同时给出警告提示。
如果坚持要使用独立的Upload_Artifacts job,需要先在扫描job中上传临时产物,再在Upload_Artifacts job中下载后重新上传,示例如下:
name: ZAP Security Scans on: push: branches: - main jobs: Full_scans: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 with: ref: main - name: ZAP Full Scan id: full_scan uses: zaproxy/action-full-scan@v0.9.0 with: token: ${{ secrets.GITHUB_TOKEN }} docker_name: 'ghcr.io/zaproxy/zaproxy:stable' target: 'www.targeturl.com' - name: Upload Temp Full Scan Artifact uses: actions/upload-artifact@v4 with: name: temp-full-scan path: | *.html if-no-files-found: warn retention-days: 1 API_scan: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 with: ref: main - name: ZAP API Scan id: api_scan uses: zaproxy/action-api-scan@v0.6.0 with: token: ${{ secrets.GITHUB_TOKEN }} docker_name: 'ghcr.io/zaproxy/zaproxy:stable' format: openapi target: 'www.targeturl.com' - name: Upload Temp API Scan Artifact uses: actions/upload-artifact@v4 with: name: temp-api-scan path: | *.html if-no-files-found: warn retention-days: 1 Upload_Artifacts: needs: - Full_scans - API_scan runs-on: ubuntu-latest steps: - name: Download Temp Full Scan Artifact uses: actions/download-artifact@v4 with: name: temp-full-scan path: full_scan_results - name: Download Temp API Scan Artifact uses: actions/download-artifact@v4 with: name: temp-api-scan path: api_scan_results - name: Upload Full Scan Artifact uses: actions/upload-artifact@v4 with: name: artifact1 path: full_scan_results/*.html if-no-files-found: warn - name: Upload API Scan Artifact uses: actions/upload-artifact@v4 with: name: artifact2 path: api_scan_results/*.html if-no-files-found: warn
这个方案通过临时artifact传递文件,再在统一的上传job中整理后输出最终产物,适合需要对产物进行额外处理的场景。
内容的提问来源于stack exchange,提问作者user23321438
相关产品推荐
相关产品推荐

