CircleCI 2.0でDocker imageをbuildしてタグを付けてContainer Registryに上げる

gcpcirclecikubernetes

(追記: 2019-04-13) 2.1からのOrbを使うと自分でjobを書かなくてもよくなる CircleCI 2.1からのOrbでdocker buildしてECRにpushし、Slackに通知させる - sambaiz-net

masterにpushしたときと、リリースタグを切ったときにビルドされるようにする。

imageとタグ

version: 2
jobs:
  build:
    docker:
      - image: google/cloud-sdk
    environment:
      GCP_PROJECT: <project_name>
      IMAGE_NAME: <image_name>
    steps:
      - checkout
      - setup_remote_docker:
          version: 18.05.0-ce
      - run:
          name: gcloud auth
          command: |
            echo $GCLOUD_SERVICE_KEY | base64 --decode > ${HOME}/gcloud-service-key.json
            gcloud auth activate-service-account --key-file ${HOME}/gcloud-service-key.json
            gcloud --quiet auth configure-docker            
      - run:
          name: docker build & push
          command: |
            docker build -t asia.gcr.io/${GCP_PROJECT}/${IMAGE_NAME}:${CIRCLE_BUILD_NUM} .
            docker tag asia.gcr.io/${GCP_PROJECT}/${IMAGE_NAME}:${CIRCLE_BUILD_NUM} asia.gcr.io/${GCP_PROJECT}/${IMAGE_NAME}:latest
            if [ -n "${CIRCLE_TAG}" ]; then
              docker tag asia.gcr.io/${GCP_PROJECT}/${IMAGE_NAME}:${CIRCLE_BUILD_NUM} asia.gcr.io/${GCP_PROJECT}/${IMAGE_NAME}:${CIRCLE_TAG}
            fi
            docker push asia.gcr.io/${GCP_PROJECT}/${IMAGE_NAME}            

workflows:
  version: 2
  master-build:
    jobs:
      - build:
          filters:
            branches:
              only: master
  release-build:
    jobs:
      - build:
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /^v.*/

Docker

dockerコマンドを実行できるようにsetup_remote_dockerする。

GCPの認証

Storageのbucketも読み書きできるようにストレージ管理者のService Accountを作成して鍵をJSONでダウンロードし、 base64エンコードしてCircleCIのEnvironment VariablesのところにGCLOUD_SERVICE_KEYで登録する。 ビルド時にはこれをデコードしてactivate-service-accountする。

branchとtagのフィルタ

workflowがなくてもbuildのjobは実行される。 しかし、ブランチのフィルタはjobの方でも設定できるが、タグは設定できないため workflowを作る必要がある。

また、tagsを設定しないとタグに反応してビルドが始まらず、branchをignoreしないとタグを切ってないときにも無条件にビルドが走ってしまうので release-buildではbranchをignoreしている。