Git trigger - modified files for pull request

Hi Codefresh community support,

I would like to setup a git trigger which triggers a certain pipeline when files in a certain directory of my project are being modified by a pull request. I am following the docs about git triggers here: https://codefresh.io/docs/docs/configure-ci-cd-pipeline/triggers/git-triggers/#monorepo-support-modified-files and using the Codefresh UI to setup a git trigger that is triggered by “Push commits” while specifying a “Modified Files (glob expression)”, e.g. src/awesome/**. The trigger works when the last commit in the pull request changes some files in src/awesome/, however if I push a new commit with no changes inside src/awesome/, the pipeline doesn’t trigger and CI tests show as passing in github, even though the triggered pipeline would fail if it were to run.

How can I achieve the desired behavior, that is the pipeline will run for every commit if files in the specified directory are different between the pull request target and the head of the branch I’m trying to merge?

Hello

First of all the “modified files” information comes from the Git provider (Github in your case). As Codefresh we simply process it and make decisions based on its contents.

The modified files is mostly used in the case of monorepos where multiple projects are in the same git repo. And the most classic scenario is

  • files change under /project1/src → launch pipeline 1
  • files change under /project2/src → launch pipeline 2

You are saying that once you do change a file under /src/awesome/ then the pipeline runs, and when you don’t change a file there then the pipeline doesn’t run. But that is the expected behavior. No? And nothing should show in Github anyway.

Can you explain a bit what exactly are you trying to accomplish?

Hi Kostis, thank you for your reply.

Sure, our use case is also a monorepo. What we are trying to do is having codefresh pipelines as gatekeepers to merge pull requests in github, and have a pipeline for each subproject in the repo, like in your example with /project1/src and /project2/src.

Now let’s say I have a trigger that is setup like in the screenshot below:
Screen Shot 2021-08-11 at 8.48.45 AM

with the following Modified Files (glob expression): /project1/**

Then if I create a pull request with a single commit containing breaking changes in /project1, the pipeline triggers and the pipeline tests will fail. The PR cant be merged, all is good. But if I then follow up with a second commit which doesn’t include changes in /project1, the /project1 pipeline is not triggered, and github gives the green light for this PR passing CI tests. I am now able to merge the PR, which includes the breaking changes to /project1 from the first commit.

I would expect the trigger based on modified files to take into account the overall diff from all commits in the PR, not just the content of the PR’s last commit. Is there a way to setup the trigger to get that behavior?

Hello

First of all if you want to work with pull requests it is best to catch specific pull request events. We have a full guide here and you can see there a different checkbox configuration Pull Requests and Branches · Codefresh | Docs

However I am really puzzled by this sentence “the /project1 pipeline is not triggered, and github gives the green light for this PR passing CI tests”. If the pipeline is not triggered at all, then how does Github show any type of status change? Can you post a screenshot of Github that has this “passing tests” status"

I would expect the trigger based on modified files to take into account the overall diff from all commits in the PR, not just the content of the PR’s last commit. Is there a way to setup the trigger to get that behavior?

No that is not how triggers work. They are not that smart. They only carry the information of the last commit. And just to clarify, this is not a Codefresh thing. All information from triggers is coming straight from the Github event payload. You can actually see by yourself what Github sends to Codefresh in the github docs https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads

If a commit is pushed that doesn’t trigger the /project1 pipeline, but other pipelines do run (because the latest commit has changes in project2 that trigger the /project2 pipeline for example, or alternatively it could be that another pipeline that tests common code shared between the projects always runs on every commit), github will show the status checks as passing. I’m not sure what would happen if no trigger gets triggered, but in my situation we do have other pipelines being triggered.

Here is a test example that I put together to demonstrate this.

Here is a PR with a commit where a file that is required to successfully run unit tests has been deleted, causing the first pipeline to fail. Github correctly indicates that 1 check has failed.

(continued from above since I’m limited to 1 screenshot per post)

Then I follow up with a second commit, which only contains a trivial change to the readme file. That commit triggers the codefresh pipeline that was passing - that pipeline is set to always run on every commit - as well as the non-code fresh check. The codefresh pipeline that is supposed to fail isn’t triggered, and codefresh shows status checks as passing. If this PR had an approving review, I would be able to merge it. See next post for screenshot attachment, apparently I’m limited to one per post

It may not be how codefresh triggers work, but that’s the behavior that I would expect to support the workflow I described. Is there a different configuration / trigger type than the “Push commits” trigger that can be used to achieve this? From the documentation page you linked it doesn’t seem like that’s the case.

Hello

So the issue here is that you have 2 pipelines setup and not just one for that . But this is not how a monorepo works.

If you have shared code, you should extract this code on a folder on its own and setup an appropriate pipeline. Each folder in the monorepo should have a single pipeline assigned to it (or multiple pipelines that all deal with just that folder and nothing else)

Would that work in your case?

Is there a different configuration / trigger type than the “Push commits” trigger that can be used to achieve this

No there isn’t. And I am not aware of any other CI/CD system that supports what you expect as all of them get the same information as provided by Github, when somebody commits a file.

Bitrise’s selective build allows you to set triggers based on changed files and it has the behavior I described, i.e. it looks at files that changed on the overall PR as opposed to just the last commit.

Ok, but I want to know more about your use case then. Why use both Bitrise and Codefresh for CI? Why not use just one of them?

If you split the common code in its own folder, then you only need one pipeline (from either service) and not 3 like you have now (2 codefresh and 1 for bitrise). Then monorepo support will work out of the box. Or is there another limitation that I am missing?