HiTTO プロダクトチームブログ

「HiTTO(ヒット)」は、シゴトのナレッジを体系化し、新しいコミュニケーションを創り出す社内向けAIチャットボットです。

HiTTOを支える技術について(インフラ編)

HiTTO株式会社エンジニアのHonMarkHuntです!HiTTOではSREとスクラムマスターとFORTNITEをして過ごしています!趣味はGOLD'S GYMです!よろしくお願いします!

本日はSREの私がバックエンド、フロントエンドに続きHiTTOのインフラ周りの紹介をさせていただきます!

product-blog.hitto.co.jp

product-blog.hitto.co.jp

(過去記事も見てね)

1. Cloud

f:id:HonMarkHunt:20211215172032p:plain:w320

HiTTOではAWSを採用しています。

GCPやAzureと比較して明確な採用基準があったわけではなく、私含め皆AWSが慣れていたので採用しました。

Organizationを利用して環境ごとにアカウントを分けたマルチアカウント運用をしています。

アプリケーションの構成に関しては特別なことはあまりなく平均的なWebアプリケーションの構成という感じです。 主に使用しているサービスを以下に記載させていただきますが、なんとなく平均的な感じが見えてくると思います。

  • ALB
  • ECS(fargate)
  • RDS
  • CloudFront
  • S3

少しだけ頑張った点をお話しするとログインは全てGSuiteのsaml認証に統一しており、入社時にGSuiteアカウントを発行すればAWS側でIAM Roleを作成したりUserを作成したりといった手間が発生せず、退職した場合もGSuiteアカウントが削除されるのでAWS側でのアカウント管理が必要なく若干のトイル撲滅になっております。

aws.amazon.com (同じような事してる記事が古いのしか見つからなかった)

2. IaS

f:id:HonMarkHunt:20211215172123p:plain:w320

AWSの構成管理にはTerraformを採用しております。

HiTTOはまだまだスタートアップのフェーズでこの人数規模で構成管理を導入するかは少し迷ったのですが

  • コンソールから操作していて悪意のない破壊的変更があった場合元に戻すことができる
  • コードによる構成管理をする事で適用前にレビューができる
  • 再利用性が高まり複数アカウント間で同じようなリソースを作成する際の手間とミスが減る

以上のメリットが考えられたため導入を決定しました。Terraformを採用したのは Cloud Formationが辛すぎるからだよ^^ 前職で利用経験があり開発も活発だったためです。

Terraformの構成については1年ほど前ですがこちらの超人気記事を執筆してあるので詳しくはこちらをご覧になってみて下さい。

zenn.dev

開発フローに関しても手元でコードを書いてからコードがインフラに反映されるまでをCI/CDを導入して自動化しており、こちらに関しても今年のHashi Talksで超人気セッションと一部で囁かれた雰囲気のする登壇をさせていただいているのでこちらをご覧になってください。

www.slideshare.net (動画もあるけど恥ずかしいから貼りません君の目で確かめてくれ!)

3. CI/CD

f:id:HonMarkHunt:20211215172147p:plain:w320

CI/CDはCircleCIを採用しています

こちらは前職でAWSのCode Pipelineを使用していましたがそれによってかなり疲弊してしまい、CircleCIを使っておきたい人生だったなぁ...と感じたため採用しました。Code PipelineとCircleCIを比較した内容で登壇させていただいたことがありこちらも大人気資料になっているのでもし良かったらご覧になってみてください。

www.slideshare.net

個人的な考えですが、CI/CDの仕組みは一度作ってはい終わりではなくアプリケーションやチームの変化に応じて変更・改善し続けるものだと捉えています。そしてカイゼンするためには現状を把握することが何より必要です。

皆さんも「ビルド遅くなってきたからなんとかしたいな〜」や「最近CIこけるけど再実行したら通るから一旦いっか...」のようなやりとりをなどSlackで見たことはないでしょうか? ここで重要なのはなんとなくの体感値で動き出すのではなく

  • ビルドのどのjobに平均時間がかかっているか
  • 失敗率は何%なのか
  • ビルド時間が増加傾向にあるか

などなどを明確に可視化することで、目標値を決めてカイゼンの一手が打てるようになります。

前置きが長くなりましたが、HiTTOではData Dogを使用してCIのメトリックスを集計・可視化しています。 まだできていませんが、将来的には目標値を決め下回った場合にはSlackにalertを出してカイゼンを行うなど、CIを利用するエンジニアに向けてのSLI/SLOを定義して運用していくことをやっていきたいと考えています。

f:id:HonMarkHunt:20211223001046p:plain

4. Monitoring

f:id:HonMarkHunt:20211215172056p:plain:w320

データの収集・可視化・アラーティング等、多岐にわたってData Dogを利用しています。

Data Dog以前は、サーバーの監視にZabbix、Logの閲覧にElastiCache + Kibana、アラーティングにPager Duty、などそれぞれでツールを用意する必要がありましたが、Data Dog登場以降は「とりあえずDD入れておけばあとはなんとかなる」のとかなり有能な機能アップデートが頻繁にある点が素晴らしいと感じ弊社でも採用しています。

弊社で主に使っているサービスは

Logs

docs.datadoghq.com

アプリケーションのログからLB、S3などなどありとあらゆるログの収集とアラーティングに利用しています。 ログはすべてjson形式で送っておりjsonで送ればData Dog側でかなり良しなに解釈してくれるのでとても助かっています。

APM

docs.datadoghq.com

バックエンドのプロセスをAPMでメソッド単位の処理時間まで確認できボトルネックを特定することができ見るたびに「APMすげえな」と言っています。

RUM

docs.datadoghq.com

フロントエンドでの実ユーザーの情報を収集し可視化しています。 今のところ集めるだけになってしまっていますが、ソースマップを使ってエラーのアラーティング、APMとの連携などを進めていきたいです。

(Data Dogにある情報センシティブすぎてスクショが乗せれずすみません)

まとめ

今の環境は0⇨1で物作りする楽しさが詰まっていて、詰まりに詰まって(タスクが)溢れかえっています。 2人目のSREに入社して欲しいです。 今気づいたんですけど弊社の求人、SREだけ出ていないので僅かでも興味を持っていただいた方はとりあえず僕にDMください。マジで頼む。

twitter.com

Best regards.

コーディング規約について(フロントエンド編)

早いもので今年も残り一週間ですね。 最近の寒さに震えるなかむーです。

今回はコーディング規約について触れてみようと思います。

HiTTOではHRTの精神のもと、基本的には実装者の設計方針やロジックを尊重していますが ある程度の方向性は揃えたい為lintに縛られない緩めのコーディング規約をドキュメント化し運用していました。

現在はlintで縛ってしまったものもあるのですが考え方等も含めて紹介させていただきます。

TypeScript

default exportではなくnamed exportを使用する

TypeScript的には有害との事なので。。named exportを使うようにしています。
詳細は以下の記事をご参照ください!

typescript-jp.gitbook.io

interface ではなく typeを使用する

interfaceだと定義されたプロパティ以外にも存在を許容するのでtypeで厳密に型定義を行っています。

importは相対パスでもOKだが上には辿らない

絶対パスだと分かりやすいので基本的には絶対パスでの指定に統一したいが、 直下のファイルにアクセスするのにも絶対パスだと少し使いづらいので 下の階層のファイルのみ相対パスでの参照を可能にしています。

コンポーネント共通の型はmodelsに定義する

複数のコンポーネントで共通で使用するような型はmodelsというディレクトリを用意してそちらの中に定義を書くようにしています。 例えばuserの権限の型だと

export const AccountRole = {
  admin: 'admin',
  user: 'user'
} as const;
export type AccountRole = typeof AccountRole[keyof typeof AccountRole];

のような定義と、GraphQLのenum⇔コンポーネントで使用する型 の変換も合わせて定義して使っています。(後述するGraphQLの型変換で使用)

  static fromGql(x: GqlAccountRole): AccountRole {
    switch (x) {
      case GqlAccountRole.ADMIN:
        return AccountRole.admin;
      case GqlAccountRole.USER:
        return AccountRole.user;
      default:
        throw new Error(`invalid role. ${x}`);
    }
  }

  static toGql(x: AccountRole): GqlAccountRole {
    switch (x) {
      case AccountRole.admin:
        return GqlAccountRole.ADMIN;
      case AccountRole.user:
        return GqlAccountRole.USER;
      default:
        throw new Error(`invalid role. ${x}`);
    }
  }

React

Templates以下のコンポーネントでGraphQLの型を使用しない

GraphQLと疎結合にするため、AtomicDesignで言うところのTemplates以下のコンポーネントではGraphQLの型定義は使用しないようにしています。
主にenumの為ですがPagesの部分でコンポーネントで使用する型とGraphQLの型を相互に変換しています。

参考:HiTTOを支える技術について (フロントエンド編) - HiTTO プロダクトチームブログ

必要に応じてContainerコンポーネントとPresentationalコンポーネントで分けて書く

シンプルなコンポーネントだと必要ないかもしれませんが、複雑なコンポーネントだとロジックの部分とPresentationalな部分が混在して見づらくなってしまい、保守性が下がってしまいます。
コンポーネントの規模に応じて必要であればロジックと見た目を分離して書くようにしています。

CSS

サイズの単位はpxを使う

HiTTOでは当初margin,padding,font-sizeの指定はremで行っていました。
しかし、Figmaのデザインとpx単位で合わせようとするとremでの表現が面倒なのと、どうしてもデザインとのずれが発生してしまうためすべてpxで指定するように変更しました。

styled-componentsに依存しすぎない

styleはstyled-componentsを使用して当てています。propsを使ってstyleの切り替え等を行っているとstyled-componentsへの依存が強くなってしまい、styled-componentsから脱却しようとした時に捨てるに捨てられない未来が来るかもしれないので、極力CSSに近い形で書いておく事で移行のハードルを下げようという方針です。

例えば下記のようなpropsを使った実装を

const Button = styled.a`
  display: inline-block
  ${props => props.primary && css`
    background: white;
    color: black;
  `}
`;

props使わないように実装するようにしています。

const Button = styled.a`
  display: inline-block
  &.primary {
    background: white;
    color: black;
  }
`;

最後に

他にもいくつかありますが主なルールを紹介させていただきました!

HiTTOでは採用のフローとして複業からのジョインを推奨しています。
自分に合わなかったらどうしよう。今の会社は辞めたくないけど気になる。。という方もマッチするかどうか複業で確認できるかと思いますので、ぜひご応募お待ちしております!

offers.jp

offers.jp

offers.jp

jobs.forkwell.com

手軽に Visual Regression Testing を始めよう!

きょんしー🐧 です。

最近はUIを作るよりテスト環境整備したりFeature Flag導入したりVite試したりRenovate運用考えたり、継続して開発していくためのことが多めになってます。

この記事ではVisual Regression Testing(以降、VRTと記述する)を手軽に始めてもらえるよう、HiTTOでの導入例を紹介します。

  • VRTの導入を試みたが失敗した
  • VRT導入してみたいけどよく分からない

といった方に向けた記事になります。
※ Storybookを導入している前提になってます🙇‍♂️

そもそもVRTとは?

そもそものVRTはどのようなテストかについてですが、ブラウザにレンダリングした際のスクリーンショットをピクセル単位で差分を検出するテストです。

正解画像(Expected Image)と実際の画像(Actual Image)を比較し、 差分が閾値以下ならSuccess、しきい値を超えたらFailedになります。

f:id:n-kyoncy:20211116163312p:plain

UIの変更をした箇所とは異なる箇所に影響が出ないかをテストすることができます。

正解画像(Expected Image)と実際の画像(Actual Image)を1px単位で比較してくれるので、差分があれば以下のように表示してくれます。

f:id:n-kyoncy:20211119103950p:plain

VRTの導入は敷居が高い?

僕自身も前職でVRTを導入しようとしましたが、以下のような壁があり断念しました。(HiTTOでやっと雪辱を果たしました🎉)

  • CI上でフォントの読み込みが解決できなくて日本語が豆腐になる

CircleCIであればフォントを追加してあげればOKです👍HiTTOでは日本語フォントにNoto Sans、英数字フォントにLatoを用いてるので fonts-lato, fonts-noto, fonts-noto-cjk を追加しています。

      - run:
          name: apt-get install
          command: |
            sudo apt-get update
            sudo apt-get install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb
            sudo apt-get install fonts-lato fonts-noto fonts-noto-cjk
  • サーバーの立ち上げを待ってスクショを取得する

この後も登場しますが、start-server-and-test を使用すればサーバーが立ち上がるまで次の処理を待つことができます。

これ以外にも理由はあるかもしれませんが、Jestを導入することに比べると敷居が高いように感じています。

また、VRTは(ヘッドレス)ブラウザを立ち上げる必要があるため導入できたとしてもCIの時間がかかる懸念もあるでしょう。最初から運用に乗せようとすると苦労すると思うので、小さく導入して効果を実感できれば敷居も下がるのではないかと思います。

StorybookにVRTを導入する

HiTTOではStorybookを使っており、デザインの認識合わせに用いています。Atomic Designを採用しているのですが、Templates以下の全てのコンポーネントを確認することができます。

参考: フロントエンド × デザイン 〜連携強化のためにしていること〜 - HiTTO プロダクトチームブログ

Templates内にある各storyに対してVRTを行なっています。
Templatesに限定している理由は、CIでの実行時間を短く抑えたいこととページAのレイアウトを変更した際にページBにまで変更が及んでないかを確認するためです。

Storybookに対してVRTの導入する方法としてStorycapを用いる方法もあったのですが、全storyのスクリーンショットを取得する必要ないかなと判断しCypressでスクショを取得するようにしました。Storycapは各Storiesをクロールしてくれるため、手軽にスナップショットを取得できるそうなので、試してみたいです👀

  • Cypress: Headlessブラウザを起動してStorybookのスナップショットを取得する
  • reg-suit: キャプチャした画像と正解画像の比較、GithubやSlackへの通知、GCSとの連携

Cypress

Cypressのセットアップ から説明します。

$ yarn add -D cypress
$ yarn run cypress open

起動できること確認したら閉じて、cypress/integration/examplesディレクトリ以下は不要なので削除します。

次に、Storybookサーバが起動するのを待ってスナップショットを取得する必要があるので、start-server-and-test をインストールします。

$ yarn add -D start-server-and-test

スナップショット取得の処理を記述します。 CI上で動かすことを考えたときの適切なcy.wait(3000)の値を探る必要はありそうです。

context('Storybook', () => {
  it('logged in', () => {
    cy.visit('http://localhost:6006/?path=/story/example-page--logged-in');
    cy.wait(3000);
    cy.get('#storybook-preview-wrapper').screenshot('login');
  });
});

以下のコマンドをnpm-scriptsに記述した上で実行すると、 cypress/screenshotsディレクトリ以下にスナップショットが出力されます。

start-server-and-test 'yarn storybook' http-get://localhost:6006 'yarn cypress:run'

reg-suit

次に、reg-suitについて説明します。

$ yarn add -D reg-suit
$ yarn run reg-suit init

最初はローカル環境でVRTを実行するために、plugins周りは省いてます。

{
  "core": {
    "workingDir": ".reg",
    "actualDir": "cypress/screenshots",
    "thresholdRate": 0,
    "ximgdiff": {
      "invocationType": "client"
    }
  }
}
  1. .reg/expected ディレクトリに cypress/screenshots ディレクトリをコピーする
  2. コンポーネントに変更加える
  3. Cypressを実行する
  4. reg-suit run
  5. npx http-server .reg でローカルサーバ立ち上げる

f:id:n-kyoncy:20211116174049p:plain

pluginsの設定

reg-publish-s3-plugin(reg-suitの結果の置き場所。gcsのpluginもあります), reg-notify-github-plugin(github連携), reg-keygen-git-hash-plugin を追加しました。

{
  "core": {
    // 省略
  },
  "plugins": {
    "reg-keygen-git-hash-plugin": true,
    "reg-notify-github-plugin": {
      "prComment": true,
      "prCommentBehavior": "default",
      "setCommitStatus": false,
      "clientId": "need to setup"
    },
    "reg-publish-s3-plugin": {
      "bucketName": "need to setup"
    }
  }
}

Github連携をしているとpull-reqに自動で結果をコメントしてくれるので、予期せぬレイアウトの崩れをVRTによって見つけることができるのでとても助かっています!

f:id:n-kyoncy:20211119103916p:plain
成功したパターン

f:id:n-kyoncy:20211119103926p:plain
差分が検出されたパターン

※ ここではGithub ActionsやCircleCIの設定に関しては触れませんでしたが、reg-suitに注意点が示されています。

最後に

HiTTOでは複業で関わってくださる方も在籍し、複業から始めていただいた上で日々の開発や1on1を通してお互いにマッチするかを確認しています。

良いUIの良いサービスとは何かを考えて継続的に届けたい!フロントエンド開発でいろんなことにチャレンジしたい!方を募集しています。HiTTO気になってるけどカルチャーにマッチするか不安だなぁという方はカジュアル面談も行っているので是非お声がけください!

offers.jp

offers.jp

offers.jp

jobs.forkwell.com

HRTな文化

どうもhongoです。

今日はHRTについて書いてみようと思います。

みなさんコードレビューやSlackでのやりとりで嫌な言われ方や、トゲのある言い方をされたことはないですか? そういうことがあると健全な対話ができない上に人間関係のトラブルに発展していってしまいます。

そういうことが起きないようにHRTな文化を根付かせることが大事になってきます。

HRTとは?

HRTはTeamGeekというエンジニア界隈では割と有名(?)な本で紹介されているものです。

チーム開発において、人間関係を円滑にするだけでなく、健全な対話とコラボレーションの基盤になるものとして以下の3つが紹介されています。

  1. 謙虚 (Humility)
  2. 尊敬 (Respect)
  3. 信頼 (Trust)

3つの頭文字からHRTでハートと読みます。

そして、『あらゆる人間関係の衝突は、謙虚・尊敬・信頼の欠如によるもの』と強い主張がされています。

f:id:r_hongo:20211110105210p:plain

謙虚(H)・尊敬(R)・信頼(T)についてそれぞれTeamGeekから引用してみます。(p.15より)

謙虚 (Humility)

世界の中心は君ではない。君は全知全能ではないし、絶対に正しいわけでもない。常に自分を改善していこう。

尊敬(Respect)

一緒に働く人のことを心から思いやろう。相手を1人の人間として扱い、その能力や功績を高く評価しよう。

信頼(Trust)

自分以外の人は有能であり、正しいことをすると信じよう。そうすれば仕事を任せることができる。

具体的にはどうするか?

TeamGeekの中では具体例としてコードレビューが挙げられていました。

悪い例

「このメソッドの制御フローは完全に間違えてますよ。みんなが使っている標準的なooを使うべきです。」

などと言ってはいけないと紹介されています。 相手は非難し、バカにされたかのように思ってしまうかもしれません。

良い例

「この部分の制御フローがよく分からないのですが、ooを使えば読みやすくなるでしょうか?」

自分の疑問として謙虚に聞くことが大事とのことです。

個人的にちゃんと普段からちゃんとできてるか分かりませんがしっかり意識しておきたいです😅

日頃意識するために

日頃から意識できるようにPullRequestのテンプレートにHRTのドキュメントへのリンクを置いています。 レビュー依頼する側、される側どちらも目にするので何もないよりは意識できる気がしています。

f:id:r_hongo:20211105154052p:plain

他にもデザインレビューやいろんなところで意識できるようにしていきたいなーと思っています。

おわりに

Zoomでのミーティング、Slackでのやりとり、デザインやコードのレビューなどコミュニケーションが発生するすべての場面でHRTを意識し、HRTに沿った振る舞いをすることでコミュニケーションの問題を減らせるかもしれません。

人間関係の問題が起きる前にぜひ取り入れてみてはいかがでしょうか。

弊社ではHRTな気持ちで一緒に働く仲間を募集しています!

offers.jp

offers.jp

offers.jp

jobs.forkwell.com

フロントエンド × デザイン 〜連携強化のためにしていること〜

ワクチン接種により左腕が上がらない、フロントエンドエンジニアのなかむーです。

f:id:t_nakamuu:20211022051012p:plain:w150

世の情勢からリモートで作業をされている方も多いと思いますが、フロントエンドチーム/デザインチーム間での連携どのように取っていますか? 物理的に集まる機会も減った今、コミュニケーションコストの増大により細かい部分の認識にズレが生じてしまうこともあるかもしれません。

今回はフロントエンドチームとデザインチームで連携強化を図るためにHiTTOで行っている取り組みをご紹介してみたいと思います!

デザイン関連の本を読む会

まずはデザインについて全員で学んでみようという事でデザイン関連の本を読み進めていく会を実施しました。 読んだ本はこちら↓

www.amazon.co.jp

輪読会的なものをやってみるのも初めてだったので毎週1章ずつ各自で読み進め、この会で感想や不明点、プロダクトに活かせそうな事を話すというできるだけ心理的ハードルが高くならないような形で始めてみました。

f:id:t_nakamuu:20211022040314p:plain
miroを使って各自付箋を貼っていきました

結果、無理なく読み終える事ができ、上記の本ではECサイトについての例がメインに書かれていて弊社のプロダクトにそのまま取り入れられない部分はあったのですがデザインについて深く考える良いきっかけになったと思います。

Atomic Designの粒度の認識を統一する会

以前よりFigma上のデザインと実装でコンポーネントの粒度が異なるものがある、という課題があり粒度の認識を統一するべく週一でFigmaとにらめっこしました。

atomsのボタン1つから始め、サイズや色、padding等の認識合わせ、「hover時の色は?」「この色使うのはどんな場合?」といった今まで不明瞭だったルールも明確化していきました。

f:id:t_nakamuu:20211022040937p:plain
Figma上に整理されたコンポーネント達(一部)

Figma上ですべてのコンポーネントの粒度整理、デザインルール確認が終わり、メンバー感での連携が深まったように思えた会でした。

(フロントエンド側の実装が追いついていないので実装を合わせて行くのが今後の課題。。)

実装後のデザインレビュー

HiTTOではGithub上でのPR作成時にNetlifyを使ってStorybookのBuildとDeployを行っています。
以前よりリリース前のQAでデザインの崩れ等が見つかる事がありQA前にデザイン関連の不具合は潰しておきたいね、という事で上記のStorybookを使って新規コンポーネントの作成時やデザインの大きな変更がある場合にデザイナーチームのレビューを挟む運用にしてみました。

Figma上のデザインとの差異が見つかる事に加え、デザインチームが意図した実装になっているか確認してもらえるので認識のズレもなくなっているのではないかと思います。

ユーザビリティテスト

UIの改善点洗い出しの為、HiTTOにjoinして日が浅いメンバーに実際に画面の操作をしてもらい - どの操作で迷っているか - 気づきづらい機能はないか 等の視点で操作を見守る事をやってみました。

一つ一つの操作を取っても画面の操作に慣れてしまっているメンバーからすると結構な気付きがあったように思います。

f:id:t_nakamuu:20211022045839p:plain
見つかった課題とその改善案

おわりに

ここまでの取り組みを紹介してきましたが、上記の取り組みは全てリモートで実施しています。 リモートでも十分にコミュニケーション図れていると思えるので今後とも連携強化を図って行きたいです。

ちなみに現状の一番の課題はFigmaのコメントをSlackのチャンネルに流すために使っていたFigma for Slackのインテグレーションが使えなくなったため Figmaのコメントが追いづらくなった件です。。Figmaアプリもメンションしか通知してくれないので中々不便です。

f:id:t_nakamuu:20211022043558p:plain
Figma for Slack が使えない悲しみ

解決策、代替案お持ちの方お待ちしております。

offers.jp

offers.jp

offers.jp

jobs.forkwell.com

HiTTOフロントエンドのRenovate運用

こんにちは、髪型を変えたらZIPのマーティンと呼ばれなくなったきょんしーです。

HiTTOではBackendとFrontendでリポジトリを分けており、それぞれでRenovateを導入しています。GitHub Apps - Renovate · GitHub として無料で使えるので導入が増えている印象です。

この記事では、FrontendリポジトリのRenovate運用をしてきての知見を共有できたらと思います。ベストプラクティスではないですが、所々参考になる箇所はあるかと思います。

運用開始前の状況

僕が入社した2021年5月時点でRenovateは導入されていましたが、PRが放置されている状態で運用に乗っているとは言い難い状況でした。

しばらくは機能追加やUI改善などに追われていたこともあり、ライブラリの対応に関しては後回しになっていました。React 17 に対応していないライブラリがあったりしたこともあり、Renovate対応に消極的になっていた部分もあったかと思います。

誰がレビューしても良いシステムになっていましたが、自由にしていいとなると逆に何をしたら良いのか分からなくなるのと同じような状況でした。誰も対応していない状況はまずいなと思ったのと、複業の方ともHiTTOの改善をしていきたい気持ちがあったので運用を見直そうと決意しました。

幸いなのかHiTTOではOKRを導入しており、四半期ごとに会社・部署・個人の単位でOKRを作成しています。そこで自身の個人KRに「複業の方も含めた開発の進め方やルールを定める」を定めてチーム開発をより良くしていくことにしました。
Issue, PRのテンプレートの改善やレビュールールの策定、複業の方にタスクをどのように取り掛かってもらうかなどを決めています。

Renovateの運用に関して

  • Reviewerがアサインされてない
  • PR作成の頻度やグルーピングなどが決まっていない

といった具体的な課題がありました。

※ 記事公開時点、HiTTOではフルタイムのフロントエンド担当者が2名、複業で関わってくださる方が2名います。複業の方は週8時間ほどを目安に仕事をしてもらっています。

チームでRenovateの運用を継続する

まずはReviewerを自動でアサインに関して取り掛かりました。 以下の記事にGithubでの設定とRenovate Configulationの設定に関して紹介しているので参考にしていただけたらと思います。

zenn.dev

大まかなステップとしては以下になります。 1. reviewerにteamを設定すると自動的にチームメンバーがアサインされるように設定する 2. RenovateがPRを生成するときにreviewerにteamを追加するように設定ファイルを記述する

この設定だけだとライブラリのアップデートがあるたびにPRが作られてしまうので、運用に役立ちそうな設定などは積極的に取り込んでいます。 HiTTOのRenovateの設定の一部を抜粋・改変しています。

{
  extends: ["config:base"],
  timezone: "Asia/Tokyo",
  labels: ["dependencies"],
  commitMessagePrefix: ":up:",
  branchPrefix: "renovate/",
  schedule: ["every weekend"],
  prConcurrentLimit: 15,
  prFooter: "Renovateの運用ルールのリンク",
  reviewers: ["team:frontend-all"],
  major: {
    stabilityDays: 7,
    prHeader: ":robot: IE11での動作確認もお願いします :robot:",
  },
  minor: {
    stabilityDays: 3,
    prHeader: ":robot: 動作確認お願いします :robot:",
  },
  patch: {
    stabilityDays: 1,
  },
  vulnerabilityAlerts: {
    labels: ["security"],
    reviewers: ["team:frontend"],
  },
  packageRules: [
    // groupingとかしています
  ],
}
  • prConcurrentLimit: Renovate が同時に作成するbranchとPRの数を制限する
  • schedule: 基本は平日にソースコードの変更が多いので被らない土日にPRを作成する
  • reviewers: HiTTOでは複業の方も含めたフロントエンド担当者のteamを作っています
  • prFooter: レビューで困った際に参照できるようにするために関連するドキュメントへのリンクを載せています
  • stabilityDays: 設定した日数が立たないとPRのステータスがSuccessにならないようにしています。majorアップデートなどの直後は何かしらバグを含むだろうという仮説の元にあります

ドキュメントを作成したりRenovateの設定を見直してから1ヶ月以上が経ちましたが、チームで運用ができてき出している状況を感じています。最初は今まで対応できていなかったpatch, minorのPRが沢山作られましたがほとんど対応でき、majorのPRが少しずつ作られるようにもなってきました。

まだまだ改善が必要

ただ、運用する中で改善点もいくつか見つかりました。

  • 毎週末にPR作られるのは多い
  • PRの数を制限しているとpatchアップデートのPRばかりになってくる

1つ目の課題に関しては、第1, 3土曜日にPRを作るようにしました。金曜に駆け込むような形でレビューすることがないように、毎日10時と18時にSlackで通知するようにしています。

schedule: ["on the 1st and 3rd day instance on saturday"]

dev.classmethod.jp

2つ目の課題に関しては、prPriority を設定していないと minor, patch のアップデートのPRが優先的に作られるようです。そのため、majorアップデートのPRに届くことが少ないようにも感じていました。

解決策としては major, minor, patch それぞれに優先順位を持たせるようにしました。具体的には minor > major > patch の順になっています。
リリースの多さだけでいうと patch > minor > major の順になると思いますし、patchアップデートの重要性も感じているのですが、「1つのライブラリに対して毎週patchアップデートが来る」ことはレビューする側として面倒に感じてしまう側面もありました。major > minor > patch の順でも良いのですがmajorアップデートの対応ばかりになるのも疲れると思ったのでこのようにしています。

一旦はRenovate運用で抱えている課題を解消しましたが、今後も発生してくると思います。HiTTOはIE対応もしているのでアップデートをしないライブラリもどんどん増えてくると思うのでレビューだけ切り取っても大変ではあります。

最後に

1ヶ月ちょっとを通してRenovateの運用改善をしてる中で思ったのは、チームの状況や依存ライブラリの多さなどによって取るべき選択肢は変わるためベストプラクティスはなさそうということです。
もちろん、reviewerの自動アサインや定期的にSlackに通知したりすることは運用をしようとしている方々にとっては共通して必要なことだと思います。

この記事では触れませんでしたが、複業の方もいる中でのIssue, PRの作り方やレビュールール、タスクをどのように取り掛かってもらうか についても整理ができてきたら記事する予定ですので興味を持ってくだされば読者のボタンを押していただくかRSSリーダーに追加してもらえたらと思います。

HiTTOをもっとスピード感を持って改善し、チャットボットの良さをもっと広めていきたいのですがエンジニアがまだまだ足りないので募集しています! 要求に従ってプロダクトを作るだけではなく、デュアルトラックアジャイルを開始し本当に価値があるのかを検証してから開発に取り掛かるようにもしています!Frontend, Backend, MLのエンジニアで興味がある方がいればHiTTOについて紹介する時間などをもらえたらと思いますのでTwitterからでも連絡くださればと思います!

offers.jp

offers.jp

offers.jp

jobs.forkwell.com

参考記事

docs.renovatebot.com

zenn.dev

HiTTOを支える技術について (バックエンド編)

HiTTO株式会社のプロダクトチームでエンジニアをしているhongoです。 今日はHiTTOのバックエンドで使っている技術を紹介したいと思います。

言語

Scalaを使っています!

HiTTOはリニューアル版として新しく作っているプロダクトで旧版はhitTOという名前なんですが、hitTOはPHPで作られていてかなり技術負債が溜まっている状態でした。そこで新しくリニューアル版を作るにあたって、どんどん成長しているプロダクトということもあり今後のスケールを見越してPHPの採用はせず、保守性やパフォーマンスに優れたScalaを採用しました。

と、書きましたがメンバーにScalaが好きだったり得意なメンバーが多かったことが使っている大きな理由ですw

f:id:HiTTO:20211007105120p:plain:w100

技術面・採用面のメリット・デメリットはどんな言語にもありますが、メンバーが書いてて楽しいというのはすごく大事なんじゃないかと思います。そして母数は少ないものの特徴的で熱狂的なファンが多いのもScalaの特徴かと思うので、楽しいとかチャレンジしたいとかそういう人が集まって、いいプロダクトができたらいいなぁと思います。Scala楽しいヨ!

フレームワーク

PlayFrameworkを使っていますが、GraphQLを使っているのでリクエストを受けた後はSangriaというライブラリで処理される感じになってます。SangriaはScalaで書いたGraphQLのスキーマがそのままGraphQLのスキーマファイルとして出力されるのでメンテナンスが楽だったり、色々と型安全になったりマクロが用意してあったりと、よくできているライブラリで便利に使わせてもらっています。

GraphQLを採用した理由としては、フロントをSPAで作っていて1ページでたくさんのAPIを叩かなくて済むというのが大きいんですが必要なものだけ取得できるしグラフになってて実際のとこ便利だなぁと思っています。

f:id:HiTTO:20211007105346p:plain:w100

アーキテクチャ

CleanArchitectureの考え方で作っています。どこで何を書くのか、そこの責務は何か、など大枠の層を決めて流れを図にして整理しながら作っています。 例えばInfrastructureの層ではDBやAPIなど外へアクセスを担当するだったり、UseCaseの層ではEntityやInfrastructureのインターフェイスなどを呼び出して処理の流れを書くといった決めにしています。

(↓はざっくり流れの図です)

f:id:HiTTO:20211007102310p:plain

CleanArchitectureの採用理由ですが、別に整理できればオニオンでなんでもよかったんですがボブおじさんの本があるので参考にするものがあっていいかもなぁというのもありました。

単体テスト

ScalaTestで書いていて、CleanArchitectureの各層の責務に合った内容のテストを書いています。

例えばInfrastructureの層であれば実際にSQLを実行してのテストを書いたり、UseCaseの層であれば処理の流れが期待したものかをテストしたりしています。

各層で閉じたテストができるようにDIしている部分をモックに差し替えて、その層の責務じゃない部分はテストしないでいいようにしています。

CI/CD

CIはCircleCIで行っていて、単体テストやscalafmt/scalafixでのフォーマットチェック、GraphQLのスキーマ生成などを行っています。

CDはPullRequestベースでdevelopやmasterにマージした時デプロイが走る形になっています。インフラの話で詳しく書くことになると思いますが、ECRやECSを使っているのでデプロイでその辺りにも更新がかかります。

外部サービス

DataDog

アプリケーションのログなどはDataDogに流してみれるようにしてあります。通知や検索など多機能で便利です。

SendGrid

サービスの特性上、多機能なメール送信サービスが必要だったのでSendGridを使っています。例えば一度に複数件送信できる機能だったり、メール開封イベントのリクエストを投げてくれる機能を使っています。

リファクタリング

いつの間にか肥大化したり冗長になってたりとか、アーキテクチャの構成ちょっと変えた方がいいかもみたいなことはありがちだと思いますが、スプリントに改善のタスクを積むので少しずつよくなっていく運用になっています。

おわりに

以上ざっくりHiTTOのバックエンドで使われている技術の紹介でした。 常に改善していこうというスタンスなので、新しいものを取り入れたり既存のリファクタリングをしたりして、いいプロダクトが作れたらいいなと思っています!

ちなみにフロントエンドの技術はこちらです。興味があればぜひご覧ください〜。

というわけでHiTTOを一緒に作っていく仲間を募集しています!(宣伝🌟)

offers.jp

offers.jp

offers.jp

jobs.forkwell.com