通常、継続的インテグレーションでは、すべての開発者が行うすべての作業が 1 つのブランチ (またはトランク) で行われます。実際、Subversion はこのタイプのワークフローを念頭に置いて設計されています。全員が同じブランチで作業することは、恐ろしく聞こえるかもしれません。結局のところ、衝突はどうなるのでしょう? 次のリリースに 1 つのバグ/機能強化/追加を含めたいが、別のバグを含めたくない場合はどうすればよいですか?
私の経験では、すべての開発を 1 つのブランチで行うように強制する方が単純にうまくいきます。これにより、開発者は小さな注意深い変更を行い、互いに協力する必要があります。問題(バグ修正と機能強化) を処理する順序は、開発サイクルの最後に選んで選択するのではなく、開発サイクルの最初に行う必要があります。マネージャは、最後に選んで選択できる柔軟性を好みますが、それはリリースの数日前に大規模なマージ サイクルが発生することを意味し、通常は急いでテストすることになります。
プライベート ブランチを使用する場合は、2 つのJenkins インスタンスをセットアップすることをお勧めします。最初は公式のものになります。トランクとリリース ブランチから構築しますが、開発者ブランチから構築することはありません。この Jenkins がすべての単体テストを行います。リリースに必要なアーティファクトを格納します。テストの報告になります。QA チームがテストのためにリリースをプルする場所になります。この Jenkins でジョブをセットアップできるのはあなただけです。
もう 1 つは開発者向けです。ジョブをセットアップし、必要に応じてテストを実行できます。これは、彼らのブランチ (プライベート ブランチまたはバグ修正ブランチ) 用になります。
あなたの最初の質問への答え: 私は Jenkins をプライベート ブランチで実行することはまったく気にしません。プライベート ブランチは、開発者が自分でプレイできるため、サンドボックスと呼ばれていました。冗談は、開発者がサンドボックスで子猫がサンドボックスで行うこととほとんど同じことをしたということです。プライベート ブランチで継続的インテグレーションを強制すると、そのブランチの目的が失われます。コードがトランクに配信されると、本当に気にするだけです。
そのため、2 つの Jenkins セットアップをお勧めします。最初はあなたのためです。コミット/チェックインが発生するたびにビルドが実行されます。2 つ目は、プライベート ブランチの開発者向けです。必要に応じてジョブをセットアップし、必要に応じてビルドを実行します。その唯一の目的は、開発者がコードがトランクに配信されたらすべてが機能することを確認できるようにすることです。
このようにすることで、質問 2 を完全に回避できます。コードがトランクに配信された後にビルドするのは、コミットが完了したときだからです。
最後の 1 つは、サーバーにコードを配置する方法です。Jenkins が配信アーティファクトを作成するのが好きです。Jenkins ビルド番号を介してリリースされるものについて話すことができます。
「運用サーバーにビルド #25 をリリースしましょう。」
「待ってください。QA はビルド #25 をテストしていませんが、ビルド #24 をテストしました。」
「よし、ビルド #24 をリリースしよう。いずれにしても US232 の問題が修正されているようだ。」
ちなみに、curlまたはwgetを使用して、ソフトウェアを Jenkins からサーバーにプルします。実際、deploy.sh
使用するスクリプトがあります。Jenkinsdeploy.sh
からスクリプトを取得して実行します。これにより、Jenkins から適切なビルドが自動的にプルダウンされ、インストールされます。サーバーをシャットダウンし、古いインストールをバックアップし、新しいソフトウェアをインストールし、サーバーを再起動して、結果を報告します。
ただし、Subversion が配信を行うという考えには何かがあります。さまざまな方法が使用されます。1 つは、Subversion がプロダクションブランチの特定の時間に自動的に更新を行うことです。productionブランチにコードを配置すると、毎朝午前 2 時に Subversion がコードを配信します。これは素晴らしいアイデアであり、私はそれを実行しました。特に、コンパイルする必要のない PHP について話している場合はそうです。
より詳細に制御でき、Jenkins ビルドのみをデプロイする必要があるため、私は最初の方法を好みます。さらに、通常、展開のsvn updateメソッドが失敗する原因となる問題があります (衝突、削除する必要のあるバージョン管理されていないファイルなど)。もちろん、これは最も重要な時期にのみ発生します。そしてもちろん、上司が年次レビューに記入する直前に起こるのは、壮大な失敗です。
それで、あなたの3番目の質問に答えて。私の好みの方法は、Subversion を使用しないことです。代わりに、ビルドされたアーティファクトを ( and を使用して) Jenkins サーバーから直接ftpし、必要なすべてを処理する実際のデプロイ スクリプトを実行します。wget
curl
ちなみに、Jenkins と統合するLiveRebelのようなさまざまな展開ツールを検討しています。Jenkins が成果物パッケージをビルドして LiveRebel に展開し、IT 部門が LiveRebel を使用してサーバーに展開できるようにするという考え方です。各 Jenkins ビルドが LiveRebel にデプロイされるかどうか、またはビルド プロモーションプラグインを使用して QA が LiveRebel にデプロイするビルドを選択できるようにするかどうかはわかりません。2 つ目は、QA が認定していないビルドをデプロイできないようにします。
補遺
返信と洞察をありがとう。私がタスクごとの分岐を検討していた理由は、いくつかの理由によるものです。
それぞれの理由にお答えします...
1) - メイン トランクから分離してタスクを実行できます。
また、タスクは互いに分離して実行することもできます。問題は、結果のコードがこれらのタスクから分離されておらず、これらのタスクが互いに互換性がない可能性があることです。
多くのマネージャーは、この分離により、次のリリースに含めるタスクを選択できるようになり、リリース時にこれを実行できるようになると考えています。最初の真の CM パッケージの 1 つは、AT&T の Salime と呼ばれ、まさにこの哲学に基づいていました。
Sablime には、リリースと呼ばれるGenericがあります。これがすべての変更のベースになります。各変更には変更要求(MR 番号) が割り当てられ、すべての作業は MR で行う必要があります。
古いベースライン ジェネリックを取得し、選択した MR を追加して、次のジェネリックを作成します。新しいジェネリックを作成できます。シンプルに聞こえます: 古いベースライン + 選択された変更 = 新しいベースライン。
残念ながら、MR はファイルと同じファイルに影響を与えます。実際、新しいジェネリックに、実際の開発者によって書かれたものではないバージョンのファイルが含まれることは珍しくありませんでした。また、ある MR が別の MR に依存することになりました。マネージャーは、MR 1001、1003、および 1005 が次のリリースにあると宣言します。これらの MR をベースラインに追加しようとすると、MR 1003 が MR 1002 に依存しており、MR 1002 はリリースしたくない MR 1008 にも依存していることがわかりました。次の週は、リリース可能な一連の MR の作成に取り組み、最終的には完全にテストされていないソフトウェアをリリースすることになります。
この問題を解決するために、最終的にベースライン間の変化を小さくしました。毎週新しいジェネリックを作成し、時には 2 つ作成することもありました。これにより、マージが機能していることを確認し、依存する MR が依存する MR の前に最初に含まれるようにすることができました。ただし、選択して選択するという概念全体も排除されました。残ったのは、Sablime に組み込まれた大量のオーバーヘッドだけでした。
2) 時間の制約がない - 各タスクの完了に時間がかかることがあり、他のタスクに影響を与えません。
2 つの別個のデータベースを持つ 2 つのまったく異なるマシンで実行される 2 つの完全に異なるソフトウェア パッケージの場合を除き、タスクは常に互いに影響を与えます。
時間に関連するコストと、そのタスクに関連する利益があるため、すべてのタスクには時間の制約があります。時間がかかりますが、メリットがほとんどないタスクは、実行する価値がありません。
開発の仕事の 1 つは、これらのタスクに優先順位を付けることです。つまり、どれを最初に実行し、どれを後で実行するかです。時間がかかりすぎるタスクは、サブタスクに分割する必要があります。
アジャイル開発では、スプリントが許容できる以上のリソースを消費するタスクは想定されていません。(スプリントはミニリリースで、通常は 2 週間の期間をカバーします。) その 2 週間の間に、開発者は満たすことができる特定の数のポイントを持っています (ポイントは一種の時間に関連していますが、実際にはそうではありません。 1 ポイントは、この思考実験の X 時間の作業を表します。) 開発者が週に 15 ポイントを達成できる場合、30 ポイントを必要とするタスクはスプリントには大きすぎるため、サブタスクに分割する必要があります。
3) - リリースと展開は、他のタスクが完了するのを待ってから、特定の時点でマルチタスク リリースを実行するのではなく、タスクごとに実行することもできます (それから逃れようとしていること) )
私が言っていることは、タスクベースの開発ができないという意味ではありません。Git を使用するサイトでは、これが頻繁に行われます。アジャイルプロセスはこれを前提としています。これは、すべての耐え難いほどの詳細がレイアウトされるまで、誰もキーボードに触れることを許可されていないウォーターフォール方式に戻ることを意味するものではありません. ただし、単純に 50 の個別のタスクを実行してから、リリースの前日にどのタスクを含めるかを選択することはできません。タスクをリリースするのではなく、ソフトウェア製品をリリースします。
タスク分岐を使用します。ただし、あなたに関する限り、変更がトランクに反映されるまでタスクは完了しません。これについては開発者が責任を負います。プロジェクトがそのタスクを完了したと見なす前に、リベース(トランクからの変更をブランチにマージ) し、リベースされたコードをテストしてから、配信(変更をトランクにマージして戻す) する必要があります。
これが、2 つの Jenkins インスタンスを持つことができるとお伝えする理由です。1 つはトランクとリリース ブランチの公式ビルド用で、もう 1 つは開発者がタスク ビルドを行うためのものです。開発者は、Jenkins とブランチ、および開発を世界中で楽しむことができます。それがトランク上にあり、Jenkins でビルドするまでカウントされません。
Git と Linux のしくみについて考えてみてください。Linux 用の公式 Git リポジトリが 1 つあります。このリポジトリからプルすると、マシン上に独自の Git リポジトリが作成されます。この Git リポジトリを友達と共有できます。心から望むことは何でもできます。Git リポジトリから別の Git リポジトリを作成するか、公式の Git リポジトリの別のコピーをプルするか、Linux の Git リポジトリを持っている他の人を見つけてそこからプルすることができます。
ただし、行ったすべての変更は、それらの変更が唯一の公式 Git リポジトリにプッシュされるまで、Linux の一部とは見なされません。