"no workflow" instead of the expected workflow

I am no expert on CircleCI or the config.yml that we are using, as we have had third-party devs to set this up for us (and yes, I have asked them also about why the behaviour is as described below).

The first thing that struck me as odd is the message, that is only visible if I show “All pipelines”:

Could not find a usable config.yml, you may have revoked the CircleCI OAuth app. Please sign out of CircleCI and log back in with your VCS before triggering a new pipeline.

Then, when I via CircleCI website use the “Trigger pipeline” (and I dont add any parameters/properties), I get a new row for the pipeline, but it says “No workflow”.
only get a valid workflow if I do the following:

  • Trigger Pipeline
  • Add Parameters → “only_build” set to true (if set to false => “No workflow”)

I am pasint the config.yml here, in the hope that someone might spot something.

version: 2.1

parameters:
  only_build:
    type: boolean
    default: false
  manual_version:
    type: string
    default: ""

references:
  workspace: &workspace
    ~/project

# Configs
  node_config: &node_config
    working_directory: *workspace
    docker:
      - image: cimg/node:lts

  android_config: &android_config
    working_directory: ~/project/android
    docker:
      - image: cimg/android:2022.04.1-node
    environment:
      TERM: dumb
      _JAVA_OPTIONS: '-Xmx2048m -XX:+UseContainerSupport'
      GRADLE_OPTS: '-Dorg.gradle.jvmargs="-Xmx2048m"'
      VARS_SUFFIX: 'android'

  ios_config: &ios_config
    working_directory: ~/project/ios
    macos:
      xcode: 13.3.1
    environment:
      FL_OUTPUT_DIR: output
      VARS_SUFFIX: 'ios'

# keys
  node_key: &node_key
    node-v{{ .Environment.CACHE_VERSION }}-{{ arch }}-{{ checksum "~/project/package.json" }}

  node_key_fallback: &node_key_fallback
    node-v{{ .Environment.CACHE_VERSION }}-{{ arch }}

  yarn_key: &yarn_key
    yarn-v{{ .Environment.CACHE_VERSION }}-{{ arch }}-{{ checksum "~/project/yarn.lock" }}

  yarn_key_fallback: &yarn_key_fallback
    yarn-v{{ .Environment.CACHE_VERSION }}--{{ arch }}

  gradle_key: &gradle_key
    jars-v{{ .Environment.CACHE_VERSION }}-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-{{checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}

  gem_key: &gem_key
    bundle-v{{ .Environment.CACHE_VERSION }}-{{ checksum "Gemfile.lock" }}-{{ arch }}

  pods_key: &pods_key
    pods-v{{ .Environment.CACHE_VERSION }}-{{ checksum "Podfile.lock" }}

# node_modules
  restore_node_modules_cache: &restore_node_modules_cache
    restore_cache:
      name: Restoring node modules cache
      keys:
        - *node_key
        - *node_key_fallback

  install_node_dependencies: &install_node_dependencies
    run:
      name: Installing node dependencies
      working_directory: *workspace
      command: |
        yarn install --frozen-lockfile --cache-folder ~/.cache/yarn

  save_node_modules_cache: &save_node_modules_cache
    save_cache:
      name: Saving node modules cache
      key: *node_key
      paths:
        - node_modules

# yarn
  restore_yarn_cache: &restore_yarn_cache
    restore_cache:
      name: Restoring yarn cache
      keys:
        - *yarn_key
        - *yarn_key_fallback

  save_yarn_cache: &save_yarn_cache
    save_cache:
      name: Saving yarn cache
      key: *yarn_key
      paths:
        - ~/.cache/yarn

# gradle
  restore_gradle_cache: &restore_gradle_cache
    restore_cache:
      name: Restoring gradle cache
      key: *gradle_key

  save_gradle_cache: &save_gradle_cache
    save_cache:
      name: Saving gradle cache
      key: *gradle_key
      paths:
        - ~/.gradle
        - ~/.m2

# gem
  restore_gems_cache: &restore_gems_cache
    restore_cache:
      name: Restoring ruby cache
      key: *gem_key

  install_ruby_dependencies: &install_ruby_dependencies
    run:
      name: Download Ruby Dependencies
      command: |
        sudo gem install bundler
        bundle config set --local path 'vendor/bundle'
        bundle check || bundle install
        sudo gem install fastlane

  save_gems_cache: &save_gems_cache
    save_cache:
      name: Saving ruby cache
      key: *gem_key
      paths:
        - vendor/bundle

# pods
  restore_pods_cache: &restore_pods_cache
    restore_cache:
      name: Restoring pods cache
      key: *pods_key

  save_pods_cache: &save_pods_cache
    save_cache:
      name: Saving pods cache
      key: *pods_key
      paths:
        - ./Pods

# android
  decode_android_key: &decode_android_key
    run:
      name: Decode Android key store
      command: echo ${ANDROID_KEYSTORE} | base64 --decode > ./${ANDROID_KEYSTORE_NAME}

  create_google_play_key: &create_google_play_key
    run:
      name: Create Google Play key
      command: echo ${GOOGLE_PLAY_KEY} | base64 --decode > ./fastlane/google_play_key.json

  switch_app_env: &switch_app_env
    run:
      name: Switch application environment to prod for specific flavor
      working_directory: *workspace
      command: yarn switch << parameters.flavor >>

  switch_app_env_to_dev: &switch_app_env_to_dev
    run:
      name: Switch application environment to dev for specific flavor
      working_directory: *workspace
      command: yarn switch << parameters.flavor >> --dev

  build_android_app: &build_android_app
    run:
      name: Build application
      command: bundle exec fastlane generate_build version:<< pipeline.parameters.manual_version >>

  deploy_internal: &deploy_internal
    run:
      name: Build and upload android build to internal testing
      command: bundle exec fastlane deploy_internal version:${CIRCLE_TAG}

  release_android_app: &release_android_app
    run:
      name: Release android app to play store
      command: bundle exec fastlane deploy_release build_number:${ANDROID_BUILD_NUM}

#ios
  decode_appstore_auth_key: &decode_appstore_auth_key
    run:
      name: Decode app store auth key
      command: echo ${IOS_AUTH_KEY} | base64 --decode > ./AuthKey_${API_KEY_ID}.p8

  prepare_ios_certs: &prepare_ios_certs
    run:
      name: Setup ios certs for current flavor
      command: bundle exec fastlane prepare_certs

  install_pods: &install_pods
    run:
      name: Install pods
      command: |
        if [ ! -d "Pods" ]
        then
          pod install
        fi

  build_ios_app: &build_ios_app
    run:
      name: Build ios application
      command: bundle exec fastlane generate_build version:<< pipeline.parameters.manual_version >>

  deploy_to_testflight: &deploy_to_testflight
    run:
      name: Build and upload ios build to testflight
      command: bundle exec fastlane deploy_testflight version:${CIRCLE_TAG}

  release_ios_app: &release_ios_app
    run:
      name: Release ios app to app store
      command: bundle exec fastlane deploy_appstore version:${CIRCLE_TAG} build_number:${IOS_BUILD_NUM}

#common
  extract_build_numbers: &extract_build_numbers
    run:
      name: Get projects build numbers and store file in root
      command: bash ../scripts/extract-build-nums.sh ${VARS_SUFFIX}

  save_workspace: &save_workspace
    persist_to_workspace:
      root: *workspace
      paths:
        - .vars/*

  restore_workspace: &restore_workspace
    attach_workspace:
      at: /tmp/

  import_vars: &import_vars
    run:
      name: Import build variables
      command: |
        if [ -f "/tmp/.vars/${VARS_SUFFIX}.env" ]; then
          cat "/tmp/.vars/${VARS_SUFFIX}.env" >> $BASH_ENV;
        else
          echo "Build vars not exists! Maybe workspace expired!"; exit 1
        fi

  print_info: &print_info
    run:
      name: Print info
      command: |
        echo "FLAVOR: << parameters.flavor >>"
        echo "VERSION: ${CIRCLE_TAG}"
        echo "ANDROID BUILD NUM: ${ANDROID_BUILD_NUM}"
        echo "IOS BUILD NUM: ${IOS_BUILD_NUM}"

  flavor_matrix: &flavor_matrix
    matrix:
      parameters:
        flavor: [ "uppsala", "kronoberg", "sormland" ]

  tag_filters: &tag_filters
    filters:
      tags:
        only: /^\d+\.\d+\.\d+$/
      branches:
        ignore: /.*/


### -- JOBS -- ###

jobs:
#  install_js:
#    <<: *node_config
#    steps:
#      - checkout
#      - *restore_yarn_cache
#      - *restore_node_modules_cache
#      - *install_node_dependencies
#      - *save_yarn_cache
#      - *save_node_modules_cache

  android_deploy_internal:
    <<: *android_config
    parameters:
      flavor:
        type: string
    steps:
      - checkout:
          path: *workspace
      - *restore_gradle_cache
      - *restore_gems_cache
      - *restore_yarn_cache
      - *restore_node_modules_cache
      - *install_node_dependencies
      - *install_ruby_dependencies
      - *save_node_modules_cache
      - *save_yarn_cache
      - *save_gradle_cache
      - *save_gems_cache
      - *decode_android_key
      - *create_google_play_key
      - *switch_app_env
      - *deploy_internal
      - *extract_build_numbers
      - *save_workspace

  android_release:
    <<: *android_config
    parameters:
      flavor:
        type: string
    steps:
      - checkout:
          path: *workspace
      - *restore_workspace
      - *import_vars
      - *restore_gradle_cache
      - *restore_gems_cache
      - *install_ruby_dependencies
      - *decode_android_key
      - *save_gradle_cache
      - *save_gems_cache
      - *create_google_play_key
      - *switch_app_env
      - *print_info
      - *release_android_app

  android_build:
    <<: *android_config
    parameters:
      flavor:
        type: string
    steps:
      - checkout:
          path: *workspace
      - *restore_gradle_cache
      - *restore_gems_cache
      - *restore_yarn_cache
      - *restore_node_modules_cache
      - *install_node_dependencies
      - *install_ruby_dependencies
      - *save_node_modules_cache
      - *save_yarn_cache
      - *save_gradle_cache
      - *save_gems_cache
      - *decode_android_key
      - *create_google_play_key
      - *switch_app_env_to_dev
      - *build_android_app
      - store_artifacts:
          path: ~/builds

  ios_deploy_to_testflight:
    <<: *ios_config
    parameters:
      flavor:
        type: string
    steps:
      - checkout:
          path: *workspace
      - *restore_gems_cache
      - *restore_yarn_cache
      - *restore_node_modules_cache
      - *install_node_dependencies
      - *install_ruby_dependencies
      - *save_yarn_cache
      - *save_node_modules_cache
      - *save_gems_cache
      - *restore_pods_cache
      - *install_pods
      - *save_pods_cache
      - *decode_appstore_auth_key
      - *switch_app_env
      - *prepare_ios_certs
      - *deploy_to_testflight
      - *extract_build_numbers
      - *save_workspace
      - store_artifacts:
          path: output

  ios_release:
    <<: *ios_config
    parameters:
      flavor:
        type: string
    steps:
      - checkout:
          path: *workspace
      - *restore_workspace
      - *import_vars
      - *restore_gems_cache
      - *install_ruby_dependencies
      - *save_gems_cache
      - *decode_appstore_auth_key
      - *switch_app_env
      - *print_info
      - *release_ios_app

  ios_build:
    <<: *ios_config
    parameters:
      flavor:
        type: string
    steps:
      - checkout:
          path: *workspace
      - *restore_gems_cache
      - *restore_yarn_cache
      - *restore_node_modules_cache
      - *install_node_dependencies
      - *install_ruby_dependencies
      - *save_yarn_cache
      - *save_node_modules_cache
      - *save_gems_cache
      - *restore_pods_cache
      - *install_pods
      - *save_pods_cache
      - *decode_appstore_auth_key
      - *switch_app_env_to_dev
      - *prepare_ios_certs
      - *build_ios_app
      - store_artifacts:
          path: ~/builds

### -- WORKFLOWS -- ###

workflows:
  version: 2
  workflow:
    jobs:
      - build_approval:
          <<: *flavor_matrix
          <<: *tag_filters
          name: << matrix.flavor >>
          type: approval
      - android_deploy_internal:
          <<: *flavor_matrix
          <<: *tag_filters
          name: android_<< matrix.flavor >>_deploy
          requires:
            - << matrix.flavor >>
      - ios_deploy_to_testflight:
          <<: *flavor_matrix
          <<: *tag_filters
          name: ios_<< matrix.flavor >>_deploy
          requires:
            - << matrix.flavor >>
      - hold_release:
          <<: *flavor_matrix
          <<: *tag_filters
          name: release_<< matrix.flavor >>
          type: approval
          requires:
            - ios_<< matrix.flavor >>_deploy
            - android_<< matrix.flavor >>_deploy
      - android_release:
          <<: *flavor_matrix
          <<: *tag_filters
          name: android_<< matrix.flavor >>_release
          requires:
            - release_<< matrix.flavor >>
      - ios_release:
          <<: *flavor_matrix
          <<: *tag_filters
          name: ios_<< matrix.flavor >>_release
          requires:
            - release_<< matrix.flavor >>
  build:
    when: << pipeline.parameters.only_build >>
    jobs:
      - brand_approval:
          <<: *flavor_matrix
          name: select_<< matrix.flavor >>
          type: approval
      - android_dev_build_approval:
          <<: *flavor_matrix
          name: android_dev_build_<< matrix.flavor >>
          type: approval
          requires:
            - select_<< matrix.flavor >>
      - android_build:
          <<: *flavor_matrix
          name: android_dev_<< matrix.flavor >>_build
          requires:
            - android_dev_build_<< matrix.flavor >>
      - ios_dev_build_approval:
          <<: *flavor_matrix
          name: ios_dev_build_<< matrix.flavor >>
          type: approval
          requires:
            - select_<< matrix.flavor >>
      - ios_build:
          <<: *flavor_matrix
          name: ios_dev_<< matrix.flavor >>_build
          requires:
            - ios_dev_build_<< matrix.flavor >>

What you have there is a master class in how to use YAML to drive the circleci build process, but that will limit the number of people who can understand the code you have posted. This is then complicated by the amount of understanding of circleci that the developer has… To be honest, I’m looking at the script and mainly saying to myself that’s cool or can I really do that?

You need to ask the original developer about how “<<: *tag_filters” is being used within all the “workflow/jobs” as this adds a filter to cause actions to only take place when a tag is added, but from your description of the steps you are taking you are not using tags.

Masterclass eh. That is a good mark, I guess. But yes, I have asked the dev to figure it out for me, but I wanted to ask the community if they could see what is going on also, since we might not have this dev any longer.