Azure DevOps YAML流水线能否依据Veracode返回的特定Payload触发阶段?
用单条YAML流水线实现Veracode异步扫描(不长期占用代理)
完全可以用单条YAML流水线实现你的需求,不需要拆分构建/发布,也不会持续占用构建代理。核心思路是拆分流水线为「资源占用型阶段」和「无代理轮询阶段」,利用无代理作业完成长期轮询,只在必要时占用代理执行上传、启动扫描等操作。
核心实现步骤
1. 上传并启动预扫描(占用代理的短作业)
这个阶段只做上传二进制、调用Veracode API启动预扫描的操作,完成后立即释放代理,同时把扫描任务ID存入流水线变量,供后续轮询使用。
2. 无代理异步轮询预扫描状态
使用Azure DevOps的server池作业(不占用构建代理),定时调用Veracode API获取扫描状态,解析返回的Payload判断是否完成:
- 若预扫描未完成:延迟30分钟后自触发当前流水线,继续轮询
- 若预扫描完成:进入下一阶段启动正式扫描
3. 正式扫描的异步等待(复用轮询逻辑)
正式扫描启动后,同样用无代理作业轮询扫描完成状态,直到扫描结束再执行后续步骤。
YAML示例代码
stages: - stage: Upload_Start_Prescan jobs: - job: Upload_Binary_Initiate_Prescan pool: vmImage: 'ubuntu-latest' # 替换为你的代理池 steps: - script: | # 实际调用Veracode API上传二进制并启动预扫描 # 示例:用curl调用API,提取扫描ID SCAN_ID=$(curl -X POST "https://api.veracode.com/appsec/v1/scans" \ -H "Authorization: Bearer $(VERACODE_API_TOKEN)" \ -F "file=@./your-app-binary.zip" \ | jq -r '.scan_id') # 将扫描ID设为输出变量,供后续阶段使用 echo "##vso[task.setvariable variable=scanId;isOutput=true]$SCAN_ID" name: SetScanId env: VERACODE_API_TOKEN: $(veracode-api-token) # 从流水线变量/密钥库读取 - stage: Poll_Prescan_Status dependsOn: Upload_Start_Prescan jobs: - job: Check_Prescan_Progress pool: server # 无代理作业,不占用构建资源 steps: - task: InvokeRESTAPI@1 inputs: connectionType: 'connectedServiceName' serviceConnection: 'Veracode_API_Service_Conn' # 预先配置的Veracode服务连接 method: 'GET' url: "https://api.veracode.com/appsec/v1/scans/$(Upload_Start_Prescan.SetScanId.scanId)" waitForCompletion: 'false' name: FetchScanStatus - script: | # 解析返回的Payload,判断预扫描状态(根据Veracode实际返回结构调整) SCAN_STATUS=$(echo $(FetchScanStatus.responseBody) | jq -r '.scan_status') PRESCAN_COMPLETED="false" # Veracode预扫描完成的状态值需参考官方文档,这里用示例值 if [ "$SCAN_STATUS" = "PRESCAN_FINISHED" ]; then PRESCAN_COMPLETED="true" fi echo "##vso[task.setvariable variable=prescanCompleted;isOutput=true]$PRESCAN_COMPLETED" name: EvaluateStatus # 未完成则延迟30分钟 - task: Delay@1 inputs: delayForMinutes: '30' condition: eq(variables['EvaluateStatus.prescanCompleted'], 'false') # 自触发流水线继续轮询,传递扫描ID参数 - task: TriggerPipeline@1 inputs: pipeline: '$(System.DefinitionId)' branch: '$(Build.SourceBranch)' parameters: '{"targetScanId": "$(Upload_Start_Prescan.SetScanId.scanId)"}' condition: eq(variables['EvaluateStatus.prescanCompleted'], 'false') - stage: Initiate_Full_Scan dependsOn: Poll_Prescan_Status condition: eq(variables['EvaluateStatus.prescanCompleted'], 'true') jobs: - job: Start_Full_Scan_Job pool: vmImage: 'ubuntu-latest' steps: - script: | # 调用Veracode API启动正式扫描 curl -X PATCH "https://api.veracode.com/appsec/v1/scans/$(Upload_Start_Prescan.SetScanId.scanId)" \ -H "Authorization: Bearer $(VERACODE_API_TOKEN)" \ -H "Content-Type: application/json" \ -d '{"action": "START_FULL_SCAN"}' env: VERACODE_API_TOKEN: $(veracode-api-token) # 这里可以复用上面的轮询逻辑,添加正式扫描的状态检查阶段
关键细节说明
- 无代理作业:
pool: server类型的作业由Azure DevOps服务器托管,不会占用你的构建代理资源,适合长期轮询场景 - Payload解析:用
jq工具(需确保环境支持)解析API返回的JSON,精准判断扫描状态,不受HTTP状态码限制 - 自触发逻辑:通过
TriggerPipeline任务重新触发当前流水线,传递扫描ID参数,避免重复上传二进制,确保轮询的是同一个扫描任务 - 资源占用优化:只有上传、启动扫描的阶段会占用代理,轮询阶段完全不消耗代理资源,解决5天扫描占用代理的问题
内容的提问来源于stack exchange,提问作者mark
相关产品推荐
相关产品推荐

