LoginSignup
6
5

More than 5 years have passed since last update.

CircleCIで特定ブランチで動くワークフローをさらに分岐させたい

Posted at

はじめに

CircleCIのworkflowを使ってjobを実行する場合に、ブランチでフィルターをかけて実行するjobを決めていました。例えばリリース用のブランチへマージされた場合のみデプロイに関するjobを実行するといった使い方です。

開発をしている中でブランチよりももう少し細かい条件で分岐でjobを分けたいという要望があり、その時行った方法について紹介します。

やりたいこと

remoteのブランチへのcommitをトリガーにブランチによって以下のようなworkflowが別れている場合に

ブランチ job
master以外 test-job
master test-job,deploy-job

masterブランチへのcommitをトリガーに実行されるworkflowを二つに分けて特定の条件の場合にテストをskipするようにしたい。

ブランチ job
master以外 test-job
master test-job,deploy-job
master(特定の条件を満たす) deploy-job

前提

前提としてはworkflowを利用する

簡単のため以下のようなシンプルなconfig.ymlがあった場合で説明していきます。

.circleci/config.yml
version: 2.1 # executorsのみ2.1の機能を使っていますが、それ以外は2.0の機能です
executors:
  default:
    working_directory: ~/sample
    docker:
      - image: hoge/hoge:latest
jobs:
  test-job:
    executor:
      name: default
    steps:
      - run:
          name: test_step
          command: echo 'execute test job'
  deploy-job:
    executor:
      name: default
    steps:
      - checkout
      - run:
          name: deploy_step
          command: echo 'execute deploy job'

workflows:
  test-and-deploy:
    jobs:
      - test-job
      - deploy-job:
          requires:
            - test-job
          filters:
            branches:
              only:
                - master

採用した方法

単純な方法ですが、commit logに特定の文字列が入っている場合にテストの実行をskipするようにしました。
例えばskip_testのような文字列が入っている場合に実行をする。場合はconfig.ymlを以下のように修正します。

.circleci/config.yml
version: 2.1
executors:
  default:
    working_directory: ~/sample
    docker:
      - image: hoge/hoge:latest
jobs:
  test-job:
    executor:
      name: default
    steps:
      - checkout
      - run:
          name: test_step
          command: | # commandの内容を修正
            if [ -z "`git log -1 --oneline | grep skip_test`" ]; then
              echo 'execute test job'
            else
              echo "skip test job"
            fi
  deploy-job:
    executor:
      name: default
    steps:
      - run:
          name: deploy_step
          command: echo 'execute deploy job'

workflows:
  test-and-deploy:
    jobs:
      - test-job
      - deploy-job:
          requires:
            - test-job
          filters:
            branches:
              only:
                - master

シンプルな方法はですが微妙な点もあります。jobの中でテストを実行するかどうかを判断しているため、テストの実行自体はスキップできますが、その前処理(例でいうとexecutorの中の処理や、checkoutの処理)は実行されるためそのそのオーバーヘッドは必ずかかってしまいます。

スクリーンショット 2019-03-16 23.19.32.png
スクリーンショット 2019-03-17 0.41.57.png

採用しなかった方法

gitのtagを使って実行するjobにfilterをかけることもできるため、tagでの制御も検討しましたが以下のような理由で採用しませんでした。

  • 今の開発チームではtagを使った運用をしていない
  • テストをスキップするためにタグを使い分けるのもタグの使い方として微妙
  • branchでfilterをかける場合と比較してfilterが複雑になってくる

以下はtagを使った制御の例になります。

発火条件 job
master以外のブランチへのコミット test-job
skiptestの文字列を含まないtagの作成 test-job,deploy-job
skiptestの文字列を含むtagの作成 deploy-job
.circleci/config.yml
# workflowsのみ抜粋
workflows:
  test:
    jobs:
      - test-job:
          filters:
            branches:
              ignore: master # masterブランチでどのjobを実行するかはtagで制御するためignore
  test-and-deploy:
    jobs:
      - test-job:
          filters:
            tags:
              only: /^(?!.*skiptest).*$/ # skiptestを含まないタグの場合のみ発火
            branches:
              ignore: /.*/ # branchへのcommitで発火しないようにignore
      - deploy-job:
          requires:
            - test-job
          filters:
            tags:
              only: /^(?!.*skiptest).*$/ # skiptestを含まないタグの場合のみ発火
            branches:
              ignore: /.*/ # branchへのcommitで発火しないようにignore
  only-deploy:
    jobs:
      - deploy-job:
          filters:
            tags:
              only: /^.*skiptest.*$/ # skiptestを含むタグの場合のみ発火
            branches:
              ignore: /.*/ # branchへのcommitで発火しないようにignore

この例ではworkflow自体がシンプルなのでそこまで複雑ではないですが、workflow自体が複雑になってくるとfilterまわりが複雑になってくるなという印象です。

まとめ

CircleCIのworkflowを使って特定ブランチで実行されるjobをさらに分けて実行する方法を紹介しました。採用した方法では不要なオーバーヘッドがかかっているので、jobレベルで分けれてもっとシンプルにできる方法がないかなあと思うところです。

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5