Dynamic Config based on changed files

I have a CI/CD pipeline that looks similar to the one below. Where on changes that are pushed to main (or manually triggered by API) I want to build and deploy the code. However, I’m now trying to implement such that if changes are only in the helm/ dir. I’d like to do a deployment without the build part. My structure and relevant config files are shown below.

I’ve successfully managed to make it work so that if there’s changes to any file (except in helm/*) it triggers build-deploy and if there’s changes only in helm/* it triggers deploy. But; in the case where changes are made to both the helm/* dir and somewhere else I only want build-deploy to run.

Any idea of how this could be solved?

.circleci/
├── config.yml
└── shared/
    ├── @commands.yml
    ├── @executors.yml
    ├── @orbs.yml
    ├── @parameters.yml
    ├── @shared.yml
    ├── jobs/
    └── workflows/
        ├── build-deploy.yml
        ├── deploy.yml
        └── pr-tests.yml

build-deploy.yml

when:
  or:
    - and:
        - not: << pipeline.parameters.only_deploy >>
        - equal: [ true, << pipeline.parameters.build_deploy >> ] 
    - and:
        - equal: [ main, << pipeline.git.branch >> ] 
        - not:
            equal: [ true, << pipeline.parameters.only_deploy >> ]


jobs:
   - JOB_build
   - JOB_deploy 

deploy.yml

when:
  or:
    - << pipeline.parameters.only_deploy >>
    - << pipeline.parameters.api_only_deploy >>
jobs:
  - JOB_deploy

config.yml

version: 2.1

setup: true

orbs:
  path-filtering: circleci/path-filtering@1.1.0
  circleci-cli: circleci/circleci-cli@0.1.9
  continuation: circleci/continuation@1.0.0


parameters:
  api_only_deploy:
    type: boolean
    default: false
  api_build_deploy:
    type: boolean
    default: false
  api_pr_tests:
    type: boolean
    default: false
  only_deploy:
    type: boolean
    default: false
  build_deploy:
    type: boolean
    default: false

jobs:
  setup:
    executor: path-filtering/default
    steps:
      - checkout
      - circleci-cli/install

      - run:
          name: Generate shared configuration
          command: circleci config pack .circleci/shared >> .circleci/shared-config.yml

      - path-filtering/set-parameters:
          base-revision: main
          config-path: .circleci/shared-config.yml
          mapping: |
            .* build_deploy true
            helm/.* only_deploy true

      - path-filtering/generate-config

      - run:
          name: Validate config
          command: circleci config validate /tmp/generated-config.yml


      - continuation/continue:
          configuration_path: /tmp/generated-config.yml
          parameters: /tmp/pipeline-parameters.json

workflows:
  setup-workflow:
    jobs:
      - setup```

(note: response generated by AI, sourced from CircleCI assets)
Based on the provided configuration, you are already using the circleci/path-filtering orb to detect changes in specific directories and trigger corresponding workflows. However, you want to modify this behavior such that when changes are made both in the helm/ directory and somewhere else, only the build-deploy workflow should run.

To achieve this, you could modify the mapping in your config.yml file to set the only_deploy parameter to true only when changes are exclusively in the helm/ directory. This can be done by adding a negative lookahead in the regular expression for the build_deploy parameter to exclude changes in the helm/ directory. Here’s how you can modify the mapping:

mapping: |
  ^(?!helm/).* build_deploy true
  ^helm/.*$ only_deploy true

In this configuration:

  • The build_deploy parameter is set to true when changes are made anywhere except the helm/ directory.
  • The only_deploy parameter is set to true only when changes are exclusively in the helm/ directory.

This way, if changes are made both in the helm/ directory and somewhere else, only the build-deploy workflow will run.

Please note that this solution assumes that the circleci/path-filtering orb supports negative lookaheads in regular expressions. If it doesn’t, this solution may not work.

For more information on how to use the circleci/path-filtering orb, you can refer to the CircleCI Developer Hub and the CircleCI Docs.

Sources: