CircleCI doesn't respect branch filters

I have multiple build configs, with branch filters setup. Though it seems to trigger the wrong build when merging into my integration branch. It triggers “build” job instead of the “integration” job.

common_config: &config
      docker:
        # specify the version you desire here
        # check here for versions available: https://hub.docker.com/r/circleci/android/tags/
        - image: circleci/android:api-26-alpha
      working_directory: ~/repo

      environment:
        # Customize the JVM maximum heap limit
        JVM_OPTS: -Xmx3200m # max container memory limit is 4G, we should try to keep it below that
                            # if we run out of memory we have to request bigger containers with CircleCI
        TERM: dumb

    restore_key: &restore_key
      key: jars-{{ checksum "build.gradle" }}-{{ checksum  "app/build.gradle" }}

    save_key: &save_key
      paths:
        - ~/.gradle
      key: jars-{{ checksum "build.gradle" }}-{{ checksum  "app/build.gradle" }}

    test_results: &test_results
      path: app/build/test-results

    upload_coverage: &upload_coverage
      name: Upload coverage data
      command: bash <(curl -s https://codecov.io/bash) -t "$CODECOV_TOKEN"

    store_apk: &store_apk
      path: app/build/outputs/apk


    # The actual CircleCI config
    version: 2
    jobs:

      # This is for integration branches only
      integration:
        <<: *config # inject common config section
        filters:
          branches:
            only:
              - develop
              - ui_refresh_integration

        steps:
          - checkout

          # Download and cache dependencies
          - restore_cache: *restore_key
          - run: ./gradlew androidDependencies
          - save_cache: *save_key

          # actual build steps
          - run: ./gradlew -PdisablePreDex testDevDebug assembleDebug lint #uploadDevDebugToHockeyApp uploadUatDebugToHockeyAPp uploadQaDebugToHockeyApp

          - run: *upload_coverage
          - store_test_results: *test_results
          - store_artifacts: *store_apk

      # PR branch build, we should try to keep this as lightweight and fast as possible
      prbuild:
        <<: *config # inject common config section
        filters:
          branches:
            ignore:
              - develop
              - master
              - release*
              - ui_refresh_integration

        steps:
          - checkout

          # Download and cache dependencies
          - restore_cache: *restore_key
          - run: ./gradlew androidDependencies
          - save_cache: *save_key

          # actual build steps
          - run: ./gradlew -PdisablePreDex testDevDebug

          - run: *upload_coverage
          - store_test_results: *test_results
          - store_artifacts: *store_apk

      # release branch
      build:
        <<: *config # inject common config section
        filters:
          branches:
            only:
              - master
              - release*

        steps:
          - checkout

          # Download and cache dependencies
          - restore_cache: *restore_key
          - run: ./gradlew androidDependencies
          - save_cache: *save_key

          # actual build steps
          - run: ./gradlew -PdisablePreDex testProdDebug assembleProd #uploadProdDebugToHockeyApp uploadProdReleaseToHockeyApp

          - run: *upload_coverage
          - store_test_results: *test_results
          - store_artifacts: *store_apk

I would recommend using Workflows. You will be able to add filters for all your jobs.

So I cannot add filters to all jobs without a workflow? Can you elaborate a bit which jobs are treated specially (when not using workflows)?

You can’t have multiple jobs without using Workflows. If you are not using Workflows, you only have one job in the config. Hope this helps.