やりたかったこと
GitLabのCI/CD環境で、自動ビルドと自動テストを実施出来るような環境を構築してみました。
パイプラインを実行するためのランナーについては、自前で用意したランナー上で実行されるような環境を作ります。
前提
- GitLabはオンプレに構築済み
- CI実行対象のリポジトリは用意済み
- ランナーはdockerコンテナとして構築する
- Rustで記載した簡単なコードに対して、ビルドとテストを実行する
今回用意したコードはこんな感じです。
とりあえずビルドとテストが実行出来れば良かったので簡単なものを用意しています。
fn sum(a: u32, b: u32) -> u32 {
return a + b;
}
fn main() {
let c: u32 = sum(2, 3);
println!("result: {}", c);
}
#[cfg(test)]
mod tests {
#[test]
fn test_sum_1() {
assert_eq!(super::sum(2, 3), 5);
assert_eq!(super::sum(2, 5), 7);
}
#[test]
fn test_sum_2() {
assert_eq!(super::sum(1, 10), 11);
assert_eq!(super::sum(0, 3), 3);
}
}
Specific Runnerの作成
Specific Runnerは、Github Actionsで言うところのSelf-hosted Runnerのようなものです。
プロジェクト単位で専有できるランナーを自前で構築して使用できます。
GitLab側のRunner設定
GitLabの「設定」⇒「CI/CD」を選択し、「Runner」を展開することで対象プロジェクトのRunner設定を確認できます。
今回は「共有 Runner」は使用しないのでオフにします。
また、「Specific runners」に記載されているURLとtokenは後のRunner登録の手順で必要となるので、メモしておいてください。
Runner用のDockerコンテナ起動
下記コマンドでランナー用のコンテナを起動します。
公式マニュアルの記載を参考にしています。
docker run -it --name gitlab-runner --restart=always \
--hostname gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /srv/gitlab-runner/config:/etc/gitlab-runner \
--tty \
gitlab/gitlab-runner:latest register
Runnerの登録
先述のコマンドでコンテナを起動すると、ランナーをGitLabのリポジトリに登録するための処理が始まります。
下記の順番で設定値を求められるので、入力します。
- Enter the GitLab instance URL
- GitLabのURLを入力します。GitLabの設定ページに記載されているものをコピペでOKです。
- Enter the registration token
- 登録用トークンを入力します。 ここもGitLabの設定ページに記載されているものをコピペします。
- Enter a description for the runner (任意)
- このランナーに対する説明文です。今回は空欄とします。
- Enter tags for the runner (任意)
- タグを付与することで、ジョブの実行対象となるランナーをタグで指定することが可能です。今回は特にタグは付与しないので空欄です。
- Enter optional maintenance note for the runner (任意)
- このランナーに対するメンテナンスノートです。今回は空欄とします。
- Enter an executor
- runner executorを指定します。今回は
docker
を指定します。
- runner executorを指定します。今回は
- Enter the default Docker image
- デフォルトで使用されるdockerイメージを指定します。今回はRust向けのため、
rust:latest
で指定します。
- デフォルトで使用されるdockerイメージを指定します。今回はRust向けのため、
ランナーの登録に成功すると、「Runner registered successfully.」とメッセージが表示されます。
GitLabの設定ページの「利用可能なSpecific Runner」に作成したランナーが登録されていれば完了です。
トラブルシューティング1: Runner登録中に「dial tcp: lookup xxx on x.x.x.x:53: no such host」のエラーが発生
自分の環境では、外向きのホスト名を解決するための設定をしていなかったため、内向きのIPアドレスを設定する必要がありました。
Enter the GitLab instance URLで入力するURLに直接IPアドレスを指定することで解決しました。
トラブルシューティング2: 作成したランナーで「runner has never contacted this instance」という警告が発生
コンテナ上でgitlab-runner verify
コマンドを実行することで解決しました。
パイプラインの作成
.gitlab-ci.ymlの作成
.gitlab-ci.yml
を作成し、プロジェクト直下に配置します。
今回はRustで作成したアプリに対して、自動ビルドと自動テストを実施するように定義しています。
また、ビルドで作成された実行ファイルは、ブラウザからartifactsとしてダウンロードできるようにしています。
image: rust:latest
stages:
- build
- test
before_script:
- echo "this is test script"
build:
stage: build
script:
- echo "this is build"
- cargo build --release
artifacts:
paths:
- target/release/rust_cicd
test:
stage: test
script:
- echo "this is test"
- cargo test
実際にリポジトリに登録するディレクトリ構成としては以下のような形になります。
(と言っても、cargo new
で作成したプロジェクトに.gitlab-ci.yml
を追加しただけです。)
パイプラインの実行
パイプラインが実行されるタイミング
作成した.gitlab-ci.yml
をリモートリポジトリにpushすることで、CIが実行されるようになります。
以降は、対象ブランチへのpushが実行されるたびに、CIが実行されます。
結果確認
プロジェクトの「CI/CD」⇒「パイプライン」で過去に実行されたCIの結果を確認できます。
ステータスが成功になっていれば、CIで定義されたジョブが全て成功しています。
各ステージを選択することで、そのジョブの実行ログを確認することが出来ます。
作成したテストケースが全てパスしているので、ジョブのステータスも成功となっています。
また、パイプラインの右側のボタンを選択することで、artifactsをダウンロードできます。
ビルド時に作成される実行ファイルをartifactsとして登録するように設定しているため、ダウンロードされるフォルダ内には実行ファイルが含まれます。
トラブルシューティング1:「Getting source from Git repository」の段階で「Couldn't resolve host」のエラーが発生
GitLabの内向きのIPアドレスを指定するように、ランナーの設定を変更してやる必要がありました。
ランナー用コンテナに入り、/etc/gitlab-runner/config.toml
を編集します。
-
clone_url
に内向きのIPアドレスを設定 -
extra_hosts
を設定
[[runners]]
name = "Test runner for rust-cicd-test"
url = "http://192.168.1.121:8080/"
id = 2
token = "xxxxxxxxxxxxxxxxxxxxx"
token_obtained_at = 2023-05-02T09:41:41Z
token_expires_at = 0001-01-01T00:00:00Z
executor = "docker"
clone_url = "http://192.168.1.121:8080"
[runners.docker]
tls_verify = false
image = "ubuntu:latest"
privileged = false
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/cache"]
extra_hosts = ["example.com:192.168.1.121"]
shm_size = 0