SPAJAM 2020 第2回予選大会に「おひっこし」として参加して、優秀賞に選ばれました #SPAJAM

9/26 (土)、27 (日) に行われたSPAJAM 2020 の第2回予選大会に、 @_bannzai_@gaopin1534@koooootake@noa_design51と共に参加し、優秀賞に選出されました。

https://history.spajam.jp/competition-result2/

www.youtube.com

やったこと

  • Firebase Cloud Firestore / Strageのデータベース関連の処理
  • 画像の合成処理の実装
  • 写真を撮った後のプレビュー画面
  • Figmaで作られたデザインを当てたり
  • デモ動画の演者

感想

ものとしては、24時間でそれなりに動くし、見た目も丁寧に作れたのでよかった。
特にプレゼン資料など、デザイナーって (@noa_design51 が) すごいと感じてた。

今回自分以外は東京集まっていたので、常時Discordで繋いでいたのはよかった。
ただ完全に同じ環境にはもちろんならなくて、食事とか打ち上げとかの面ではちょっと寂しい感じになった。
オンラインだから同じ予選会のチームで出れたのではあるのだけど。

あと、めちゃくちゃ久しぶりにハッカソンに参加して、徹夜が非常に辛かった。

優秀賞ということで、本選に行けるかは、全ての予選終了後の復活にかかっている状態。
今回のメンバーのバランスがよかったので、本選に行って、次はみんなと同じ場所で一緒にやりたい。
たのむ!!!!

iOSDC Japan 2020に参加 & LT登壇しました #iosdc

前々回: iOS Japan 2018に参加 & LT登壇しました #iosdc - がんばってなんか書く
去年は書いてなかったことが発覚した。

全体

今年は時世もあり、オンライン開催ということだった。

iosdc.jp

👍

  • 暑い中の移動が無
  • ノベルティを持ち帰らなくていいのが、非常に楽
    • 宿泊を伴うと、荷物が面倒なので
  • 複数トラックの並行視聴が可能
    • 自分は途中で諦めた
  • 起床、即参加が可能

👎

  • 京都に住んでいると、iOSDCだけに限らず、カンファレンス参加は出張チャンスなのだけど、今年は家で一人
  • Ask the Speakerに行かないと、トークを待っている時間が長く感じる
  • 休憩ルームで人と話すことがメインで参加しているので、オンラインだとその点を完全には補完する術がない
    • Discordの雑談チャンネルはよかったけど、喋っているのは大体固定のメンバー (かつ、大体いつもカンファレンスで話している人たち) で、「自分たちの会話を顔の見えない不特定多数に聞かれている」という感覚が、2.5日では慣れることができなかった
  • コーヒーを自分で淹れる必要がある
  • 昼食タイミングが難しい

LT

fortee.jp

xcrun Essentialsという題目で話した。 ギリギリまで5分に収まるように調整していたり、そもそもオンラインでの登壇も初めてだったので、ここ最近で最もプレッシャーがあった。

LT待機室では、他の登壇者の様子も見えていたけど、自分ばかり話していた気がする。 *1

やっぱり、準備した全ての内容を5分で話すことはできなかったので、Ask the Speakerで話させてもらった。 アップロードしたスライドには、完全版として掲載している

speakerdeck.com

👍

  • 一人でいるので、LTの練習がしやすい
  • カンペ見放題
  • LT中の焦りが、視聴者からは見えづらい
  • ニコ生を意識した煽り

👎

  • 今年はLTのみがライブだったので、周りに共感者が少ない
  • 自分はZoomが好きではなく *2 、慣れていなかったためにセットアップでの不安やZoomを通すとKeynoteのTransitionsアニメーションがもたつく *3 ので、非常にストレスフルだった
  • カメラの目線が難しい
  • 自分のワイプが配信に載る時に、左右反転することを先に知りたかった
    • 内側を向くようにカメラを調整したつもりだった

f:id:yutailang0119:20200923142232j:plain
タイムシフトからいいの撮れた

最後に

今年もお疲れさまでした

*1:スタッフ側の画面に自分ばかり映ると言われた

*2:Macに修正パッチ出させたあれの印象が強い

*3:諦めてアニメーション切った

リポジトリに含まれるコード量/比率をMackerelに記録する with GitHub Actions & action-mackerel-api

リポジトリを管理していると、何かの拍子にリポジトリのコードベースの変遷を可視化したくなる場合があります。
例えば、以下の場面です。

  • ある時からのリポジトリの成長
  • 実装言語を置き換える際のコードベースの遷移

やり方はいろいろありますが、今回は GitHub ActionsGitHub API v3 、そして Mackerel API を使って、Mackerelのサービスメトリックに記録してみます。

実行サンプル

Posting language lists to Mackerel with GitHub Ac…

GitHub APIの仕様上、特定ファイルの除外ができないことは、ここでは考慮していません。
JavaScriptは得意じゃないので、37行目からのscriptを効率化できる案があれば、教えてもらえると助かります。

グラフ例

Mackerel上でのおすすめのグラフ定義は、以下です。

  • 単位: bytes
  • グラフの種類: 積み上げ

f:id:yutailang0119:20200713021940p:plain
グラフ定義は bytes と 積み上げ を設定

利用しているグッズ

actions/github-script はyml内にJavaScriptが書けて、異常な便利さがあります。

yutailang0119/action-mackerel-api

上記の例でさらっと使っていますが、GitHub ActionsからMackerel APIを使用するために、Mackerel APIGitHub Actionsを作りました。
Mackerel APIの薄いWrapperです。

github.com

Marketplaceにも 公開 しています。
Marketplaceを検索する と、Mackerel と名のつくGItHub Actionsは他に公開されていないようです。*1

とりあえず動くものをと作ったので、まだ足りない部分がありますが、今後追加にご期待ください。

余談

shellが苦手すぎて、README/Usage が actions/github-script を使って、 body を作るサンプルになっています。
単にエスケープした文字列を入れればいいだけのはずなので、回答のPull Requestをお待ちしています。

*1:GitHub内検索 でもほとんどない

fastlane-plugin-mackerel_apiを作って、fastlaneにコントリビューションもした

rubygems.org

github.com

これはなに

Mackerel APIインターフェイスを、fastlane 向けに提供するPluginです。
実装は fastlane/actions/github_api.rb を元として、Mackerel API向けに調整しました。
Actions.shcurl を実行するだけでも事足りるのですが、せっかくなのでPlugin化しました。

例) ビルドにかかった時間をトラッキングする

発端は、はてなブックマークアプリでの開発環境にまつわる情報をトラッキングするために、MackerelのService Metricsを使おうと考えたことでした。
Service Metricsについては こちら

以下のように使うことで、処理にかかった時間を、Mackerelに投稿します。*1

start_time = Time.new.to_i
# scanなどの処理
end_time = Time.new.to_i
duration = (end_time.to_f - start_time.to_f) / 60 # 単位を分に変換

result = mackerel_api(
    api_key: ENV['MACKEREL_API_KEY'],
    http_method: "POST",
    path: "/api/v0/services/#{ENV['MACKEREL_SERVICE_NAME']}/tsdb",
    body: [
        {
            "name": "#{ENV['MACKEREL_GRAPH_NAME']}.#{ENV['MACKEREL_METRIC_NAME']}",
             "time": end_time,
             "value": duration
        }
    ]
)

結果

f:id:yutailang0119:20200522152407p:plain
社に了解を得て掲載しています

緑のグラフが跳ねているのは、Xcode 11.5を利用するように変えた時に、CIのキャッシュを破棄したからです。
こういった情報をグラフで記録できます!

ビルド時間の他にも、テストカバレッジの変動の記録にも使用しています。

感想

GWにゲームしながら、合間に作っていました。
fastlaneを使い始めて、早いもので3年強経ちますが、Pluginを作ったのは初めてでした。
最近はfastlaneのDSLよりも、Rubyらしく書けるようになりたいと思っていて、 fastlane new_action でActionとして作ることが多くなっています。
Pluginの実装は、Actionを作るのとほぼ同じように作れるため、何から始めればよいかはわかりやすかったです。

GitHub Actions for Android Lintを作ってる - がんばってなんか書く を作った時にも感じたことですが、テンプレートから生成して、そこにGitHub ActionsやTravis CIなどのテスト環境が用意されていると、ちゃんとテスト書くようになるのでよいですね。
特に慣れていないプログラミング言語のプロジェクトだと、実行結果があっているのかの自信もないので、自然とテストを書くようになれます。

fastlaneにコントリビューションもした

github.com

最近のCI環境は、もっぱらGitHub Actionsで暮らしています。
この fastlane-plugin-mackerel_api でも、GitHub Actions上でテストを行なっています。
これまで fastlane new_plugin からは、Travis CIとCircle CIでの実行テンプレートが生成されていました。
fastlane-plugin-mackerel_apiGitHub Actionsでの知見を培ったので、Pluginテンプレートに追加するPull Requestを出し、無事マージされました🎉
fastlane pluginの作成を始める開発者は、CI環境としてこれまでのTravis CIとCircle CIに追加して、新たにGitHub Actionsを選びやすくなりました。
v2.148.1 でリリースされています。

今回の変更の恩恵は、fastlaneのエンドユーザーでは感じることがないので、ぜひPluginを作ってみてください!

大変だったこと

1つ目は、テストの書き方やrakeなどのRubyを扱うそのもの。
Rubyに慣れていないので、Error throwsのテストの書き方がわからずに、めっちゃ調べました。

2つ目は、RubyGemsへの公開。
fastlaneのドキュメント Create your own fastlane pluginの中のPublishing your plugin には、

bundle install
rake install
rake release

で公開すると書かれていて、GitHub Actionsでやろうとしましたが、 rake release がgitのタグを打とうとする挙動を知らずに、はまりました。
bundle exec gem push pkg/*.gem とすることにしました。

その他に、GitHub ActionからのRubyGems公開には、OTP codeを突破できないという課題が残っています。
それを除けば、たぶん release.yml で動くと思うのだけど、OTPの回避方法を知っている人が教えてください。

まとめ

ぜひ、ご利用ください!

*1:実際にはこの処理をさらにWrapしたActionを作っています

GitHub Actions for Android Lintを作ってる

github.com

f:id:yutailang0119:20200413222656p:plain
Marketplace

Danger x Android Lint

自分は仕事ではAndroidアプリの開発もしています。
Android Lintも使っていて、danger/dangerloadsmart/danger-android_lintを組み合わせて、Pull RequestにLint結果を表示するという、一般にも使われていそうな方法で利用しています。

danger-android_lintの問題点

Dangerはすごく便利なのだけど、Lintからの指摘とDangerfileに指定したルールからの指摘とが混在してしまうのは、情報が多くなりがちで、目が滑るのが気がかりでした。
Dangerからの指摘には、Project specificな情報やレビュー上で確認必須なルールをDangerfileに指定して、Lintの情報は別にまとめたい。

GitHub Action for SwiftLint

ところで、最近はGitHub Actionsが時流らしいし、自分もaction.ymlを書くのにだいぶ慣れてきました。
Swiftだとnorio-nomura/action-swiftlintを使うと、GitHub Actionsで簡単にrealm/SwiftLintが実行できます。

norio-nomura/action-swiftlintのいいところは、実行が簡単なだけではありません。
Workflow commandswarningerrorを使って、Review CommentのようにPull Requestの対応コードにLint結果を表示します。
これが最高に便利。

ということで、Android Lint版を作った

github.com

やっていることは単純で、Android Lintで生成されたxmlをparseして、Workflow commandの形式に変換して echo しているだけです。
mobileposse/github-android-lint-action *1を参考にさせてもらいつつ、Annotationの表示にはWorkflow commandsを使うようにすることで、GitHubaccess tokenが不要になっています。

追加機能の予定

Android Lintが生成する lint-results.xml に載っている情報を全部使えているわけではないので、もう少しはアップデートしようと思っています。
id とか priority のフィルタリング機能とか。

あとは、このActionだけでAndroid Lintの実行までを行うようにすると嬉しいのかどうか...

まとめ

フィードバックをぜひお願いします!
みなさんもぜひ便利なGitHub Actionsを作って、公開してください!!!

[おまけ] GitHub Actionを作る

今回のActionは、xmlのparseして、 echo するだけで、環境依存はありません。
よって、Javascript actionで作りました。
かつ、型がある方が嬉しい*2ので、actions/typescript-actionをTemplateにして、作成を始めました。
TypeScriptを久々に触りながら、出来上がりを優先して作っているので、クオリティはいまいちかもしれませんが、テストはちゃんと書いているので、ある程度の品質は担保できているはず。

READMEとaction.ymlの情報で、Marketplaceに公開されます。
Update action.yml for branding · yutailang0119/action-android-lint@f183f3c · GitHub

f:id:yutailang0119:20200413183312p:plain
GitHub Marketplaceに公開するために、iconとcolorを指定するのおもしろい

*1:残念なことにアーカイブされてしまっている😐

*2:結果的にxmlのパース部分は、型定義ファイルがないので、 any を扱うことになったけど

WEB+DB PRESS Vol.116 特集1 「はじめてのトラブルシューティング」に寄稿しました #wdpress

宣伝

2020/04/24 (金) に発売予定WEB+DB PRESS Vol.116 *1 に寄稿しました!
担当は、特集1 「はじめてのトラブルシューティング」の第4章「モバイルアプリ」です。
id:Soudai さん、 id:rukiadia0401 さん、@maeponさんとの特集共著です。

一部の大手書店様では、4/16 (木) から、先行販売もあるようです。
外に出づらいご時世ですが、電子書籍版の販売もありますので、合わせてよろしくお願いします!

f:id:yutailang0119:20200410105814j:plain:w300
表紙
WEB+DB PRESS|gihyo.jp … 技術評論社

iOSAndroidの両方の解説で、誌面の関係で掲載を断念せざるを得なかった内容も多くあります。
以下を意識しています。

  • 4月発刊の新人歓迎号と銘打っているので、基礎の基礎から説明
  • 限られた誌面の中でも、できるだけ広い領域を拾えるように
  • 日頃からトラブルへの準備をできるように
  • プロフェッショナルな皆様にも、いくつかは学びがあるように

経緯

今回の寄稿は id:Soudai さんより、声をかけてもらいました。
たしか、去年の12/20 (金) *2
id:Soudaiid:yutailang0119 の組み合わせといえば、なつかしのマグロですね。

yutailang0119.hatenablog.com

Web+DB PRESSid:yutailang0119

読者としては、初めてWeb+DB PRESSを読んだのかが、いつかは覚えていないのですが、 builderscon tokyo 2017で「WEB+DB PRESS 100号記念特別企画」に関わらせてもらいました。

https://builderscon.io/tokyo/2017/session/17d5767a-4f26-11e7-aa42-42010af00d0a

www.youtube.com

このbuilderscon tokyo 2017開催レポートを、101号に寄稿させてもいただきました。

そういえば、「4月は新人歓迎号」という話も、この時に聞きましたね。
2年半経って、自分もついに技術記事で寄稿の機会をいただくことができたし、なんと 特集1 !!!

謝辞

同じ特集1の共著者メンバーの id:Soudai さん、 id:rukiadia0401 さん、@maeponさん、編集の稲尾さん、いろいろ大変な時期でしたが、お疲れ様でした!
ありがとうございました!

はてなの同僚の id:cockscomb id:ikesyo id:itokjp の皆様には、レビューと称して、かなり校正もしてもらいました。
ありがとうございました!

最後に

2020/04/24 (金) 発売予定 WEB+DB PRESS Vol.116 を、よろしくお願いします!

*1:URLはまだ404だけど、たぶんこれのはず

*2:忘年会中にDM来た

iOS/iPadOSアプリ PixelaUI 0.1.0 をリリースしました #pixela

PixelaUI

PixelaUI

  • Yutaro Muta
  • ユーティリティ
  • 無料
apps.apple.com

これはなに?

PixelaiOS/iPadOS向けクライアントアプリケーションです。
アプリ名は、後述する使用frameworkである SwiftUI ともかけています。
サポートOSバージョンは iOS/iPadOS 13.2以上 です。

どうやって使うの?

Pixelaの使い方を見てもらうとよいです。
これの主要機能を、iOS/IPadOSのUser Interfaceで提供しています。*1
blog.a-know.me

Pixela自体はAPIのみを提供していて、User Interfaceサードパーティ製というスタンスを取られています。
一方で、Programableと結びつきにくい日常生活の中で手軽に使うにはハードルが高い側面があります。
iOS/iPadOSで気軽に扱えるように、という思いで作りました。

どうやって作ったの?ほか

2020/01/07の深夜に思い立って、約2週間でリリースまで来ました。

開発時間の記録は、このグラフに取っています。
pixe.la

実装は SwiftUI を使っています。
WWDC 19での発表当初から遊んでいたので、20時間弱で一通りの使える機能実装はできていました。
仕事から帰ってからの時間だけでも、1週間くらいでできたし、Viewerとしてのアプリなら、もっと楽にできそうな印象です。*2

ここからマルチアカウント機能つけたり、Context Menuによるincrement*3を実装したり、エラーハンドルをちゃんとしたりで、なんだかんだで倍くらいかかってしまった。*4

仕事やPyCon JP名義 でのリリースはして来たけれど、実は個人としてのアプリリリースは初でした。

Special Thanks

(以下、敬称略)

Pixelaの生みの親で、はてなの同僚でもある id:a-know には、アイコン画像を提供してもらったり、API仕様の相談をしたり、機能提案をもらったりと、開発をとても助けていただきました!
改めてお礼を、ありがとうございます。

また、同僚の id:cockscomb, id:ikesyo にも、SwiftUIやEmbeded Frameworkの話で相談に乗ってもらいました。

それから、Twitterでアイディアをくれた @omochimetaru@giginet@tarunon@_bannzai_@nakiwo もありがとうございました!
実は v0.1.0 では、まだ修正に着手できていなくて、微妙な挙動をしています🙇‍♂️ *5

お知らせ

サポートOSバージョン

SwiftUIを使っている関係上、iOS/iPadOS 13.0以上は必須なのですが、開発環境で確認しやすいiOS/iPadOS 13.2以上とさせてもらいました。
また、今後のアップデートでも、SwiftUIアップデート時のAPI diffによっては、サポートOSバージョンを変更する可能性があります。
ご了承ください。

今後の非互換変更

実装がしっくりきていない部分があるので、 今後非互換変更を入れることになるかもしれません 🙇‍♂️
アプリ内からアカウントを作成した場合も、別途セキュアな領域に token を保存しておくことを、強くおすすめします。

そういった理由で、アプリバージョンも v0.1.0 としています。
非互換変更を経た後に、 v1.0.0 を迎えたいと思います。

完成度

上記以外にも、作り込みの足りない箇所が多々あります。
これは自分自身のSwiftUIへの理解度が足りていないことが原因でありつつも、SwiftUI自体にUIコンポーネントが全て出揃っている訳ではないことも理由の一つです。
id:yutailang0119 のレベルアップと、SwiftUIのアップデートにご期待ください。

有料化

前述の v1.0.0 のタイミングなどで、有料アプリに変更する可能性があります。
これは id:yutailang0119 の気まぐれで行われると思うので、 2020/01/23現在はいつ変更するのかは未定です。
サブスクモデルではなく、パッケージモデルのつもりなので、無料の内にダウンロードしておくと、お得かもしれません。

無料アプリだけど、ぜひ支援させてくれという方がいましたら、おたよりお待ちしています 🙏

おたより

おたよりはこちら

*1:今後のアップデートで、対応APIを追加予定です

*2:もちろん世間一般で言われているバギーな印象も持っています。

*3:f:id:yutailang0119:20200122121920p:plain:w250:rightグラフのint or floatに合わせて、incrementされます

*4:審査通ってからリリースボタンを昨日の昼に押したのですが、夜中まで公開されずやきもきしていました。

*5:APIの仕様を変更してもらいました。