首页 > 解决方案 > 如何在 GitHub Actions 上将 PNPM 工作区项目作为并行作业运行?

问题描述

给定一个包含两个包的存储库结构,如下所示:

$ tree
.
└── packages
   ├── foo
   └── bar

$ cat pnpm-workspace.yaml
packages:
  - 'packages/**'

$ pnpm -s m ls --depth -1
monorepo /monorepo
@mono/foo@0.0.0 /monorepo/packages/foo
@mono/baz@0.0.0 /monorepo/packages/bar

我想运行 GitHub Actions CI,以便它自动将每个项目作为单独的作业运行。在这里,我设置了一个手动执行并行化的作业:

name: CI

on:
  push:

jobs:
  build:
    strategy:
      matrix:
        package: ["@mono/foo", "@mono/bar" ]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: pnpm/action-setup@v2
        with:
          version: 6.9.1
      - run: pnpm run --filter ${{ matrix.package }} test

这运行得很快,因为每个项目都作为并行作业运行,但我不想手动维护该matrix.package列表。如何利用pnpm提供输入到 GitHub Actions CI 的工作区项目列表?

标签: continuous-integrationgithub-actionsmonorepopnpm

解决方案


嗯...我对此进行了更多尝试,并且找到解决方案。

我首先编写了一个package.json脚本来将pnpm输出转换为 json 数组片段:

$ cat package.json
{
  "scripts": {
    "list-packages": "echo [$(pnpm -s m ls --depth -1 | tr \" \" \"\n\" | grep -o \"@.*@\" | rev | cut -c 2- | rev | sed -e 's/\\(.*\\)/\"\\1\"/' | paste -sd, - )]",
  }
}
$ pnpm -s list-packages 
["@mono/foo","@mono/bar"]

(我对 shell 还不够好,不知道是否有更简单的方法来表达这种转换,所以我很乐意学习!)

然后我按照 GitHub 文档动态设置矩阵变量并创建了这个工作流程:

name: CI

on:
  push:
  workflow_dispatch:

jobs:
  packages:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
    steps:
      - uses: actions/checkout@v2
      - uses: pnpm/action-setup@v2
        with:
          version: 6.9.1
      - run: $(echo pnpm -s list-packages2)
      - id: set-matrix
        run: echo "::set-output name=matrix::{\"packages\":$(pnpm -s list-packages)}"
  build:
    needs: packages
    strategy:
      matrix: ${{ fromJson(needs.packages.outputs.matrix) }}
    runs-on: ubuntu-latest
    steps:
      - run: echo ${{ matrix.package }}

packages作业现在获取 的输出$(pnpm -s list-packages)并将其放入矩阵变量中,这使得 GitHub Actions 可以并行运行它们:

GitHub Actions 的屏幕截图,显示


推荐阅读