GitLab CD


ページ内目次
 Netlify準備
 Netlifyデプロイ
 継続的デリバリー
 EtoEテスト
 バージョン

🚀 手動デプロイはもう古い!GitLabでNetlifyに自動デプロイしよう


こんにちは!今回は、手動で行っていたNetlifyへのデプロイを自動化する方法を学びます。これを実現するために、Netlify CLIというツールを使い、GitLabと連携させます。

📦 ステップ1:Netlify CLIをインストールする

手動でファイルをドラッグ&ドロップする代わりに、Netlify CLIというコマンドラインツールを使ってデプロイします。このCLIを使えば、ブラウザを開くことなく、コマンド一つでデプロイが完了します。

  • なぜCLIを使うの?

    • GitLabのような自動化ツールは、ブラウザを操作したり、ボタンをクリックしたりすることはできません。

    • CLIを使えば、手動で行っていた一連の作業をコマンドで再現でき、自動化のパイプラインに組み込むことが可能になります。

GitLab CIにNetlify CLIをインストールする

.gitlab-ci.ymlファイルに新しいジョブを追加して、Netlify CLIをインストールします。

netlify_cli:
  stage: .pre # パイプラインの最初で実行
  image: node:22-alpine # Node.jsが必要
  script:
    - npm install -g netlify-cli # Netlify CLIをグローバルにインストール
    - netlify --version # インストールが成功したか確認

このジョブをstage: .preに設定することで、他のジョブが始まる前にインストールが完了し、問題があればすぐに気づくことができます。


🔑 ステップ2:認証情報をGitLabに安全に保存する

Netlify CLIをインストールしただけでは、誰のウェブサイトにデプロイするのか、誰がデプロイを許可されているのかがわかりません。そこで、以下の2つの情報をGitLabに設定します。

  1. サイトID:デプロイ先のNetlifyサイトを特定するためのID

  2. 認証トークン:GitLabがNetlifyへのデプロイを許可するための鍵

サイトIDを.gitlab-ci.ymlに設定する

Netlifyのサイト設定から**Site ID**をコピーし、.gitlab-ci.ymlのジョブ内に変数として定義します。

netlify_cli:
  # ...
  variables:
    NETLIFY_SITE_ID: "あなたのサイトID" # NetlifyからコピーしたIDをここに貼り付ける
  script:
    # ...
    - echo "Deploying to Site ID: $NETLIFY_SITE_ID"
  • 💡ポイント💡$変数名という形式で、スクリプト内で定義した変数にアクセスできます。

認証トークンをGitLabのCI/CD変数に設定する

認証トークンは機密情報です。コードの中に直接書くのは非常に危険なので、GitLabの安全なストアに保存します。

  1. Netlifyでトークンを生成

    • Netlifyのユーザー設定からOAuth > Personal access tokensへ移動します。

    • New access tokenをクリックして、新しいトークンを生成します。

  2. GitLabにトークンを保存

    • GitLabのプロジェクトページでSettings > CI/CD > Variablesを開きます。

    • Add variableをクリックし、以下の設定でトークンを保存します。

      • KeyNETLIFY_AUTH_TOKEN (この名前はNetlify CLIが自動で探すので、大文字で正確に記述します)

      • Value:Netlifyで生成したトークン

      • FlagsMask variableProtect variableを無効にします。(今は開発中のブランチで使いたいからです)

この設定をすることで、**NETLIFY_AUTH_TOKEN**がジョブのログに表示されることはなく、安全に管理されます。

なぜコードに書かないのか?

  • セキュリティ:コードに直接書くと、意図せず公開されたり、他の人が簡単にアクセスできてしまいます。

  • メンテナンス性:認証情報が変わった時に、コードを変更することなく、GitLabのUIから簡単に更新できます。

  • 環境管理:本番環境と開発環境で異なる認証情報を、同じパイプライン設定で使い分けることができます。

これで、Netlifyへの自動デプロイの準備が整いました。


ご提供いただいた内容をもとに、Netlifyへの最終的なデプロイと、その後のスモークテストについて、ブログ記事として整理し直します。


✅ 最終段階!Netlifyへの自動デプロイとスモークテスト


こんにちは!いよいよ自動デプロイの最終章です。今回は、これまでに設定したNetlify CLIと認証情報を使って、実際にプロジェクトをデプロイし、その後にスモークテストでデプロイが成功したかを確認する手順を解説します。


🚀 ステップ1:Netlifyにデプロイする

まず、最終的なデプロイのジョブを.gitlab-ci.ymlに作成します。これまでのジョブはtestステージにありましたが、デプロイは新しい**deployステージ**に移動させます。

デプロイジョブの作成

stages:
  - build
  - test
  - deploy # 新しいステージ

netlify_deploy:
  stage: deploy
  image: node:22-alpine # Node.jsとnpmが必要
  script:
    - netlify deploy --prod --dir build # Netlify CLIでデプロイを実行
  needs:
    - job: build_website # このジョブはbuild_websiteの完了を待つ
  • netlify deploy:デプロイを実行するコマンドです。

  • --prod:本番環境としてデプロイすることを指定します。

  • --dir build:デプロイするファイルがbuildディレクトリにあることを指定します。

  • needsnetlify_deployジョブが、build_websiteジョブの完了と成果物を必要とすることを明示しています。これにより、ビルドが完了した後にのみデプロイが実行されます。

この変更をコミットしてパイプラインを実行すると、deployステージが追加され、自動的にプロジェクトがNetlifyにデプロイされます。ジョブログでDeploy is liveというメッセージが表示されれば成功です!


💨 ステップ2:スモークテストで確認する

デプロイが成功したとしても、実際にウェブサイトが正しく表示されるかはブラウザで確認しないとわかりません。しかし、これも自動化できます。そこで行うのがスモークテストです。

  • スモークテストとは?

    • 元々は、電子回路に電源を入れて煙が出ないか(ショートしていないか)を確認するテストに由来します。

    • ソフトウェア開発では、**「システムが最低限の機能を持っているか」**を素早く確認するテストのことです。

ここでは、curlというコマンドを使って、デプロイされたウェブサイトにアクセスし、特定の文字列(例:GitLab)が含まれているかを確認します。

スモークテストの追加

netlify_deployジョブのscriptに、以下のコマンドを追加します。

netlify_deploy:
  stage: deploy
  image: node:22-alpine
  script:
    - netlify deploy --prod --dir build
    - apk add curl # curlをインストール
    - curl "https://your-site.netlify.app" | grep "GitLab" # スモークテストを実行

💡ポイント💡

  • apk add curl:Netlify CLIをインストールしたDockerイメージにはcurlが含まれていません。apkというコマンドを使って、curlをインストールする必要があります。

  • curl ... | grep "..."curlでウェブサイトのコンテンツを取得し、それをgrepコマンドで「GitLab」という文字列があるか検索しています。

このテストが成功すれば、以下のことが証明されます。

  • ウェブサイトにアクセスできること

  • デプロイが成功し、ウェブサイトが正しく表示されていること

  • 最低限のコンテンツがページに含まれていること

🤔もしテストが失敗したら? ジョブが失敗した場合、考えられる原因は様々です。

  • curlが見つからないapk add curlが正しく書かれていない可能性があります。

  • curlがタイムアウト:ウェブサイトにアクセスできない、またはサーバーが応答していない可能性があります。

  • grepが文字列を見つけられない:ウェブサイトの内容が変わってしまった可能性があります。

何が原因かを特定するために、まずはブラウザで直接URLにアクセスし、ウェブサイトが正常に表示されるか確認するのが最も簡単なデバッグ方法です。


これで、ビルドテストデプロイ、そしてスモークテストという一連の流れが完全に自動化されたパイプラインが完成しました!


🏗️ DevOpsの世界へ!継続的デリバリーと環境管理の基礎


自動デプロイの仕組みを理解したところで、いよいよDevOpsのより実践的な概念である継続的デリバリーレビュー環境ステージング環境について学びましょう。これらは、より安全で効率的なソフトウェア開発には欠かせない要素です。


🙅‍♂️ なぜマージリクエストで本番環境にデプロイしてはいけないのか?

私たちは、開発者が新しい機能を開発するフィーチャーブランチや、その変更をレビューするマージリクエストから直接本番環境にデプロイすべきではありません。

  • 理由:まだレビューやテストが完了していないコードが、直接ユーザーに届けられてしまう可能性があるからです。これは、サービスの安定性を損ない、顧客からの信頼を失う原因になります。

この問題を解決するために、パイプラインのルールを設定して、特定のブランチ(例:mainブランチ)にマージされた時だけ、デプロイが実行されるようにします。

パイプラインにルールを追加する

デプロイジョブに**rules**という設定を追加することで、実行条件を制御できます。

netlify_deploy:
  stage: deploy
  # ...
  rules:
    - if: '$CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
  • $CI_COMMIT_REF_NAME:パイプラインが実行されているブランチ名が入るGitLabの事前定義変数です。

  • $CI_DEFAULT_BRANCH:リポジトリのデフォルトブランチ名(通常はmain)が入る事前定義変数です。

これにより、このデプロイジョブはmainブランチへのプッシュ、またはマージがトリガーされた時だけ実行されます。


🔄 継続的デリバリー(Continuous Delivery)とは?

継続的デリバリーとは、**「デプロイ可能な状態のビルドを、手動での承認ステップを経て、いつでも本番環境にリリースできるようにする」**開発手法のことです。

⏸️ 手動承認ステップを追加する

デプロイジョブに**when: manual**という設定を追加することで、自動実行を止め、手動での承認ステップを挟むことができます。

netlify_prod:
  stage: deploy_prod
  # ...
  when: manual # 手動で実行する必要がある

これにより、パイプラインはステージング環境へのデプロイが完了した後に一時停止し、GitLabのUIに表示される**「▶️」ボタン**をクリックするまで、本番環境へのデプロイが実行されません。

この手動ステップは、以下のような場面で非常に役立ちます。

理由説明
品質保証(QA)人間による最終チェック(見た目やコンテンツなど)が必要な場合に有効です。
リスク管理デプロイ前にビジネス上のリスクを評価し、最終承認が必要な場合に役立ちます。
コンプライアンス変更を記録し、承認する義務がある場合に使用します。

🌍 開発環境の管理:ステージングとレビュー環境

デプロイプロセスをさらに安全にするために、ステージングレビューという2つの環境を導入します。

  • レビュー環境:マージリクエストごとに自動で作成される一時的な環境です。

    • 目的:マージする前に、その変更がどのように見えるかを開発者やレビュー担当者が確認できます。これにより、バグや予期せぬ変更を早期に発見できます。

    • GitLabでの実装:デプロイジョブにenvironment: { name: "review/..." }urlを設定し、.gitlab-ci.ymlファイル内でJSONを解析して動的にURLを抽出する必要があります。

  • ステージング環境:本番環境とほぼ同じ設定の、恒久的なテスト環境です。

    • 目的:本番環境にデプロイする前に、最終的な動作確認を行います。ここでのテストが成功すれば、本番環境でも成功する可能性が高いです。

    • GitLabでの実装:レビュー環境と同様に、environmentブロックを設定します。

GitLabでの環境表示

レビュー環境とステージング環境を適切に設定すると、GitLabの**Deployments > Environments**メニューに、それぞれの環境と、そこにデプロイされたバージョンが一覧で表示されるようになります。

これにより、プロジェクトの全ての環境とデプロイ履歴が一目で確認でき、ログの中からURLを探す手間がなくなります。

環境名説明
レビュー (review/branch-name)マージリクエストごとに一時的に作成されます。
ステージング (staging)最終的なテストを行うための、本番環境の複製です。
本番 (production)ユーザーがアクセスする、ライブ環境です。

これらの環境を適切に管理することで、自動化されたデプロイメントプロセスをより安全で、見通しの良いものにすることができます。


👨‍💻 開発者としてCI/CDを体験しよう:プロジェクトシミュレーション


これまではDevOpsエンジニアとしてパイプラインの設定に集中してきましたが、今回は開発者の視点に立って、GitLab CI/CDを体験してみましょう。

🤝 複数のマージリクエストを同時に進める

実際のプロジェクトでは、複数の開発者が同時に作業を進めることがよくあります。ここでは、2つの異なる変更を、それぞれ独立したブランチで作成し、マージリクエストを出してみます。

  1. 新しい段落の追加feature/add-new-paragraphブランチで新しい段落を追加します。

  2. ロゴの削除bugfix/remove-logoブランチで不要なロゴを削除します。

これらのマージリクエストはそれぞれ独立してパイプラインを実行します。

レビュー環境の力

マージリクエストのパイプラインが完了すると、レビュー環境が作成されます。これにより、コードレビュー担当者は、実際にブラウザで変更を確認できます。

  • feature/add-new-paragraphブランチのレビュー環境には、新しい段落が表示されます。

  • bugfix/remove-logoブランチのレビュー環境には、GitLabのロゴだけが表示されます。

💡重要なポイント💡これらの変更は、まだメインブランチにはマージされていません。 開発中の変更が、他の人に影響を与えることなく、独立した環境でテストできるのが、レビュー環境の最大のメリットです。

🔄 マージの競合とリベース

bugfix/remove-logoが先にmainブランチにマージされると、feature/add-new-paragraphのマージリクエストは**「リベースが必要」と表示されます。これは、mainブランチが先に進んだため、feature/add-new-paragraphブランチのコードが古くなっている**ことを意味します。

GitLabの**「Rebase」**ボタンをクリックするだけで、最新のmainブランチの変更を自分のブランチに取り込むことができます。これにより、手動でコードをマージする手間が省け、変更の衝突を未然に防ぎます。


🧪 品質保証:エンドツーエンドテストの自動化


手動での目視確認だけでなく、自動化されたテストは品質保証に不可欠です。ここでは、Playwrightというツールを使って、アプリケーションのエンドツーエンドテストをパイプラインに組み込みます。

  • エンドツーエンドテスト(E2Eテスト)とは?

    • ユーザーの行動(例:ログイン、ボタンクリック)をシミュレートし、アプリケーション全体が最初から最後まで期待通りに動作するかを確認するテストです。

    • スモークテスト(最低限の機能確認)よりもさらに詳細なテストで、すべてのコンポーネントが連携して機能することを確認します。

⚙️ パイプラインへの組み込み

  1. 新しいステージの追加post_deploy_reviewという新しいステージを作成し、エンドツーエンドテストのジョブをここに配置します。

  2. Playwright Dockerイメージの使用:Playwrightには、テストに必要なブラウザ環境がすべて含まれた専用のDockerイメージがあります。これを使用することで、セットアップの手間が省けます。

  3. 環境変数の受け渡し:レビュー環境のURLを、デプロイジョブからテストジョブに渡す必要があります。

dotenvファイルを使った変数の受け渡し

デプロイジョブで作成したレビュー環境のURLは、そのままではテストジョブに渡せません。そこで、.envファイルを作成し、**artifacts: reports: dotenv**を使ってその内容を次のジョブに渡します。

  • deploy_reviewジョブ

    • Netlifyのデプロイ結果から、jqというツールを使ってURLを抽出し、REVIEW_URLという変数に格納します。

    • echo "REVIEW_URL=$REVIEW_URL" >> review.envというコマンドで、そのURLをreview.envファイルに書き込みます。

    • artifacts: reports: dotenv: review.envを設定し、次のジョブでこのファイルが利用できるようにします。

  • e2eジョブ

    • APP_BASE_URLという環境変数に、前のジョブで渡されたREVIEW_URLの値を設定します。

    • npm run e2eコマンドを実行し、Playwrightテストを開始します。

この仕組みにより、ハードコードされたURLを排除し、パイプライン全体で動的に生成されたレビュー環境のURLを使ってテストを実行できます。

📊 テストレポートの公開

Playwrightはテスト結果をJUnit形式で出力できます。これをGitLabに公開することで、マージリクエストのページでテスト結果のサマリーを確認できます。

e2eジョブに以下の設定を追加します。

e2e:
  # ...
  artifacts:
    when: always
    reports:
      junit: reports/junit/results.xml # Playwrightが出力するJUnitレポートのパス

これにより、テストが成功したか失敗したか、どのテストが失敗したかをGitLabのUIで確認でき、ログを深く掘り下げる必要がなくなります。


🚀 CI/CDのさらなる高みへ!デプロイされたアプリのバージョンを追跡する


GitLab CI/CDのパイプラインを設定することで、プロジェクトのビルド、テスト、デプロイを自動化しました。しかし、デプロイされたアプリケーションが、**「どのコミット」「どの環境」**にデプロイされたのかを、アプリ自体で確認できたらもっと便利ですよね。

🏷️ アプリケーションのバージョンを動的に設定する

この講義では、GitLabの事前定義変数を使って、アプリケーションのバージョン情報を自動で埋め込む方法を学びます。

アプリケーション側の変更

src/App.jsxのようなアプリケーションのソースコードに、バージョン情報を表示するための記述を追加します。ここでは、Viteというビルドツールが提供する環境変数の仕組みを利用します。

// `import.meta.env.VITE_APP_VERSION`はビルド時にGitLabの変数に置き換えられます
const version = import.meta.env.VITE_APP_VERSION;

// アプリケーションのどこかにバージョンを表示
<p>Application Version: {version}</p>

パイプラインでの変数の設定

VITE_APP_VERSIONという変数は、ビルド時にGitLabのパイプラインから提供する必要があります。ここでは、コミットIDの短縮版であるCI_COMMIT_SHORT_SHAという変数を使用します。これはすべてのコミットに一意であり、バージョン情報として最適です。

variables:
  # ...
  VITE_APP_VERSION: $CI_COMMIT_SHORT_SHA # コミットIDの短縮版をバージョンとして使用

この設定により、パイプラインが実行されると、そのコミットのIDがアプリケーションに埋め込まれ、ウェブサイトのフッターなどにバージョン情報として表示されます。これにより、どのコミットがどの環境にデプロイされたかをアプリ自体で簡単に確認できるようになります。


🤔 最高のパイプラインを目指して:自己評価と改善

パイプラインが動くようになったら、それで終わりではありません。より効率的で、より信頼性の高いパイプラインにするためには、定期的な自己評価と改善が重要です。

評価ポイント改善のヒント
実行時間⏳ パイプラインの実行時間が長い場合、Dockerイメージの最適化を検討します。毎回必要なツール(netlify-cli, curl, jqなど)をインストールするのではなく、あらかじめそれらが含まれたカスタムDockerイメージを作成することで、時間を大幅に短縮できます。
コードの重複🔁 ステージング環境と本番環境で同じテストを繰り返す場合など、コードの重複は保守性を下げます。再利用可能なテンプレートを作成して、共通の設定をまとめることで、パイプラインをよりシンプルに保てます。
ハードコードされた情報📝 パイプラインのファイルにサイトIDやURLなどの情報を直接書き込む(ハードコードする)のは避けましょう。これらはGitLabのCI/CD変数として管理することで、安全性が高まり、変更も容易になります。
デバッグのしやすさ🐛 パイプラインが失敗したとき、原因を素早く特定できるように、**echocat**などのデバッグコマンドを一時的に追加して、変数の値やファイルの内容を確認する習慣をつけましょう。

🌱 CI/CDの真の価値:なぜこれが重要なのか?

CI/CDは単なる自動化ツールではありません。それは、開発プロセス全体を変革する考え方です。

CI/CDのメリット説明
問題の早期発見🔍 バグを早期に発見・修正することで、コストとフラストレーションを大幅に削減できます。
高品質なソフトウェア🌟 自動テストと継続的な品質チェックにより、信頼性の高いソフトウェアを常に提供できます。
生産性の向上📈 手動での作業が減り、開発者はより多くの時間をコーディングに費やせます。
継続的な統合🤝 頻繁に小さな変更を統合することで、マージ地獄(コードの衝突)を回避できます。
迅速なフィードバック⚡️ テストの失敗を即座に通知することで、問題を迅速に修正し、開発者としてのスキルも向上します。
自信を持ってデプロイ✅ リリースが日常的なものになり、プロダクトマネージャーやユーザーも安心してアップデートを受け入れられます。

CI/CDを導入することで、開発プロセスはストレスの多いイベントから日常的で退屈なタスクへと変わります。これは、成功するソフトウェア開発において、非常に強力な武器となります。