コンテンツにスキップ

GitHub Actions

ビルドとスペックの実行

コミットがプッシュされるたびに、そして誰かがプルリクエストを開くたびに、サンプルアプリケーションを継続的にテストするには、この最小限のワークフローファイルを追加します

.github/workflows/ci.yml
on:
  push:
  pull_request:
    branches: [master]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Download source
        uses: actions/checkout@v2
      - name: Install Crystal
        uses: crystal-lang/install-crystal@v1
      - name: Run tests
        run: crystal spec

GitHub Actionsを使い始めるには、このYAMLファイルをGitリポジトリの.github/workflows/ディレクトリにコミットし、GitHubにプッシュして、Actionsタブを確認します。

クイックスタート

必要なCI機能を備えた設定をすばやく入手するには、 _`install-crystal`_アクションの設定ツールを確認してください。または、詳細については、読み続けてください。

これは、GitHubのデフォルトの「最新のUbuntu」コンテナで実行されます。リポジトリ自体からソースコードをダウンロードし(現在のディレクトリに直接)、Crystalの公式GitHub Actionを介してCrystalをインストールし、`spec/`ディレクトリにスペックがあると仮定して、それらを実行します。

いずれかのステップが失敗した場合、ビルドは失敗として表示され、作成者に通知され、プッシュの場合は、プロジェクトの全体的なビルドステータスが失敗に設定されます。

ヒント

より健全なコードベースにするために、`crystal spec`にこれらのフラグを検討してください
`--order=random` `--error-on-warnings`

スペックがない場合

テストカバレッジが十分でない場合は、少なくともサンプルプログラムを追加し、CIの一部としてビルドすることを検討してください

ライブラリの場合

          - name: Build example
            run: crystal build examples/hello.cr

アプリケーションの場合(スペックがあっても実行することを強くお勧めします)

          - name: Build
            run: crystal build src/game_of_life.cr

異なるバージョンのCrystalでのテスト

デフォルトでは、Crystalの最新リリースバージョンがインストールされます。ただし、Crystalの「ナイトリー」ビルド、およびプロジェクトでまだサポートしている古いバージョンでもテストする場合があります。ワークフローの上部を次のように変更します

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        crystal: [0.35.1, latest, nightly]
    runs-on: ubuntu-latest
    steps:
      - name: Download source
        uses: actions/checkout@v2
      - name: Install Crystal
        uses: crystal-lang/install-crystal@v1
        with:
          crystal: ${{ matrix.crystal }}
      - ...

これらすべてのバージョンは_並列_にテストされます。

Crystalのバージョンを指定することにより、最新バージョン(_移動するターゲット_です)のサポートを_オプトアウト_し、特定のバージョンのみをサポートすることもできます。

複数のオペレーティングシステムでのテスト

通常、開発者はUbuntuでのみテストを実行します。プラットフォーム依存のコードがない場合は問題ありません。ただし、別のシステムをテストマトリックスに追加するのは簡単です。ジョブ定義の上部に次を追加するだけです

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - ...

Shardsパッケージのインストール

ほとんどのプロジェクトには、外部依存関係である「shard」があります。 `shard.yml`でそれらを宣言したら、ワークフローにインストールステップを追加するだけです(`install-crystal`の後、テストの前)

      - name: Install shards
        run: shards install

最新の依存関係か、ロックされた依存関係か?

リポジトリにチェックインされた`shard.lock`ファイルがある場合(通常はアプリケーションに適しています)、CIへの影響を考慮してください。`shards install`は常にそのファイルで指定された正確なバージョンをインストールします。ただし、ライブラリを開発している場合は、依存関係の新しいバージョンがライブラリのインストールを中断した場合に最初に知りたいと思うでしょう。そうでなければ、ロックは推移的に適用されないため、ユーザーが最初に知ることになります。したがって、`shards install`の代わりに`shards update`を実行するか、`shard.lock`をチェックインしないことを強く検討してください。そして、スケジュールされた実行をリポジトリに追加することは理にかなっています。

バイナリ依存関係のインストール

アプリケーションまたは一部のshardは、外部ライブラリを必要とする場合があります。それらをインストールする方法は大きく異なります。一般的な方法は、Ubuntuで`apt`コマンドを使用してパッケージをインストールすることです。

インストールステップを冒頭付近に追加します。たとえば、`libsqlite3`を使用する場合

      - name: Install packages
        run: sudo apt-get -qy install libsqlite3-dev

コードフォーマットの強制

すべてのコードが`crystal tool format`でフォーマットされていることを確認する場合は、ワークフローの終わり近くに、対応するチェックをステップとして追加します。誰かが正しくフォーマットされていないコードをプッシュした場合、これはテストの失敗と同じようにビルドを中断します。

      - name: Check formatting
        run: crystal tool format --check

このチェックを_Gitプリコミットフック_として自分自身に追加することも検討してください。

公式Dockerイメージの使用

GitHubが提供するデフォルトのOSイメージにCrystalをインストールするために「アクション」を使用してきました。これには複数の利点があります。ただし、Crystalの公式Dockerイメージを使用することもできますが、これはLinuxにのみ適用されます。

基本設定は代わりに次のようになります

.github/workflows/ci.yml
jobs:
  build:
    runs-on: ubuntu-latest
    container:
      image: crystallang/crystal:latest
    steps:
      - name: Download source
        uses: actions/checkout@v2

      - name: Run tests
        run: crystal spec

コンテナのその他のオプションは、`crystallang/crystal:nightly`、`crystallang/crystal:0.36.1`、`crystallang/crystal:latest-alpine`です。

キャッシュ

依存関係(特にshard)をダウンロードしてインストールするプロセスは、実行ごとに最初から行われます。GitHub Actionsのキャッシュを使用すると、重複した作業の一部を節約できます。

安全なアプローチは、次のように定義されたactions/cacheステップ(** `shards`を使用するステップの前**)を追加することです

      - name: Cache shards
        uses: actions/cache@v2
        with:
          path: ~/.cache/shards
          key: ${{ runner.os }}-shards-${{ hashFiles('shard.yml') }}
          restore-keys: ${{ runner.os }}-shards-
      - name: Install shards
        run: shards update

重要

別の `key`と`restore-keys`を**必ず**使用してください。静的キーのみを使用すると、キャッシュは最初の実行後の状態のみを保存し、変更に関係なく、それを永久に再利用し続けます。

しかし、これはリポジトリを_最初にダウンロード_するのにかかる時間だけを節約します。

「より大胆な」アプローチは、`lib`ディレクトリ自体をキャッシュすることですが、これは`shard.lock`に完全に依存している場合にのみ機能します(最新の依存関係か、ロックされた依存関係か?を参照)。

      - name: Cache shards
        uses: actions/cache@v2
        with:
          path: lib
          key: ${{ runner.os }}-shards-${{ hashFiles('**/shard.lock') }}
      - name: Install shards
        run: shards check || shards install

`shards check`に基づいてインストールを条件付きにしたことにも注意してください。これにより、さらに時間を節約できます。

実行ファイルの公開

プロジェクトがアプリケーションの場合は、実行可能ファイル(「バイナリ」)ファイルとして配布することをお勧めします。Linux x86_64の場合、群を抜いて最も一般的なオプションは、Alpine Linuxで静的にビルドしてリンクすることです。これは、GitHubのデフォルトのUbuntuコンテナとインストールアクションを_使用できない_ことを意味します。代わりに、公式コンテナを使用してください

.github/workflows/release.yml
jobs:
  release_linux:
    runs-on: ubuntu-latest
    container:
      image: crystallang/crystal:latest-alpine
    steps:
      - uses: actions/checkout@v2
      - run: shards build --production --release --static --no-debug

これらの手順に続いて、生成された実行ファイル (bin/*) を公開するためのアクションが、次の 2 つの方法のいずれか (または両方) で実行されます。

macOS (例を検索) および Windows (例を検索) 用の実行ファイルの配布も可能です。