Help
cancel
Showing results for 
Search instead for 
Did you mean: 
Copilot Lvl 2
Message 1 of 5

Basic workflow structure for a monorepo

Hi all! I never worked with "monorepo" up until now and I am a bit confused how to organize my workflows for such case.

 

Currently, I have 4 workflows which I'd like to use in more or less every "package" of my monorepo:

 

.github/workflows
├── create-pr.yml
├── lint.yml
├── publish-package.yml
└── run-tests.yml

 

In my workflows, I am currently using "paths" to trigger the job for a specific package, for example:

 

name: package1 lint

on:
  push:
    paths:
      - 'packages/package1/**'

jobs:
  eslint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: lint
        uses: reviewdog/action-eslint@v1
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          reporter: github-pr-review
          eslint_flags: 'packages/package1/'

 

Should I rename current workflow files to follow package name convention (i.e. "package1-create-pr.yml, "package1-lint.yml", etc.) or is it possible to organize them in folders (I think that actually won't trigger GitHub action) or can I use a single workflow file for each of my "packages" and then define all 4 jobs in a singe file (if that is possible too in the first place)?

 

Thanks a lot for help and suggestions!

 

 

 

4 Replies
GitHub Partner
Message 2 of 5

Re: Basic workflow structure for a monorepo

The workflow file only requires  '.yml' or '.yaml' as an extension, you can specify the name you'd like.

All the workflow files are stored in the '.github/workflows' directory, you cannot put them in another folder, it will not trigger the workflow.

If you'd like to monitor the event separately for each 'package',  you can create a single workflow which contains 4 jobs(create,lint,publish,test) for each 'package'.

If you’d like to monitor all 'packages' in one workflow file, you can get the commit path from code below, it identify which package the commit comes from, hope it helps.

jobs:
  packagecheck:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: check1
        id: filepath
        run: |
          echo ::set-output name=commitpath::$(git diff-tree --no-commit-id --name-only -r ${{ github.sha }})

      - name: echo
        run: |
          echo ${{ steps.filepath.outputs.commitpath }}
Copilot Lvl 2
Message 3 of 5

Re: Basic workflow structure for a monorepo

Thanks for the reply!

 

The option to "create a single workflow which contains 4 jobs" seems interesting, but what if my current jobs rely on different rules in "on" step - one is triggered on push on "develop" branch, the other on "master" branch.

Can I still use a "single .yml file for single npm package" approach?

 

For example:

name: package1

on:
  push:
    branches:
      - develop
    paths:
      - 'packages/package1/*'

jobs:
  tests:
    runs-on: ubuntu-latest
    steps:
      ...

on:
  push:
    branches:
      - master
    paths:
      - 'packages/package1/*'

jobs:
  publish-package:
    runs-on: ubuntu-latest
    steps:
      ...
Copilot Lvl 2
Message 4 of 5

Re: Basic workflow structure for a monorepo

I've been trying to use your other approach - to handle all packages in one workflow file, but I'm a bit confused how to use "${{ steps.filepath.outputs.commitpath }}" from your example?

 

How to parse that output of "git diff" command if it contains multiple files and multiple packages? I was trying something like this:

- name: setpkgname
  if: startsWith(steps.filepath.outputs.commitpath, 'package1')
  run: echo "::set-env name=PKG::${{ steps.filepath.outputs.commitpath }}"

but of course this sets my "PKG" env variable to "commitpath" value which is the list of all committed files, and if the first one doesn't start with the name I defined, the whole step is skipped.

GitHub Partner
Message 5 of 5

Re: Basic workflow structure for a monorepo

  1. You cannot monitor 'on-push' event for different branches at the same time in a workflow file. In this case, please create individual workflow file for each branch.
  2. If the commit contains mutliple files and multiple packages, the output will be like below:

commitpath.png

startsWith() doesn’t accept variables, you can use bash command with if to parse the content.

code like below:

      - name: path
        run: |
          if [[ "$STR" == *"package1"* ]] && [[ "$STR" == *"package2"* ]]; then
            echo package1and2
          elif [[ "$STR" == *"package1"* ]]; then
            echo package1
          elif [[ "$STR" == *"package2"* ]]; then
            echo package2
          fi
        env:
          STR: ${{ steps.filepath.outputs.commitpath }}