Continuity is The Father of Success

Androidアプリとかゲームとか。毎日続けてるものについて。

Androidのライブラリ選定とメンテナンス

先日、某所で使っているライブラリのAGP 4.0対応とAndroidXへの更新を行い使える状態にしてみた。

github.com

ありがとうJitPack。

jitpack.io

差分はThreeTenABPから java.time に移行したことと、Migrate to AndroidX したこと、各種SDKのバージョンを更新した程度。*1 本当にマイナーな(とは云えテストはしたい内容だけれど)アップデートをした感じ。

表題の話。 アプリの機能実現の時にライブラリを利用しようとすると、「サポートがされなくなると困る」みたいな話があるし、「OSSならサポートされるんじゃない! 自分でサポートするんだよ!」みたいな話があがってくる。

github.com

今回の場合、PRを出したのだけれどなかなか対応されず(別件で小さなAndroid Lintの修正PRも出してみた)、どうしても java.time.OffsetDateTime が使いたいってことでフォークしてJitPackの配信をするに至った次第。 人間がやることだから、開発が続くことも止まることもあると思うし、それは気長に待ちたいなというスタンスではあるのだけれど。

どうしても早く対応したいとか、これだけはやっておきたいなんてことがあれば、フォークして修正してサクッと配信できるこの状況が一番の正解なのかもな、と思ったという日記。

AtCoderのコンテストに参加してみて(3ヶ月)

Stay Home の一貫として、あと自分のプログラミング能力が足りていないと漠然と思うところがあり、3月末からAtCoderのコンテストに参加するようにしています。

atcoder.jp

f:id:D_R_1009:20200601002437p:plain

f:id:D_R_1009:20200601002442p:plain

おおよそABCに参加しつつ、とりあえず参加できる時に開催しているコンテストには参加する程度のモチベーション。 過去問を解かなきゃなーと思いチマチマ挑戦しつつも、ML Study Jams vol.4とかGCPのキャンペーンコースなどの期間限定モノがGWに公開されていたので、なかなか学習の時間が取れない感じです。 コンテストのたびに解けない問題でパターンを覚えている(DFSとかBFSとか)状態なので、D問題が解ける解けないで毎回苦しんでいる感じですね。脱したい。

やってみての効果について。

仕事ではAndroidiOSをそれぞれKotlinとSwiftで書いているのですが、以前よりリストの操作に慣れたような感じです。 特にレビュー時に「こうした方がもうちょっと良い感じになる気がします」な視点が増えたような。

あと、普段Android/iOSアプリを使っていると LongInt の境目とかをあまり気にすることがありません。 金融系でもないので BigInteger も滅多に使うことはないし、 StackQueue を実装した記憶もないです。 ただ Long は(主にユーザーの入力を中心とした)アプリを作っているので使わないのはしょうがないのかもしれませんが、 データ構造は「もし習熟していれば」より良いコードを書けた箇所があったかもしれないので、大きな損失だなーと思っています。

まだまだしばらくは、コーディングの実力をつけるために挑戦していきたいなと思いっています。6月もやるぞ。

Github Actionsの悩ましいところ

昨日Githubがリリース出してGithub Actionsがprivateでfreeプランでも使えるようになりました。

github.blog

そこでGithub Actionsでキャッシュを設定するにあたり調べたことをまとめておきます。

help.github.com

github.com

CircleCIとかBitriseとかのサービスから移行したとき、混乱するのがキャッシュ周りだと思います。 実行環境のスペックを見てみると分かる通り、環境自体にそこまでの差は感じません。

Github Actionsのキャッシュが独特な点は、Github Repositoryのブランチが影響する点です。 キャッシュの key はCircleCIのキャッシュと同じような key の一致判定と、一致しなかった場合に検索される restore-keys になります。 (Bitriseのキャッシュはあれはあれで特殊なので、比較は控えておきます。。。)

- uses: actions/cache@v1
  with:
    path: ~/.gradle/caches
    key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
    restore-keys: |
      ${{ runner.os }}-gradle-

https://github.com/actions/cache/blob/master/examples.md#java---gradle

保存されるキャッシュは「1つのRepositoryあたり5GBまで」です。 CircleCIやBitriseでは明示的に制限されていない箇所になるため、大量のPRが同時に存在したりするケースでは期待するキャッシュの動作を異なることがあり得ます。

https://help.github.com/ja/actions/configuring-and-managing-workflows/caching-dependencies-to-speed-up-workflows#usage-limits-and-eviction-policy

扱いが難しいのは、キャッシュのアクセス制限です。 キャッシュへのアクセスについての制限から引用をします。

pull_requestのclosedイベントの場合を除く、push及びpull_requestイベントで起動されたワークフロー内のキャッシュにのみアクセスできます。 詳しい情報については、「ワークフローをトリガーするイベント」を参照してください。

ワークフローは、現在のブランチ、baseブランチ(フォークされたリポジトリのbaseブランチを含む)、デフォルトブランチ(通常はmaster)で作成されたキャッシュにアクセスし、リストアできます。 たとえばデフォルトブランチのmasterで作成されたキャッシュは、どのプルリクエストからもアクセスできます。 また、feature-bブランチがfeature-aをbaseブランチとして持つなら、feature-bで起動されたワークフローはデフォルトブランチ(master)、feature-a、feature-bで作成されたキャッシュにアクセスできます。

アクセス制限は、異なるワークフローとブランチ間の論理的な境界を作成することによって、キャッシュの分離とセキュリティを提供します。 たとえばfeature-aというブランチ(baseブランチはmaster)用に作成されたキャッシュは、feature-bというブランチ(baseブランチはmaster)へのプルリクエストからはアクセスできません。

なお"baseブランチ"はGitの概念にない(調べた限り……)ため、GithubのPRで指定するマージ先のブランチを指していると思われます。

help.github.com

CircleCIのように key が一致したかどうかだけで考える必要がないため、誤ったビルドキャッシュを利用することによるビルドクラッシュが防がれます。一方で、先述の5GB制限もあるため想定外のタイミングでキャッシュがヒットしないことも発生します。

つまり、ステップの記述と動作までは問題なく済んだ場合でも、キャッシュが想定通りに扱われているかは注意深く調整する必要があります。 一度作ったキャッシュを使い回すことでビルド時間を大幅に短縮していた場合には、想定外のビルド時間延長が発生することがあり得るため、ご注意ください。

ここまでが少し"ネガティブ"な話をしてしまったので、最後に"ポジティブ"な話を一つ。

Github Actionsのcacheステップは、呼び出した順に"restore"を実行し、その逆順に"store"を実行します。実例は下記のステップとその実行結果を見てみてください。

Studyplus-Android-SDK/unit_test.yml at 2.6.2 · studyplus/Studyplus-Android-SDK · GitHub

Update README · studyplus/Studyplus-Android-SDK@78bb889 · GitHub

このためキャッシュ→タスクの実行という処理を書けば、キャッシュのリストア→タスクの実行→キャッシュのストアがタスクが実行した時のみ行われるようになります。 結果として、ビルドキャッシュの保存が非常に簡単に行えるようになりました。

キャッシュへのアクセス制限にある通り"baseブランチ"で作成されたキャッシュを利用することができるため、適切に扱えば機能開発時のDangerチェックを簡単に差分ビルドで行うことができるようになっています。

自分もまだまだGithub Actionsに入門したばかりで、できることはわかっていても、なかなか最適なステップを組むことができていません。 是非、便利な使い方やより正しい理解などを指摘いただければと思っています。