Heroku CI
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2023年08月25日(金)
Table of Contents
Heroku CI では、アプリの GitHub リポジトリへのプッシュのたびにアプリのテストスイートを自動的に実行するため、開発者はコードベースに変更をマージまたはデプロイする前にテスト結果を容易に確認できます。テストは、ステージング環境と本番環境によく似た廃棄可能な環境で実行されるため、結果は正確であり安全に取得されることが保証されています。
Heroku CI は Heroku Pipeline とシームレスに連携します。
セットアップ
アプリ用の Heroku Pipeline の作成がまだの場合、ここで作成します。
パイプラインとそれに関連付けられたすべてのアプリを所有する、検証済みの Heroku ユーザーまたはチームを 1 つ選択します。Heroku Dashboard で、このユーザーまたはチームに所有権を割り当てます。Heroku CI の使用料金は、関連付けられたパイプラインを所有するアカウントが請求先になります。
Heroku Dashboard でパイプラインの
Settings
(設定) タブに移動し、アプリの GitHub リポジトリに接続します。リポジトリへの管理者アクセスが必要であることに注意してください。さらに、パイプラインの
Settings
(設定) タブから、Enable Heroku CI
(Heroku CI の有効化) をクリックします。
アプリにおいて、共通のテストフレームワークをアプリに関連付けられた言語に対して使用する場合、Heroku CI はすでに、使用中のテストスイートに対して正しいコマンドを実行するように設定されています。GitHub リポジトリに対するプルリクエストを作成してみてください。Heroku CI が正しく設定されている場合、Heroku Dashboard で、実行中のテストスイートをパイプラインの Tests
(テスト) タブから確認できます。
GitHub プルリクエストの Conversation
(会話) タブでも、Heroku アイコンの横に CI の結果が表示されます。
Heroku CI で正しいコマンドが実行されないか、テスト環境のリソース不足のため一部のテストが失敗する場合、テスト環境を設定することによってこれらの問題を容易に解決できます。
テスト環境を設定する
Heroku CI テスト環境は、app.json
マニフェストをリポジトリのルートディレクトリに含めることによって設定できます。CI テストの実行中、このファイルの test
環境で定義されたキーは、アプリの基本設定内の一致するキーよりも優先されます。
CI 環境の設定に影響を及ぼすキーには、以下のものがあります。
scripts
addons
env
buildpacks
formation
カスタムテストコマンドを指定する (scripts
)
app.json
マニフェストの scripts
セクションでは、テストスイートをセットアップして実行するために Heroku CI が実行するコマンドを上書きできます。Heroku で正式にサポートされている言語の一般的な用途では、これらを指定する必要はありません (言語別の追加の説明については、こちら)を参照してください)。
scripts
フィールドには、test-setup
と test
の 2 つのキーを含めることができます。
それぞれのキーには、アプリケーションリポジトリ内に存在する実行可能ファイルのパスを含め、任意のシェルコマンドを指定できます (例: make tests
)。
test-setup
テストスイートを実行する前に、次のような 1 回限りのセットアップタスクを実行する test-setup
スクリプトを含めます。
- コードリンター、コンパイラ、テストランナーなどのテスト依存関係のインストール
- データベースのセットアップとシーディング
test
test
スクリプトは、テストを実行するために使用するコマンドです。多くの場合、bundle exec rspec
や npm test
など、ローカル環境で使用するものと同じコマンドです。
例
Ruby アプリにはテストがないが、Rubocop を使用してすべての新しいコード変更を分析する場合は、次のようにテストスイートとして Rubocop をインストールおよび実行できます。
{
"environments": {
"test": {
"scripts": {
"test-setup": "gem install rubocop",
"test": "rubocop ."
}
}
}
}
アドオンのプロビジョニング (addons
)
Heroku では、プロジェクトの app.json
マニフェストを使用して、一時的なデプロイメント (Heroku CI とレビューアプリによって実行されるデプロイメント) のためにプロビジョニングするアドオンサービスを決定します。
Heroku CI をサポートする多くのアドオンには、テストラン用にプロビジョニングされる特別なプランがあります。これらのプランは、機能的には本番アドオンプランに似ていますが、プロビジョニングとその解除が高速化されています。
たとえば、Heroku Postgres と Heroku Data for Redis のどちらにも、テストラン中にしかプロビジョニングできない一時的な in-dyno
プランがあります。詳細は、「Heroku CI In-Dyno Databases」(Heroku CI In-Dyno データベース) を参照してください。
一部のアドオンでは Heroku CI をサポートしていません。テストラン中、そのようなアドオンをプロビジョニングしようとすると、<add-on service slug> has opted out of supporting Review and CI apps
などのエラーメッセージが表示されます。
例
次のスニペットは、in-dyno
Heroku Data for Redis プランのインスタンスを Heroku CI でテストラン用にプロビジョニングすることを指定します。
{
"environments": {
"test": {
"addons":[
"heroku-redis:in-dyno"
]
}
}
}
環境変数の設定 (env
)
アプリまたはそのアドオンで、テストラン中に特定の環境変数が必要な場合、次のように env
キーを使用して指定できます。
{
"environments": {
"test": {
"env": {
"PHOTON_TORPEDOES": "online"
}
}
}
}
レビューアプリと違って、Heroku CI は親アプリから環境設定を継承しないことに注意してください。
(アクセストークンのように) 機密性が高いか流動的な環境変数は app.json
に含める形で設定することが望ましくないため、その代わりに Heroku Dashboard でパイプラインの Heroku CI 設定に追加することができます。
ここで指定した値は、すべてのテストランで利用可能です。
不変の環境変数
次の環境変数はすべての Heroku CI テストランで利用可能であり、変更できません。
CI
: これが継続的インテグレーション環境であることを示す文字列。この値は常にtrue
です。HEROKU_TEST_RUN_BRANCH
: テスト中のコミットのブランチを表す文字列。HEROKU_TEST_RUN_COMMIT_VERSION
: テスト中のコミットバージョンを表す文字列 (これは通常、コミットの SHA です)。HEROKU_TEST_RUN_ID
: テストランの一意の ID を表す文字列 UUID。
テストランの動作
パイプラインで Heroku CI を有効にすると、それ以降、GitHub リポジトリへのプッシュのたびに自動的にテストが実行されます。つまり、すべての GitHub プルリクエストが、(通常はステージングにデプロイされる) マスターへのマージと共に自動的にテストされます。
テストランは、テストランごとにプロビジョニングされる一時的な Heroku アプリ内で実行されます。実行が完了すると、そのアプリは自動的に破棄されます。
パイプラインのプロモーションのとき、またはパイプライン内のアプリに直接デプロイするときは、CI が実行されません。パイプラインの Tests
(テスト) タブで利用可能な手動のテストランを使用して、任意のブランチをテストできます。
すべての Heroku CI テストランは (親アプリが Private Space) で実行されている場合でも) Common Runtime で実行されます。したがってテストランでは、Private Space 内で実行されているアプリまたはリソースにアクセスできません。
自動デプロイでの使用
Heroku の GitHub 統合では、リポジトリの指定されたブランチが更新されるたびに、アプリの新しいバージョンを (通常は開発またはステージングに) 自動的にデプロイできます。
このブランチへの更新が自動的にデプロイされる前に Heroku CI テストランが合格することを義務化できます。方法については「自動デプロイ」を参照してください。
サポートされている言語
Heroku CI では、Testpack API を通じて言語サポートを提供します。buildpack はこの API を利用してテストのためにアプリを準備でき、場合によっては、どのテストを実行するかを検出できます。
Heroku で正式にサポートされているすべての言語で、Heroku CI が完全にサポートされています。一部のサードパーティ製 buildpack もサポートを提供します。
Heroku CI サポートを buildpack に追加するには、buildpack で Testpack API を実装する必要があります。例については、Elixir buildpack に対するこちらのプルリクエストを参照してください。追加のヘルプまたは支援については、heroku-ci-feedback@heroku.com からお問い合わせください。
Go
Heroku Go buildpack は Heroku CI をサポートしています。
- 検出されたツールで依存関係をコンパイルおよびインストールします (例:
govendor
、godep
)。 go test ./…
でテストを実行します。
Node
Heroku Node buildpack は Heroku CI をサポートしています。
NPM_CONFIG_PRODUCTION=false
およびNODE_ENV=test
を指定してテストをコンパイルします (これにより、テストと開発の依存関係がインストールされます)。- 必要に応じて
npm test
またはyarn test
でテストを実行します。
このため、一般的な Node アプリについては、app.json
でテストスクリプトを定義する必要はありません (ただし、package.json
では必要な場合があります)。
Java
Heroku Java buildpack は Heroku CI をサポートしています。
- Maven の
test-compile
ライフサイクルを実行して、テストソースコードをtarget
ディレクトリにコンパイルします。 - 独自の Maven ラッパーの使用有無に応じて、
mvn -B test
またはmvnw -B test
を実行してテストを実施します。
PHP
Heroku PHP buildpack は Heroku CI をサポートしています。
composer.json
のrequire-dev
からの依存関係がテストラン用にインストールされます。- テストは次の順序で自動検出され、見つかった最初の一致だけが実行されます。
composer test
(composer.json
のscripts
セクションからtest
を実行)codecept run
behat
phpspec run
atoum
kahlan
peridot
phpunit
- Heroku CI では、PHP 7 アプリケーションに対して
zend.assertions
INI ディレクティブが有効です。
テストの依存関係を確認してください。たとえば、phpunit/phpunit
が composer.json
の require-dev
セクションにあること、また composer.lock
が最新であることを確認してください。
実行中の Web サーバーが (受け入れテストなどの) テストに必要な場合、Procfile
でも使用しているブートスクリプトをバックグラウンドで起動し、その出力をすべて抑制する必要があります。これは test-setup
ステップでも実行できます。
{
"environments": {
"test": {
"scripts": {
"test-setup": "heroku-php-apache2 >/dev/null 2>&1 & sleep 5",
"test": "codecept run"
}
}
}
}
sleep 5
の呼び出しにより、テスト開始前に PHP-FPM と Web サーバーが完全に起動していることが保証されます。
Python
Heroku Python buildpack は Heroku CI をサポートしています。
requirements.txt
内で指定されたすべての依存関係がインストールされ、requirements-test.txt
は必要に応じてインストールされます。
Python buildpack はテストを自動検出しません。environments.test
内で scripts.test
を使用して実行するテストを、app.json
で Heroku CI に指示する必要があります。
app.json
の例を次に示します。
{
"environments": {
"test": {
"scripts": {
"test": "nose test"
}
}
}
}
Ruby
Heroku Ruby buildpack は Heroku CI をサポートしています。
Gemfile
で定義されたdevelopment
およびtest
の依存関係をインストールします。- データベーステストを準備するとき、
:ruby
および:sql
両方のデータベーススキーマをサポートします。加えて、rake db:migrate
を実行します。 - 適切な Rake コマンド (
bundle exec rspec
、bin/rails test
、rake test
など) を使用してテストを実行します。
一般的な Ruby アプリの場合、app.json でスクリプトを定義する必要はありません。
Ruby buildpack では、Rails CI テスト実行用に lib/tasks/heroku_clear_tasks.rake
ファイルをアプリケーションに作成します。Heroku Postgres アドオンでは、作成、削除、またはリセットのアクセスは提供されません。このレベルのアクセスはテストスイートの実行には不要なため、heroku_clear_tasks
によってアクセス制限が回避されます。
Heroku CI では現在、capybara-webkit
をサポートしていません。ブラウザとユーザーの受け入れテスト (ベータ) のサポートに関する項目を参照してください。
Rails アプリ用の例を次に示します。
{
"environments": {
"test": {
"addons":[
"heroku-redis",
"heroku-postgresql"
]
}
}
}
Gradle
Heroku Gradle buildpack は Heroku CI をサポートしています。
gradlew check
でテストを実行します。
Scala
Heroku Scala buildpack は Heroku CI をサポートしています。
sbt test
でテストを実行します。
Clojure
Heroku Clojure buildpack は Heroku CI をサポートしています。
lein deps
を実行してテスト環境を準備します (これは、LEIN_BUILD_TASK
環境設定によって上書きされます)。lein test
でテストを実行します。
Elixir
サードパーティの Elixir buildpack は Heroku CI をサポートしています。
MIX_ENV=test
で依存関係をコンパイルおよびインストールします。mix test
でテストを実行します。
Elixir は正式にサポートされている言語ではないため、app.json
ファイルで buildpack を指定する必要があることに注意してください。また、Heroku Postgres アドオンを追加すると自動でデータベースが作成されるため、mix.exs
ファイルの test
エイリアスによってデータベースが作成されないことを確認してください。
app.json
の例を次に示します。
{
"buildpacks": [
{"url": "https://github.com/HashNuke/heroku-buildpack-elixir"}
]
}
リリースフェーズと Heroku CI
Heroku CI テストランの間、リリースフェーズは無視されます。テストの前に実行する必要があるスクリプトがある場合、test-setup
スクリプトに配置することをお勧めします。
Heroku CI での並列テストラン
Heroku CI での並列テストランは、アプリのテストスイートを複数の dyno に分散して実行時間を大幅に短縮することができます。
Heroku CI でのブラウザテストと UAT
(headless) Chrome buildpack は、Chrome を要求するテスト (例: Selenium やその他の UAT 技術) を有効にします。 その他のソリューションもサポートされています。
詳細は、Heroku CI のユーザー受け入れテスト (UAT) に関するドキュメントを参照してください。
デバッグ
Heroku CLI には、デバッグテストランを開始するために使用できる ci:debug
コマンドが含まれています。これによって、Heroku CI 環境と、テスト dyno 内でのテストの実行を検査できます。これは、テストがローカルでは合格するが CI では合格しない問題の解決や、テストのセットアップの問題のデバッグに便利です。
このコマンドはリポジトリ内から実行する必要があります。このコマンドにより、新しいテストランがビルドされ、テストのセットアップフェーズが実行されます。heroku ci:debug
コマンドでは、最新のコミットを GitHub にプッシュすることは要求されない点に注意してください。コマンドを実行すると、最新のローカルコミットに基づいて新しいテスト dyno が作成されます。
$ cd my-repository
$ heroku ci:debug
Preparing source... done
Creating test run... done
Running setup and attaching to test dyno...
~ $ npm test # or whatever test command your application uses
(セットアップの問題をデバッグするために) テストのセットアップフェーズをスキップするには、--no-setup
フラグを指定して実行します。
$ heroku ci:debug --no-setup
Preparing source... done
Creating test run... done
Attaching to test dyno...
▸ Skipping test setup phase.
▸ Run `sprettur setup && for f in .profile.d/*; do source $f; done`
▸ to execute a build and configure the environment
~ $
テストランのライフサイクルの技術的詳細
サードパーティの buildpack のメンテナーは、Heroku CI の明示的なサポートを buildpack に追加することができます。自らが管理する buildpack にこのサポートを追加する方法については、Heroku にお問い合わせください。
テストラン中に Heroku CI によって実行されるイベントの順序については、「Heroku CI: Technical Detail on Test Run Lifecycle」(Heroku CI: テストランのライフサイクルの技術的詳細) を参照してください。この情報は、技術力のある開発者が特定のテストランの失敗をデバッグするためにも役立ちます。
費用
Heroku CI 対応のパイプラインの従来の料金は月額 $10 でした。
テストラン期間中の dyno およびアドオンの実行時間には、秒単位の従量課金で通常料率の料金が発生します。この価格設定により、パイプラインで Heroku CI を試す費用を低く抑えることができます。
費用の詳細は Heroku の料金ページで確認できます。
dyno
デフォルトでは、テストランは Performance-M dyno で実行され、その料金は秒単位で課金されます。Performance-M タイプの dyno がアカウントで使用できない場合、代わりに 、2X dyno が使用されます。この実行時間には test-setup
フェーズと test
フェーズの両方が含まれます。たとえば、5 分間のテストランで発生する dyno の費用は $0.03 で、計算式は次のとおりです。
$250/month * 5 minutes / 43200 minutes/month = $0.03
dyno サイズを変更する場合、app.json
ファイルの test
環境セクションの formation
キーで指定できます。 standard-1x
以上の dyno サイズがサポートされています。次に例を示します。
"environments": {
"test": {
"formation": {
"test": {
"quantity": 1,
"size": "standard-1x"
}
}
}
}
アドオン
テストランが作成されると、app.json
マニフェストの test
環境にリストされているアドオンが、アドオンベンダーによって指定された “一時的デプロイ” プランでプロビジョニングされます。test
環境が存在しないか addons
キーが不足している場合、ベースマニフェストのアドオンのリストが使用されます。
アドオンプロバイダーには、一時的な CI 実行をサポートするためにこれらのアドオンが使用されることが通知されます。また、アドオンプロバイダーにより、長期間のログ記録や定期的なバックアップの省略など、アドオンのプロビジョニングと破棄を高速化するための措置が実施される場合があります。
テストランが完了 (failed
、errored
、または succeeded
として報告されます) した後、テストランのアドオンはプロビジョニング解除および破棄されます。つまり、有料のアドオンは、各プランの料金を基準に、テストランの実行時間のみに対して秒単位で請求されます。無料アドオンプランは Heroku CI でも無料のままです。
請求
パイプラインのインターフェースにあるパイプラインの Settings
(設定) ページで、Configure Heroku CI から、CI 実行の請求対象ユーザーを選択できます。
Heroku Enterprise Organization が所有するリソースのみでパイプラインが構成されている場合、当該の組織が請求対象になるオプションのみが表示されます。
既知の問題
Rails のフィクスチャと参照整合性
Rails のデフォルトのフィクスチャは、最初に参照整合性を無効にしてテストデータをロードします。この機能を使用している場合、デフォルトの Heroku Postgres アドオンは使用できません。代わりに、In-Dyno データベースを使用できます。
Docker デプロイ
現在、Heroku CI を使用してコンテナビルドをテストすることはできません。
Heroku CI の無効化
特定のパイプラインで Heroku CI を無効化するには、Heroku Dashboard でパイプラインの Settings
(設定) タブを開いて Disable
(無効化) をクリックします。
パイプラインでの CI 有効化と CI 実行に対する請求はすぐに停止します。CI は秒単位で請求されることに注意してください。