幻魔ナイトブログ

主に絵、音楽、プログラミングなどについて書きます。

gitlab-ciのチュートリアルを試してみた。

f:id:MahiroN:20200212233423p:plain:w300

概要

会社でgitlab CIを使った自動化を行っており今まで先代作ったものを騙し騙し使っていたがいろいろわからないことが多いので基本に立ち返ることにする。。

今回は超初心者向けチュートリアルを実施して全体を学び直すことにした。
ただ、このチュートリアル色々と端折られているためハマる箇所があるので より細かな点までやったことを書くようにしました。

プロジェクトを作ろう!

gitlabでプロジェクトを作ります。詳細は公式ページを見たほうがいいでしょう。

ブランチを作成しよう!

ブランチの細かい説明は猿でもわかるGItlab入門に任せるとしてざっくり言ってしまうと複数の開発者が同じソースをいじれるようにする仕組みです。
ソースコードパラレルワールドといえば想像しやすいかもしれません。同じソースでもブランチが違えば他の開発者が行なっている影響を受けず、開発が終わってからマージするのが一般的な開発スタイルになります。
しかし、一人で使う場合はフォルダ感覚で使うことができます。
今回はci-testというブランチを作りました。

.gitlab-ci.ymlを用意しよう

.gitlab-ci.ymlはとても大切なファイルでここに自動化の処理をyaml形式で書いていきます。
作り方は
1. 名前はなんでも良いのでプロジェクトを作成する。
2. 右上のsetup ciをクリックするとファイルの編集画面が現れます。これが.gitlab-ci.yamlで処理を書いていくのですが、今回はチュートリアルのので以下のように記述します。

test:
  script: cat file1.txt file2.txt | grep -q 'Hello world'

するとプロジェクトのルートにgitlab-ci.ymlが作成されます。実は普通にファイル作成から作ってしまっても構いません。

file1.txtとfile2.txtを用意しよう!

このチュートリアルではビルドを「2つのファイルの内容を取得してgrepを行う」という処理としているようです。
もちろん実際にはもっと複雑な処理が走るのですが、簡単のためにこうなったのでしょう。 以下のようにfile1.txtとfile2.txtを用意します。

  • file1.txt
Hello 
  • file2.txt
world

注意!)file1.txtの「Hello」のあとスペースを入れるようにしましょう。ハマりポイントでした。

ciを実行しよう!

ここまで出来たらciツールを実行します。
左下の「ロケット」のようなボタンをクリックします。

どのブランチに対してパイプラインを実行するか選びます。
ここで初めて出てきましたが。「パイプライン」とはWikipediaによるとあるプロセスの出力を次のプロセスに渡せるようにする処理のことなようで、感覚的に書くと、コマンドの出力を入力として次のコマンドを実行する処理です。Linuxユーザーはよく「パイプ」でコマンドを繋げていますね。
gitlabもそういった処理を内包しておりパイプライン呼びます。
今はパイプラインを実行すれば.gitlab-ci.ymlに書かれた一連の処理が実行されるという風に捉えていただければ良いです。

パラメーターは。。。今回はしていしないですが、gitlab-ciはパラメーターを渡すことができます。

ちなみにここまでの処理の説明をします。
.gitlab-ci.ymlの中の「test」の部分はジョブ名で実行中のパイプラインをブラウザで見たときに今どのジョブが実行されているのかがわかります。
ジョブの中の「script:」の左に書かれている処理がジョブ内で実行される処理です。今回の場合はfile1.txtとfile2.txtの内容を繋げて取り出しパイプ処理で「Hello world」という単語をgrepしています。

Hello worldという単語がないとパイプラインがエラーとなって終了します。
ハマりポイントと書いたのはfile1.txtにHelloとだけ書いていたのでは繋げたときにHelloworldとなってしまいgrepでエラーとなってしまうことでした。
チュートリアルで行っているよにworldをAfricaに変えたりしたら当然エラーとなります。

ちなみに新しい変更をアップするたびにパイプラインが走る設定になっているようです。
ここまでで基本的なgitlab-ciの話は終わりです。

パッケージ処理を追加しよう

このチュートリアルではさらにパッケージング処理も追加します。
ということでジョブを増やしましょう。
以下のように.gitlab-ci.ymlにジョブを追加します。ジョブ名は「packege」ですね。

test:
  script: cat file1.txt file2.txt | grep -q 'Hello world'

package:
  script: cat file1.txt file2.txt | gzip > package.gz

実はここがハマりポイントです。チュートリアルを作成した人のミスなのか、最初の方はpackage.gzに書き出すように設定されていたファイル名が途中からpackaged.gxに変わっています。

それではパイプラインを実行してみましょう。testとpackageの2つのジョブが走っていますね。
さて、パッケージングのようにアウトプットを出力する場合当然それをダウンロードしたくなりますね。アーチファクトセレクションをジョブに対して設定することでジョブ内での作成物をダウンロードできるようになります。

artifactのタグ内にpathsを用意し、出力先のパスを書くことでpathsニア書かれたファイルをダウンロードボタンからダウンロードできるようになります。.gitlab-ci.ymlがあるルートディレクトリが基準となります。
artifactはscriptと同じインデント箇所に記載いします。
ジョブの結果からpackage.gzというファイルをダウンロードできることを確認しましょう。

stagesを使ってジョブの実行順序を決定しよう。

ここで敢えてtestジョブをしっぱいさせてみましょう。 Hello worldのところをHello wordlsにします。
パイプラインの結果を見てみるとtestジョブは見事に失敗していますが、packageジョブは成功しています。
実はgitlab-ciのパイプラインではジョブはそれぞれ非同期に実行されているのです。

しかしtestジョブが成功してからじゃないとpackageジョブを動かしたくないというような順序性を考慮しないといけないジョブももちろんあります。
そんな時のために.gitlab-ci.ymlの中で実行するジョブを明示的に指定する必要があります。

そのためにstagesタグを使用します。
以下のように記述し、stages内にどんなstageがあるかを記述し、さらにジョブの設定内部にどのstageに当たるか記述します。

stages:
- test
- package

test:
  stage: test
  script: cat file1.txt file2.txt | grep -q 'Hello worlds'
  
package:
  stage: package
  script: cat file1.txt file2.txt | gzip > packaged.gz
  artifacts:
    paths:
    - packaged.gz 

するとパイプラインは下の図のようにジョブ同士が繋がった状態となり、testジョブが失敗したせいでpackageジョブは実行されなくなりました。
チュートリアルでは更にcompileジョブも追加しているようです

お問合わせはこちら