GitHub Actions
既定のブランチのコミットごとにマップを記録し、プルリクエストでは変更が影響するテストだけを実行します。アクションが TestDetta 自体をビルドし、マップを Actions のキャッシュに保持します。
ワークフロー
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
actions: read # lets pull requests find the newest coverage map in the Actions cache
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7 # pin to a commit SHA
with:
fetch-depth: 0 # TestDetta compares with the merge base
persist-credentials: false
- uses: actions/setup-dotnet@v6 # pin to a commit SHA
with:
global-json-file: global.json
# Also the full test run of main. Leave out projects that cannot run here, such as
# integration tests that need a database; they are then decided by name on pull requests.
- if: github.event_name == 'push'
uses: <owner>/testdetta@<sha>
with:
mode: record
projects: |
tests/Shop.Tests/Shop.Tests.csproj
- if: github.event_name == 'pull_request'
uses: <owner>/testdetta@<sha>
with:
mode: test
dotnet-test-args: --logger trx
license: ${{ secrets.TESTDETTA_LICENSE }}
完全な履歴が必要です。シャロークローンの場合、アクションはエラーで停止します。fetch-depth: 0 でチェックアウトしてください。
マップがプルリクエストに届くしくみ
- record モードでは、マップを Actions のキャッシュに
testdetta-coverage-<commit>という名前で保存します。プルリクエストはベースブランチのキャッシュを読み取れます。 - プルリクエストは、マージベースのマップか、マージベースから最大
max-map-age個の first-parent コミット前までに記録された最新のマップを使用します。 - 完全に一致しないマップを探すにはリポジトリのキャッシュを一覧表示する必要があり、そのために
actions: readが必要です。この許可がない場合はマージベースのマップしか見つからず、ステップがその旨を通知します。 - マップがまったくなくても
mode: testは動作し、名前だけで判断します。
記録中にテストが失敗しても、ジョブが失敗する前にマップは保存されるため、プルリクエストは引き続きマップを利用できます。
アクセス許可
| アクセス許可 | 理由 |
|---|---|
contents: read | リポジトリをチェックアウトするため。 |
actions: read | Actions のキャッシュを一覧表示し、max-map-age の範囲内で最新のマップを探すため。 |
persist-credentials: false を指定すると、ジョブの後半でプライベートリポジトリを再びフェッチすることはできません。ただし、fetch-depth: 0 の時点ですべてのブランチを取得しているため、ベースブランチは存在しています。
入力
| 入力 | 既定値 | 説明 |
|---|---|---|
mode | プルリクエストでは test(影響を受けるテストを実行)、既定のブランチでは record(カバレッジマップを記録)。必須です。 | |
base | PR のベースブランチ | test モードで比較するブランチ。プルリクエスト以外で使う場合は指定してください。 |
configuration | Debug | テストのビルドと実行に使うビルド構成。 |
projects | すべてのテストプロジェクト | record モード:.csproj のパスを 1 行に 1 つずつ指定します。 |
parallel | 1 | record モード:テストプロジェクトごとのテストホストプロセス数。各プロセスはテストを 1 つずつ実行します。テストスイートが複数のテストプロセスの同時実行に耐えられる必要があります。 |
no-build | false | record モード:true にすると、前のステップで同じ configuration によって作成されたビルドを記録します。 |
dotnet-test-args | test モード:dotnet test に渡す追加の引数(スペース区切り)。 | |
max-map-age | 50 | test モード:マップがマージベースより何コミット遅れていてよいか。その間の変更は橋渡しされます。0 を指定すると完全に一致するマップだけを使用します。 |
drift-fallback | all | test モード:古いマップ以降の変更にビルドファイル、構成、グローバル using が含まれる場合、all は影響を受けるテストプロジェクトを丸ごと実行し、name は名前で判断します(高速ですが、構成やリフレクションを介した呼び出しは捉えられません)。 |
github-token | github.token | test モード:最新のマップを探すために Actions のキャッシュを一覧表示します(actions: read が必要)。 |
license | test モード:ライセンス文字列。TESTDETTA_LICENSE のようなリポジトリまたは組織のシークレットから渡します。パブリックリポジトリでは不要です。有効なライセンスがない場合はすべてのテストを実行し、それが原因でジョブが失敗することはありません。 | |
working-directory | . | 分析するリポジトリ内の任意のディレクトリ。 |
setup-dotnet | true | TestDetta の実行に必要な .NET 10 SDK をインストールします。ジョブにすでにインストールされている場合は false に設定してください。 |
ジョブサマリー
test モードでは、TestDetta は選択内容をジョブサマリーに書き込みます。変更されたファイルと比較したベース、各テストプロジェクトがフィルター付きで実行されたか、丸ごと実行されたか、まったく実行されなかったかとその理由、テスト結果、そして関係がある場合はライセンスの状態です。リポジトリ由来のパス、クラス名、理由はコードとして書き込まれるため、プルリクエスト内のファイル名によってページにリンクやメンションが挿入されることはありません。
テストスイートの一部だけを記録する
記録ではテストスイート全体をカバレッジ付きで 1 回実行します。既定のブランチでは、これがそのまま完全なテスト実行にもなります。データベースが必要な統合テストなど、ランナー上で実行できないプロジェクトは projects で除外してください。プルリクエストでは、それらのプロジェクトは名前で判断されます。
前のステップですでに同じ構成でソリューションをビルドしている場合は、no-build: true を設定します。複数のテストプロセスの同時実行に耐えられるテストスイートでは、parallel によって各プロジェクトのテストクラスを指定した数のプロセスに分散できます。