Classi開発者ブログ (original) (raw)

Classi で提供している学習トレーニング機能を裏で支えているコンテンツ管理システム ( 以下、内部 CMS ) では、バックエンドに GraphQL を採用しています。 この GraphQL は Classi 内の様々なシステムで広く利用されています。

tech.classi.jp

内部 CMS の開発チームでは、この GraphQL スキーマの API ドキュメントを自動生成して GitHub Pages でホスティングしています
GitHub Pages は GitHub Actions ワークフローを作成するだけで簡単に静的サイトをデプロイすることができます。また、 Classi では GitHub Enterprise Cloud を利用しており GitHub Pages のアクセス範囲を制限することもできるため、社内向けドキュメントも安全にホスティングすることが可能です。

docs.github.com

GitHub Pages でホスティングすることで社内メンバーはいつでも簡単に API ドキュメントを参照できるため、チーム内外を問わず GraphQL スキーマに基づいた議論やコミュニケーションを円滑にする上で非常に役に立っています。

API ドキュメントの自動生成には Magidoc を使用しています。

この記事では Magidoc を利用して GraphQL スキーマから API ドキュメントを自動生成し、生成したドキュメントを GitHub Pages でホスティングする方法を紹介します。

Magidoc について

Magidoc は GraphQL スキーマから API ドキュメントを自動生成するためのツールです。API ドキュメントは HTML 形式で生成されます。

実際にどのようなドキュメントが生成されるのかは以下のサイトで確認できます。

Magidoc の使い方

1. インストール

Magidoc CLI は npm パッケージとして提供されているため、 npm コマンドでインストールできます。

$ npm install -g @magidoc/cli@latest

インストールが完了すると magidoc コマンドが実行できるようになります。

$ magidoc --help Usage: Magidoc [options] [command]

Magidoc CLI helps you build beautiful and fully customizable GraphQL static documentation websites in seconds.

Options: -V, --version output the version number -h, --help display help for command

Commands: generate [options] Generates a full static website using a template. Using this command gives you access to a limited range of customization. If you wish to customize the website further than what is available, use the eject command. preview [options] Preview the documentation website generated with the generate generate command. dev [options] Starts a development server with hot-reload as changes occur to watched files. eject [options] Ejects from Magidoc basic template configuration, to allow for full customization of the template. This will initialize a folder from a template of your choice, which can then be modified however you wish. help [command] display help for command

もちろん npx コマンドで実行することもできます。

$ npx @magidoc/cli@latest --help

2. 設定ファイルを作成する

Magidoc の設定は magidoc.mjs というファイルに記述します。

// magidoc.mjs export default { introspection: { type: "sdl", // スキーマをファイルから読み込む場合は "sdl" を指定する paths: ["schemas/**/*.graphqls"], // スキーマファイルのパスを指定する }, website: { // テンプレートを指定する // v6.1.0 時点でデフォルトで用意されてるのは "carbon-multi-page" のみ template: "carbon-multi-page",

// Web サイトのルートパスを指定する
// Public な GitHub Pages の URL は https://<オーナー名>.github.io/<リポジトリ名>/ のようになるので、
// ここには "/<リポジトリ名>" を指定する必要がある
siteRoot: "/example-repository",

}, };

他にも様々な設定が用意されています。以下はその一例です。

詳細については公式ドキュメントをご参照ください。

magidoc.js.org

3. API ドキュメントを生成する

magidoc generate コマンドで API ドキュメントを生成することができます。

$ magidoc generate

$ npx @magidoc/cli@latest generate

生成されたドキュメントは ./docs/ ディレクトリに出力されます。 ( 出力先は設定ファイルで変更可能 )

docs/ ├─ index.html ├─ _app/ │ └─ ... ├─ introduction/ │ └─ ... ├─ mutations/ │ └─ ... ├─ queries/ │ └─ ... └─ types/ └─ ...

生成されたドキュメントをローカルで確認するには magidoc preview コマンドを実行します。サーバーが起動し、 http://localhost:4000 からドキュメントを閲覧することができます。

$ magidoc preview

$ npx @magidoc/cli@latest preview

localhost:4000

生成したドキュメントを GitHub Pages にデプロイする

GitHub Pages にデプロイするには以下の 2 通りの方法がありますが、今回は GitHub Actions からデプロイする方法を紹介します。

それぞれの方法の詳細については公式ドキュメントをご参照ください。

docs.github.com

1. GitHub リポジトリの設定

GitHub リポジトリの Settings をクリックして設定画面に遷移します。

左サイドメニューから Pages をクリックして、 SourceGitHub Actions に設定します。

2. GitHub Actions ワークフローを作成する

GitHub Actions から GitHub Pages をデプロイするには以下の 2 つのアクションを利用します。

ワークフローは以下のようになります。この例では、 main ブランチに変更が push されるたびに GraphQL API ドキュメントを生成して GitHub Pages にデプロイします。

name: Publish API Docs

on: push: branches: - main

jobs: publish-api-docs: runs-on: ubuntu-latest permissions: contents: read

  pages: write
  id-token: write
environment:
  name: github-pages
  url: ${{ steps.deployment.outputs.page_url }}
steps:
 
  - uses: actions/checkout@v4
  - uses: actions/setup-node@v4
    with:
      node-version: 20

 
  - run: npx @magidoc/cli@latest generate

 
  - uses: actions/upload-pages-artifact@v3
    with:
      path: ./docs
  - uses: actions/deploy-pages@v4
    id: deployment

GitHub Pages へのデプロイが完了すると https://<OWNER>.github.io/<REPOSITORY> から API ドキュメントを閲覧できるようになります。


冒頭で紹介した内部 CMS の GraphQL API ドキュメントのデプロイでは、実際には以下のようなワークフローを作成しています。内部 CMS の GraphQL スキーマのリリースには googleapis/release-please-action を利用しているので、 release_created output を参照することで「新しいバージョンがリリースされるたびに API ドキュメントを更新する」ということを実現しています。

tech.classi.jp

name: Release Please

on: push: branches: - main

jobs: release-please: runs-on: ubuntu-latest outputs: release_created: ${{ steps.release-please.outputs.release_created }} steps:

  - uses: googleapis/release-please-action@v4
    id: release-please
    with:
      release-type: node

publish-api-docs: needs: - release-please

if: ${{ needs.release-please.outputs.release_created == 'true' }}

まとめ

リッチな API ドキュメントがあるとテンションが上がります。
よりイケてるドキュメントにするために設計や説明文もしっかり書こうという気持ちになりますね。モチベーション大事。

id:aerealです。Goの話をします。

sql.Openとsql.OpenDBの違い

GoでRDBMSなどに繋ぐ際にはふつうdatabase/sqlを使います。ORMを使う場合でも内部的にはこのパッケージに依存していることがほとんどです。

特定のデータベースに対して接続を確立したりクエリを実行する実装をドライバーと呼び、契約によって定められたインターフェースを実装したドライバーを利用者がdatabase/sqlに渡すことで、拡張性と独立性を実現しています。

sql.DBはa database handle representing a pool of zero or more underlying connections.と説明されており、いわゆるアプリケーションレベルのコネクションプールを表現した構造体といってよいでしょう。 Perl monger的にはsql.DBはDBIx::Handlerに相当するものというとわかりやすいでしょう。

sql.DBを得る方法は2つあり、ひとつはsql.Open, もうひとつはsql.OpenDBです。 sql.OpenDBはGo 1.10で追加されたAPIでより新しいです。

新しいAPIが導入された動機は以下の通りです。

Drivers that want to construct a sql.DB for their clients can now implement the Connector interface and call the new sql.OpenDB function, instead of needing to encode all configuration into a string passed to sql.Open.

Drivers that want to parse the configuration string only once per sql.DB instead of once per sql.Conn, or that want access to each sql.Conn’s underlying context, can make their Driver implementations also implement DriverContext’s new OpenConnector method.

sql.Openはdata source name (以下、単にDSN) と呼ばれるDBへ接続するための情報を文字列として受け取ります。

DBへ接続する際は、ふつうドライバーが文字列から構造体へ変換してたとえば接続先のホストやポートなどを抽出して使用します。

この変換処理は新しい接続を確立する度に行われますが非効率です。

加えて単純な文字列であるDSNを用いる場合、関数やポインタなどリッチな言語表現が使えません。

たとえばイベントに応じて呼ばれるコールバック関数を受け取りたいという場合、標準のdatabase/sqlのAPIだけでは相互運用できず不便です。

こうした主に2つの問題を解決するために新しいsql.OpenDBというインターフェースが導入されました。

ドライバーごとの接続情報の事情

ここでは主にgo-sql-driver/mysqljackc/pgxの話をします。

まずこれらドライバーの接続設定を表す構造体は以下の通りです:

mysqlのほうは比較的単純ですがpgxはOnNoticeやOnPgErrorなど関数として持つフィールドが散見されます。

関数や構造体 (のポインタ) をとるフィールドを見ているとDSNをパースして得られる値と同等の値をアプリケーション内で組み立てられるのかが気になってきます。 つまりデフォルト値が公開されているのか、それともコピペしなければいけないのかということです。

pgxのDSNをパースする処理を見ると、BuildFrontendやBuildContextWatcherHandlerなどの関数のデフォルト実装そのものは公開されていませんが、公開メンバのみを使っているのでコピペすることは可能そうです。

気になるのがTLS接続の設定を決めるconfigTLSという実装です。

これはパラメータに加えてファイルシステムに配置された証明書の状況に応じてTLS接続に用いるオプションを決めるもので、最終的にtls.Configを返すのですが、かなり込み入っていることが一目でわかります。

この複雑なロジックはlibpqのsslmodeなどのパラメータ定義に倣ったもので、利用者にとっても明確な定義が外部にあることは嬉しいことが多いのですが、このconfigTLS関数は現時点で公開されておらずコピペするほかありません。

アプリケーションにおいてTLS接続設定の決定は、これほど柔軟である必要はないでしょう。せいぜい商用環境でTLS接続を厳格な設定で用い、ローカルでは無効にする程度の設定で十分です。

しかし先に述べた関数を値にとるフィールドが少なからずあることなどを踏まえると、ライブラリのデフォルト値にせいぜいホスト名やポート番号程度を加工した程度のpgconn.Configを得るためにpgconn.ParseConfigを用いずスクラッチから組み立てる実装を作るのはかなり不合理に思えます。

まとめ

database/sqlの簡単な歴史について触れ、MySQLとPostgreSQLのドライバー実装を読み解き、「ライブラリが提供するパース関数を使うか、それとも構造体をスクラッチから作るか」の実用性について検討しました。

変換処理が明らかにボトルネックでない場合、つまり文字列ではなく構造体として設定を持ち回ることで見通しをよくすることだけが目的であれば、go-sql-driver/mysqlはsql.OpenDBに移行してよい・jackc/pgxは割に合わないので従来通りsql.Openでも構わないという評価に落ち着きました。

MySQLとPostgreSQL両方に繋ぐアプリケーションで統一感を図ろうと考えたことがきっかけですが、結果的にこれまできちんと読んでこなかったドライバーの実装を読み進められました。

go-sql-driver/mysqlはフラットなパッケージ構成で極めてシンプルな実装でそれが設定構造体にも表れており、対してjackc/pgxはもともとlib/pqに欠けていた機能を補完するという目的があったためか現時点でも十分にリッチでかつ拡張性も見据えた実装になっています。

最後に、どちらも活発に開発されているライブラリなので記事の記述と実装に乖離がある場合、最新の実装が常に正しい点をご留意ください。

こんにちは、ソフトウェアエンジニアの中村 ( id:kozy4324 ) です。

2024年10月25日 (金) から 26日 (土) に、東京の有明セントラルタワーホール & カンファレンスで開催予定の Kaigi on Rails 2024 にて、「ActiveRecord SQLインジェクションクイズ (Rails 7.1.3.4)」というタイトルで登壇させていただくことになりました。

今回は、このテーマを選んだ背景や、登壇を通じて達成したいことについて、事前にお伝えしようと思います。

Rails アプリケーション開発におけるセキュアコーディング、できていますか?

これは自戒の念を込めた問いかけでもあります。

昨年末、私は Ruby on Rails を使った新規サービス開発プロジェクトにジョインしました。それを機に、Rails におけるセキュアコーディングを再確認したいと思い、情報収集や学習を続けてきました。

Web アプリケーションのセキュリティに関する体系的な知識・情報としては、IPA が公開している「安全なウェブサイトの作り方」や、書籍『体系的に学ぶ 安全なWebアプリケーションの作り方』が非常に参考になりました。

Rails にフォーカスした内容でいえば、Railsガイドの「Rails セキュリティガイド」は必読です。

しかし、こうした学習を進める中で、Rails のセキュアコーディングに関する体系的な情報は、まだ多く存在していないと感じました。世の中の Rails エンジニアはどのようにしてセキュアコーディングを身につけているのでしょうか?これから Rails を学ぶ人々は、どのようにしてこの重要なスキルを習得していくべきなのでしょうか?

さらに、過去の Kaigi on Rails の登壇タイトルを見ても、セキュアコーディングを題材にした発表は少ないように感じました。

そうした背景から、私が学んできた内容をまとめて発表することが、同じように興味を持って学んでいる方々にとって有益になるのではないかと考えました。また、それが自分自身の学習機会にもつながると感じ、プロポーザルを提出し、この発表の機会をいただけることになりました。

SQLインジェクションというテーマについて

SQLインジェクションは、IPAの「安全なウェブサイトの作り方」においても最初に取り上げられるような、セキュアコーディングにおいて基本的かつ重要な項目です。Rails ではいくつかのポイントを押さえることで対策できますが、その内部でどのように対策が施されているのかを掘り下げることで、興味深いトピックになると考えました。ターゲット層は Rails 初学者から中級者までを想定し、このテーマを選びました。

登壇を通じて達成したいこと

私はセキュリティのエキスパートではなく、Web セキュリティをこれからさらに学んでいきたいと考えているエンジニアの一人です。この登壇を通じて、Rails におけるセキュアコーディングについて、私自身も含めて皆さんと一緒に学んでいけたら嬉しいです。また、Rails 開発における SQLインジェクションに対する不安を少しでも払拭することができれば、幸いです。

おわりに

タイムテーブルも発表され、どちらのセッションを聴講しようか迷ってしまうものばかりで非常に楽しみですね。当日、お会いできることを楽しみにしております!

開発グループ2(通称:kobitoチーム)のチームリーダーをしている前川です。今回は、チームメンバーを中心に『ルールズ・オブ・プログラミング』という本の読書会を行いました。

『ルールズ・オブ・プログラミング』

オライリーの『ルールズ・オブ・プログラミング』紹介ページ

全世界で1,000万本に迫る実売数を誇り、日本でも累計実売数100万本を突破(2023年5月時点)した大ヒットゲーム『Ghost of Tsushima(ゴースト・オブ・ツシマ)』をはじめ、『怪盗スライ・クーパー』などで著名なゲーム制作スタジオ、Sucker Punch Productions(サッカーパンチプロダクションズ)の共同創設者であるChris Zimmermanによる、プログラミングのベストプラクティス集。

きっかけは「リファラジ」

読書会を開くきっかけは、チームメンバーlacolacoが行っているPodcast「リファクタリングとともに生きるラジオ」の#19 雑談回 『ルールズ・オブ・プログラミング』を紹介したい!を聴いたことです。自分たちのチームのルールを考えるたたき台として機能するということや、そこで解説されている「ルール1 できるだけ単純であるべきだが、単純化してはいけない」の話など、とても興味深い紹介だったので、読書会を提案し実施しました。

読書会の進め方

全体的な方針

会の進行

各回60分で進行しました。1つのルールにフォーカスし、担当者が15〜30分でそのルールの要約を発表し(本を読んでいなくても内容が伝わる程度)、その後全員でディスカッションを行います。ポイントは、ルールを単に理解するだけでなく、実務にどう適用するかを話し合うことです。

例えば、 「一般化には3つの例が必要」 というルールでは、一般化を急ぐことでコードが複雑化するリスクを議論し、シンプルで読みやすいコードの重要性について深く考えました。

印象的だったルールと成果

読書会を通じて、いくつかのルールがチームに大きな影響を与えました。振り返り会で特に印象に残ったルールを一部抜粋して紹介します。

ルール4「一般化には3つの例が必要」

読書会で最も名前が挙がったルールの1つです。チーム全体で、過剰な一般化を避け、シンプルで用途を限定したコードを書く方針が確立され、実際のプロジェクトでもその考え方が浸透しました。

ルール8「実行されていないコードは動作しない」

デッドコードに対する意識が向上し、不要なコードを見つけ次第削除するという行動が定着しました。

ルール15「雑草は抜け」

小さなリファクタリングや不要なコードの削除に対する心理的ハードルが下がり、スムーズにコードを整理する動機が共有されました。

チームでの読書会のメリット

読書会の最大のメリットは、1人で読むよりもチーム全員で議論することで、さまざまな視点が共有されることです。この読書会を通じて得た知識が、チームのコーディングスタイルに良い影響を与え、日常の開発に活かされつつあると感じています。例えば、不要な一般化を避けるという考え方は、チームの議論のなかで頻繁に出るようになりました。

振り返り会での感想(抜粋)

メンバーの感想を一部紹介します。

今後の展望

今回の読書会では、全てのルールを取り上げたわけではありませんが、最初から全てのルールを扱う予定はなかったので、残りを取り上げる回は予定していません。むしろ、チームでこの本を読書会として取り上げることの有効性が実感できたので、今後は社内外を問わず、同様の読書会が広がってほしいと願っています。このエントリーがそのきっかけになれば嬉しいです。

まとめ

『ルールズ・オブ・プログラミング』 を題材にした読書会は、チーム全体でコーディングのベストプラクティスを共有し、実務に活かすための素晴らしい機会です。興味があれば、ぜひ他のチームやプロジェクトでも試してみてください。チーム全体のコーディング文化の向上に役立つこと間違いなしです!

はじめに

こんにちは、エンジニアの id:kiryuanzu です!今回はチームで管理するRailsリポジトリ9個の CI/CD を CircleCI から GitHub Actions に移行した際の話を共有します。

概要

Classi では全社的な方針により、メインで使う CI/CDプラットフォームを CircleCI から GitHub Actions に移行することにしました。
主な理由としては、複数の CI/CD サービスを並行して利用し続けるのは運用管理・コスト管理で負担があったこと、社内の知見交換で片方に寄せた方が良いと判断したためです。

筆者が所属するチームでは当時9個のリポジトリの運用を行っていました。それらのリポジトリの CI/CD を全て置き換えることになったため、期日までに全て移行できるように中期的な計画を立てて進めました。
今回の記事では、移行の際にまず取り組んだこと、取り組みを通して得た知見について紹介したいと思います。

取り組んだこと

複数のリポジトリの CI/CD の移行を進める上で、まずは1つのリポジトリを選定し叩き台にし、チーム共通となるデプロイフローを作りました。
最初に着手するリポジトリの選定基準は、チーム内でもっともデプロイ頻度が高かったものにしました。デプロイの試行回数が多ければ、考案したデプロイフローの改善点を見つけやすいと判断したためです。

そのようにして、作成したデプロイフローについてチームからフィードバックをもらい、より効率的なデプロイフローに作り替えた上で他リポジトリの移行作業に着手するようにしました。

チーム共通で使うデプロイフローを考案する

CircleCI から GitHub Actions に移行する上で、まずはどのようなデプロイフローに作り替えるとより良い運用方法になるかを考えました。
各リポジトリの環境に多少の差異があっても先にチームで共通で使うデプロイフローを決めておけば、用意するワークフローの大部分は同様の設計で作ればよいため、より効率的に移行できます。

GitHub Actions は GitHub 関連のイベントをトリガーとして使えるため、CIrcleCI時代に比べてより柔軟にデプロイフローの設計を考えることができました。

docs.github.com

最初はチームメンバーと相談して以下のように CI(lint, テストの実行)とステージング環境のデプロイはPR作成後にコミットがプッシュされる度に、プロダクション環境のデプロイは PR がレビュアーから approve された時に実行するようにしました。

最初に考案したデプロイフロー図

しかし、チームで運用する中で、以下の問題点が見えてきました。

その問題点を踏まえて、以下のデプロイフローに作り替えました。

フィードバックを受けて修正したデプロイフロー図

主な変更点

デプロイフローの変更により不便だった点が解消され、チームメンバーからはデプロイがスムーズになって楽になったというフィードバックをもらいました。

このように、一度デプロイフローを決めた後も、不便な部分が分かってきたら柔軟に変えていくようにしました。
チームの人数やリポジトリの運用の仕方によって適したデプロイフローは変わるため、柔軟に別の種類のワークフローのトリガーやアクションを試していくのが良いでしょう。

例えば、Classi 内の他チームでも Release Please という GitHub Actions のアクションライブラリを使ってリリース自動化した例が開発者ブログの記事で紹介されています。

tech.classi.jp

タスクのチェックリスト作成・見積もりを立てる

チーム共通のデプロイフローを決定後、実際に対象リポジトリの移行作業を1つずつ対応する作業に移りました。
やり方としては、タスクのチェックリストを作成し1PRごとにどの順番でワークフロー・ジョブを追加する計画を立てて実際にPRを作るようにしました。

最初のリポジトリの作業では完了まで2週間前後かかりましたが、最終的に1リポジトリごとで3〜5日で移行できるようになりました。

実際に作成したタスクのチェックリストの一部

早く終えられるようになった理由としては、各リポジトリの環境の差異もありデプロイに必要なビルドの手順が違う部分がありつつも、大部分のワークフローの実装を共通で利用することで見積もりが立てやすくなったためだと捉えています。
CI/CD の構築が未経験のチームメンバーにも1つのリポジトリの作業にチャレンジしてもらい、前述したワークフローを通して作業を進めてもらいました。CI/CD の作り方を学ぶ良い機会になりました。

これは筆者の個人的な感覚かもしれませんが、CI/CD の移行作業は追加するワークフローやジョブごとでタスクを分割できるため、見積もりに関しては他のアプリケーション開発のタスクよりもイメージしやすい作業だと感じました。

また、CI/CD を考える上では対象のリポジトリのインフラ・アプリケーション構成を再確認してデプロイフローを組み立てていくことになるため、リポジトリに対する最低限の技術理解も求められます。
上記の点により、チームのオンボーディング向けのタスクとして CI/CD に触れてもらうのはとても良いと考えています。

筆者自身、この CI/CD 移行作業は半年間の休職から明けて初めて取り組んだ開発でした。
復帰後にまずこのタスクから取り組めたことは良いリハビリになったと感じています。

まとめ

このような流れで進めていき、9個あったリポジトリの CI/CD をCircleCI からGitHub Actions の移行作業を予定していた期間までに完了できました。

また、本記事の中では紹介しませんでしたが、GitHub Actions を触る中で細かい詰まり所がいくつかありそれらの知見を社内の esa で共有する活動もしました。

kiryuanzu.hatenablog.com

これらの経験を通して GitHub Actions や CI/CD周辺の技術に対して少し自信を持てるようになりました。チーム内で CI/CD周りの困り事があれば率先して動くようにし、チームに貢献する範囲を広げることができました。

移行自体は完了しましたが、より効率的なデプロイフロー・自動化の設計やCIのコスト削減などまだまだ改良できるポイントが多い領域です。効率化を進めることが顧客へ届けるリードタイムの短縮・有事の際のMTTR短縮にも繋がります。

今後も CI/CD 周辺の知見を増やし実践することで、社内の開発サイクルの効率化に繋げていきたいです。

こんにちは。tetoruでUXデザイナーをしている原田です。 tetoruチームでは年数回、チームビルディングとして関係者全員参加のワークショップを開催しています。今回はその取り組みを具体例を交えてご紹介します。

tetoruのチームビルディングとは

このチームビルディングは2時間のワーク/3ヶ月程度に1回開催/メンバー全員参加(ただし商談などは優先)/普段の業務から離れ、異なる視点でtetoruを捉えるための対話の時間として開催されています。tetoruのチームメンバーはセールス/マーケ/CS/デザイナー/エンジニア/QAなどがひとつのチーム(※)としてまとまっており、業務内容によってはよく喋る人と全然関わりのない人が発生してしまい、ひとつの事業を一緒に行なっていても分断が発生してしまうことを解消するために行っています。チームビルディングを通して交流する時間を意識的に作ることによってメンバーの人となりを知ることや、他職種向けの業務相談や質問しやすい空気作りを醸成しています。ワーク内容はtetoruに関連することをその時に合わせオーダーメイドで組み立て、原田がファシリテーションをしています。

(※チームメンバーはこちらをご確認ください)

これまでのチームビルディング

過去2年半のワーク内容はこちらです。内容としては事業戦略に対するバリューの言語化/共通化のような真面目な内容もあれば、この1年の年表をみんなで作るといった少しくだけた内容もあったりします。

過去の施策一覧

具体例「大事な価値観ワークショップ」の紹介

直近では8月に「Wevox Values Cardで仕事における大事にしたい価値観を整理しよう」というテーマでチームビルディングを行いました。 これはtetoruチームでは定期的に取り上げている題材であり、今回で4回目です。

get.wevox.io

Wevox Values Cardとはテーマを決め、カードが5枚配られた状態からスタート。トランプのように山札から1枚カードを選び、テーマとは一番遠いカードを1枚ずつ捨てていき、最終的に手元に残った5枚のカードが自分を表す価値観になるというものになります。Wevox Values Cardは実物のカードもありますがオンライン版もあります。tetoruチームは地方在住のメンバーもいるので毎回オンラインで行っています。

ここからは事前準備と本番当日、実施後にわけてトピックごとにご紹介します。

事前準備

①偏りがないチーム分け

メンバーは20名ほどいるので、ファシリテーターが事前に4チーム分のチーム分けを行います。チーム分けは入社年月や職能(セールス/マーケ/CS/デザイナー/エンジニア/QAなど)を考慮した上で、偏りがなくフラットな状態になるように割り振りをしています。またチーム分けの際にチームリーダーも設定し、チーム内でうまく時間内にワークができるような配慮もしています。

②当日調整もできるようなタイムスケジュール

毎回のワークは2時間と決まっているので、事前に大体のタイムスケジュールを作成しています。目安の時間を事前に整理しておくことで当日は時間調整なども行うことができ、想定時間をイメージしながら当日の盛り上がりによって流れを調整しています。

③トラブルも想定した連絡用Slackの準備

当日は回線がつながらないといったトラブルに見舞われる可能性もあります。そういった事態に備えてSlackに専用の連絡用スレッドを作成しておきます。スレッド内にはチームメンバーをメンションしておき、ワーク中のオンラインの拠り所を誘導しています。

チームごとの連絡用スレッド

本番当日

④キャプチャを積極的に活用する

Wevox Values Cardのゲームの特徴として「捨てる」行為があります。 ワークは手元にある価値観カードから一番遠い価値観カードを毎回捨てていきます。時々「それ捨てちゃうの?!」というものに遭遇することもあります。もしそういうクスッと笑えるものに出会えたらSlackに投稿するようお願いしていました。

これは弊社の取締役が「責任感」を捨てた時のもの

⑤自分の言葉で大事な価値観を話してもらう

価値観ワークを終えると個人ごとに5つの価値観のキャプチャを生成することができるので、そのキャプチャを共有してもらいます。

5つの価値観をみんなで共有

自分の言葉でなぜその5つの価値観を選んだのかを1-2分で話してもらいます。それをまわりのメンバーは聞き、リアクションやコメントを残してもらいます。同じ価値観を選んだとしてもその理由はひとりひとり異なりますし、別チームで同じ価値観を選んでいると親近感も生まれやすいです。カードを捨てた際のキャプチャがある場合は、なぜその価値観を捨てたのかより説明しやすい状況を生み出すことも可能です。

実施後

⑥2回目以降は自分の価値観の変化を楽しめる

このワークは同じ内容を定期的に実施しているため、前回の価値観を比較することも可能なメンバーもいます。実際に私も計4回行っており、自分の価値観の変化を楽しむこともできます。こうやって並べてみると自分がどういうことを大事にしているのか、変わらないものと変わっているものが整理でき、自己分析に役立てることもできます。

過去4回分の価値観の変化

⑦メンバーの人となりが見える

5つの価値観は自分の言葉で話してもらうので、とてもダイレクトにその人のことを知れる機会につながります。実際に過去の例ではCSメンバーがユーザーからの問い合わせでエンジニアメンバーに声をかけやすくなったということもありました。

感想コメント

おわりに

こういった自分が大事にしたい価値観を周りの人にしゃべる機会はなかなかありません。 そのため、tetoruチームではチームビルディングという施策を通して自分の考えとメンバーの考えを共有しあう場を意図的に生み出し、今後の業務に役立てられるようにしています。 もし、通常の業務以外の場ですこしカジュアルな時間を作ってメンバーと喋る機会を設けたい人がいらっしゃいましたら、ぜひ活用いただければと思います。

こんにちは。4月にClassiへ新卒で入社した伊森です。

私は4月から8月上旬までの約4ヶ月、Classiのエンジニアとして働くための新卒研修を受けてきました。 今回はその研修期間を経て、大まかな内容の振り返りや身についた考え方を紹介していきます。

入社前の状態

大学生時代はPythonを使用した画像処理を主に勉強しており、これまでWeb上で動くものを開発する世界に踏み込んだことはほとんどありませんでした。 そのため、Webの基本的な概念であるHTMLなどはぼんやりとした理解に留まっており「触ったことはあるがそれでゼロから何かを作成したことはない」状態でした。

具体的なことを何も知らなかったのでWebに関連する技術はとにかくなんでもやってみたく、そのため入社前面談では「フロントエンドもバックエンドもとにかくやってみたい!」ということを伝えていました。 2024年度の新卒入社は私1人だったのもあり、その意向を汲んで今年度の研修カリキュラムを作成していただきました。

研修内容の概要

以下が研修内容となっています。研修項目を完了することで、Webサイト上で動作する最低限のWebアプリケーションが構築できるようになっています。

4月にはWebアプリケーションエンジニアの基本的な知識としてGit&GitHubの使い方やフロントエンドに関する知識を身につけ、5, 6月にはバックエンドを含めたより専門的な知識をフィヨルドブートキャンプを筆頭に学んでいきます。そして、7月には身につけた知識をもとにWebサイト上で動作するアプリケーションを構築する万葉カリキュラムを行います。

4月

5・6月

7・8月上旬

上記の研修の中でも、今年度初の試みとなる研修2つと、その経験が特に生きたと感じられた研修1つの計3つを紹介していきます。

AWS研修

Classiの従来のAWS研修ではUdemyという動画教材を参考に、実際にインフラを構築する研修をされていました。 今年は趣向を変え、昨年10月に日本語化の対応されたAWS Cloud Quest: Cloud PractitionerでAWSの基本的な概念を学びました。

以下ではAWS Cloud Questについて簡単に紹介していきます。

AWS Cloud Questとはゲーム形式でAWSのサービスについて学ぶことができる教材です。ゲームのコンセプトとしては、街で困っている人をAWSのサービスを通して解決していき、目標のクエストを全て達成するとゲームクリア!となっています。

Cloud Practitionerコースでは12個のクエストが用意されています。内容としては、S3, EC2, RDSなどのAWSの基本的サービスについての紹介から、アクセス集中や天災に対する耐障害性などのAWSの利点について学ぶことができます。

各クエストは学習・計画・実践・DIYの4つに分かれています。学習・計画ではクエストを達成するための前提知識の紹介とクエストのざっくりとした流れが紹介されます。実践・DIYでは実際にAWSコンソール上で手を動かしていきます。実戦ではこれからやることが順番に示されるのでその通りに手を動かし、DIYでは実践の内容を踏まえたお題が出され、クリアするとクエストが達成となります。

以上を踏まえ、AWS Cloud Questを用いた研修の良かったところ、逆にここは物足りなかった…と思ったところについて紹介していきます。

良かったところ

物足りなかったところ


AWS Cloud Questの強みは何よりも環境構築をしてくれることです。AWS全くわからない…という人にとっては手軽にサービスに触れるための環境が用意されているのはとても初心者に優しい仕様です。 一方で、AWS Cloud Quest: Cloud Practitionerでは一つのWebアプリケーションを作成する際のAWSのサービス同士の連携方法は学べませんでした。サービスの全体を知るにはAWS Cloud Quest外のドキュメントなどを読む必要があります。 総括としては、Cloud Practitionerコースは基本的なサービスの学習ができるので、AWSに対する知識を0から1にするには非常に優れた教材です。今回こちらで学習させていただいて、大きく知識を身につけることができました。

そして、AWS研修の最後には学んだことを発表する会を設けていただきました。学んだAWSのサービスの網羅図を作成し、多くの方に見ていただきました。

発表の際に作成した網羅図 (当時のまま) です。改めて見ていると当時指摘いただいたことがわかったり、例えばルーターはネットワークのトラフィック処理をするサービスであって、アクセス許可を制御するのはルートテーブルじゃないか?などの認識が間違っていた点を発見したりして味わい深いです。

AWS研修のまとめとして作成した図

5日間のAWS研修でしたが、始める前は知識ゼロだったことを考えると、AWS Cloud Questを通じてAWSのサービスに親しみを持つことができました。ぜひAWS未経験の方にやっていただきたいです。

QA研修

こちらも今年度から初の試みの研修となっています。研修内容についてはQAチームメンバーの方が記事を作成されているので、より詳しい研修の目的はそちらの記事をご覧ください。

私からはQA研修前後のQAに対する意識の違いについて述べていきます。 研修前の状態を正直に申し上げると、QAという単語自体が何を意味する言葉なのか知りませんでした。Question Answer…?という状態です。 その状態から始まった研修でしたが、QAとは?という講義から始まりClassiにおけるQAの体制を紹介していただき、日々の業務の流れやテスト項目の作成方法を学んでいく形式の研修はとても理解しやすかったです。

印象深かった研修内容は二つありました。それぞれ順に紹介します。

実際に手を動かすテスト項目の作成課題

この研修では、「macOS標準のリマインダーアプリに対してテスト項目を作成するなら?」というお題で、実際の業務で使われているテスト観点表を利用してテスト項目の作成を行いました。

この研修の良かった点は二つあります。 一つ目に、初日の段階では観点表の使い方を軽く紹介するだけに留められたことです。最初は手本を見ずに一人で考えてテスト項目を作成しました。こうすることで、翌日にQAメンバーの方が作成された観点表と比べると改善点が浮き彫りになるのが非常に面白かったです。

二つ目に、受けたフィードバックや考えたことを翌日の課題に反映できたことです。 この課題は計4日間実施され、前半は単体テストを、後半は組み合わせテストの観点表を作成しました。この形式にしていただくことで、前日作ってきた課題の反省点をすぐ翌日の課題に反映させることができました。 それによってフィードバックを受けてすぐにやり直すことができるスピード感が生まれ、さらにQAチームの方が作成された観点表に私が作成した観点表が近づいていくのは成長を実感しやすい仕組みでした。

「品質が高い」とはどの状態を指す言葉?というディスカッション

ここでは、QAチームの方が日々考えている「品質が高いこととは何をもって定義されるか?」を一緒に考えていきました。最初に品質の種類について紹介していただき、障害を起こさないためには?品質の責任の所在は?などを一緒に考えていく時間をとっていただきました。

このディスカッションを通じて、今まで私が考えていた「品質が高い」というのは、ユーザー目線に限定されていたことに気づきました。具体的には、「この機能が揃っている!」や「応答が早い!」などの視点しか考えられていなかったのです。

QAチームの方からご回答いただいた「品質を高める」ために実践されていることとしては以下の点がありました。

この経験から、外部的な品質に対する視点だけではなく内部的な品質を評価する視点が増えたと感じています。

総括して、QAチームの業務について知る研修はソフトウェアエンジニアとして働く上で非常に重要でした。今回学んだことを活かして、テストの観点をQAメンバーの立場になって考えたり、製品の品質についてこれからも考えていきたいです。

万葉カリキュラム

オリジナルのカリキュラムは以下になります。

この研修はWeb上で動くアプリケーションを作成することをテーマにした、Classiの新卒研修では恒例となる研修です。今年はフィヨルドブートキャンプでプログラミングの技術について深く学ばせていただいたので、万葉カリキュラムではアプリケーションの機能面を充実させることよりもWeb上での実装を重視した研修となりました。

Web上で動くアプリケーションを作成するのは初めての経験だったため、Dockerの環境構築やCIを活用した開発もこの研修を通して学びました。最初は設定ファイルの書き方がわからず非常に苦戦しました。わからないことは尽きなかったため、他の人に対して質問をする力がつきました。また、今やっていることを発言しながら作業するWorking Out Loudの精神が育まれたと感じています。

また、アプリケーションを作成する際に古い書き方になっていないか?わかりにくい書き方になっていない?などをGitHubのPRでレビューしてもらうことで、事前に気をつけるべき点を意識するようになりました。以前はできなかった公式ドキュメントを参照する力も養われ、アドバイスをいただく際に信頼できる情報源を知ることができました。

この研修では、 開発と単体テストを同時に行うことを実践していました。この際にQA研修で作成したテスト観点表が役立ちました。具体的には、テスト項目を考えるときやテストの網羅性を検討する際に自然とテスト観点表が思い浮かぶようになり、考えるための土台になったと感じています。

最後にAWSへ構築した環境へデプロイを行いました。最初に構成図を作成し、それをもとに手順書とサービス構築を行いました。作成した構成図は下の通りとなります。

万葉カリキュラムのアプリケーションの構築環境を表す図

デプロイの際にはAWS研修でサービスについて学んだことでAWSに触れるハードルが大きく下がったように思います。GUIの画面やサービス構築方法を知っていたのはこの時の作業で非常に役に立ちました。

一方、AWS研修ではわからないことも多くありました。今回の実装はEC2インスタンスやRDSが1つしか存在しておらず、環境として特殊だったこともありますが、例えば「WAFのルールを適用させるためにALBを使う必要がある。ALBの環境構築には最低二つ以上のAZに分かれたサブネットが必要になる。」という所で複数のサブネットを用意していなかったためにつまづきました。

また、Rubyの環境構築の際に無料利用枠のt2.microインスタンスではCPU使用率が100%になって環境構築ができないことがありました。結果的にそれぞれのインスタンスのCPU性能などを知る良い機会になりましたが、この辺りでうまくいかずに苦労しました。

それでもデプロイが完了し、作成したアプリケーションがWeb上で動いているのを見るととても達成感が得られました。同じことをする上での今後の自信に繋がりましたし、ここまでの成果が4ヶ月間の集大成となると感じられるように作られている研修プログラムが非常に良かったです。

研修プログラム以外にも学んだこと

研修期間中にここが良かった!見習いたい!と思ったことを書いていきます。

良かった点の一つ目として、新卒だからと言って良い意味で手加減をされなかったことです。もちろん細やかな誘導はしていただいていたのですが、これもできるといいねという発展課題の提示や、ここは○○が理由で間違っているという指摘は妥協せずにしていただきました。細かい助言や指摘を受けることで関連知識を身につける機会が必然的に増えましたし、いきなり答えが提示されなかったことで問題解決する力を養えたように思います。

また、私が研修で気づいたことや知ったことを共有すると、メンターの方も知らなかったやり方や技術だったことがありました。そんな時にもメンターの方は素直に知らないと言って新しい知識を取り入れられたり、一緒に学んでいこうという姿勢を見せてくれました。この学びに対する姿勢はClassiのバリューにもあることですが、見習っていかなければと感じさせてくれました。

まとめ

Classiの新卒研修はフルサイクルエンジニアを目指す上でとても理にかなった研修プログラムでした。Git&GitHubの使い方やフロントエンド研修から始まり、フィヨルドブートキャンプやAWS、QA研修で細かな技術を学び、万葉カリキュラムではデプロイをしてWebでアプリケーションを動かせるまでになりました。スポットで開催していただいたそーだい塾や日々のやりとりを経て、エンジニアとして働くための心構えを身につけていきました。

フルサイクルエンジニアを目指す研修は私が入社前からやりたかったことです。この研修を通じて、Webアプリケーションについてほぼ何もわからなかった私が、ここまでできるようになったことにとても満足しており、エンジニアとして大きく成長できました。今後は実際の業務で恩返しや価値の提供をしていけるように頑張っていく所存です。

読んでいただきありがとうございました!