GitHub Action
Get changed workspaces
This action finds all workspaces
in monorepo that has changed files. Then, you can build, test and lint only those packages that has been changed. If you aren't familiar with npm workspaces
, see documentation for npm and yarn.
- Create new workflow inside
.github/workflows
Example configuration
name: Monorepo CI
on:
pull_request:
branches:
- main
- master
jobs:
get-changed-workspaces:
runs-on: ubuntu-latest
outputs:
packages: ${{ steps.changed-packages.outputs.packages }}
empty: ${{ steps.changed-packages.outputs.empty }}
steps:
- uses: actions/checkout@v2
- name: Find changed workspaces
uses: AlexShukel/[email protected]
id: changed-packages
build:
runs-on: ubuntu-latest
needs: [get-changed-workspaces]
strategy:
matrix:
package: ${{ fromJson(needs.get-changed-workspaces.outputs.packages) }}
steps:
# describe steps for each modified package using ${{ matrix.package.name }} and ${{ matrix.package.path }}
- Define
workspaces
in rootpackage.json
. Also it can be passed via action input workspaces.
This action can handle 2 types of events:
pull_request
- action will comparecurrent
branch withtarget
branch of pull request.push
- by default action will compare a commitbefore
push event occured withcurrent
commit. You can passbase-ref
input to make another comparison (for example, with main branch).
Below is the list of all possible options that can be passed in the action.
This input is an alternative to the property of package.json
. It should be similar to npm workspaces. One difference is that each element of array should be on the new line.
Example:
- uses: AlexShukel/[email protected]
with:
workspaces: |
packages/*
tools/*
app/frontend
This input is required when your monorepo is located in different directory than git root. Example:
- uses: AlexShukel/[email protected]
with:
working-directory: ./app/frontend
This input option (regular expression) allows to filter changed packages by their names. Example:
- uses: AlexShukel/[email protected]
with:
filter: "@packages/*"
This filter will select only those packages that match "@packages/*" regular expression.
This input affects execution only when push
event occurs. You can specify target of comparison (branch name or commit SHA).
Example:
- uses: AlexShukel/[email protected]
with:
base-ref: main
Below is the list of all possible outputs that this action produces.
Array of changed packages, each containing its name and path. Provided as JSON string.
Example: '[{"name":"@monorepo/core","path":"packages/core"},{"name":"@monorepo/react","path":"packages/react"}]'
If you want to use it in action matrix, parse input with fromJson.
Boolean that indicates if there was any changed packages. Provided as JSON string.
For example, if you want to skip a job when there was no changed packages, you can use this configuration:
generate_matrix:
name: Get changed packages
runs-on: ubuntu-latest
outputs:
empty: ${{ steps.changed_packages.outputs.empty }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Find changed packages
id: changed_packages
uses: alexshukel/[email protected]
build:
name: Build
# Skip build job if there wasn't any changed packages
if: ${{ !fromJson(needs.generate_matrix.outputs.empty) }}
MIT © Aleksandras Sukelovic