ユニファ開発者ブログ

ユニファ株式会社プロダクトデベロップメント本部メンバーによるブログです。

できることもできないことも増えていく。ユニファ開発チームの2019年を振り返る

みなさまメリークリスマス、ユニファCTOの赤沼です。

UniFa Advent Calendar 2019 もついに最終日。この記事を読んでいただけているということは私もちゃんと役目を果たせたということで仕事納め気分です(まだ早い)。

さて、2019年ももうすぐ終わりですが、今年もユニファではスタートアップらしく、一年の間で色々なことがありました。その中で今回は開発に関連するトピックを雑に振り返った後で、最近思ったことを書いてみたいと思います。

プロダクトの追加・拡大

プロダクトに関連することとしては、念願の一つであったルクミーフォトのリニューアルを実施しました。2013年創業時のファーストプロダクトであるルクミーフォトは、サービスの立ち上げスピードと初期ユーザ獲得を最優先としていました。リリースから時間も経ち、サービスのフェーズも変わってくるとどんなプロダクトでもレガシーな部分に対するコストが増大していきます。ルクミーフォトも今後のサービス拡大やユーザビリティ向上のためにも今リニューアルすべきという決断のもとリニューアルを実施しました。リニューアル中は大きな機能追加等はできなくなりますので、ビジネスのメンバーからも多大な協力を得て実現することができました。

tech.unifa-e.com

tech.unifa-e.com

tech.unifa-e.com

tech.unifa-e.com

また、今までリクルートマーケティングパートナーズさんが開発・運用されていた保育園向けICTサービスである Kidsly を、弊社の販売パートナーであるフレーベル館さんを経て事業譲渡いただき、弊社での開発・運用が開始しました。すでに多くのユーザに利用いただいている大規模なサービスの移管は弊社でも初めての経験で、手探りなことも多かったのですが、無事に完了し、今後のユニファの保育園向けICTサービスの中核となっていくプロダクトが加わりました。

kidsly.jp

ルクミー午睡チェックも正式リリースから一年が経過し、弊社初のIoTサービスとしてまずは1年間運用が行えたことにホッとしています。導入数も順調に伸びていますので、今後も安心・安全を提供するプロダクトとして安定的な開発・運用を続けていきたいと思います。

unifa-e.com

開発チームのスケール&開発プロセス改善

開発チームとしても体制が大きく変わりました。今年だけでも開発チームに19名の新メンバーが加入し、今までの倍の規模になりました。また、そのうち11名は外国籍メンバーということで、一気に多国籍チーム化が進みました。開発者採用はスタートアップにとっては特に厳しい市場環境である中、これだけのメンバーに入社いただけたのは本当に嬉しい限りです。

エンジニア以外にもディレクターやデザイナーメンバーも増え、各ロールでのチーム体制や、ディレクターを中心としたプロダクト開発体制も以前より充実させることができ、スクラムを主軸としたアジャイル開発プロセスのプラクティスも積極的に導入しています。ビジネスメンバーも含めたプラクティス浸透のための取り組みもメンバーが積極的に実施してくれているので、今後さらにプロセスの改善が進めていけるのではないかと思っています。

tech.unifa-e.com

R&Dのメンバーも増員され、主に Machine Learning / Deep Learning 領域について今まで以上に幅広く取り組むことができてきました。ビジネスメンバーとも連携して、企画案についての技術的な実現可能性の検討なども行なっています。スタートアップでR&Dチームを置いているケースはあまりないと思いますが、我々が目指すスマート保育園の実現のためには欠かせないと思っています。

podcast.unifa-e.com

デザイナーも人数が増え、やっとチームと言える形になってきました。自社プロダクトのデザインはもちろん、外部向けの露出も増やしていくことができそうですし、社内全体においてのチーム作りという点でもデザインが持つ力は大きいと思っています。

podcast.unifa-e.com

ちなみに入社時から現在の規模になるまでのチームのスケールについては、今年の CTO Night & Day での登壇時にお話しさせていただき、下記の資料も公開しています。

prezi.com

技術ブランディング注力

今年多くの開発メンバーが入社してくれたということは、年始の段階でもそれだけの採用を見込んでたということで、今まで以上に外部向けの技術ブランディングに注力した年でした。以前から継続していた開発者ブログもメンバーが増えたことによって投稿数も大幅に増え、今回のような Advent Calendar が成立するまでになりました。昨年末からスタートした Podcast も不定期ながらなんとか継続し、今月で一年が経過しました。またカンファレンスのスポンサーも初めてやらせていただき、RubyKaigi や builderscon でスポンサーさせていただいた他、 RubyWorld Conference や ServerlessDays Tokyo、 プロダクトマネージャーカンファレンス等ではブースも出させていただきました。当日は登壇させていただく機会があったり、ブースにお越しいただいた方と色々とプロダクトについてお話しさせていただいたり、私たちとしても世界が広がっていく感覚を持つことができました。さらには自社単独や他社との共催での Meetup イベントも開始し、参加いただいた方の中から入社が決まった方もいました。

podcast.unifa-e.com

podcast.unifa-e.com

podcast.unifa-e.com

tech.unifa-e.com

tech.unifa-e.com

podcast.unifa-e.com

tech.unifa-e.com

tech.unifa-e.com

tech.unifa-e.com

これらの実行については準備段階から実際の運用まで、今までの規模では行うことが難しかったですが、メンバーが増え、それぞれ積極的に協力してくれたからこそのもので、開発だけではなく人事や広報等の他の部署のメンバーの協力もあったからこそ実行できたものです。その甲斐あって最近他社の方と会って話をする際に、ユニファのことを目にしたことがある方が増えてきた感触がありますし、すでに繋がっていた方からも、露出機会の多さに注目いただくことが増えました。

また、今年はユニファ開発チームから初めて海外のTech系カンファレンスに1人ではありますが参加することができました。AWS re:Invent や Google I/O、 WWDC など、海外のカンファレンスは日本のものとはスケールが違いますし、最新の技術情報のキャッチアップももちろん重要ですが、何よりテクノロジーに対しての盛り上がりを実際に体験してくるということはとても重要なことだと考えています。来年以降どうなるかはまだわかりませんが、ひとまず最初の一歩が踏み出せたという点では前進できたと思っています。

tech.unifa-e.com

できることが増えてきた。でもできないことも増えていく

ここまでは主に今年やったこと、規模が大きくなったことでできるようになったことをお話ししてきましたが、一方で、できないことも増えてきているとも感じています。規模が小さい時には、今後人数が増えてくればどんどんできることも増えていって、できないことは減ってくるイメージをしていましたが、実際に開発チームや会社全体の規模が大きくなってくると、もちろんできることが増えてきてはいるものの、今までとは違ったできないことが増えていっているという感じです。

プロダクト数や開発チーム、会社規模が拡大してくると、工数などの問題以外にも様々な力学が発生してきます。また、人が増えればやりたいことの総数も増え、指向性も多様になっていき、いずれかを選択せざるを得ないケースも増えてきます。さらにスタートアップとしては対象とする業界の情勢や自社の状況などは日々めまぐるしく変わっていきます。

こういった中では、会社も個人も自分を変えていき、向上させていく必要があります。自分が今までと同じアウトプットを出していたとしても、周りが変わっていき向上していく中では、相対的に自分達のバリューは下がっていってしまいます。

一方で、どれだけ変化する状況の中でも変えてはいけないもの、守らなくてはいけない大事なものがあるのも確かだと思っています。この、変えていくべきことと変えてはいけないことの判断は簡単ではありません。痛みを伴ってでも変えるべきことなのか、流されずに抗うべきことなのか、この判断がとても難しいと最近は感じています。経営、チーム、プロダクト、どの面を取ってもこの判断を間違えた場合、リカバリが困難になる可能性があります。

日々の 1 on 1 等でメンバーと話す中で上がってくるボトムアップでの課題、マネージャー陣から上がってくる会社組織としての改善点、経営陣と話す中で論点になる事業上の問題点など、それぞれ違った視点から、みんなもっと現状を改善したいという想いで様々な課題があげられます。意思決定をしていく立場としては、上がってきている課題は適切な内容か、自分の判断は会社の経営者として正しいのか、CTOとして開発視点から通すべきことを主張できているか、単にメンバーの要望に迎合しているだけになっていないか、他の経営陣の声に流されていないか、セクショナリズムを排除してフラットに判断できているか、こういった様々な思いが日々渦巻いています。

自分の判断が正しかったのかどうかはその瞬間にはわかりません。後になってわかるものです。そうした中で意思決定していく上で大切なのは、自分の中で芯のある結論を出せたか、これで間違っていたら仕方ないと思えるような、これならメンバーにどう思われても仕方ないと思えるような決断になっているかなのかなと思っています。なんとなくで決めてしまったものは失敗することも多いですし、その後もモヤモヤしたものが残りがちです。もちろん考え抜いた上で決定したことでも失敗することはあるのですが、その場合には自分の中で整理もつけやすく、次に向けてピボットしていける気がしています。要はそれぞれの意思決定に対して自分にも他者にも真摯に向き合って手を抜かずに考え抜けたかどうかなのだと思っています(できているとは言ってない)。

来年も保育をハックする

さて、とりとめもなく色々と書いてしまいましたが、我々ユニファ開発チームは来年も保育をハックしていきます。この「保育をハックする」というのは我ながら開発チームのマインドを一言で表していて良い感じだなぁと思っています。また、上記で色々と書いたように組織としてももっと強くしていく必要がありますので、チームをハックしていくことも必要だなと思っています。今年は技術ブランディング等で外向けの施策にも注力していましたが、来年はどちらかというとチームを強くしていくための内部的な施策に重点を置きたいなと思っていますので、保育をハックしていくためのより強いチームを作っていけたらと思っています。一緒に保育をハックしていくためにチームに加わっていただける方もまだ募集していますので、興味のある方はぜひご連絡ください。

unifa-e.com

今年の Advent Calendar の記事としてはこれが最終回となりますが、今後もいろんなところで露出していけるように頑張りたいと思います。また、一年後に2020年を振り返った時に、あの決定は正しかったと言える決定を一つでも増やせるように取り組んでいきたいと思いますので、このブログを始め、引き続きユニファをよろしくお願いします。それでは、良いお年を。

f:id:akanuma-hiroaki:20191223222353j:plain

会社でスナックを立ち上げた話

~お品書き~

ご挨拶

あらこんばんは、私「スナック洋子」というスナックのママをやらせていただいております洋子と申します。
昼間は ディレクター 兼 QA をやっておりまして、二足の草鞋を履かせていただいております。 あ、 ディレクター 兼 QA 兼 ママ なので三足ですわねおほほ。(足は三本もない。)

すみませんちょっとつらくなってきたので、ここからはいつもの感じで書きますね。

今回は社内コミュニケーションを活性化させる場としてこういう方法もあるよーってことで紹介できたらいいなーと思っております。

ゆるい話なのに、思ったより長くなりましたすみません。

「スナック洋子」について

8月にオープンしたばかりでして、ママとしてはまだまだ駆け出しです。
「スナック洋子」は社内向けと社外向け、それぞれで開店しています。

今回は「社内向け」のお話がメインです。
(社外向けは最後にチラっとだけ話します。)

社内では月に一度、最終金曜日に開催しています。
開催場所はオフィスの一角でやっています。

やりたかったこと

社内みんなのオフな場所をつくりたい

会社もなかなか大変なフェーズなので、社内はドタバタ。もう本当にドタバタ。

そんな中、みんなにとって「気晴らしの場」でも「ただ楽しい場」でもなんでも良いのでつくりたかったという感じです。

「あー疲れたなーちょっとスナック寄って帰るかー」
「お、なんかやってる楽しそうー」

ってみんなに思ってもらえていたら大成功です。

社内コミュニケーションの活性支援

ユニファはものすごい勢いで社員が増えています。
(私が入社した4年前は15人で、今や150人以上…!10倍やばい…!)

会社の規模がおおきくなってくると一度も話したことがない!という人が出てきます。
私の体感ですが、100人を超えたくらいから発生しはじめる気がします。

部署をまたいでのコミュニケーションが減り「あそこの部署何やってんだ状態」や、「もはや正社員かパートさんか委託さんなのかがわからない状態」や「役員と一度も直接しゃべったことない状態」ですね。

それを少しでも減らすために、会話をするきっかけをつくれたらなーと思っています。

「最近何してんのー?」
「お、はじめましてー!」
「土岐でございます」←CEO

って会話が生まれていたら大成功です。

私が楽しみたい

今までの話全部忘れてもらっていいくらいここです!(笑)

ママが一番楽しまなくてどうするんですかくらいに思っています。
何事も続けるには運営している側が楽しまなきゃ続かないですよ。(仕事も同じだと思う。)

私は会社のみんなが好きなので、みんなが楽しそうにキャッキャウフフしているのを見ながらお酒が飲めればそれが私にとっての最高です。

スナックをつくる

といっても、自分でつくってないんですよねこれが(笑)

私個人的な話をしますと、私は「人と酒が好き」って理由でスナックをやるのが夢だ!ってみんなに宣言していました。
そんな中、オフィス移転をしまして、カウンターが設置されました。
これはスナックいけるのでは…!って思っていたところ、
みんながロゴをつくり、名刺をつくり、看板をつくり、勝手にスナックが出来上がりました(笑)

目的や運用ルールを決める

さて、スナック自体はみんなの力でできました。
次は運用ルールや集客です。

1. Googleドキュメントで目的・ルールを作成

叩きはスナック洋子の後援者の方が作成してくれました。(みんなで作っている感じ良いね。)
叩きを元にこんなのもあったほうがいいよねーって話をして決まった内容が以下です。

趣旨と目的

  • 趣旨(開催日と開催場所など)
  • 運営目的
  • ルール策定の目的

ルール

  • 片付けの徹底
  • 深酒の禁止
  • 残業している方への配慮
  • ボトルキープ方針(誰がどれだけ飲んでもOKなものだけキープできる)
  • 出禁ルール(年間でルール違反3回で1年間出禁)

これができたら役員や部長陣へ「本当にスナックやるよー!」って宣言と総務の了承を得てきます。

ありがたいことに、会社としてGOGOでした。
こういう活動の背中を押してくれる会社は良いなーと思いました。(いつか予算もぎとりたいと思っている。)

2. お客さまへの情報発信の場をつくる

Slackにチャンネルを作成して、お客さまへの連絡や活動報告をする場としました。

開催後にはこんな感じで報告しています。

f:id:unifa_tech:20191220180344p:plain
スナック活動報告

お客さまのお金を預かる以上、ちゃんと報告はしないとですよね。

3. お客さまの集客

全社員がいるSlackチャンネルで活動開始のご連絡をし、チャンネルへ入ってもらいました。

2回目以降も同じ感じで、全社員へ周知→チャンネル誘導→チャンネルで詳細をご連絡、という形です。

いよいよスナック開店!

開店までにやったことを箇条書きします。

  • お客さまの人数把握
  • お客さまのスケジュール登録と、目的・ルールの周知
  • 食べ物・飲み物の確保
  • 開催日が近くなったらリマインドと人数再確認

得られたもの

そりゃあもうみんなの笑顔ですよね!(なんつって)

仕事やプライベートな話から、ボードゲームやったり、そりゃもうキャッキャウフフですよ。
実際みんなの話を聞いていると、狙った部分の会話もしてくれていたりと、最高でした。
また、役員もよく遊びに来てくれるのでみんな役員とたくさん話せて楽しそうでした。

実際の効果がどれくらいあったのかはどうやって測ろうかなぁは考えていますが、
それよりもみんなが楽しんでくれていればもう大成功なのではって正直思っています。

f:id:unifa_tech:20191220183149j:plain
看板をつくった張本人
f:id:unifa_tech:20191220183209j:plain
黒服担当
f:id:unifa_tech:20191220183119j:plain
オープン初日の様子
f:id:unifa_tech:20191220183155j:plain
ロゴをつくった漁師(太刀魚を捌き中)
f:id:unifa_tech:20191220183204j:plain
ボードゲーム盛り上がり中

カイゼン

もちろん課題もあるのでそれは今後運営しながらカイゼンしていき、より良いスナックにしていきたいと思っていきます。

  • 正社員じゃない方への周知方法(チャンネルに気軽に入れないなど)
  • 他部署が何をやっているかわからない問題は解決していないので、LT大会とかやりたい
  • お酒の管理(スナック開催日の夕方から冷蔵庫がパンパンになってしまう)

CEOに大きい冷蔵庫をねだろうかと思っています。
(土岐さーーーん見てますか!?冷蔵庫欲しい!冷蔵庫冷蔵庫!!!)

まとめ

社内でスナックをオープンさせると楽しいよ!

場をつくるのはちょっとたいへんだけど、それ以上に測れない何かを得られるよ!

ということで以上です。
思っていたより長くなりました、最後まで読んでくれたあなたはもうスナック洋子のお客さまです!

ちなみに社外向けの「スナック洋子」については、採用活動の一環としてオープンしております。

  • ユニファのプロダクトを知ってもらう
  • QAチームやディレクターの働き方やプロダクト開発について、こんな感じでやってるよーの紹介

などなど、ユニファに興味があるかたはどうぞご来店ください。
(TwitterとかFacebookとか、なんとかしてママに連絡とってもらえれば日程調整して開催します!)

看板設置するだけでどこでも「スナック洋子」になるので簡単なのです(笑)

それではみなさまのご来店を心よりお待ちしております。ママより

Bloom Filterについて

こんにちは、プロダクト開発部のちょうです。最近だいぶ寒くなってきて、こたつからなかなか出られません。こたつとみかんがあれば一日いきれると思いつつ、普段自分が学んでいる内容をすこし紹介したいと思います。

今回の内容はBloom Filterです。Bloom Filterは一言でいうと、空間効率のいい確率的データ構造です。要素が集合のメンバーであるかどうかのテストに使われます(wikipediaより)。確率ですので、使えるものではないと思う人が多いかもしれないが、Bloom Filterの特徴を理解すれば問題なく利用できます。

要素が集合のメンバーであるかどうかを確認するには、一番普通の方法はHash関数を元にするHashSetというデータ構造を使います。HashSetは基本 O(1) の速さで判断できます。もちろん、Hash関数による衝突の可能性があります。最悪の場合、HashSetの内部tableのサイズを倍にする必要があります。それに、要素数が非常に多い領域では、普通のHashSetだと空間効率が悪いと予想できます。ここで、Bloom Filterの登場です。

Bloom Filterは空間効率のいいデータ構造です。なぜなら、利用するメモリー領域を倍にする必要がありません。最初から固定してもいいです。それと、Bloom Filterの要素の単位は bit です。32bitマシンでinteger型だと最大32個の要素が入れます。

Bloom Filterは複数のHash関数を利用します。一つのHash関数だと衝突による実際集合のメンバーではないのにメンバーですという結果になる可能性が高いので、複数Hash関数で可能性を減らします。

サイズは8のBloom Filterを例にします。

| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |

最初すべてのbitが0です。要素 foo を入れます。Hash関数を3つにしましょう。Hash1、Hash2とHash3。3つのHash関数の結果は2, 4と7とします。

| 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 |

foo を入れたBloom Filterです。indexが2、4と7の位置を1にセットします。次は要素 bar を入れます。3つのHash関数の結果は1, 2と3とします。

| 0 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |

同じく、indexが1、2と3の位置にセットします。

では要素をテストしましょう。要素 foo でテストすると、3つのHash関数の結果で、場所2、4と7にすべて1にセットされ、メンバーであるということになります。同じく要素 bar でテストしてもメンバーであることもわかります。

続いてメンバーではない要素をテストします。 要素 aaa にたいして、Hash関数の結果を2, 5, 7とします。index 2と7に1がセットされましたが、5がセットされないです。ゆえ、 aaa がメンバーではありません。要素 bbb にたいして、Hash関数の結果は2、3と4とします。すべての位置に1がセットされ、メンバーであるという結果になりますが、実際はメンバーではありません!

ここでわかったことは、Bloom Filterはメンバーではない要素でもメンバーであるという結果になる可能性があります。これはfalse positiveということです。こういう問題があって、Bloom Filterは使えものにならないと思う人がいるかもしれないが、Bloom Filterはメンバーではない要素をメンバーであるという結果にならない(つまり、メンバーではない結果でしたら絶対メンバーではない)です。まとめてみると、

要素 事実 テスト
foo メンバー メンバー
bar メンバー メンバー
aaa メンバーではない メンバーではない
bbb メンバーではない メンバー

要素 aaa はメンバーではないの結果なので、メンバーではないということが断言できます。逆に、メンバーであるという結果になったら、メンバーではない可能性があります。

こういう特徴を受け、Bloom Filter + DBの使い例を考えみましょう。

DBに100万のレコードがあり、サイズ200万(メモリーやく244KB)のBloom FilterをDBの前にします。毎回レコードを取得するとき、まずBloom Filterを通して、もし存在しないなら、レコードはかならず存在しないので、存在するレコードだけDBと問い合わせします。

こうすることで、Bloom Filterでいらない問い合わせを減らすことができます。Bloom Filterの確率的という特徴もカバーできます。実際、Bloom Filterを利用するシーンはほとんど、レコードは非常に多く、例えばメールボックスのSpam Filter、Bloom Filterなしだと裏側のデータソースへものすごく負荷をかかることが予想できます。

Bloom Filterの特徴を理解できると、以下のような簡単なBloom Filterが書けます。

import java.util.*

interface Hasher<K> {
    fun apply(key: K): Int
}

class SimpleStringHasher(
        private val seed: Int, 
        private val max: Int
) : Hasher<String> {
    override fun apply(key: String): Int {
        return key.fold(seed) { acc, c -> acc * seed + c.toInt() } and (max - 1)
    }
}

class SimpleBloomFilter<K>(
        private val bitSet: BitSet, 
        private val hashers: Collection<Hasher<K>>
) {
    fun mightContains(key: K): Boolean {
        return hashers.all { bitSet.get(it.apply(key)) }
    }

    fun put(key: K) {
        hashers.forEach { bitSet.set(it.apply(key)) }
    }
}

fun main() {
    val size = 2048
    val bloomFilter = SimpleBloomFilter(BitSet(size), listOf(
            SimpleStringHasher(1, size),
            SimpleStringHasher(7, size),
            SimpleStringHasher(23, size)
    ))
    for (i in 1..1000) {
        bloomFilter.put(i.toString())
    }
    println((1..2000).count { bloomFilter.mightContains(it.toString()) })
    // 1024 -> 1582
    // 2048 -> 1000
}

SimpleBloomFilterのソースコードをすこしみてみましょう。mightContainsはすべてのHash関数が計算した位置に1がセットされればtrueを返します。putはすべてのHash関数が計算した位置に1をセットします。

main関数では、サイズ2048のBloom Filterを作ってました。それと1から1000までという要素をBloom Filterに入れます。最後は1から2000までの要素でテストします。サイズは2048だと、最後はきれいに1000とカウントされますが、サイズ1024の場合は1582の結果になります。ぜひ試してください。

最後に、false positiveつまり誤判断を減らすにはサイズどれぐらいにすればいいでしょうか。その質問にたいして、Bloom Filterの論文に答えがありますが、ここで結論を出します。

Pfpをfalse positiveの確率とします。nは入れようとする要素の数です。mはBloom Filterのサイズです。

m = - (n * ln Pfp) / (ln 2) ^ 2

おまけに、Hash関数の数kも

k = (m / n) * ln 2

いかがでしょうか。すこしBloom Filterに理解していましたでしょうか。普段の開発に使わないかもしれないが、こういうものがあると覚えていただければ幸いです。

GitHub Actionsで「さくらのレンタルサーバ」にFTPしようと思ったらドツボにハマって3日3晩寝不足になった話

TL; DR

「国外IPアドレスフィルタ」をOFFにしましょう。

はじめに

みなさんこんにちは。

ユニファ初のアドベントカレンダーの12月22日を担当します。サーバーサイドエンジニアの柿本です。

知り合いに頼まれてホームページを作ることがあります。まあ本職ではないしデザインセンスの問題もあるのですが、それほどのレベルは求められないのでお小遣い稼ぎと思って作ります。
*ちなみにユニファは副業OKです!ユニファの数ある良いところのうちの一つですね。

静的サイトを作る時もソースコードをGitHubで管理しますが、ホスティングサーバーにFTPでアップして、それとは別にGitHubにpushするという二度手間をなんとかしたいと思っておりました。

GitHub Actions があるじゃないか!

GitHub Pagesを使えばpushするだけで反映されますが、サーバーサイドスクリプトが使えません。つまり、問い合わせフォームを置くのが難しくなります。

そこでGitHub Actionsの登場です。 https://github.blog/jp/wp-content/uploads/sites/2/2019/08/ActionsHero.png?w=1200

GitHub ActionsはGitHubのリポジトリにビルトインされているのでお手軽に使えるし、レンタルサーバーにFTPすればPHPも使えます。

GitHub Universe 2019で正式版リリースが発表されたばかりですね。早速使ってみます。

セットアップ

GitHub Actionsでやりたいことはたった一つ

masterブランチにpushされたら「さくらのレンタルサーバ」にFTPする

GitHub Actionsのセットアップの仕方をここにつらつらと書こうと思ったのですが、ネットで検索すればたくさん情報が出てくるので割愛します。

最終的な私の成果物はこちら↓↓↓

github.com

GitHub Actionsがいかに簡単に使えるかはご理解いただけると思います。

長い旅の始まり

FTP-Deploy-Action というFTP関係のものでは比較的人気のあるサードパーティ製のactoinsを使って実行したのですが、待てども待てども終わりません。

f:id:unifa_tech:20191219022740p:plain
20分ほど待ちましたが終わりません

lftpを直に使ってもダメでした。

f:id:unifa_tech:20191219024212p:plain
ログすら見れません 泣

curlでftpを使ってもダメでした。

f:id:unifa_tech:20191219024414p:plain
`curl: (56) response reading failed` になります

SFTPにしてみても、ダメでした。

f:id:unifa_tech:20191219023711p:plain
`Permission denied` になります

その他100通りくらい(は大袈裟ですが 汗)の手段を試しましたが、どれもダメでした!!

自分のmacでubuntu:latestをdockerで走らせて、そこからは問題なくFTPできるのですが、なぜかGitHub Actionsでは動きません。

IP制限でした

気づいてしまえば、「まあそうだよね」て話なのですが、FTPサーバーのIP制限が原因でした。 さくらのレンタルサーバはデフォルトで「国外IPアドレスフィルタ」がONになっています。 help.sakura.ad.jp

GitHubのサーバーが海外であることは想像に難くないですね。このフィルタ機能をOFFにしましょう。

f:id:unifa_tech:20191219030030p:plain
ついに成功!!

学んだこと

1晩頑張ってうまくいかなかったらテクニカルサポートに問い合せしよう。

おそらく一瞬で解決したと思います。

ユニファでは、一緒に「保育をハックする」エンジニアを募集中です!

3日3晩寝不足になっても技術が好きな人を募集中です。(寝るのも大事)

unifa-e.com

Rails + Webpacker + Vue.jsの構成でSystem Testを動かしてみる

こんにちは、Webエンジニアのほんまです。

ユニファのAdvent Calendar 2019も21日目ですね。 昨日は、弊社インフラエンジニアのすずきによるAWS Lambda Provisioned Concurrencyに関するエントリでした。 25日間、連続で記事を書き続けられるほどメンバーが集まったんだなぁと思うと、感慨深いものがあります。

それでは本題に入っていこうと思います。 先日、私が所属するチームで担当したルクミーフォトのリニューアルでの変更点を紹介しました。

tech.unifa-e.com

このエントリ内で「フロントエンドではVue.jsを使用したシングルページアプリケーション(SPA)になっている」と紹介しています。 一方、Rails 5.1からは System Test が導入されており、E2E(End To End)の画面レベルでのテストを容易に実現できるようになっています。 画面内で実行されるJavaScriptにも対応しており、この機能を使った自動テストをやってみたいなーと思っていました。

ここで1つ疑問がありました。 「Vue.jsを使ったSPAのアプリケーションも、RailsのSystem Testでテストできるのだろうか?」ということです。

今後、画面レベルでのテストも自動化していきたいと考えており、この機能がリニューアル後のルクミーフォトでも利用可能なのか、今回試してみようと思います。

続きを読む

AWS Lambda Provisioned Concurrencyをゆるく検証

もういくつ寝るとお正月ございます(適当な挨拶)。

ユニファのインフラ見ているすずきです。

ユニファのアドベントカレンダーの20日目となります。

re:Inventの時差ボケも治り快調です。

そして昨日Reproさんでre:Invent報告会で話してきました。

repro-tech.connpass.com

その後半でAWS Lambda Provisioned Concurrencyを検証した結果を話したのですが、 そのことについてブログにしようと思います。

続きを読む

ユニファのQAになってフラットにものづくりに関われた時の思い出

ごあいさつ

こんにちは。

ユニファアドベンドカレンダーをご覧いただきありがとうございます。 QAチームの斉藤と申します。 今回は私がユニファに入社して「ものづくりに関わってるなぁ」と実感した思い出をふりかえります。

技術的なことは全く書いてないので、のんびり読んで頂ければと思います。

読んでほしい人

  • ユニファのQAに興味がある人
  • QAのものづくりってどういうことだろう?って思ってる人

ご注意

言葉ってふしぎなもので、使う人によって意味が全く違います。 あなたの「ものづくり」と私の「ものづくり」、たぶん意味が違う可能性の方が高いです。 ここでは私が考える「ものづくり」とはこういうことで、具体的にはこんなことしたんだな、と読んで頂けたら嬉しいです。

自己紹介

最初に少し自己紹介させてください。

2019年1月にユニファに入社しました。プライベートでは小学生と保育園児のママです。 QA歴は5年と少し。 ユニファでは、比較的規模が大きいプロジェクト内でのテスト設計と実行、探索的テストなどを担当しています

前職でのQA活動

ユニファ入社前は、ファッションECサイトを運営する会社で、主にコーディネートアプリやサイトのQAとして働いていました。

仕様書やデザインはほぼ確定していて、それをテストベースにテスト設計を行い、テストケース作成、テスト実行、不具合があれば報告、 修正されたものがあれば修正確認テストと、いうのが基本的な流れです。

開発とQAは拠点が違うため、基本的にやり取りはslack。

開発者さんは皆いい人ばかりで、定期的にMTGで顔を合わせてはいましたが、 サービスについてQAから気軽にアイディアを出したり、ということはあまりありませんでした。 (これは、QAとしてもっと頑張ればよかったなーという心残りもあります。)

ユニファでのQA活動

ユニファに入社後、ルクミーフォトのリニューアルプロジェクト(園管理画面)にアサインされました。 プロジェクトではスクラム開発を取り入れており、QAもテスト自体はスクラムの外で行いましたが スクラムイベントには参加していました。 私が「ものづくりにかかわれたなぁ」と感じたのは、次の3つです。

思い出① QA視点でデザインルールを変更してもらえた

f:id:unifa_tech:20191217222450p:plain
へっぽこデザインイメージ

ルクミーフォトの園管理画面では、ある情報を登録するためのコードを発行する画面があります。 いくつかの項目を選択し、「発行する」というボタンをクリックすると、上のような印刷画面に遷移するためのウィンドウがでます。 当初のデザインルールでは、上のようなウィンドウが表示された場合

  • ウィンドウ内の右上の✕ボタンをクリック
  • ウィンドウ外のグレー背景をクリック

すると、ウィンドウそのものを閉じるルールでした。

スプリントレビュー(ユニファではおさわり会と呼んでます。そこはかと漂うギリギリ感がすてき)で公開後、私が触ってみて感じたことは「グレー背景のとこ、うっかり結構クリックしちゃう」でした。

一応、仕様をしっているQAの私ですらうっかり結構クリック、そして閉じられるウィンドウ、すると項目数は少ないけどもう再度情報入力→クリックという作業を、園の先生に強いてしまう…

これ、ちょっと気になるなぁ…と、おずおず聞いてみたところ、なんとその場で「そうだねーたしかにー」となり、以降

ウィンドウ外のグレー背景をクリック

は撤廃されました。

え?

いいの?

まだ入社1か月の新参者で、みんながここまで作り上げてきた背景とか知らないんだけど、いいの?

とびっくりしたのを覚えています。

思い出② QAが開発者さんにアイディアだしたら採用された

f:id:unifa_tech:20191217222411p:plain
へっぽこ画面イメージ

ある日のデイリースクラム、開発者さんがちょっぴりお悩みをかかえていました。

ルクミーフォトの園管理画面では、ある設定①を登録する時にオプションを選ぶと、区分がちがう設定②も同時に登録することができます。

設定①と設定②は、区分が違う以外はほぼ同じ情報として扱われます。

開発者さんが悩んでいたのは、設定①と設定②を編集する時。DBの都合上、設定①と設定②が連動している構成にはなっていないが、片方を編集した時、もう片方にも反映させたいのです。

プロダクトオーナー、スクラムマスター、開発者さん、デザイナーさん、QA全員でしばしうんうん悩みました。

みんなが悩んでいるので、私も素人ながら頭をぞうきんしぼるような気持ちで考えました。

そして、ふと「登録が同じタイミングなので、IDは連番になるはず。設定①を編集時に、設定①の前後のIDかつ設定①の編集前の各項目で検索かけて、同じものがヒットしたらそれは設定②なので、同時に更新してはどうですか?」とあきれられちゃうかなーと思いながら、話してみました。

結果、開発者さんの方でこのアイディアを元に、もう少し手を加えて実装に採用してもらえることになりました。

採用決定時の開発者さんのおほめの言葉が、すごくつぼなのできいてください(笑)

「一番実現可能な小手先でどうにかする方法だった」

思い出③ QAが仕様書つくってステークホルダーあつめて仕様確定までしちゃったよ

ルクミーフォトのリニューアルプロジェクト、実装完了のバックログがたまってきて、QAもテストで忙しくなってきた2019夏。

新しく入社したテストマネジメントに強いチームメンバー(以下、野生のクマと呼称します)と私は少し困っていました。

なぜなら、リニューアルプロジェクトのテスト範囲のあるアプリの仕様書ができておらず、テスト設計に入れなかったからです。

リニューアルプロジェクトでは、スクラムマスター(ディレクター)が仕様書やデザインワイヤーを作成し、プロダクトオーナーや開発者さんと仕様を詰めるのですが

この時、スクラムマスター(ディレクター)は多忙で 、なかなかアプリの仕様書まで手が回っていない状況でした。

以前の私なら、「忙しいならしょうがない。できるまで待とう」と思っていましたが、この時はWACATE(詳しくはこちら)参加後でやる気が加速モードだったので

「ならQAで作っちゃおう!」となって、

  • 現行のアプリの仕様
  • リニューアル後のデザイン(ペイント)
  • リニューアル後の仕様
  • 未検討事項

などをまとめた仕様書を作ってしまいました。

f:id:unifa_tech:20191217222322p:plain
へっぽこ仕様書イメージ

ついでに、スクラムマスター、プロダクトオーナー、デザイナーさん、アプリの開発者さん、サーバサイドの開発者さんを集めて仕様確定MTGもセットして、そのMTGで仕様ほぼ確定させてもらえました。

まとめ

以上、私がユニファに入って「ものづくり」に関われたなぁと感じた思い出3つでした。

ユニファのQAって、品質をあげるための活動は何でもできるところが魅力だなと思います。

ながながとおつきあい頂き、ありがとうございました。

おまけ

ユニファのQA、もしくはユニファに興味のある方は、こんなイベントもやってます! ご興味あるかたはチェックしてみてください!