🐁

CircleCI CLIを触ってみた

2021/02/10に公開

背景

先日こちらの本を読んでCircle CIについて基礎を勉強していました。
https://gihyo.jp/book/2020/978-4-297-11411-4

そのなかでCircleCI CLIが興味深かったので、触ってみました。
Circle CIはクラウド環境で実行するイメージしかありませんでしたが、ローカル環境でも実行できるみたいです。
目的としてはconfig.ymlの文法チェック、ジョブの実行確認などが挙げられます。
CircleCI CLIをローカルマシンにインストールすればすぐに使うことができましたので、試しに入れてみて触った感想を記載していきます。

CircleCI CLIについて

CircleCI CLIはローカル環境でCircleCIを実行させることが可能で、Dockerコンテナの上で実行されます。なのでローカルマシンにはDockerをインストールすることが必須となります。
インストール手順や詳細な使い方は公式のリファレンスが充実していますので、こちらと上記の技術書をベースに使い方を記載していきます。
https://circleci.com/docs/ja/2.0/local-cli/

インストール方法

公式リファレンスにも書いてありますが、curl -fLSs https://circle.ci/cli | bashのワンライナーでインストールできます。
ただ私のPCで実行しても/usr/local/binのパーミッションエラーが出てインストールに失敗しました。リファレンスにもエラーに関する注意書きがあり、sudoをつけて実行しましたが、結果が変わらずパーミッションエラーが出たままでした。
rootユーザーに切り替えて実行しましたが、次のようなエラーが発生しました。

curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to XXXXXXX.com:443

接続のURLはメモし忘れましたので、ぼかしますがSSL接続ができないというエラーのように思われます。
はじめて見るエラーでしたので、ググりましたが端末再起動という解決策が複数サイトで見つかったので、再起動し改めてrootユーザーで実行してみたところ、問題なくインストールすることに成功しました。

root@yuta-PC:~# curl -fLSs https://circle.ci/cli | bash
Starting installation.
Installing CircleCI CLI v0.1.12331
Installing to /usr/local/bin
/usr/local/bin/circleci

CircleCI CLI使用感

.cirlceci/config.ymlがあるカレントディレクトリでcircleci config validateを実行するとconfig.ymlの文法エラーとCircleCIの設定エラーの2つを確認できます。

$ ll .circleci/
合計 12
drwxrwxr-x 2 yuta yuta 4096  29 22:57 ./
drwxrwxr-x 9 yuta yuta 4096  29 22:57 ../
-rw-rw-r-- 1 yuta yuta 1198  210 14:04 config.yml
$ circleci config validate
Config file at .circleci/config.yml is valid.

例として以下のように設定的に間違えているconfig.ymlvalidateしますとエラー箇所を教えてくれます。

config.yml
version: 2
job: #jobsが正しい
  build:
    docker:
$ circleci config validate
Error: ERROR IN CONFIG FILE:
[#] required key [jobs] not found

設定チェックが問題なければ、circleci local executeコマンドを実行することで、ローカル環境でジョブを実行します。
注意点ですが、ローカル環境での実行ではワークフローが未対応のため、一度に実行できるジョブは1つのみとなっております。

サンプルコード(出展:CircleCI実践入門 技術評論社)

config.yml
version: 2
jobs:
  build:
    docker:
      - image: cimg/node:lts
    steps:
      - run: echo "Hello world"
$ circleci local execute
Docker image digest: sha256:d0a50c4f6c2eb88d74bb28feba214c5e8dac1d86c4d923cf3323b819343d983a
====>> Spin up environment
Build-agent version  ()
System information:
 Server Version: 20.10.3
 Storage Driver: overlay2
  Backing Filesystem: extfs
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Kernel Version: 5.4.0-65-generic
 Operating System: Linux Mint 20
 OSType: linux
 Architecture: x86_64

Starting container cimg/node:lts
Warning: No authentication provided, using CircleCI credentials for pulls from Docker Hub.
  image cache not found on this host, downloading cimg/node:lts
lts: Pulling from cimg/node
da7391352a9b: Pull complete 
14428a6d4bcd: Pull complete 
2c2d948710f2: Pull complete 
603b7cf6e7bd: Pull complete 
cbec34148b39: Pull complete 
dc24fb0b5dbb: Pull complete 
4c9b37fdf62a: Pull complete 
790651f8eba1: Pull complete 
75d371ea9273: Pull complete 
Digest: sha256:f6ab0eb78b007434b722a3a5b9345010d5a4a0ec5a7aa4acf802aa2d88fb0090
Status: Downloaded newer image for cimg/node:lts
  pull stats: download 478.8MiB in 3m44.278s (2.135MiB/s), extract 478.6MiB in 1m9.556s (6.881MiB/s)
  time to create container: 117ms
  using image cimg/node@sha256:f6ab0eb78b007434b722a3a5b9345010d5a4a0ec5a7aa4acf802aa2d88fb0090
Time to upload agent and config: 1.319735557s
Time to start containers: 1.103826375s
====>> Preparing environment variables
Using build environment variables:
  BASH_ENV=/tmp/.bash_env-localbuild-1612941111
  CI=true
  CIRCLECI=true
  CIRCLE_BRANCH=
  CIRCLE_BUILD_NUM=
  CIRCLE_JOB=build
  CIRCLE_NODE_INDEX=0
  CIRCLE_NODE_TOTAL=1
  CIRCLE_REPOSITORY_URL=
  CIRCLE_SHA1=
  CIRCLE_SHELL_ENV=/tmp/.bash_env-localbuild-1612941111
  CIRCLE_WORKING_DIRECTORY=~/project


The redacted variables listed above will be masked in run step output.====>> echo "Hello world"
  #!/bin/bash -eo pipefail
echo "Hello world"
Hello world
Success!

使っていてうっかりしていた部分

サンプルコードで挙動を確認した後、自前のconfig.ymlを実行してみましたが、実行に失敗しまして、技術書に書いてない仕様に引っかかりましたので、記載します。
私の使っているcofig.ymlですが、ジョブ名が以下の通りになっていました。

config.yml
version: 2
jobs:
  test1:
    docker:
      - image: cimg/python:3.8.2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  test2:
    docker:
      - image: cimg/python:3.8.2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

workflows:
  version: 2
  Yuta-test:
    jobs:
      - test1
      - test2
$ circleci local execute
Downloading latest CircleCI build agent...
Docker image digest: sha256:d0a50c4f6c2eb88d74bb28feba214c5e8dac1d86c4d923cf3323b819343d983a
====>> Spin up environment
Build-agent version  ()
Error: 
Configuration errors: 1 error occurred:
	* Cannot find a job named `build` to run in the `jobs:` section of your configuration file.
If you expected a workflow to run, check your config contains a top-level key called 'workflows:'



Step failed
Task failed
Error: 1 error occurred:
	* Cannot find a job named `build` to run in the `jobs:` section of your configuration file.
If you expected a workflow to run, check your config contains a top-level key called 'workflows:'

ワークフローが含まれている場合でも技術書によると単独で実行できると記載がありましたので、一番最初のtest1だけ実行できるとかと思いましたが、test1の実行も失敗してしまいました。
CircleCIのジョブ名ですが、デフォルトではbuildになっており、circleci local executeと実行するとジョブ名がbuildのジョブを実行しようとします。
ところが、ジョブ名をカスタマイズし、自分でジョブ名をネーミングしますとローカル環境ではジョブbuildがないため実行エラーとなってしまいます。
技術書では特に触れられていませんでしたが、リファレンスによりますと特定のジョブを実行したい場合、オプション--job JOB_NAMEをつけることで実行できると記載されています。

$ circleci local execute --job test1
Docker image digest: sha256:d0a50c4f6c2eb88d74bb28feba214c5e8dac1d86c4d923cf3323b819343d983a
====>> Spin up environment
Build-agent version  ()
System information:
 Server Version: 20.10.3
 Storage Driver: overlay2
  Backing Filesystem: extfs
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Kernel Version: 5.4.0-65-generic
 Operating System: Linux Mint 20
 OSType: linux
 Architecture: x86_64

Starting container cimg/python:3.8.2
Warning: No authentication provided, using CircleCI credentials for pulls from Docker Hub.
  image is cached as cimg/python:3.8.2, but refreshing...
3.8.2: Pulling from cimg/python
Digest: sha256:c9ed9ed9f63877d250c949cd8570a5de5f2a6dcb04f574a06d18809474dfa817
Status: Image is up to date for cimg/python:3.8.2
  pull stats: N/A
  time to create container: 75ms
  using image cimg/python@sha256:c9ed9ed9f63877d250c949cd8570a5de5f2a6dcb04f574a06d18809474dfa817
Time to upload agent and config: 1.249984947s
Time to start containers: 676.321988ms
====>> Preparing environment variables
Using build environment variables:
  BASH_ENV=/tmp/.bash_env-localbuild-1612880807
  CI=true
  CIRCLECI=true
  CIRCLE_BRANCH=
  CIRCLE_BUILD_NUM=
  CIRCLE_JOB=progate3
  CIRCLE_NODE_INDEX=0
  CIRCLE_NODE_TOTAL=1
  CIRCLE_REPOSITORY_URL=
  CIRCLE_SHA1=
  CIRCLE_SHELL_ENV=/tmp/.bash_env-localbuild-1612880807
  CIRCLE_WORKING_DIRECTORY=~/repo


The redacted variables listed above will be masked in run step output.====>> Checkout code
Making checkout directory "/home/circleci/repo"
Copying files from "/tmp/_circleci_local_build_repo" to "/home/circleci/repo"
====>> Run Lesson3 script
  #!/bin/bash -eo pipefail
python lesson3/script.py
じゃんけんを始めます
名前を入力してください:Test
何を出しますか?(0: グー, 1: チョキ, 2: パー)
ゲストはグーを出しました
コンピューターはグーを出しました
結果は引き分けでした
Success!

--jobをつけてジョブ名を明示することでローカル環境でもジョブが動くことが確認できました。
後は、いつものようにgit addして、git commitして、git pushすればクラウド上のCirlceCIが動きCIが始まります。

所感

私としてはYAMLファイルは読みやすくて好きですが、記述ミスが見落としやすく、エラー発生時の原因調査で時間がかかる場合があります。config.ymlを変更したら逐次validateを行なうことでミスに気づき、時間短縮に繋がりますので積極的に使っていきたいと思います。
個人的にはAnsibleやTerraformのようにCircleCI CLIにもconfig.ymlのテンプレート作成コマンドがあれば、便利だなと思いますが、現状自分で一から作成する以外方法がない感じですかね🤔
(circleci initこんなコマンドがほしい)

GitHubで編集を提案

Discussion