如何让Yarn Workspaces跑完所有工作区测试后再返回失败结果
解决Yarn Workspaces全工作区测试不中断并最终返回失败状态的问题
问题背景
我使用Yarn Workspaces(Yarn 1.22.19)在GitHub Actions中执行所有工作区的测试,需求是即使某个工作区测试失败也不停止执行,跑完所有工作区后再统一返回失败状态,方便一次性收集所有失败结果。
当前执行命令为yarn workspaces run test --passWithNoTests,所有工作区的package.json中test脚本均基于Jest执行测试。但Jest测试失败会返回退出码1,导致yarn workspaces run直接终止,无法继续运行后续工作区的测试。
补充说明:使用Bash环境,不能用set -e或|| true这类直接屏蔽错误的方案,必须保证所有测试跑完后,若存在失败则最终返回失败状态。
举例:3个工作区workspace a、workspace b、workspace c,若workspace b测试失败,需跑完全部3个工作区的测试后,再返回失败结果。
解决方案
核心思路是遍历所有工作区,逐个执行测试并记录失败状态,最后根据记录返回最终退出码。
方案1:使用jq解析工作区路径(依赖jq工具)
在项目根目录的package.json中新增脚本test:all:
"scripts": { "test": "yarn workspaces run test --passWithNoTests", "test:all": "FAILURES=0; for workspace in $(yarn workspaces list --json | jq -r '.location'); do echo \"=== Running tests in $workspace ===\"; cd \"$workspace\"; yarn test --passWithNoTests || FAILURES=1; cd - > /dev/null; done; exit $FAILURES" }
yarn workspaces list --json:以JSON格式输出所有工作区信息,通过jq -r '.location'提取工作区路径- 初始化
FAILURES为0,代表初始无失败 - 遍历每个工作区,进入目录执行测试;若测试失败,将
FAILURES设为1 - 所有工作区执行完成后,通过
exit $FAILURES返回最终状态:0表示全部通过,1表示存在失败
方案2:纯Bash解析工作区路径(无额外依赖)
若环境未安装jq,可改用Bash内置工具解析yarn workspaces list的默认输出:
"scripts": { "test": "yarn workspaces run test --passWithNoTests", "test:all": "FAILURES=0; for workspace in $(yarn workspaces list | awk '{print $2}'); do echo \"=== Running tests in $workspace ===\"; cd \"$workspace\"; yarn test --passWithNoTests || FAILURES=1; cd - > /dev/null; done; exit $FAILURES" }
yarn workspaces list默认输出格式为workspace name path,通过awk '{print $2}'提取路径
修改GitHub Actions工作流
将原测试步骤中的yarn test替换为yarn test:all,完整工作流如下:
name: Run All Tests on: pull_request: branches: ['develop'] jobs: build: runs-on: ubuntu-latest strategy: matrix: node-version: [16.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} cache: 'npm' - name: Install dependencies run: yarn install --frozen-lockfile # 若环境未预装jq,取消下方注释安装 # - name: Install jq # run: sudo apt-get install -y jq - name: Run all workspace tests run: yarn test:all
内容的提问来源于stack exchange,提问作者Oded
相关产品推荐
相关产品推荐

