loading...

Running Nx Affected Commands in GitHub Actions

devinshoemaker profile image Devin Shoemaker Updated on ・2 min read

GitHub Actions is a powerful feature that allows developers to automate their CI/CD workflows directly in GitHub. It's pretty easy to get up and going with the official Node.js workflow template, however, Nx can be a bit tricky to work with.

Nx has a powerful set of commands that allow you to rebuild and retest what is affected by a change, but due to the way that GitHub Actions checks out a branch to execute a workflow, these will not work properly with the standard Node.js workflow.

The first thing to change from a standard Node.js workflow is the parameters passed into the checkout action:

- uses: actions/checkout@v2
  with:
    fetch-depth: 0

The ref command explicitly sets the commit to be checked out as the latest commit from the pull request that was initiated.

When fetch-depth is set to 0 then then the entire history of commits is fetched.

Next, we need to fetch origin master so that we have a base to run the affected commands against:

- run: git fetch --no-tags --prune --depth=5 origin master

Finally, you can begin running the affected commands:

# npm

npm run affected:build -- --base=origin/master

# Yarn

yarn affected:build --base=origin/master

Here is a full example borrowed from my nxtend repo:

name: Nx Affected CI

on:
  push:
    branches: [master]
  pull_request:
    branches: [master]

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [12.x]

    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node-version }}
      - run: git fetch --no-tags --prune --depth=5 origin master
      - run: yarn install --frozen-lockfile
      - run: yarn affected:build --base=origin/master
      - run: yarn affected:lint --base=origin/master
      - run: yarn affected:test --base=origin/master
      - run: yarn affected:e2e --base=origin/master

In order to use this, create the file nx-affected.yml in the directory .github/workflows in your repository.

Conclusion

GitHub Actions are powerful and easy to add to your CI/CD pipeline. As your code scales with Nx, so should your testing.

Special thanks to Plysepter on GitHub for their suggestions that helped get this working.

References

GitHub Actions

Starting with the Node.js workflow template

Nx - Rebuilding and Retesting What is Affected

@nxtend
Plysepter on GitHub

Discussion

pic
Editor guide
Collapse
masonembry profile image
Mason Embry

Thank you for this. Migrating our app into nx has been quite painful and this I hope is one of the last pain points. Cheers!

Collapse
devinshoemaker profile image
Devin Shoemaker Author

Thanks! I have noticed that this doesn't appear to work with PR's from a separate repo (e.g. somebody made a PR to my open source project and the workflow failed due to branching weirdness). However, if you're not dealing with forked repos then this should work well! If I find a solution for forked repos then I will be posting an update.

Collapse
poloagustin profile image
Agustin Polo

Any ideas on those forking cases? I'm dealing with
Error: Command failed: git merge-base origin/master HEAD
Was hoping this post would shine a light on this 😅

Thread Thread
poloagustin profile image
Agustin Polo

For forked repos I was able to run a gh actions workflow by removing the ref: ${{ github.event.pull_request.head.ref }} from your example. This enabled the workflow to pull the forked branch commit, with it's history, then fetch the base master branch with the defined depth and the affected:lint command worked in the end :)
Hope it helps someone!

Thread Thread
devinshoemaker profile image
Devin Shoemaker Author

Cool! Thanks for the reply! I will test that out and update the post if it works well!

Thread Thread
devinshoemaker profile image
Devin Shoemaker Author

I finally got around to testing this fix and updating this blog post. Thanks again Agustin!