LoginSignup
8
6

More than 5 years have passed since last update.

CircleCI 2.0におけるGitタグ・ジョブ実行

Posted at

CircleCI 1.0では正常動作したGitタグ・ジョブ実行が、CircleCI 2.0ではうまく動きませんでした。どうにかしようと四苦八苦したログをここに残します。

結論

GitタグをpushしてもCircleCIジョブが起動しませんでした。なので、masterブランチにpushされたときに最後のGitタグを取得してデプロイ処理を実行するようにしました。

動作確認用にu6k/sample-circleci-2.0リポジトリを作成しましたので、こちらの.circleci/config.ymlをご覧ください。

Gitタグ・ジョブ実行の関連スレッド

CircleCIコミュニティや公式ドキュメントの関連スレッドを挙げます。

このスレッドによると、2017/8にGitタグ・ジョブ実行が有効になったとのこと。

「Git Tag Job Execution」にジョブ(というかワークフロー)の設定方法が説明されていますが、この通りに設定してもそもそもGitタグのpushでCircleCIジョブが起動しませんでした。

config.ymlの説明

GitタグのpushでCircleCIジョブが起動しないので、しかたないのでmasterブランチのpushで必要な処理を実行するようにしました。以下のconfig.ymlが設定例です。

version: 2
jobs:
    build:
        docker:
            - image: docker:17.07.0-ce-git
        steps:
            - checkout
            - setup_remote_docker:
                version: 17.07.0-ce
            - run:
                name: Build docker image
                command: docker build -t u6kapps/sample-circleci-2.0 .
            - run:
                name: Test docker image
                command: docker run u6kapps/sample-circleci-2.0
            - run:
                name: Save docker image
                command: |
                    mkdir -p ~/caches
                    docker save u6kapps/sample-circleci-2.0 -o ~/caches/image.tar
            - save_cache:
                key: docker-{% raw %}{{ .Revision }}{% endraw %}
                paths:
                    - ~/caches/image.tar
    push:
        docker:
            - image: docker:17.07.0-ce-git
        steps:
            - checkout
            - setup_remote_docker:
                version: 17.07.0-ce
            - restore_cache:
                key: docker-{% raw %}{{ .Revision }}{% endraw %}
                paths:
                    - ~/caches/image.tar
            - run:
                name: Load docker image
                command: docker load -i ~/caches/image.tar
            - run:
                name: Push docker image
                command: |
                    TAG=`git describe --abbrev=0`
                    docker login -u ${DOCKER_USER} -p ${DOCKER_PASS}
                    docker tag u6kapps/sample-circleci-2.0 u6kapps/sample-circleci-2.0:${TAG}
                    docker push u6kapps/sample-circleci-2.0
workflows:
    version: 2
    build-and-push:
        jobs:
            - build
            - push:
                requires:
                    - build
                filters:
                    branches:
                        only: master

要所を説明します。

docker:
    - image: docker:17.07.0-ce-git

ジョブで使用するDockerイメージを指定します。この時、-gitのイメージを使用しないと、gitコマンドが使用できません。

- setup_remote_docker:
    version: 17.07.0-ce

setup_remote_dockerステップは隔離されたDocker環境を構築するためのステップです。ここでバージョンを指定しない場合、docker imageで指定したバージョンとは異なるデフォルトのバージョン(17.03?)が割り当てられ、multi stage buildが使えません。

なので、無難にdocker imageで指定したバージョンと同じバージョンを指定しておきます。

- run:
    name: Save docker image
    command: |
        mkdir -p ~/caches
        docker save u6kapps/sample-circleci-2.0 -o ~/caches/image.tar
- save_cache:
    key: docker-{% raw %}{{ .Revision }}{% endraw %}
    paths:
        - ~/caches/image.tar
- restore_cache:
    key: docker-{% raw %}{{ .Revision }}{% endraw %}
    paths:
        - ~/caches/image.tar
- run:
    name: Load docker image
    command: docker load -i ~/caches/image.tar

ジョブをまたいだファイルの使用は、キャッシュを経由する必要があります。なので、ビルド・ジョブでDockerイメージをtarに出力してキャッシュを保存、pushジョブでキャッシュからtarを取得してDockerイメージを復元します。

- run:
    name: Push docker image
    command: |
        TAG=`git describe --abbrev=0`
        docker login -u ${DOCKER_USER} -p ${DOCKER_PASS}
        docker tag u6kapps/sample-circleci-2.0 u6kapps/sample-circleci-2.0:${TAG}
        docker push u6kapps/sample-circleci-2.0

CircleCI 1.0では${CIRCLE_TAG}という環境変数にGitタグが設定されていましたが、envコマンドで確認したところGitタグのような環境変数はありませんでした。しかたないのでgit describeで最後のGitタグを取得して、それをDockerタグに設定します。

workflows:
    version: 2
    build-and-push:
        jobs:
            - build
            - push:
                requires:
                    - build
                filters:
                    branches:
                        only: master

pushジョブをmasterブランチの時のみ実行するように設定しています。CircleCI 1.0の時はGitタグがpushされた時のみ、という設定ができましたが。

実際の動作

developブランチとmasterブランチでファイルを修正してGit pushしたところ、CircleCIでは以下のように実行されました。

circleci-001

developブランチのビルドではbuildジョブだけ動作していることに対して、masterブランチの場合はbuildジョブとpushジョブが動作しました。

circleci-002

pushジョブでは最後のGitタグを取得してdocker pushが成功していることが分かります。

おわりに

CircleCI 2.0にするだけでビルドが早くなった!という記事をよく見ますが、まだ落とし穴が多く、移行はもう少し様子を見てからにします。

Link

8
6
1

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
8
6