NX Monorepo场景下如何基于动态数据调用YAML流水线任务?
解决NX Monorepo动态受影响应用的流水线任务循环问题
针对你在Azure Pipelines中遇到的动态遍历NX受影响应用、执行ArchiveFiles等任务的问题,这里提供一个可行的实现方案,核心思路是通过动态生成job matrix来实现循环执行:
步骤1:检测受影响的应用并生成动态矩阵
首先添加一个前置job,负责调用NX命令获取受影响的应用列表,并将其转换为流水线可识别的matrix格式:
jobs: - job: DetectAffectedApps steps: # 调用NX命令导出受影响的应用列表,保存为文本文件 - bash: | nx show projects --affected --type=application --plain > affected-apps.txt displayName: '识别受影响的Angular应用' # 将应用列表转换为matrix格式的JSON,并设置为输出变量 - pwsh: | # 读取文本文件,过滤空行,转换为matrix所需的include结构 $apps = Get-Content -Path affected-apps.txt | Where-Object { $_ -ne "" } | ForEach-Object { @{ name = $_ } } $matrix = @{ include = $apps } | ConvertTo-Json -Compress # 将matrix设置为输出变量,供后续job使用 Write-Host "##vso[task.setvariable variable=AppMatrix;isOutput=true]$matrix" name: SetMatrix displayName: '生成动态任务矩阵'
步骤2:基于动态矩阵执行批量任务
添加一个依赖于前置job的新job,使用动态生成的matrix来为每个受影响的应用执行ArchiveFiles、发布等任务:
- job: ProcessAffectedApps dependsOn: DetectAffectedApps # 引用前置job生成的动态matrix strategy: matrix: $[ dependencies.DetectAffectedApps.outputs['SetMatrix.AppMatrix'] ] steps: # 执行文件压缩任务,用$(name)引用当前应用名称 - task: ArchiveFiles@2 displayName: '压缩应用 $(name)' inputs: rootFolderOrFile: 'dist/apps/$(name)' includeRootFolder: false archiveType: 'zip' archiveFile: '$(Build.ArtifactStagingDirectory)/$(name).zip' replaceExistingArchive: true # 可添加其他任务,比如发布到存储或部署,同样用$(name)引用应用名 # - task: PublishBuildArtifacts@1 # displayName: '发布应用 $(name) 包' # inputs: # PathtoPublish: '$(Build.ArtifactStagingDirectory)/$(name).zip' # ArtifactName: '$(name)-package' # publishLocation: 'Container'
关键说明
- 为什么不能用静态
${{ each }}:Azure Pipelines的模板表达式是编译阶段执行的,而NX的affected应用列表是运行时生成的,编译阶段无法获取到动态列表,因此静态遍历语法不适用。 - 动态matrix的优势:每个应用会启动独立的job实例执行任务,支持并行运行,且能清晰区分每个应用的任务日志,便于排查问题。
- 适配调整:根据你的实际目录结构,修改
rootFolderOrFile等参数的路径,确保指向正确的应用构建产物目录。
内容的提问来源于stack exchange,提问作者CeejeeB
相关产品推荐
相关产品推荐

