for Startups Tech blog

このブログのデザインを刷新しました。(2023/12/26)

GithubActions未経験者がcreateトリガーでブランチのフィルタ条件を追加してみた話

こんにちは、2022年4月にフォースタートアップスにジョインしたエンジニアの八巻(@hachimaki37)と申します。主に社内向けプロダクト「タレントエージェンシー支援システム(SFA/CRM)」のシステム開発を担当しております。

今回は初めてGithubActionsの改修チケットに関わることになり、途中ヒイヒイ言いながらも試行錯誤して解決に至った話について書いていければと思います。

本題に入る前に、まずは「GithubActionsとは?」と「GithubActionsの導入経緯について」簡単に述べていきたいと思います。

GithubActionsとは?

GithubActionsはGithubが2019年に出したCI/CDサービスです。

GitHub Actionsを使用すると、ワールドクラスのCI / CDですべてのソフトウェアワークフローを簡単に自動化できます。 GitHubから直接コードをビルド、テスト、デプロイでき、コードレビュー、ブランチ管理、問題のトリアージを希望どおりに機能させます。

引用元:https://github.co.jp/features/actions

当社の導入経緯について

弊社のユースケースですとGithubActionsの方にコストメリットがあることがわかったため「コスト削減」を目的にCircleCIからGithubActionsへ移行しました。

導入されたがこんな問題があった

当社の場合、pushトリガー + ブランチのフィルタ条件を用いて発火条件を制御しております。

サンプルコード

name: staging Build and Deploy

on:
  push:
    branches:
      - staging_axx**
      - staging_bxx**
      - staging_cxx**

※サンプルコードをベースに以下話を進めています

1. Github上からブランチを作成するとGithubActionsが発火しない

pushを発火条件としているため、Github上でのブランチ作成(=pushなくGithub上にブランチができあがる)がこの条件にヒットせず、発火されない

2. ブランチのpush順序をミスるとGithubActionsが発火されない

▶︎正しい順序

  1. ローカルPC上で、作業用ブランチをmasterから作成する(feature/hogehoge)
  2. ローカルPC上で、stagingブランチを作業用ブランチから作成(staging_axx/hogehoge)しpushする
  3. 作業用ブランチ(feature/hogehoge)をpushする

▶︎誤った順序

  1. ローカルPC上で、作業用ブランチをmasterから作成する(feature/hogehoge)
  2. 上記3を先に実行する(作業用ブランチ(feature/hogehoge)をpushする)
  3. 上記2を次に実行する(ローカルPC上で、stagingブランチを作業用ブランチから作成(staging_axx/hogehoge)しpushする)

当社では、github-flowに沿った運用を採用しております。誤った順序でpushした場合、pushトリガーの条件にヒットせず、GithubActionsが発火されない

上記の体験から非常に使い勝手が悪い!!そんな声が開発メンバーから上がっておりました。

どんな状態を目指したのか

シンプルに「必要な時に、適宜GithubActionsを発火させたい」ということです。

最初のアイディアは、pushトリガーのようにブランチフィルタを使えば簡単に実現できる!と思っていたのも束の間、実現にあたってこんな問題を抱えておりました。

The create event does not support branch filter and tag filter.つまり、pushトリガーのようなブランチのフィルタ条件が、createトリガーにはサポートされていなかったのです。悲しい...

調査と試したこと

ここからヒイヒイ言いながら試行錯誤の日々が始まりました。

  • createトリガーを追加したらどのような動作が走るのかまず試してみる
  • ん?createトリガーってブランチフィルターをそもそもサポートしてないんじゃ無理くないか?と思いながら、いい解決方法ないかなぁとググりまくる。あった!→https://github.com/orgs/community/discussions/26286
  • jobs自体に条件を追加してみる
  • stepsに条件を追加してみる
  • 良い記述方法を模索する
  • 条件を追加してもSyntax errorがたくさんでる..そもそもどうやって記述すればいいのだろうか

などなど、試行錯誤をしながら進めておりました。

苦労したこと

  • 適切な箇所(jobs, stepsなど)への条件追加を模索したこと、追加したはいいもののSyntax errorが多発するなど、最初は構文理解に苦労しました。「コードを追加してみてpush」「Github上からブランチをcreateする」を繰り返すことで、徐々に理解に繋がりました。
  • 全てのブランチでjobsが発火してしまう。当たり前ですが、createトリガーを追加すると全てのブランチを作成したタイミングでjobsが発火してしまうため、頭を悩ませました。ここは記事(https://github.com/orgs/community/discussions/26286)を参考にコードを書いてみて、特定のブランチ名だと「success」「skipped」になる方法で、解決に至りました。

実装したサンプルコード

createされたブランチが、以下のブランチ名にマッチする場合に発火するよう、条件を追加しました。

name: staging Build and Deploy

on:
  push:
    branches:
      - staging_axx**
      - staging_bxx**
      - staging_cxx**
  create:

jobs:
  build:
    name: Build and Push
    runs-on: ubuntu-latest
    timeout-minutes: 30
    environment: staging

    if:
      contains( github.ref_name, 'staging_axx/' ) ||
      contains( github.ref_name, 'staging_bxx/' ) ||
      contains( github.ref_name, 'staging_cxx' )

    env:
      省略

    steps:
    - name: Checkout
      uses: actions/checkout@v2

- name: hogehoge
      run: test1
- name: foofoo
      run: test2
- name: fugafuga
      run: test3

createされたブランチがマッチした場合

ブランチ名:staging_axx/fix-hogehoge

createトリガーが発火し、GithubActionsが実行される

createされたブランチがマッチしなかった場合

ブランチ名:staging_zxx/fix-hogehoge

createトリガーが発火せず、skipされる

あとがき

正直結構な時間を費やしてしまいチームにご迷惑をおかけしてしまいましたが、リリース後、チームの方からは嬉しい嬉しいフィードバックがありました!!!

今回記述した設定ですと、対象ブランチの数が増加するとコードが​​冗長になるので、リファクタリングができないか?と考えておりますが、問題自体は無事解消に至りました。

私自身エンジニア歴は3年ほどで、今まではサーバーサイドをメインに経験を積んできました。次のステップを考えた際にフルスタック(コーディング以外も含む)に動けるエンジニアへの成長を目指し、フォースタートアップスにジョインしました。

今回初めてGithubActions周りのチケットに携わりましたが、直近はVue.jsなどフロントエンドにも関わる機会が増え、嬉しい成長痛を日々感じ業務にあたっております。

なかなか経験のないチケット着手はワクワクと不安の感情が入り混じりますが、当社では初めてのチケットの場合「good first issue」を付け、初めてでも取っ掛かりやすい環境を構築しております。

まだまだやるべきこと、やりたいことがたくさんあります。ぜひ一緒に成長していきませんか? 当社は採用大募集中です。ご興味ありましたらぜひ一度カジュアルにお話できたらと思います。

採用ページはこちら。(冒頭のTwitterにDM頂いてもOKです!)

MetabaseとRedashどっちが良い?組織の成長とデータ活用の悩み

こんにちは、エンジニアの速水です。

フォースタは22年度4Qで社員が115名となりました。その数は毎年130%成長が続き、まさに拡大中の組織です。組織が100人にもなると役割分担ができてくる一方、事業の全体感をパッとつかむのは難しくなってきます。「タレントエージェンシー支援システム(SFA/CRM)」では、スタートアップ企業、転職を希望される人、ポジションの情報を集約しているのですが、組織の拡大に伴いデータ分析を必要とするシーンも増えてきました。 以前からBIツールのRedashを導入していたのですが、運用で出てきた苦しみ、そこからのMetabaseの導入、残る悩みどころについてまとめていきます。

Redash運用で発生した問題

  • 管理できないほどにクエリが増殖した(その数なんと1400以上!)

  • 開発チームへSQLに関するヘルプが増える

ミニマム導入からスタートしたこともあり、Redashはルールがほぼない状態でした。全員が自由にクエリを作成でき、命名規則やタグ管理、アーカイブ基準は曖昧なまま、クエリはどんどん増えていきました。 それに社員が増えることで、下記状態に陥ります。

  • XXについてデータを出したい!

  • 同じような分析をしているクエリを探すが見つからない!(よくわからん!)

  • SQLを0から書くのは大変だから、とりあえず開発チームに相談しよう!

開発チームはプロダクト開発の中でデータベースもエンハンスしているので、相談を受けないわけにはいきません。とはいえ、表示項目の順番が異なるだけのクエリや、企業や職種などの絞り込みが若干異なるだけのクエリに、毎度エンジニアの工数をかけるのは苦しくなってきました。データ分析はしてもらいたい、だけどエンジニアが都度個々人の依頼を受けカスタマイズしたSQLを書くのも難しい。 エンジニアがSQL勉強会を開きデータ分析の民主化を図ったりもしましたが、定着は難しく一部の人が習得するのみにとどまりました。

Metabaseで解決できるのか

私はRedash上のクエリ分析を経て「同じデータ元で視点が異なるクエリが並列に保存されていること」を課題と定義しました。

例えば企業の採用支援のシーンにおいて、

  • 企業担当は、自分の担当企業のデータが見たい

  • マネージャーは、担当チームの企業データが見たい

という状況があります。 データ元は同じなのに、視点(絞り込み、表示項目の有無/順序)の違いによって並列にクエリが増えてしまうと、その見分けは難しくなる一方です。

MetabaseはRedashにないGUIとクエリをディレクトリ管理できることが強みです。

  • 表示項目の増減/順序の変更・絞り込み条件の指定がGUIで変更できる

  • クエリを階層型ディレクトリで管理できる

https://www.metabase.com/

簡単なデータ出力であれば、GUIでクエリを組み立てることができますし、出力におけるカラム(列)の順序変更や、カラムごとの絞り込みがマウス操作でできます。実際に検証環境で何人かに見てもらい、これならSQLを書けない自分でも操作できると感じていただけたのが導入の後押しとなりました。

項目や日付データでの絞り込みがGUIでできるのは純粋に便利

またクエリをディレクトリに入れて管理ができるので、分析軸ごとに整理することが可能です。ディレクトリごとにパーミッション(クエリを編集できる、閲覧のみ、閲覧できず)も設定できるので、ユーザグループの作成と合わせて「誰がどこを閲覧/編集できる」を明確にすることができます。

MetabaseはAWS Fargateで手動構築し、Terraformでリソース管理するようにしました。環境を作ってしまえばデータベースと接続するだけなので、短期間で進めることができました。 https://hub.docker.com/r/metabase/metabase

Metabaseで困ったこと

複雑なクエリをRehashから移行しようとすると詰まることが多いです。変数を複数設定したようなクエリは「;」でsyntax errorが出てしまったり。Temporary Tables もサポートされていません。複雑なクエリはSQLをそのままコピーするだけでは動きませんでした。 またGUIで簡単にクエリが作成できる反面、多数のJOINで出力データがとても大きくなることもあるので注意が必要です。

現状

Redashは継続利用しながらMetabaseを利用し始めた段階で、クエリの移行はもちろん、数が増えた時に混乱しないような整理を、悩みながら進めている最中です。進めていて実感しているのは、ディレクトリでクエリ管理できるようになっただけで、パッと見た時にどんなデータがあるのかわかりやすいということです。移行途中でクエリが少ないからじゃない?というツッコミはあれど、以前よりは直感的に認識できるようになったと思います。

フォースタートアップスでは共に働く仲間を募集中です。本記事を読んで興味を持っていただけましたら採用情報をご覧ください。

t_wadaさんに社内向けTDD研修を開いてもらったよ

どうも、ばやし(@bayashimura)です。

先日、和田卓人(@t_wada)さんにフォースタートアップスのエンジニア向けにTDD(テスト駆動開発)研修をやってもらったので、紹介していきます。

きっかけ

フォースタートアップスでは私が入社する前から自動テストに一定の投資をしていました。 大体の機能に関してはテストが存在し、テストを書かずにプルリクを投げると「書いてください」と返ってくる文化でもあります。 しかしプロダクトのコードが増えるに従い、テストコードも増加し、以下のような問題が発生しておりました。

  • テストの可読性が低く、テスト内容に対する認知負荷が高い
  • テストのメンテナンスコストが高くてしんどい(すぐ壊れる)
  • e2eテストを導入したがflakyで、導入したことをちょっと後悔してる

こういった課題にもやもやしたものを抱えつつそのうちどうにかしないとな、と日々を過ごしていた中、CTOから「研修やりたいんだけどなにか心当たりない?」と聞かれました。
これは!と思い和田さんのTDD研修を提案し、実現する運びとなりました。 最初は問い合わせ先もわからなかったのですが、NTTコミュニケーションズの岩瀬(iwashi86)さんに紹介していただき、見事開催の運びとなりました。岩瀬さんありがとうございます!

研修内容に関しての詳細は割愛しますが、午前中は和田さんのライブコーディングを見て、午後はみんなで実際にTDDで書きつつ、和田さんとの公開1on1をするという形式でした。
これがめちゃめちゃ良くて、研修実施後アンケートでも、満足度は最高5のところ、驚異の平均4.9。 感想も「学びしかない」「これまで受けてきた研修で一番良かった」といった感想がきており、最高といった感じです。

テスト研修後にチームに起きた変化も書いていこうと思います。

テスト駆動開発で書くメンバーがでてきた

今回のTDD研修を受け、TDDで開発する人が私を含め何人かでてきました。慣れないテスト駆動開発で、正直コードを書くスピードは遅くなったなという感覚はありますが

  • 設計に対して丁寧に向き合えるようになった
  • 一度に向き合うものを減らしたことで沼にはまらなくなった

という感覚があります。もうちょっと熟達したらもっとメリットが出てきそうな感覚です。

生みの苦しみ中

一山越えたあと

テストケースを日本語で書くようになった

今までRSpecのテストケースは英語で書いていました。 ただ母国語ではない英語で書くにあたり、細かいニュアンスを書くのが難しく

context 'if valid request' do
  it 'response success' do
  end
end

上記のようなテストケース名などがたくさんありました。

TDD研修でテストケースは仕様を表すということを学び、和田さんから 「テストケースは母国語、チームの公用語で書くのをおすすめしています」 という教えもあり、それから一部のチームではテストケースは日本語で書くようになりました。 新しく書く場合や、テストケースに変更を加える場合は基本的に日本語にしているのですが、早速地獄の蓋が開いてきてる感じがあり、最高だなといった感じです。 以上、t_wadaさんに社内向けTDD研修を開いてもらった話でした。 想像以上に良い学びを得たので、今後も有識者を招いてこういった研修をやっていきたいと思います。

うらやましいと思ったそこのあなた。弊社採用大募集中なので、お気軽にどうぞ。

採用ページはこちら

開発に至る前の要件定義で四苦八苦した話

こんにちは、エンジニアの藤田です。 普段は社内向けのプロダクト「タレントエージェンシー支援システム(SFA/CRM)」の開発をしています。

ヒューマンキャピタリストはTA(タレントエージェンシー)本部という部署に所属しており、そのTA本部が使うシステムを内製で開発しています。

エンジニアとしてジョインして約半年、ここでの開発手法はアジャイルでフラットな開発チームであり、優先順位はあるもののタスクは開発者の裁量で取って進めていくスタイルで割と自由に開発しています。

書籍『アジャイルサムライ』第2章冒頭で書かれている、

典型的なアジャイルチームには、あらかじめ決まった役割分担は存在しないッ!!

というやつですね。

普段のタスク内容は、RubyやVue.jsを使ったシステム開発、バージョンアップ対応、インフラに強いメンバーはインフラ整備など行っています。

さて、ここ最近私が取ったタスクが「POと共にユーザヒアリングに同席しながら要件定義していく」というタスクでした。

正確に言えば、当初は「とある機能追加の為のUI、設計を考える」タスクであり、平行で動いている別の改修タスクと切り離し可能な作業と考えていたのですが、進めていくうちに他の改修機能との兼ね合いを考慮する必要もでてきたり、別のタスクが自分のタスクにも影響でてきたりして、こう思ったわけです。

「もっと上流から考え直す必要があるじゃん。。」

ということで色々苦労したのですが、ユーザの声を聞けたいい経験でもあったのでその時の記録を書いていこうと思います。

TA本部のとある課題と我々開発チームのミッション

おおよその業務は社内向けシステムで運用を管理できているのですが、当然ですが組織や事業は日々変化していきます。
そのため我々が気づかないうちに新たな運用が発生し、別のツール(スプレッドシートやその他管理ツール)を現場でカスタマイズし管理していくケースが往々にして発生します。
今回要件定義したものも、詳細は書けませんがこういった業務のひとつです。

別のツールだとしても管理できているならいいじゃんとなるかもしれませんが、次のようなデメリットもいくつかあるので

  • 情報が分散されてデータが管理しにくい
  • 属人化してしまう

今回は組織として挙がった課題を解決できるよう、システムに組み込むといったものになります。

開発者の課題

要件定義をしようとしたところ、以下の課題に直面しました。

  • 何となくやりたいこと、現場の課題があることはわかったが、具体的な「システムで管理できていない運用」のところがよくわかっていない。
  • 通常の運用も具体的なところまではわかっていない部分はある。

というわけで、いきなり躓くわけです。

困った時のヒミツ道具ということで手元にある『エンジニアリング組織論への招待』を開いてみると以下のことが書かれていました。

ソフトウェアにおける実現

それは誰かの曖昧な要求からスタートし、それが具体的で明確な何かに変わっていく過程が実現で、その過程のすべてがエンジニアリングという行為です。
つまり、「曖昧さ」を減らし、「具体性・明確さ」を増やす行為が「エンジニアリングとは何か」という答えでもあるのです。

1-2. 不確実性とエンジニアリング

具体性・明確さを増やすために、まずはユーザの運用から整理しようと思い、業務フロー図を作成しました。

業務フロー図作成

ユーザヒアリングまで少し時間があったので、業務の理解と整理の為に業務フロー図の作成準備に入りました。
先にこれをやるメリットは以下が考えられます。

  • 事前に図として整理することでヒアリングの質が向上する。
  • 質問の準備ができる。
  • 図を共有しながら話もできる。

どのような運用をしているかはslackのやり取りにもヒントがあったり、開発チームでも知見のあるメンバーはいるのでそれらの情報を集め整理しながら簡単な業務フロー図を作成しました。
あくまでチームで理解の共有ができればOKなので、結果以下のような図になりました。

登場人物の関係性と下半分は時系列の処理フローのような図があったり、パターンを考えた図も含まれています。
教科書通りの業務フロー図とは異なりますが、いいのでしょうか?

いいということにしましょう!

最初の段階では仮説思考的に作成したものとなり、その後にチーム内で相談、議論したりユーザから正確な運用をヒアリングしながら図を更に肉付けしていきました。

ユーザヒアリングや業務フロー図作成の過程で以下のようなことがわかってきました。

  • ユーザの業務運用フローはどういったものか
    • どのように管理しているのか
  • 課題の具体的な特定

また、今回システム改修をする上で考慮しなければならない点も整理できるようになりました。

組織として

  • 現場の運用をシステムで管理したい。

現場として

  • スプレッドシート管理の拡張性は手放せない。
  • システム化することで業務が回りづらい状態になっては困る。

開発チームとしては上記、両方考慮しながら開発しなければなりません。

ちなみにユーザヒアリングについては1.5ヶ月の間にトータル10回程行いましたが、POは別途回数こなしてヒアリングしていました。 様々なチームや役割があるので多角的に情報収集し、その中でベストな方向性を模索しました。

システムの新機能について要件定義

システムで管理出来ていない運用フローについて明らかになってきました。次のステップはどのように既存システムに新機能を組み込むかになります。

まずはPOが大まかな仕様を考えたり、壁打ちしたり、開発チームで仕様を検討するMTGを行いました。
仕様について検討する機会が多くなったため、仕様検討MTGを増やして議論を重ねました。

チームミーティングは1回のMTGで1時間〜2時間を週に2〜4回くらい、その時の課題によって増やしたり減らしたりしました。トータルで10~20時間は仕様検討に使いました。
この段階でシステム開発における「達成すべきもの」が徐々に明確になってきました。

ワイヤーフレーム、画面遷移図、ER図を作成

また、この工程でワイヤーフレーム、画面遷移図、ER図も作成します。
ワイヤーフレームはチーム内で理解のズレが無いよう、できる限り正確な情報でデザインしていき、それを基に更に開発チーム内で議論、ユーザとも感触を伺ったりしていき、改良を重ねていきました。

この段階での正確なワイヤフレーム作成手法はその昔、ECサイト開発をしていた時に一緒に働いたWeb制作会社のやり方を真似ました。
完成品をイメージしやすいのはもちろんですが、なかなか綺麗なワイヤーフレームを見て感心したものです。
バックエンドエンジニアの自分がやっても下手で時間的コストが掛かるので簡単な対応の時はやりませんが、他人と理解のズレが発生しそうな仕様を考える時などはこのやり方を意識してます。

話を戻しますが、ここで重要になるのが、先に挙げた以下2点です。

  • この新たな機能追加が組織の課題解決になっているか、かつ
  • 現場の業務改悪になっていないか。

ユーザは既に別の管理ツールで運用しており、我々が下手な追加機能を開発しても使ってもらえません。社内のユーザとはいえ、使いたいと思う機能を提供しないと使われないのは一緒です。
開発者として使われないまま負の遺産になることは何としても阻止しなければなりません。

そこで開発チームの提案とユーザの考えの違いに差がないか、慎重に仕様を詰めていきます。
ズレていたら再度、仕様見直しと共にドキュメント修正、開発チームで議論、ユーザへ提案またはヒアリングを繰り返していきます。
週一2時間でプラニングポーカーの見積もりミーティングがあるのですが、この対応の話をしていていたら長引いて見積りができない回が何回かありました。
もちろん見積りミーティングはリスケです。

またここまで、できる限り正確なワイヤーフレームを作成してきましたが、開発中に「こっちの方がいい」はどうしても出てくるのであくまでチームの共通理解が主な目的になります。

ER図等のDB設計についても「DB設計検討作業」をチケット化し、担当者が数パターンを開発チームに提案、チームで合意を得ながら進めていきました。

ユーザーストーリー作成、タスク化

この段階まで来たらかなり「曖昧さ」が減り、「具体性・明確さ」が増えてきました。
あとはユーザーストーリー作成や作業のタスク化をし、開発メンバーでプランニングポーカーの見積もりをしていきます。

また、この段階でフロント→バックエンドの仕様を描いたシーケンス図も作成しましたが、これも開発段階で変わってくることはあるので、あくまで参考程度の情報にしています。

最後に

組織の課題解決をどのようにシステムに落とし込むかを皆で頭抱えながら進めていき、話し合いの最中や開発の段階でも新たな課題が発生しては、仕様詰め、設計、見積もりを繰り返してきましたが、無事に開発も着手でき、部分的にリリースもできてきました。

今回の開発作業では、「組織の課題を解決できるだけでなく、現場のユーザの使い勝手」の2つを考えなければならないのが大変でした。
開発チームの提案がユーザ側には通らない場面も多々あり、運用ヒアリングしていく中で「なるほど」と納得する場面が多く勉強になりました。

手段として、色々ドキュメント書いたりミーティング増やしたりしましたが、「何の為に作るか」の目的は常に意識する必要があるかなと思いました。
もちろん手段もいいやり方を吸収していきたいです。