如何在Bitbucket Pipelines中结合Angular Nx使用nx affected
你使用的nx print-affected命令方向完全正确,只需要适配Bitbucket Pipelines的运行机制,解决动态步骤生成、跨步骤环境变量传递的问题,就能实现仅针对变更影响的库跑并行测试的目标。
适配要点与实现步骤
1. 修正受影响项目列表的获取命令
你目前写的命令在CI环境下会有两个常见问题:
- 对比基线只写
master,在CI环境里会找不到本地分支引用,必须加上origin前缀 - 命令默认输出JSON格式的项目数组,带双引号、换行符,直接传递容易出现解析错误
调整后的可直接在CI环境运行的命令为:npx nx print-affected --target=test --base=origin/master --select=tasks.target.project | jq -r 'join(" ")'
执行后会输出空格分隔的纯项目名字符串,没有格式杂质,可直接用于后续逻辑判断。
2. 跨步骤传递受影响项目列表
Bitbucket Pipelines的每个步骤是独立的运行沙箱,步骤之间的变量不共享,你需要在流水线最开始加一个前置准备步骤,专门计算受影响的测试项目列表,通过Bitbucket内置的.env文件把列表传递给后续所有步骤:
- step: name: 计算受影响测试项目 script: - npm ci - AFFECTED_TEST_PROJECTS=$(npx nx print-affected --target=test --base=origin/master --select=tasks.target.project | jq -r 'join(" ")') # 将列表写入.env文件,后续所有步骤会自动加载该文件的环境变量 - echo "export AFFECTED_TEST_PROJECTS='$AFFECTED_TEST_PROJECTS'" >> .env
如果是PR触发的流水线,还可以把基线参数替换为Bitbucket内置的
BITBUCKET_PR_DESTINATION_BRANCH变量,自动适配不同PR的目标分支,不需要硬编码master。
3. 改造并行测试步骤为动态模板
你目前的并行配置是写死对应lib1/lib2/lib3的项目名,只需要把配置改成可复用的模板,让每个并行位自动从受影响列表里取对应位置的项目运行,没有对应项目就自动跳过,就能实现动态的受影响测试:
- 先定义通用的测试模板锚点
.test-run-template: &test-run-template image: node:18 caches: - node script: # 按当前并行位的索引,从受影响列表里匹配对应项目 - STEP_INDEX=$((BITBUCKET_STEP_RUN_NUMBER - 1)) - CURRENT_PROJECT=$(echo $AFFECTED_TEST_PROJECTS | cut -d' ' -f$((STEP_INDEX + 1))) # 匹配不到对应项目就直接跳过,不报错 - if [ -z "$CURRENT_PROJECT" ]; then echo "无匹配受影响测试项目,跳过当前步骤"; exit 0; fi # 执行对应项目的测试 - npx nx test $CURRENT_PROJECT
- 再把原本写死的并行步骤替换为复用模板的配置,并行位的数量设置为你所有库的总数即可,多余的空位会自动跳过
- parallel: - step: <<: *test-run-template name: 测试执行位1 - step: <<: *test-run-template name: 测试执行位2 - step: <<: *test-run-template name: 测试执行位3
可选的简化方案
如果不需要跨沙箱节点的并行,完全可以直接使用Nx内置的并行能力,不需要拆分多个Bitbucket步骤:
在单个执行步骤里运行命令 npx nx affected:test --base=origin/master --parallel=3,Nx会自动识别受影响的测试项目,在当前节点内按配置的并行数同时跑多个测试任务,配置逻辑比动态步骤简单很多,适合项目数量不多的场景。
内容的提问来源于stack exchange,提问作者wildbisu

