astamuse Lab

astamuse Labとは、アスタミューゼのエンジニアとデザイナーのブログです。アスタミューゼの事業・サービスを支えている知識と舞台裏の今を発信しています。

flyway + gitlab-ciで最新のテーブル定義を用いてdaoのテストをする

こんにちは、アプリケーションエンジニアのchotaroです。

最近RTA動画を見ることにハマっています。
最速ルートとリスクのどちらをとるのか?それはなぜなのか?また本番でしくじったときいかにその場でロスを少なくできるか?
特にイベントのアーカイブが解説ありで見応え満点です。是非。

さて今回は、チーム内で作ったCIのしかけについての紹介です。

解決する課題

  • そもそもテーブルの変更履歴を管理していないとその差分も追えず開発の負荷が高くなってしまう
  • daoとテーブル定義の差異をステージング環境で統合する前に確認したい

最終的な形(現状版)

  • テーブル定義の変更をflywayで管理する
  • flywayの設定とともにddlをgitで管理する
  • gitlab-ci上で,flywayを用いてDBを構築し、そこに向けてdaoの自動テストを行うようにする

実践

概要図

こんな形式(厳密ではないですが。)

f:id:astamuse:20190607095603p:plain

.gitlab-ci でやっていること

postgresql install

ubuntu向けのinstall

    - echo "deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main" >> /etc/apt/sources.list.d/pgdg.list
    - wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
    - apt-get --quiet update --yes
    - apt-get --quiet install postgresql-10 sudo --yes
    - service postgresql start

set deploy key ~ git clone

ddlはgitlab上のinternalなrepositoryに配置しています。そのため、git cloneするにはdeploy keyを利用する必要があります*1

【事前準備】 * ddlを格納しているリポジトリにdeploykeyを設定する * deploykeyのペアになる秘密鍵をdao側のリポジトリに配置

【test時】 * sshの設定を行うscriptを実行。target-gitlab-hostにはgitlabのホストを入れて、そのホストのときにはこの鍵を使う、という設定を行います

    - mkdir -p ~/.ssh && chmod 700 ~/.ssh
    - ssh-keyscan -H <target-gitlab-host> >> ~/.ssh/known_hosts
    - chmod 400 deploykey
    - eval $(ssh-agent -s)
    - ssh-add deploykey
  • git clone target-repository でcloneする

flyway install

linuxの向けのflywayコマンドをインストールします

    - apt-get --quiet install tar wget sudo --yes
    - wget -qO- https://repo1.maven.org/maven2/org/flywaydb/flyway-commandline/5.2.4/flyway-commandline-5.2.4-linux-x64.tar.gz | tar xvz && ln -s `pwd`/flyway-5.2.4/flyway /usr/local/bin
    - flyway -h

完了後、flyway migrate でDBセットアップが完了します

あとはテストするだけ!

sbt test

効果

課題感が解消されたので、個人的にめっちゃ気が楽です。

gitlab-ciはpushされるたびにpipeline上で実行されるので、failしたらすぐわかります。
逆にいえば、successし続けられればデータベースアクセス上は問題ないことになるので、大変安心して進められています。

謝辞

ここで紹介した仕組みは私一人で考えることができたものではなく、チームメンバーでの改善の結果こうすることができた、というものです。
この場を借りて感謝申し上げます。いつもお世話になっております。これからもガンガンお世話になります。よろしくお願いいたします。

また、そもそもpostgresqlのイメージを使ったりすればいくらかciのymlファイル自体はスマートになるはず*2で、いわゆるベストプラクティスではない、とも考えています。

これからも走りながら地道にやっていくしかないとこではありますが、並走者も随時募集中ですので、気になられた方がおられればバナーからよろしくお願いいたしますー

それでは。

*1:refs: https://docs.gitlab.com/ee/ssh/#deploy-keys

*2:runner含めた設定が必要になってしまうので検証が足りておらず、仕掛けとして作れていません。

Nuxt.jsのライフサイクル覚書

デザイン部でフロントエンドエンジニアをしているkitoです。React.jsとVue.jsの登場で、JS界隈は一時期の混沌とした時代から落ち着いてきましたが、今や両者それぞれのエコシステムが豊かになるフェーズに移行しています。jQueryがデファクトスタンダードになり、盛んにプラグインが開発されていた頃を彷彿とさせます。
Vue.jsのエコシステムのなかでもNuxt.jsは、完成度の高さからVue.jsのサーバーサイドレンダリングのフレームワークとして広く利用されようとしています。

今回は、そんなNuxt.jsを実際のサービスで使うさいに欠かせないライフサイクルの知識について書きたいと思います。といっても、私自身、最近までNuxt.jsのライフサイクルついて十分に理解していたかというと、心もとないところがありました。公式サイトのライフサイクルダイアグラムをみてわかったようなわからないような気になっていたのです。

そのひとつの原因としては、Nxut.jsは、Vue.jsのサーバーサイドレンダリング用のラッパーのようなものなので、それぞれのライフサイクルを頭に入れ「どこからこどまでがサーバーサイドのライフサイクルなのか?」「どこからがクライアントサイドなのか?」を把握しなければならないからでしょう。
今回、曖昧だった疑問を整理し、Vue.jsとNuxt.jsをひとつにつなげたライフサイクルとして図を作成しました。

Nuxt.jsとVue.jsのライフサイクル

早速ですが、下記がライフサイクルの図になります。

f:id:astamuse:20190529112056p:plain

nuxtServerInit

nuxtServerInitは、Nuxt.jsのライフサイクルの最初にくるメソッドで、サーバーサイドから直接データをstoreにセットしたいときなどに使います。ログイン認証でセッションIDをstoreに保存したいときはこのメソッドで行います。まだブラウザのwindowオブジェクトにアクセスできないので、localStorageにデータを直接保存することはできません。

middleware

次に、nuxt.config.jsに記述されているmoduleやmiddleware、pluginが呼び出されます。もし、severMiddlewareとしてexpress.jsを使っている場合もここで呼ばれます。 図では省略していますが、クライアントサイドでnuxt-linkをクリックして遷移したときは、ここまで戻って実行されます。

validate

validateは、動的ルーティングしているcomponentsのパラメータをバリデーションします。

asyncData or fetch

asyncDataでは、外部APIからのデータをサーバーサイドレンダリングしたい場合は、ここでaxiosなどを使って取得します。 fetchは、asyncDataとよく似ています。異なるのはfetchは、値をstoreにセットできますがcomponentsに値をセットできない点です。

render

renderでcomponentsがレンダリングされるわけですが、ここはサーバーサイドとクライアントサイドの境界にあり、beforeCreateやcreatedは両方から利用できるメソッドになっています。

クライアントサイド

これから下はクライアントサイドのみの領域になり、Vue.jsのみのライフサイクルに入っていきます。beforeMonuntはVueインスタンスがマウントされる前に呼ばれ、mountedはマウント直後に呼ばれます。DOMにアクセスしたいならここで。

ライフサイクルの重要性

ライフサイクルへの意識が特に必要になるのは、ログイン機能をつけるときでしょう。ユーザー認証のためにtokenを一定期間保持しなければなりませんが、asynDataではまだブラウザのcookieやlocalStrageにはアクセスできません。最初のリクエスト時、nuxtServerInitでtokenをStoreにセットしておくことが必要になるでしょう。 また、DOMを直接触ろうとするなら、クライアントサイドのライフサイクルに入ってからでないと不可能です。

まとめ

Nuxt.jsなら、モダンなフロンエンド開発に欠かせない設定が隠蔽されているので、容易にサーバーサイドレンダリングされたWebアプリが作成できます。 しかし、ログイン機能のような少し複雑な機能を追加しようとすると、途端にライフサイクルやVuexの状態管理の知識が必要になります。 今後、Nuxt.jsが選択されることが増えていくと思われます。Nuxt.jsへの技術的投資は、さらに重要になっていくのではないでしょうか。

アスタミューゼでは、エンジニア・デザイナーを募集中です。ご興味のある方は遠慮なく採用サイトからご応募ください。お待ちしています。

PM としてアスタミューゼに転職して

はじめまして、PM として入社しました Gyopi です。
アスタミューゼでは複数の Webサービスや社内サービスを持ちながら、
Product Manager を専業でやっている人間がいませんでした。

そんな中入社した一人 PM からみたアスタミューゼと最近やったことのお話です。
(以下、PM は全て Product Manager のことを指します)

(経歴)Webエンジニアの経験を PM に

「Product Manager」とはどいういう役割かプロダクトやフェーズにより異なるかなと思いますが、

Product の魅力によりユーザーに得をさせる。
そのために、メンバーが魅力を作り上げやすい状況を作り出す。

というのがざっくりとした役目だと思っています。

私はキャリアの最初から PM だったわけではなく、
最初は Ruby on Rails で BtoB のサービス開発を行うエンジニアでした。

PM は直接的に開発者の領域を侵してはならないと思いますが、
少なからず開発知識があることは議論において役に立っている実感があります。
エンジニア時代の周囲の人々には今も感謝が絶えません。


また、前職にて新規サービスを立ち上げて拡大していく中で
Growth Hack の試みを行ったり大口顧客に法人営業を行ったり、
ユーザーのことを考え・ユーザーに直に接する機会も得られました。

事業の目線で物事を考える上では新規サービスでの Product Owner(PO)を務めた経験も大きいです。
サービスを拡大させる中で複数の立場を経験できたこと、
その中でもユーザーに直に接した経験は「ユーザーに得をさせる」の発想に至る原体験だと思います。

転職理由)プロダクトとの向き合い方を磨くために

幸いにも新規サービスは成長し、
事業側も開発側もアグレッシブなメンバーに恵まれていましたが、
最終的には5年ほど務めた前職からの転職を決断しました。

法人向けのサービスにやりがいを感じながら、事業として1つだけの領域で試行錯誤をすることに限界を感じていました。
携わっていたサービスが Google などのビッグプレイヤーが競合となるドメインにいたこともあり、より独自性の強いサービスに携わりたかったです。
とはいえ、やりきった達成感が故の転職でもあったように思います。


アスタミューゼへ決めた理由は、採用面接で今の上司から受けた会社やデータの説明が興味深かったから、というのが大きいです。
ロジックで考える条件もありますが、こういう人たちと働くのは面白いだろうと、面接を楽しく感じさせてもらえたことは確実にプラスに作用しました。
最初は別の職種で応募していながら、適性を踏まえて PM を推奨してくださったことも嬉しかったです。


また、以前から Scala で開発していることを知っていたので開発者目線でも以前から知っている会社でした。
転職してから全然プログラミングできてないな、という自戒も込めて敢えて初心を記しておきます。

転職してみて)アスタミューゼで自分に何ができそうか

流れの速い事業・プロダクトに携わっているということでもあるのですが、最初のキャッチアップが何より大変でした。
社内の打ち合わせで「アグリー」とか「ケイパビリティ」とネタではなく口にする人がいて、転職の実感を感じた次第です。
とはいえ総じて周りの方は優しくて、聞いたらなんでも教えてくれるし、ご飯にも誘ってくれるし、お陰様で慣れるのは早かった気がします。


専門用語が飛び交って会話が進むので「これはドメイン知識を得るのが大変だ」ということで少しずつ社内用語集を作りました。
用語集はたまに近くの部署の人に今でも共有することがあり、フットワーク軽く作ってよかったなと思っています。
その後、同じタイミングで入社した池田 (@yukung)が社内 Wiki を整備してくれたので情報共有はかなり前進しています。


アスタミューゼには開発面やインフラ、新規事業コンサルなど様々な経験・スキルを持つメンバーがいて本当に多種多様です。
プロダクトも人数の割に多いですし、何より新規も運用中のものもデータがとにかく多いです。
その中で都合よく一人 PM という立場を利用してフットワーク軽く様々な面に顔を出すことで、意外と気づきづらいチームやプロジェクトの滞りを解消できたらなと思っています。


これまでアスタミューゼのプロダクト設計はどちらかといえば解決策ドリブンのものが多かったようです。
データや社内の専門的知見が多種多様なことを考えると、それにも納得がいきます。
それを新しい Web サービスとしてソリューションだけでなく価値を試行錯誤し、チームみんなで成長していければいいなと考えています。

最近やったこと)サービスについてみんなで議論を

最近やったことの中から、Lean Canvas を書いてみたというエピソードを少し。
Lean Canvas はサービスを「誰のどんな課題を解決するためにどういった機能を届けるか」を固めるものですが、
やったことがないと書いてみることに高いハードルを感じてしまいがちです。

今までにメンバーを少し入れ替えながら何度かトライしてみました。
その中でも一番初めは少し見切り発車気味に進めましたが、
「意外にみんなで埋められる!」という実感を得ることができたのではないかと思っています。


検討を重ねる中で、サービスの何に着目していくかという次の分類を気にしながら取り組みました。
・CPF (Customer Problem Fit)
・PSF (Problem Solution Fit)
・PMF (Product Market Fit)
とはいえ、まだ CPF がひと段落という段階です。
各フェーズなどについてはまた別の記事でお話しできればと思います!


実装する機能や、KPI 達成の施作には日常の中で確実に注目していますが、
「どうしてこういった KPI に落としこまれるのか」は定期的に振り返らないといけないなと改めて感じました。
また、メンバーによってどれくらい詳しく言語化することで判断材料として納得がいくのか、などの特徴も出てきたかと思います。


他にもこの数カ月で開発スタイルがアジャイル・スクラム化されたり、
機能要件を User Story 形式にしはじめたり、
開発チームでモブプロとかはじめたり、
チームの成長がすごいので今から未来が楽しみです!

おわりに

私は Web サービスの PM というところをメインに働いていますが、
社内システムを刷新したり、持つべきデータの企画をおこなったり、事業と技術を繋げていくべき役割が社内にたくさんあります。


決まり文句になりますが、We’re hiring!! ということで
エンジニアやデザイナーだけでなく PM も募集中です!
アスタミューゼに、Product Manager に、興味を持っていただければお気軽に採用情報をご覧になってください!





Blog を一回分飛ばしてしまったので、次回は締め切りにコミットできるようにしたいと思います。

Copyright © astamuse company, ltd. all rights reserved.