Skip to content

AlexShukel/get-changed-workspaces-action

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

Get changed workspaces action

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.

Usage

  1. 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 }}
  1. Define workspaces in root package.json. Also it can be passed via action input workspaces.

Events that can trigger action

This action can handle 2 types of events:

  • pull_request - action will compare current branch with target branch of pull request.
  • push - by default action will compare a commit before push event occured with current commit. You can pass base-ref input to make another comparison (for example, with main branch).

Action inputs

Below is the list of all possible options that can be passed in the action.

workspaces

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

working-directory

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

filter

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.

base-ref

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

Action outputs

Below is the list of all possible outputs that this action produces.

packages

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.

empty

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) }}

License

MIT © Aleksandras Sukelovic