GitHubActionsとCircleCIを使い分ける
こんにちは、tkyです。
今私が携わっているAndroidプロジェクトのCIは基本的にCircleCIを採用しています。
そんな中、同時にGitHubActionsも採用した経緯とどんなことをしているのか、ちょっとハマったことを書き留めておこうと思います。
また、本記事は「こうしたら良い」というわけではなく、「とある課題から解決策を模索した」結果なだけなので
皆さんのプロジェクトに合わせて最適な形を模索するための材料の1つとなれば幸いです。
今までのCIの運用
コードはGitHubで管理しており、PullRequestをトリガーにCIが回るようになってます。
※コミット単位にするとCIの作動回数が多くなるので節約の目的があります。
- UnitTest
- Lint
- DangerでTestとLint結果を報告
- DeoloyGateのdebug apkアップロード
[課題]developブランチとapkが一致しない
pull requestごとにdebug apkが作られるため最新Developブランチとapkが一致せず、debug用のapkはPRの動作確認用になっていました。
しかも実際はブランチをチェックアウトして自分でビルドして動作確認しており現状のapkは事実上形骸化していました。
チームメンバーと会話して「develop最新と紐付いているapkを常に確認できる状況作っておきたいよね」ということで
DeoloyGateのdebug apkアップロード
のワークフローのトリガーを
developブランチにマージされた時(developにコミットされた時)に変更します。
Circle CIの設定見直し
現在CircleCIの管理画面ではこの2がONになっています。
- Only build pull requests (PRコミットのみCIが回る)
- Auto-cancel redundant builds (そのブランチの最新のコミットでCIを回す。古いものは自動キャンセル)
developブランチにマージされた時にしたい場合 Only build pull requests
をOFFにしてfilterでdevelopのみ動作するワークフローを作ればよいのですが
そうするとPR以外のリモートへのコミットでもCIが回るのでそれもなぁ・・・という感じです。
上記をを許容できるならGitHubActions使う必要ないのでこの話は終わりですw
もう少し頑張りたいよね、というところでdevelopブランチにコミットされた時のトリガーだけをGitHubActionで切り出すことにしました。
実際に検討で使った図です
そんなこんなで以下のように話をまとめて現在のプロジェクトで2つのCIツールを運用している、という話でした。
- CircleCI: PRした時に処理したい場合
- GitHubActions: (特定ブランチに)コミットされた時に処理したい場合
なぜGitHubActionsにすべて移動しないのか?
GitHubの各トリガーに柔軟に対応できるGitHubActionsを使えばやりたいことは全部できるでしょう。
しかしながら後述するskip-buildの機能やSSHデバッグなどCircleCIがデフォでできる機能は各々でアクションを定義する必要があります。
ローカルCLIもないため実際にPR上げてtry&errorで動作確認になるのでコストも高いです。(一応CLI実行できるnodeプロジェクトがあったような気がする)
仮に私がaction全部作れたとして、ほかメンバーがそれを管理運用できるか、という問題も浮上してきます。
そういう部分もあり、いきなり全てをGitHubActionsにして逆にコストがかかることを考慮して一部だけ切り出しただけなので、今後の状況によってはありえるかなと思っています。(当分先になりそうですが・・・)
GitHubActions導入してみた
こんな感じのymlを作成します。これがDeploygateにアップロードする(gradleタスクを実行する)ワークフローとなります。
色んな人がAndroidのビルドしていたりするのでコピペで色々貼り付けてます。
.github/workflows/upload_apk.yml
name: upload_apk # CIツールの使い分け # ・CircleCI: PRした時に処理したい場合 # ・GitHubActions: (特定ブランチに)コミットされた時に処理したい場合 on: push: branches: - develop jobs: build_canceller: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: stop old workflow uses: yellowmegaman/gh-build-canceller@master with: github_token: ${{ secrets.GITHUB_TOKEN }} workflows_filter: "upload_apk" deploygate-develop: name: Upload apk to deploygate for developDebug runs-on: ubuntu-latest needs: build_canceller steps: - name: Check out uses: actions/checkout@v2 - name: set up JDK 1.8 uses: actions/setup-java@v1 with: java-version: 1.8 - name: NDK cache id: cache-primes uses: actions/cache@v2 with: path: ${ANDROID_HOME} # GithubActionsコンテナに入っているNDKバージョンとプロジェクトの必要NDKバージョンが異なるため # コンテナに必要NDKバージョンをインストールする # ビルドエラーが出た場合cacheステップとInstallステップに記述のバージョンを更新してください key: ${ANDROID_HOME}/ndk/21.0.6113669 restore-keys: | ${{ runner.os }}-ndk- - name: Install NDK run: echo "y" | sudo $ANDROID_HOME/tools/bin/sdkmanager --install "ndk;21.0.6113669" --sdk_root=${ANDROID_SDK_ROOT} - name: Gradle cache uses: actions/cache@v2 with: path: ~/.gradle key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} restore-keys: | ${{ runner.os }}-gradle- - name: Upload DeployGateDevelopDebug run: | ./gradlew uploadDeployGateDevelopDebug
[ハマったこと]古いビルドはキャンセルされない
CircleCIのskip-buildと同じような機能はGitHubActionsにはないので自力でなんとかする必要があります。
そういうActionがあるのでありがたく使わせていただくことにします。
GitHubActionsを無料稼働枠内で使うための節約テクニックみたいな感じです・・・
※2020/11/21現在最新は
build_canceller: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: stop old workflow uses: yellowmegaman/gh-build-canceller@master with: github_token: ${{ secrets.GITHUB_TOKEN }} workflows_filter: "upload_apk"
以上です。