如何让GitHub Actions矩阵各条目执行不同命令并并行运行?
我在配置GitHub Actions的matrix时遇到问题:触发工作流选择「All Tests」选项时,希望matrix的「UI」条目执行UI Playwright测试命令,「API」条目执行API Playwright测试命令,且两个任务并行运行。但多次尝试后始终只执行第一个命令,请求解决。
三次尝试的问题分析
第一次尝试
name: Run Automation On Demand on: workflow_dispatch: inputs: URL: description: 'Which url do you want to run this one?' required: true default: 'xxxx' choice: type: choice description: Which suite do you want to run? options: - All Tests - All UI - All API - Login jobs: build: runs-on: macos-latest-xlarge strategy: matrix: node-version: [21.x] automation-type: [UI, API] 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: npm ci - run: npx playwright install chromium - name: If All Tests, Run UI Playwright Tests if: ${{ github.event.inputs.choice == 'All Tests' }} && ${{ matrix.automation-type.UI }} run: URL=${{ github.event.inputs.URL }} npx playwright test playwright/dashboard --workers=8 - name: If All Tests, Run API Playwright Tests if: ${{ github.event.inputs.choice == 'All Tests' }} && ${{ matrix.automation-type.API }} run: npx playwright test playwright/api --workers=20
错误点:matrix.automation-type.UI 语法错误,matrix.automation-type 是字符串变量,不能通过 .UI 来判断值,正确写法是用 == 'UI' 做相等判断。
第二次尝试
# 仅展示修改后的步骤部分 - name: If All Tests, Run UI Playwright Tests if: ${{ github.event.inputs.choice == 'All Tests' }} && ${{ matrix.automation-type == 'UI' }} run: URL=${{ github.event.inputs.URL }} npx playwright test playwright/dashboard --workers=8 - name: If All Tests, Run API Playwright Tests if: ${{ github.event.inputs.choice == 'All Tests' }} && ${{ matrix.automation-type == 'API' }} run: npx playwright test playwright/api --workers=20
错误点:语法本身没问题,但误解了matrix的运行逻辑。matrix会生成两个独立的job实例:一个对应automation-type: UI,另一个对应automation-type: API。在UI实例中,第二个步骤的if条件不满足,只会执行UI测试;在API实例中,第一个步骤的if条件不满足,只会执行API测试。两个实例是并行运行的,但你可能误以为是在同一个job里顺序执行两个命令,所以觉得只执行了第一个。
第三次尝试
# 仅展示修改后的步骤部分 - name: If All Tests, Run All Playwright Tests if: ${{ github.event.inputs.choice == 'All Tests' }} run: | ${{ matrix.automation-type.UI }} URL=${{ github.event.inputs.URL }} npx playwright test playwright/dashboard --workers=8 ${{ matrix.automation-type.API }} npx playwright test playwright/api --workers=20
错误点:同样犯了语法错误,matrix.automation-type.UI 不是有效的表达式;同时这种写法会在同一个job里尝试执行两个命令,但matrix的每个实例只会对应一个值(UI或API),导致其中一条命令的前置判断失效,最终只执行其中一个。
正确配置方案
要实现选择「All Tests」时并行执行UI和API测试,同时支持单独选择「All UI」「All API」「Login」的需求,可通过动态生成matrix参数 + 每个matrix实例执行对应命令来实现:
name: Run Automation On Demand on: workflow_dispatch: inputs: URL: description: '要测试的URL' required: true default: 'xxxx' choice: type: choice description: 选择要运行的测试套件 options: - All Tests - All UI - All API - Login jobs: run-tests: runs-on: macos-latest-xlarge strategy: matrix: node-version: [21.x] # 根据输入的choice动态生成automation-type的取值 automation-type: ${{ github.event.inputs.choice == 'All Tests' && ['UI', 'API'] || github.event.inputs.choice == 'All UI' && ['UI'] || github.event.inputs.choice == 'All API' && ['API'] || ['Login'] }} steps: - uses: actions/checkout@v3 - name: 使用 Node.js ${{ matrix.node-version }} uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} cache: 'npm' - name: 安装依赖 run: npm ci - run: npx playwright install chromium # 根据automation-type执行对应测试命令 - name: 执行UI测试 if: ${{ matrix.automation-type == 'UI' }} run: URL=${{ github.event.inputs.URL }} npx playwright test playwright/dashboard --workers=8 - name: 执行API测试 if: ${{ matrix.automation-type == 'API' }} run: npx playwright test playwright/api --workers=20 - name: 执行登录测试 if: ${{ matrix.automation-type == 'Login' }} run: # 替换为你的登录测试命令
配置说明
- 动态matrix:根据用户选择的
choice自动生成automation-type的取值数组:- 选「All Tests」时,生成
['UI', 'API'],启动两个并行的job实例 - 选「All UI」/「All API」时,只生成对应单个值的数组,启动一个job实例
- 选「Login」时,生成
['Login'],执行登录测试
- 选「All Tests」时,生成
- 步骤条件判断:每个步骤根据当前matrix的
automation-type值决定是否执行,确保每个job实例只运行对应的测试 - 并行运行:选择「All Tests」时,UI和API的job实例会自动并行执行,满足需求
内容的提问来源于stack exchange,提问作者awhisler

