- 同じゲームの異なるバージョンのA / Bテストの必要性
- あるゲームから別のゲームへの機能の再利用を最大化する機能
- ゲームのクライアント側に関与する開発者からの地理的距離の高い確率
さらに、将来的には、おそらくサポートタスクを含め、開発者のアウトソーシングが原因で、チームが拡張される予定でした。 これらの条件下で、実装を成功させるために、プロジェクトのバージョン管理、パッケージ化、および多数の開発ステップの標準化とともに、 継続的な配信プラクティスを導入することが決定されました。
この記事の目的は、実行されたステップ、行われた決定について話し、結果を説明することです。

インフラ
歴史的に、当社でサーバーサイドWebアプリケーションを開発するための主要言語はPHPであるため、これはツールの選択を大きく事前決定していました。
要約リスト:
- Git-バージョン管理システム
- Gitolite-リポジトリ管理
- Composer-依存関係マネージャー
- Phing-アセンブリおよびインストールスクリプト
- Jenkins-継続的統合サーバー
- phpunit 、 behat-テスト
- phploc 、 phpmd 、 pdepend 、 phpcs 、 phpcpd 、 phpcb 、 phpdox-その他のユーティリティ
分岐モデル
分岐モデルを選択する際に、「成功したGit分岐モデル」を基礎として使用しましたが、 ここでは少し違いがあります:A / Bテストは、異なる機能分岐のセットから形成された個別のリリース分岐を準備することによって決定されました。 その結果、開発ブランチの役割はリリースブランチに完全に割り当てられ、このブランチ自体は消滅しました。 そうしないと、次のリリースを作成するときに、その前にリリースされたすべての機能を含める必要がありますが、これは常に受け入れられるとは限りませんでした。
この状況は、次の例で示すことができます。 オリジナルによると、それを思い出してください:
この時点で開発するには、少なくとも、ビルドするリリースを対象とするすべての機能をマージする必要があります。 将来のリリースを対象とするすべての機能はそうではありません—リリースブランチが分岐するまで待つ必要があります。
そして、2つのリリースがすでにリリースされているとします-機能Aを備えたリリース1.0と機能AおよびBを備えたリリース2.0、および機能AおよびCを備えたリリース1.1をリリースする必要があるとします。現在、開発ブランチには機能AおよびBが既に含まれているため、次に、最も簡単な解決策は、リリースブランチ1からブランチCの機能を作成し、それをマージして戻すことです。

パッキングとバージョン管理
すべてのプロジェクトは作曲家パッケージとして設計されています。
あるプロジェクトから別のプロジェクトに機能を再利用するために、プロジェクトの一部を分離して別のパッケージに分離するために広く使用されています。
これには、1つのパッケージを別のパッケージに置き換える、1つのパッケージを2つに分割する、または1つのパッケージから別のパッケージに機能を転送することが伴います。 このような状況では、パッケージのセマンティックバージョニングがより詳細な制御に使用されました。
このタイプのバージョン管理は、コンポーザーで「〜」文字を使用してサポートされています。例:
"require": { ... "alawar/packet-post-process-server": "~1.3", ... },
プロジェクトの「アセンブリ」
PHPの場合、プロジェクトソースを実行可能コードに変換するプロセスとして、古典的な意味でのアセンブリについて話すことは不可能です。 それでも、主なタスクはすぐに使用できるソフトウェアを取得することなので、「アセンブリ」という名前は非常に正しいものです。
組み立て手順:
- composerを介した依存関係のポンピング
- データベースの移行-構造と静的データベースデータのみの更新
アセンブリを実装するために、各プロジェクトのルートには、target'amiを含むアセンブリphingスクリプトがあります。
- ビルド-ビルド手順を完了する
- runtestsおよびruntest-with-coverage-テストの構築と実行、およびメトリックの収集の両方
ほとんどのプロジェクトのアセンブリスクリプトは同じで、プロジェクトの名前(属性名、タグプロジェクト)のみが異なります。
テスト中
プロジェクトの自動テストの実装は、BehatとPHPUnitの2つのフレームワークを使用して行われました。
最初のものを使用すると、テストだけでなく、いわゆる生活文書の作成にも大きな利点があります 。 Gherkinのテストは、新しいプログラマーのプロジェクトに精通するとき、コードレビューを行うとき、および他の多くの作業を行うときの出発点の1つです。
こことここの資料に精通しているにもかかわらず、これらのテストの深さと詳細に関して均一な推奨事項はありません。したがって、その内容は次のように異なる場合があります。
: # - : | action | uid | | get-user-bonus-code | player1 | "GetUserBonusCodeResponse.txt" # : | action | code | | get-rewards-info | | "template8.txt"
そのような:
: -
PHPUnitは単体テストの実装に使用されます。単体テストの存在と内容は完全にプログラマーに任されているだけでなく、小さな回避策を使用してBehatテストを実行するためにも使用されます。 これにより、すべてのテストを1つのチームで実行できるだけでなく、テストの結果とコードのカバレッジに関する統一されたレポートを作成できます。
ビルドサーバー
Jenkins CIサーバーを使用してビルドします。 同時に、リリースブランチリリース/ XYごとに、ステージング環境で個別のアセンブリタスクがセットアップされます。
- ターゲット「build runtests-with-coverage」でアセンブリphingスクリプトを実行します
- 補助ユーティリティのテストレポートと結果を収集します
- プロセスがエラーなしで完了した場合、$ VERSION_NO。$ BUILD_NUMBERのリポジトリに新しいタグを作成します($ VERSION_NOはブランチ名から取得したバージョン番号(2.1など)、$ BUILD_NUMBERはこのアセンブリタスクのアセンブリシリアル番号です)
アセンブリスクリプト自体と同様に、アセンブリタスク自体は、 ここで説明したものに基づいて構築されました。 これが、追加ユーティリティのこのような豊富なリストを決定するものです。

上記のリンクにリストされているプラグインのリストに加えて、次のものがインストールされました。
- EnvInject- $ VERSION_NO変数を初期化する
- ChuckNorrisとCIゲーム -楽しみのためだけに
展開
複数のアプリケーションの展開を同時に管理できるソリューションを見つける必要がありました。各アプリケーションは、複数のサーバーグループ(テスト、実稼働)にインストールできます。
最初に、設定ファイルに従って、いくつかのアクションを実行するphingスクリプトによって展開が実行されました。
- 作成されたファイル、フォルダー、およびシンボリックリンク
- 目的のブランチ/タグのソースコードをチェックアウトしました
- プロジェクトを組み立てた
- また、2012-01-01T23:59:59という形式の新しいフォルダでチェックアウトが実行されるたびに、最新の展開バージョンを示す最新のシンボリックリンクが更新されました。
これは、リモートサーバーへのインストールが完全にサポートされていないため、あまり便利ではありませんでした。
Capistrano 、 Magallanes 、およびその他のツールを使用したいくつかの実験の後、このスクリプトに加えてインストーラーコンソールアプリケーションが実装されました。 インストールスクリプトを必要な設定とともに目的のリモートサーバーグループにコピーし、そこで実行します。
また、このアプリケーションには、アプリケーションの可能なバージョンを取得し、サーバーにインストールされているバージョンを要求するコマンドが組み込まれています(写真は、本番環境のプロジェクトをバージョン1.0.19から1.0.20に更新する可能性を示しています)。

そして、設定ファイルの形式はより便利な.ymlに置き換えられました:

このコンソールアプリケーションはビルドサーバーに展開され、コンソールインターフェイスコマンドを実行するパラメーター化可能なビルドジョブJenkinsの形式でWebインターフェイスが作成されました。
/home/projects/installer/installer.phar $command $recipe $environment
どこで
- $ command-実行するコマンドの名前(インストール、ステータス、バージョンなど)
- $レシピ-インストールを目的としたプロジェクトのバージョンに割り当てられたコード
- $ environment-プロジェクトをインストールするサーバーのグループのオプション名
そして、このタスクは、 Parameterized Trigger Pluginプラグインを使用したリリースブランチのアセンブリタスクのダウンストリームプロジェクトとして注目されました。
最後に
その結果、次の一連の手順で連続配信を実装する問題を解決しました。
- 開発者はリリースブランチに変更を加えます
- 受信後フックgitoliteは、このブランチに対応するJenkinsビルドタスクを開始します
- アセンブリタスクは、成功したバージョンをテストし、タグでマークします
- Jenkinsは、プロジェクトに必要なパラメーターと、プロジェクトの更新が必要なサーバーのグループを使用して、ダウンストリームプロジェクトインストーラーを起動します
- インストーラーは、グループのすべてのサーバーを順番に確認し、それらに最新バージョンを展開し、最新のシンボリックリンクを更新します
将来的には
使用される分岐モデルにより、時間の経過とともに異なる分岐が互いに大きく異なる可能性があり、古いリリースに新しい機能を導入する際に問題が発生します。 これは今のところ重要ではありませんが、開発統合ブランチに戻り、A / Bバージョンを準備するために別の手法を使用するというアイデアがあります。おそらく機能トグルのようなものです 。
Jiraトラッカーとのさまざまなタイプの統合を試みることに関心があります。 どういうわけか、たとえば、自動化:
- 特定のタイプの新しいチケットのブランチを作成する
- テスト結果に応じてチケットのステータスやコメントを更新する
- 変更ログの形成
composerの現在の実行時間は約数分であり、多数のネイティブパッケージがcomposer.jsonファイルの非常に大きなリポジトリセクションにつながります。 これらの問題を解決するために、 サティスで実験したいと思います。
おわりに
私たちは私たちの前に提起された問題を解決しました:
- バージョン管理システムの個別のブランチを使用して、A / Bバージョンを作成します
- パッケージマネージャーを使用すると、プロジェクト間で機能を再利用できます
- Gherkinのテストとその実装は、プロジェクトへの新しい開発者の接続を簡素化するのに役立ちます
- また、上記の継続的配信スキームにより、ゲームのクライアント部分の開発者からフィードバックを受信する時間が最小限に抑えられます。
このスキームは、本番環境でのプロジェクトの実際の更新にはほとんど使用されないことに注意してください。これは、新しいリリースの問題や、以前のバージョンとの互換性がない可能性があるためです。 その主なアプリケーションは、アプリケーションが展開されているすべてのサーバーへの新しい機能の迅速かつ自動化された配信であり、可能または重要ではない場所での更新です。
セルテ!