カバレッジの変化をプルリクエストに通知する GitHub Actions を作った

動機

ある日ふとこんなことを思いつきました。

テストのカバレッジを集計する SaaS として CoverallsCodecov があります。これらの SaaS は詳しいカバレッジの変化や、GitHub Status としてカバレッジ閾値を設定できたり様々機能があります。しかし、GitHub Actions がある今なら一分機能を外部に依存することなく実現できるのではと考えました。

先人が似たものを開発していないか、GitHub Marketplace で 「coverage 」をキーワードに検索してみましたが見つかりませんでした。 https://github.com/marketplace?query=coverage

そこで今回自作したのが「Coverage History Action」という GitHub Actions です。

github.com

使い方

以下のような workflow を用意します。

name: CI


on:
  push:
    branches:
      - "master"
  pull_request:
    types: [opened, synchronize]


jobs:
  report:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Use Node.js 12.x
      uses: actions/setup-node@v1
      with:
        node-version: 12.x
    - name: yarn install
      run: |
        yarn install --frozen-lockfile
      env:
        CI: true
    - name: Run test
      run: |
        yarn test
      env:
        CI: true
    - name: Coverage History Action
      uses: odanado/coverage-history-action@v0
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}

この workflow が発火するタイミングは 「master ブランチへの push したとき」と「プルリクエストの登録と更新したとき」です。
前者のタイミングで、master ブランチのカバレッジGitHub Actions の cache に保存されます。後者のタイミングで、プルリクエストのコメントに2つのブランチでのカバレッジの様子が通知されます。

通知の様子

f:id:odan3240:20200531001148p:plain

Perl でちょっと CPAN モジュールを試すのに Google Colaboratory が便利

モチベーション

NodeJS である npm パッケージを試したいとなった場合 RunKit is Node prototyping がとても便利です。任意の npm パッケージをインストールができ、なおかつ他人のその結果を共有できます。例えば、これは誰かと一緒にある npm パッケージの使い方の相談をするときによく使います(e.g. lodash の groupby の使い方を示したり)。

Perl でも同様に任意の CPAN モジュールをインストールして、他人に結果を共有できるサービスがあると便利なのですが、一般公開されているものを見つけることはできませんでした。

そんな気持ちを持ちつつ、ある日突然 Google Colaboratory を使えば目的を達成できるのではと気付いたので、これを紹介します。

やり方

perl.ipynb · GitHub にアクセスします。

画像の Open in Colab をクリックすると notebook が開きます。

f:id:odan3240:20200313014752p:plain

ランタイム > 全てのセルを実行 を選ぶと Perl と cpanm とよく使いそうな CPAN モジュールがインストールされます。 f:id:odan3240:20200313014911p:plain

任意のモジュールをインストールする場合は !cpanm --notest --quiet SQL::Maker などと実行すればよいです。

f:id:odan3240:20200313015210p:plain

まとめ

かなり便利では??

2019年 ふりかえり

2019年あっという間だった

ふりかえり

GitHub

一覧

issue と pull request が合計で16件でした。ethereum/web3.js や terser/terser にコントリビュートできたのが印象的でした。

issue のバグを再現したり、英語考えたりするのは大変だけど継続したい。

個人開発

合計5件でした。

年の真ん中の時期はサービス系の開発は何もしてない...。

Web サービス系

odan3240.hatenablog.com

odan3240.hatenablog.com

npm

github.com

github.com

github.com

登壇

合計5件でした。

Presentations by odanado - Speaker Deck

Docker + NodeJS の開発環境のモヤモヤを話したら予想以上の人に見てもらえたのが嬉しかった。
PyCon JP で登壇したけど、うまく内容をまとめられなくてとてもつらい気持ちになった...。

ブログ

はてなブログ6件、Qiita 2件、会社のブログ2件でした。
全然書けてないという印象です。

記事一覧 - odan’s diary odanado - Qiita

来年は

  • バグを見つけたらもっと積極的に issue とか pull request を立てていきたい
  • 今年と同じ数ぐらい登壇したい
    • 大きめなカンファレンスでも話したい
  • 個人開発も継続したい
  • ブログをもっと書いていきたい
    • 特に会社のブログ
      • 会社のブログが活発な会社で働いていたいという気持ちがあるので、自分からやっていきたい

数字

  • GitHub: 50 ぐらい
  • 登壇: 6件
  • 個人開発: 3つぐらい?
  • ブログ
    • 個人のやつ: 6つ
    • 会社のやつ: 6つ

Android ユーザーでも Splatool.net で対戦分析したい

これは Splathon Advent Calendar 2019 の 12 日目の記事です。

昨日はつぼさんの スプラトゥーンの X パワー向上のきっかけになったこと でした。

Splatool.net とは

Splatool.net とはスプラトゥーンに関する様々なツールが公開されているサイトです。

いくつかあるツールの中でも対戦分析ツールが個人的にお気に入りです。以下の URL はサンプルデータを表示している様子です。
各プレイヤーの勝率やキルレなどが集計されており、プラベ後のふりかえりに重宝します。

https://splatool.net/analytics/chk.php?c=15347260365591&m=p

対戦分析ツールの使用方法にもある通り、json 形式で出力した イカウィジェット2 のバックアップデータをアップロードすることで、対戦の分析結果を閲覧できます。

Android ユーザーの悲しみ

イカウィジェット2はありがたいことに、iOS 版だけでなく Android 版 も提供されています。

iOS 版と Android 版の間に機能や UI の差はほぼありません。しかし、バックアップデータの形式は iOS 版と Android 版で差があります。具体的には Android 版はバックアップを実行すると .ikax という謎の拡張子を持つファイルが生成されます。 f:id:odan3240:20191212223814p:plain

Splatool.net の対戦分析ツールは、この ikax ファイルには対応していません。実際にサイトにも (もしAndroid版でも出力可能でしたら、ご指摘下さい) という注書きがあります。

Web アプリを作った

どうしても対戦の分析をしたかったので、先月中旬頃から謎の ikax ファイルを json ファイルに変換する Web アプリを開発していました。それがこちらです。

splatool-converter.firebaseapp.com

使い方

ikax ファイルを選択する

中央のアップロードできるところ (伝われ) をクリックしてローカルにある ikax ファイルを選択します。一般に ikax ファイルのサイズは数十 MB と大きめなことが多いので注意してください。あと Google Drive などクラウドストレージにある ikax ファイルのアップロードはエラーが発生して失敗するので、一度ローカルにダウンロードすることをオススメします。

f:id:odan3240:20191212225845p:plain

ikax ファイルをアップロードする

アップロードボタンを押下すると ikax ファイルのアップロードが始まります。30秒ぐらい時間がかかります。待ってください

f:id:odan3240:20191212230113p:plain

json ファイルをダウンロードする

アップロードが終わると直近100戦の対戦データが一覧で表示されます。json ファイルとしてダウンロードしたい試合についてチェックボックスを選択してダウンロードボタンを押下すると json ファイルがダウンロードされます。Android だと同時に10個までしかファイルをダウンロード出来ないようなので気を付けてください。

f:id:odan3240:20191212230601p:plain

仕組み

時間がないので箇条書きで済ませます。そのうちどっかで清書したいです。あとコードも公開したい...。

  • ikax ファイルは実は zip ファイル
    • file コマンドを実行するとわかる
  • zip ファイルの中には Realm 形式のファイルが入っている
  • ikax ファイル → json ファイルへの変換は Cloud Functions で行っている
    • Realm の JavaScript SDK はネイティブモジュールに依存しているのでブラウザで動かない
      • wasm に変換できればわんちゃんあるかも...?
  • ikax ファイルは Cloud Functions に直接 POST せず Cloud Storage にアップロードしている
    • Cloud Functions は1リクエストあたり 10 MB の制限がある
    • Cloud Storage へのアップロードをトリガーに Cloud Functions を実行している
  • Realm => json への変換はルールベース

終わりに

Splatool.net の対戦分析ツールは Android 版未対応だったので、これを何とかする Web アプリを作った話 & 紹介をしました。 11月中旬から開発を開始していたので、12月12日のアドベントカレンダーには余裕で間に合うやろwと思っていたのですが、基本的な機能の開発だけでギリギリになってしまいました。

今後も開発を継続する予定ではあるので、もしよろしければ使ってみてください!

明日は tellusium さんの「Middle League まとめを書こう書こうと思ってかけていないので Deadline Driven Development を実行する」です。tellusium さんと同じチームで Middle League に参加していたので個人的に楽しみな記事です。

上京して1年半の間に自炊して良かった料理

この記事は、 大阪工業大学 Advent Calendar 2019 の3日目の記事です。

誰?

2018年に学部を卒業したodanです。普段はツイッターにいます。

twitter.com

自炊について

上京するまでは実家から学校に通っており、お米を炊いたことがないレベルで自炊の経験がありませんでした。しかし、上京を機に自炊を始めてみたところ、意外にも継続できていて気付いてみると1年半近く経過しました。 自炊をした日のうちのいくつかの日については写真を tumblr にアップロードしています(最近は投稿の頻度が下がっていますが...)。

odan-food.tumblr.com

今回はこの中のうち自炊して良かった料理を紹介します。

メニュー

親子丼

親子丼の良いところは、材料の鶏肉と玉ねぎの値段が安く材料費がかなり抑えられる点です。 あとご飯に合う点も加点ポイントです。

https://odan-food.tumblr.com/post/187281062809/%E8%A6%AA%E5%AD%90%E4%B8%BC
odan-food.tumblr.com

オムライス

オムライスの材料は上で紹介した親子丼と同じなため、これらの料理を連続して作ることが多いです。親子丼と同様に材料費が安い点や、玉ねぎをバターと塩で炒めている時の幸せな匂いのおかげで料理中の体験が良い点が加点ポイントです。

https://odan-food.tumblr.com/post/188622020634/%E3%82%AA%E3%83%A0%E3%83%A9%E3%82%A4%E3%82%B9
odan-food.tumblr.com

牛ステーキ

上京するまではステーキは高級な料理という認識がありました。しかし、スーパーで売っている一番安い牛ステーキ用のお肉は300gで500円程度とお手頃な値段で、上手に料理すれば美味しくいただけます。 疲れたしお肉を食べたいなーと言う日は牛ステーキになることが多いです。

https://odan-food.tumblr.com/post/181154798639/%E3%82%B9%E3%83%86%E3%83%BC%E3%82%AD
odan-food.tumblr.com

冬は白菜と豚肉を購入して鍋に突っ込めば美味しい鍋ができるので自炊が楽です。

https://odan-food.tumblr.com/post/181673781459/%E3%83%9F%E3%83%AB%E3%83%95%E3%82%A3%E3%83%BC%E3%83%A6%E9%8D%8B
odan-food.tumblr.com

カレーライス

いつもこのレシピのカレーを作っています。

my-kaji.com

調理時間に約2時間程度かかってしまいますが味が良く、しばらく料理をしなくても良くなるので土日など時間のある日にたまに作ります。料理中にビールを飲めるのも体験として良い点です。

https://odan-food.tumblr.com/post/187417475204/%E3%82%AB%E3%83%AC%E3%83%BC%E3%83%A9%E3%82%A4%E3%82%B9
odan-food.tumblr.com

まとめ

上京してきて始めた自炊で良かった料理を5つ紹介しました。自分は食べたいものを作るというポリシーで料理を作るタイプなので楽しく継続できています。 どなたかの参考になれば幸いです。

dotfiles に Ansible Playbook を導入した

最近、4年間使っていた MacBook Air が突然壊れてしまい、新しい MacBook Pro を購入しました。

新しいマシンを手に入れたらまず最初にやることは dotfiles のデプロイです。これまでの dotfiles のデプロイはお手製のシェルスクリプトによって行っていましたが、色々問題を抱えていたため、機会があれば Ansible Playbook を導入したいと考えていました。今がそのタイミングだなと感じたので実際にやってみました。

github.com

各 role の紹介

Best Practices — Ansible Documentation に従い ansible-playbook/roles 以下に各 role を配置しています。

ansible-playbook/roles
├── anyenv
├── apt
├── cli
├── dotfiles
├── homebrew
├── homebrew_cask
├── powerline
├── system
├── vscode
└── zsh

anyenv

anyenv と anyenv によってインストールされる xxenv をインストールするための role です。
anyenv の README にある通りに git cloneanyenv install --init を実行しています。
anyenv のインストール先を anyenv.install_dir という変数で指定できる仕組みにしています。この状態で anyenv install --init を実行するには PATH に anyenv があるディレクトリへのパスを追加する必要がありますが、 このパスに ~ が含まれていると anyenv コマンドの lookup ができないという問題がありました。そこで今回は regex_replace を使って ~lookup('env', 'HOME') の値で置き換えるようにしています。

https://github.com/odanado/dotfiles/blob/145ff7278708f7a0cd5f1cf6e18ba145f0cdaef4/ansible-playbook/roles/anyenv/tasks/main.yml#L20

apt

apt でインストールするパッケージを管理する role です。
特に変なことはしていません。

cli

cli ツールのインストールを管理する role です。
GitHub Releases にアップロードされている cli ツールのバイナリファイルダウンロードし、指定のディレクトリに配置する機能があります。この機能は ansible-playbook/roles/cli/files/installer.sh に実装しています。複数あるファイルの中から OS と CPU の種類を判定して適切なファイルをダウンロードする仕組みはかなり雑になっています。今後インストールする cli ツールが増えるたびにちょっとずつ改善していくつもりです。

dotfiles

dotfiles をデプロイする role です。
.tmux.conf や .gitconfig のシンボリックリンクをホームディレクトリに向けて生成しています。

homebrew/homebrew_cask

homebrew/homebrew_cask でインストールするパッケージを管理する role です。
特に変なことはしていません。

powerline

powerline を導入するための role です。
pip で powerline をインストールして、config を ~/.config/powerlineシンボリックリンクを作成しています。

system

Macdefaults の値などを管理する role です。
スクリーンキャプチャの名前や保存先の変更などをここで行っています。

vscode

VSCode拡張機能を管理する role です。
code --list-extensions でインストール済みの拡張機能を取得して、インストールしていない拡張機能だけをインストールするようにしています。

https://github.com/odanado/dotfiles/blob/145ff7278708f7a0cd5f1cf6e18ba145f0cdaef4/ansible-playbook/roles/vscode/tasks/main.yml#L10

そのうち設定ファイルのデプロイも行うようにしたいです。

zsh

zshrc のデプロイや zplug のインストールを行う role です。
zsh の plugin 管理には zplug を使用しているのでインストールを行っています。
zplug install の実行も ansible から行いたかったのですが、エラーが出て解決できなかったためここでは行っていません。

Github Action によるテスト自動化

Github Action では Linux だけでなく macOS のサーバを用いたテストを実行できるため、macOSUbuntu の両方でセットアップが成功することをテストしています。

Ubuntu のテストは Docker コンテナ上で実行しています。最初は docker-compose を用いてホストマシンからコンテナ内に対してコマンドを実行していました。しかしこの方法ではローカルでは再現しない tty 周りエラーでハマりました。ググっても解決策が見つからず時間もなかったため、docker コマンドを直接実行する方法に変更しました。

https://github.com/odanado/dotfiles/blob/145ff7278708f7a0cd5f1cf6e18ba145f0cdaef4/.github/workflows/ubuntu.yml

今のところ trigger は push だけですが、cron で定期的に壊れていないことをチェックするようにしたいです。

参考

Ansible Playbook を使って macOS の初期化を行う話はネット上に数多く存在し大変参考になりました。

ISUCON 9 予選 参加記

ISUCON 9 の予選にチーム「5000兆IOPS欲しい!」で参加してきました。 メンバーは「@shora_kujira16」と「@smiken_61」です。

最終的に7000点ちょっとのスコアでした。バックエンド何もわからない...。

やったこと

だいたい時系列順

nginx とか mysql の設定

kataribe を使えるようにしたり、slow query の設定をやりました。練習で一度やっていたのでスムーズにできました。 あと restart.sh というシェルスクリプトを用意して systemd のサービスのリスタートや、設定ファイルの cp を一発で出来るようにしました。

categories のインメモリ化

getCategoryByID の実装がやばいので手を付けたいとなって、categories テーブルは件数少ないかつ変更されないのでメモリに載せて良いことがわかりました。 実装してベンチ投げると4000点ぐらいが返ってきました。

その他

自分がやったのは↑2つぐらいで他は大体 @shora_kujira16 さんがやってくれました

  • 画像を nginx から配信
  • select する時に不要な column を削除
  • 3台構成
    • 1台目が nginx + mysql
    • 2台目と3台目が app server
  • 適宜 index 付与
  • getNewItems の N+1解決
  • campaign の値を 0-4 に変えてスコアガチャ

考えていたこと

  • クエリの実行が遅いしどこかでロックが発生してそう?
  • ユーザーにあった商品を並べることで、売上は上がりそうだけど、これは ISUCON なのか??