CircleCIのマイグレーション用エンドポイントで1.0のプロジェクトから2.0のコンフィグを生成してみた

2018.03.06

2018年8月31日(金)にCircleCI 1.0でのビルドが終了するとのアナウンスがありました。1.0で動いているプロジェクトがある場合、バージョンアップを促すメールがきているのではないでしょうか。

設定のバージョンアップについての資料がこちらにまとまっています。

マイグレーションガイド自体はこちらなのですが、config.yml translatorといったツールが提供されております。 本記事ではこちらを試してみました。

config.yml translatorとは

なんと呼ぶのが正しいのかいまいちわからないのですが、こちらで説明されているツールです。 何をしてくれるツールかというと、既存のCircleCI 1.0のプロジェクトからCircleCI 2.0の設定を生成してくれます。

注意

生成された2.0の設定を適用した際に、アップデート前と完全に同じ動作をすることは保証されていません。 生成された設定をそのまま本番環境に適用するのではなく、適用前に新しい設定を使ったテストを行う必要があります。

2.0の設定を取得してみる

認証済みのブラウザからURLを叩いて取得する方法と、認証せずにトークンを使って取得する方法が提供されています。

認証済みのブラウザからの場合は、以下のURLにアクセスするとコンフィグがレスポンスされます。 https://circleci.com/api/v1.1/project/:vcs-type/:username/:project/config-translation

  • :username=inaba-jun
  • :project=sample-project
  • :vcs-type=GitHub

であれば、 https://circleci.com/api/v1.1/project/github/inaba-jun/sample-project/config-translation となります。

Bitbucketを利用している場合は:vcs-typebitbucketになります。(bbやghではありません。)

認証なしで取得する場合はクエリパラメータにcircle-tokenを追加してください。 https://circleci.com/api/v1.1/project/github/inaba-jun/sample-project/config-translation?circle-token=XXXXXX

トークンはこちらのURLから取得できます。(:username:projectはプロジェクトに合わせて変更してください) https://circleci.com/gh/:username/:project/edit#api

取得した設定ファイル

1.0の設定(変換前の元の設定)

machine:
  timezone:
  timezone: Asia/Tokyo
  java:
    version:
      oraclejdk8
general:
  artifacts:
    - "build/reports/tests"
test:
  override:
    - ./gradlew test
  post:
    - mkdir -p $CIRCLE_TEST_REPORTS/junit/
    - find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} $CIRCLE_TEST_REPORTS/junit/ \;
checkout:
  post:
    - chmod +x ./gradlew

2.0の設定(生成された設定)

# This configuration was automatically generated from a CircleCI 1.0 config.
# It should include any build commands you had along with commands that CircleCI
# inferred from your project structure. We strongly recommend you read all the
# comments in this file to understand the structure of CircleCI 2.0, as the idiom
# for configuration has changed substantially in 2.0 to allow arbitrary jobs rather
# than the prescribed lifecycle of 1.0. In general, we recommend using this generated
# configuration as a reference rather than using it in production, though in most
# cases it should duplicate the execution of your original 1.0 config.
version: 2
jobs:
  build:
    working_directory: ~/inabajunmr/ciecleci-config-transration
    parallelism: 1
    shell: /bin/bash --login
    # CircleCI 2.0 does not support environment variables that refer to each other the same way as 1.0 did.
    # If any of these refer to each other, rewrite them so that they don't or see https://circleci.com/docs/2.0/env-vars/#interpolating-environment-variables-to-set-other-environment-variables .
    environment:
      CIRCLE_ARTIFACTS: /tmp/circleci-artifacts
      CIRCLE_TEST_REPORTS: /tmp/circleci-test-results
    # In CircleCI 1.0 we used a pre-configured image with a large number of languages and other packages.
    # In CircleCI 2.0 you can now specify your own image, or use one of our pre-configured images.
    # The following configuration line tells CircleCI to use the specified docker image as the runtime environment for you job.
    # We have selected a pre-built image that mirrors the build environment we use on
    # the 1.0 platform, but we recommend you choose an image more tailored to the needs
    # of each job. For more information on choosing an image (or alternatively using a
    # VM instead of a container) see https://circleci.com/docs/2.0/executor-types/
    # To see the list of pre-built images that CircleCI provides for most common languages see
    # https://circleci.com/docs/2.0/circleci-images/
    docker:
    - image: circleci/build-image:ubuntu-14.04-XXL-upstart-1189-5614f37
      command: /sbin/init
    steps:
    # Machine Setup
    #   If you break your build into multiple jobs with workflows, you will probably want to do the parts of this that are relevant in each
    # The following `checkout` command checks out your code to your working directory. In 1.0 we did this implicitly. In 2.0 you can choose where in the course of a job your code should be checked out.
    - checkout
    # Prepare for artifact and test results  collection equivalent to how it was done on 1.0.
    # In many cases you can simplify this from what is generated here.
    # 'See docs on artifact collection here https://circleci.com/docs/2.0/artifacts/'
    - run: mkdir -p $CIRCLE_ARTIFACTS $CIRCLE_TEST_REPORTS
    # This is based on your 1.0 configuration file or project settings
    - run:
        working_directory: ~/inabajunmr/ciecleci-config-transration
        command: 'echo ''Asia/Tokyo'' | sudo tee -a /etc/timezone; sudo dpkg-reconfigure
          -f noninteractive tzdata; sudo service mysql restart; sudo service postgresql
          restart; '
    - run:
        working_directory: ~/inabajunmr/ciecleci-config-transration
        command: sudo update-alternatives --set java /usr/lib/jvm/jdk1.8.0/bin/java; sudo update-alternatives --set javac /usr/lib/jvm/jdk1.8.0/bin/javac; echo -e "export JAVA_HOME=/usr/lib/jvm/jdk1.8.0" >> $BASH_ENV
    # Checkout
    #   This would typically go in either a build or a build-and-test job when using workflows
    # This is based on your 1.0 configuration file or project settings
    - run: chmod +x ./gradlew
    # Dependencies
    #   This would typically go in either a build or a build-and-test job when using workflows
    # Restore the dependency cache
    - restore_cache:
        keys:
        # This branch if available
        - v1-dep-{{ .Branch }}-
        # Default branch if not
        - v1-dep-master-
        # Any branch if there are none on the default branch - this should be unnecessary if you have your default branch configured correctly
        - v1-dep-
    # The following line was run implicitly in your 1.0 builds based on what CircleCI inferred about the structure of your project. In 2.0 you need to be explicit about which commands should be run. In some cases you can discard inferred commands if they are not relevant to your project.
    - run: if [ -a ./gradlew ]; then gradlew dependencies; else gradle dependencies; fi
    # Save dependency cache
    - save_cache:
        key: v1-dep-{{ .Branch }}-{{ epoch }}
        paths:
        # This is a broad list of cache paths to include many possible development environments
        # You can probably delete some of these entries
        - vendor/bundle
        - ~/virtualenvs
        - ~/.m2
        - ~/.ivy2
        - ~/.bundle
        - ~/.go_workspace
        - ~/.gradle
        - ~/.cache/bower
    # Test
    #   This would typically be a build job when using workflows, possibly combined with build
    # This is based on your 1.0 configuration file or project settings
    - run: ./gradlew test
    # This is based on your 1.0 configuration file or project settings
    - run: mkdir -p $CIRCLE_TEST_REPORTS/junit/
    - run: find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} $CIRCLE_TEST_REPORTS/junit/ \;
    # Teardown
    #   If you break your build into multiple jobs with workflows, you will probably want to do the parts of this that are relevant in each
    # Save test results
    - store_test_results:
        path: /tmp/circleci-test-results
    # Save artifacts
    - store_artifacts:
        path: /tmp/circleci-artifacts
    - store_artifacts:
        path: build/reports/tests
    - store_artifacts:
        path: /tmp/circleci-test-results

プロジェクトに取得した設定を適用してみる

生成された設定をプロジェクトの.circleci/config.ymlに配置してCircleCIをもう一度実行してみます。

失敗しました。

どうやらgradlewコマンドをパスなしで実行している部分で失敗しているようなので修正しました。(30行目)

version: 2
jobs:
  build:
    working_directory: ~/inabajunmr/ciecleci-config-transration
    parallelism: 1
    shell: /bin/bash --login
    environment:
      CIRCLE_ARTIFACTS: /tmp/circleci-artifacts
      CIRCLE_TEST_REPORTS: /tmp/circleci-test-results
    docker:
    - image: circleci/build-image:ubuntu-14.04-XXL-upstart-1189-5614f37
      command: /sbin/init
    steps:
    - checkout
    - run: mkdir -p $CIRCLE_ARTIFACTS $CIRCLE_TEST_REPORTS
    - run:
        working_directory: ~/inabajunmr/ciecleci-config-transration
        command: 'echo ''Asia/Tokyo'' | sudo tee -a /etc/timezone; sudo dpkg-reconfigure
          -f noninteractive tzdata; sudo service mysql restart; sudo service postgresql
          restart; '
    - run:
        working_directory: ~/inabajunmr/ciecleci-config-transration
        command: sudo update-alternatives --set java /usr/lib/jvm/jdk1.8.0/bin/java; sudo update-alternatives --set javac /usr/lib/jvm/jdk1.8.0/bin/javac; echo -e "export JAVA_HOME=/usr/lib/jvm/jdk1.8.0" >> $BASH_ENV
    - run: chmod +x ./gradlew
    - restore_cache:
        keys:
        - v1-dep-{{ .Branch }}-
        - v1-dep-master-
        - v1-dep-
    - run: if [ -a ./gradlew ]; then ./gradlew dependencies; else ./gradle dependencies; fi
    - save_cache:
        key: v1-dep-{{ .Branch }}-{{ epoch }}
        paths:
        - vendor/bundle
        - ~/virtualenvs
        - ~/.m2
        - ~/.ivy2
        - ~/.bundle
        - ~/.go_workspace
        - ~/.gradle
        - ~/.cache/bower
    - run: ./gradlew test
    - run: mkdir -p $CIRCLE_TEST_REPORTS/junit/
    - run: find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} $CIRCLE_TEST_REPORTS/junit/ \;
    - store_test_results:
        path: /tmp/circleci-test-results
    - store_artifacts:
        path: /tmp/circleci-artifacts
    - store_artifacts:
        path: build/reports/tests
    - store_artifacts:
        path: /tmp/circleci-test-results

修正後に実行が成功しました。(2回目の実行以降2.0で実行されています。)

コマンドによってテストが実行されていることも確認できました。

まとめ

config.yml translatorによって、CircleCI 1.0のプロジェクトからCircleCI 2.0の設定ファイルを生成してみました。

個人的にはワークフローの仕組みの把握などもかねてマイグレーションガイドを見ながら段階をおってバージョンアップするのも良いかなと思うのですが、叩き台作成としての選択肢に入れても良いのではないでしょうか。

繰り返しとなりますが、生成された2.0の設定を適用した際に、アップデート前と完全に同じ動作をすることは保証されていません。 生成された設定をそのまま本番環境に適用するのではなく、適用前に新しい設定を使ったテストを行う必要があります。

私からは以上です。