GreenHopper を使用した Bamboo と Bitbucket の自動化

*本ブログは Atlassian Blogs を翻訳したものです。本文中の日時などは投稿当時のものですのでご了承ください。
*原文 : 2012 年 8 月 27 日、Sarah Goff-Dupont 投稿 “Using GreenHopper to Automate Bamboo & Bitbucket ("What the whaaaa?…")

アジャイル 2012 のカンファレンスが最近開催されたダラスの蒸し蒸しした暑さに関する言葉を聞いていると、「鬼のような」とか「うだるような」という表現をよく耳にします。どちらの表現でもかまいませんが、お好きな方で想像してみてください。実際どんな感じだったかお分かりいただけたでしょうか。私自身は Atlassian ブースの中で JIRA、GreenHopper、Bamboo のデモを行い、非常に充実した時を過ごしていました。お客様がどんなことに関心があるかを聞くのは素晴らしいことでしたし、多くの方たちが Git と Mercurial を使用していると聞いて少しも意外には思いませんでした。これを 口実 きっかけに、数名の 生贄 熱意ある参加者の皆さんと協力してもう 1 つの開発者用タスクである機能ブランチの作成と終了を自動化するちょっとした概念実証をご披露しました。アジャイル 2012 の参加者から「すごい!」と上々の反応をいただいたので、そのやり方をブログに載せることを約束しました。

「よく分かりません。何がそんなに重要なんでしょう?」

基本的な考えは、JIRA 課題を GreenHopper ボードの新しい列にドラッグすると、それがトリガーとなって Bamboo がブランチ操作スクリプトを実行するということです。これは大きな開発ワークフローの小さな一端であり、採用する人が増えてきています。詳細は以下のとおりです。

  1. JIRA 課題が作成され、イテレーションに取り入れられます。
  2. 開発者が課題を選択し、"進行中" のステータスに移動します。ここで ワークフロー事後操作が作動します。その課題のストーリー ブランチが自動的に作成され、レポジトリにプッシュされます。
  3. 開発者がブランチの作業を開始します。これにはコードのプルダウンは不要です。IDE やレポジトリのナビゲーションに使用している GUI ベースのツール (SourceTree など) でブランチを切り替えるだけです。または、コマンド ラインから「git checkout ${branch_name}」と入力します。
  4. レポジトリにプッシュされるたびに Bamboo は継続的にそのブランチをビルドおよびテストします。このワークフローではプッシュの方が安全であることを覚えておいてください。あなたの作業はブランチで隔絶されており、同僚の作業に悪影響を与えないためです。開発者が Bamboo で自動マージ オプションを有効に設定しているのが理想的です。これによりブランチをビルドするたびにマスターからのコードにマージし、一種の正常性チェックのような役割を果たして早目にマージや統合に関する問題を洗い出すことができます。
  5. 実装が完了したら、開発者は課題を "解決済み" のステータスに移行します。ここで再度ワークフロー事後操作が作動します。Bamboo によるマスターへのブランチのマージをトリガーし、ブランチをクローズします。
  6. マスターにはマージから得た新しいコードがあるため、Bamboo はそれを検出してマスターをビルドします。
  7. マスターには新しいユーザー ストーリー/タスク/バグ修正が含められ、いつでもデプロイできるようになります。

率直に言って、チームが 課題ごとに開発ブランチを作成する慣習 を採用 (または検討) していない限り、上記の手法にこだわる必要はありません。 この手法には 3 つの意義があります。1 つ目として、ブランチ作成、マスターへの最終マージ、およびブランチの削除が自動化されます。これによって課題の実装にかかる時間が何時間も短縮されるというものではありません。しかし、開発者の作業項目からいくつかの管理タスクを省いてくれます。また、ストーリー ブランチの実践も促します (チームがそうすると決めた場合)。しかも、しつこくメールをしたり、井戸端会議で愚痴を言ったり、チーム ミーティングをしたりすることなく、洗練されたやり方でそれが実施されます。3 つ目として、これらのブランチに対する命名規則が自動化されます。チームのレポジトリ内のブランチを見るときに格段に見分けやすくなります。

重要性が分かったところで、本題に入りましょう。

前提条件

まず、認めるべき功績は認めましょう。これは私の GreenHopper マーケティングの相棒である Nick Muldoon 氏が考え出したものです。彼と私は実装に関しても協同で行っています。ありがとう、Nick! 次に、いくつか前提を提示します。私たちはバージョン管理に Git レポジトリを、レポジトリのホストに Bitbucket を、Bamboo と JIRA/GH のファイアウォール越しのインスタンスのホストに Ubuntu サーバーをそれぞれ使用しました。この記事を参考にして他の VCS、レポジトリ管理システム、およびサーバー OS を使用することは可能ですが、他の技術の組み合わせに潜んでいる固有の事項については言及できませんのでご了承ください。

高レベルにおいて、相互のやり取りが必要なコンポーネントが 3 つあります。JIRA/GH インスタンス、Bamboo インスタンス、およびレポジトリです。ワークフロー トランジションの事後操作を使用して、JIRA は REST API 経由で Bamboo を呼び出し、機能ブランチを作成およびコミット (またはマージおよび削除) するシンプルなシェル スクリプトを含むビルドをトリガーします。当然、特別なセットアップを必要とせずに Bamboo はレポジトリからコードをチェックアウトできます。ただし、Bamboo がレポジトリをプログラム的に実際に操作できるようにする (つまりログイン資格情報を入力する必要なくプッシュを行う) には、SSH キーをセットアップする必要があります。

Bamboo ホストに入ってどのユーザー アカウントが Bamboo プロセスを持っているかを確認することから始めましょう。私たちのケースでは 'ubuntu' ユーザーがそれに該当しました。次に、秘密/公開キーのペアを見つけるか生成し、Bamboo ホストの ${USER_HOME}/.ssh に配置します。お使いの種類のサーバーのマニュアルを参照し、キー ペアにまつわる命名規則について確認してください。Ubuntu では 'id_rsa' および 'id_rsa.pub' という名前である必要があります。

そして Bitbucket では、[アカウント (Account)]、[SSH キー (SSH Keys)]、[新しいキーの追加 (Add New Key)] で自分のアカウントに公開キー (id_rsa.pub) を追加しました。お使いのレポジトリが一般公開されている場合はこの手順を省くことができます。私の場合はユーザー ログイン、つまり SSH キーが必要です。自宅 (または職場) から作業していて、公開レポジトリの sans キーにアクセスできる場合は、この記事にコメントを残してお知らせください。クラウドソーシングが確実ですね。

他に揃えるべきものとして、Atlassian マーケットプレイスまたは JIRA のプラグイン マネージャーで入手できる JIRA 用 HTTP Request Workflow Function プラグインがあります。その洗練されたネーミングからは想像もつきませんが、このプラグインは名前以上の機能を備えています。しかも無料です (ありがとう、hasCode.com!!)。このプラグインを使用するとワークフロー トランジションの一環として HTTP 経由で REST 呼び出しを行えます。この例ではカスタム事後操作として追加します。

(私みたいに) 面倒くさがりな人向けの機能ブランチ作成

HTTP ワークフロー事後操作を使用して Bamboo でプランのビルドをトリガーできるようになる前に、当該プランをセットアップする必要があります。それをプラン S としましょう。一つのプランはブランチを新規作成し、一つのプランはそれをクローズする。一つのプランはすべてをマージし、暗黒の中に繋ぎ止め… おっと失礼。指輪物語の話じゃなかったですね (コホン)。 ブランチ作成プランはまずレポジトリを Bamboo の現在の作業ディレクトリにチェックアウトします。次に、インライン スクリプトとして構成された一連の Git コマンドを実行します。以下のスクリーンショットにあるのがスクリプト全体です。短いコマンドが 4 つだけです。最後の行の "-u" オプションは、まだマスターと対比して変更がない新しいブランチのプッシュに必要です。

鋭い皆さんのことですから、ここで使われている変数にお気づきになったでしょう。Bamboo でプラン レベルの変数としてセットアップすることもできましたが、その必要はありませんでした。名前と値の両方が REST 呼び出しでパラメーターとして取り入れられています。(はいはい、分かってます。今説明しますから少し落ち着いて!) さらに、JIRA の課題キーがブランチ名に含まれていることに気付いたかもしれません。これはオプションですが、Bamboo 4.2 で新登場した便利な課題-ブランチ リンク機能を活用したものです。Atlassian のオタクたちがどのようにその機能を活用しているか詳しく知りたい場合は、Bamboo 開発者の Stefan による こちらのブログ をご覧ください。

さて、JIRA に戻って例の事後操作 REST 呼び出しをようやく実装できます。ワークフローを編集するには jira-administrators グループに入っている必要があるので、適切な権限を持っていない場合はシステム管理者に頼んでください。[管理 (Administration)]、[課題 (Issues)]、[ワークフロー (Workflows)] の順にアクセスし、目的のワークフローで [編集 (Edit)] を選択します。これでドラフトが作成されます。課題が "オープン" から "進行中" に移行するたびにブランチ作成プランを開始したいので、ワークフローでは "進行中" トランジションをクリックして編集しました。

トランジション設定内で事後操作タブを選択し、[追加 (Add)] をクリックします。プラグインがインストールされている場合、"HTTP Request Function" というオプションが表示されるのでそれを選択します。ここまで来ると私は休み時間の子供になった気分になります。(smile) 多くの利用可能な課題関連の変数で遊んだり、呼び出しに使用する Bamboo REST API の全セットをいじったり!(ちなみにマニュアルはこちら。)

ビルドをトリガーするには、認証資格情報と他のお好みのパラメーターが詰まった POST 呼び出しを Bamboo のキュー API に対して行います。ユーザーのパスワードを POST 呼び出しで晒す必要がないよう、Bamboo インスタンスに "GreenHopper" ユーザーを作成するのが一番簡単だと分かりました。これはオプションですが、いずれにしても param 文字列内のユーザーがプランをビルドする権限を持っていることを確認してください。POST 呼び出しは結局以下のようになりました。

http://bamboo.atlassiandemo.com:8085/rest/api/1.0/queue/EVAL-ANW?os_authType=basic&os_username=greenhopper&os_password=greenhopper&executeAllStages=true&bamboo.variable.issueKey=%ISSUE_KEY%&bamboo.variable.issueAssignee=%ISSUE_ASSIGNEE%

"EVAL-ANW" が目的のプランのキーです。上記の Bamboo スクリプト タスクで示した変数は、"&bamboo.variable.issueKey=%ISSUE_KEY%" などプラグインに付属のプリセットを使用して POST 呼び出しで宣言され、割り当てられる点に注意してください。事後操作が設定されているので、変更をワークフローに発行して試すことができます。GreenHopper ボードを使用して課題を "オープン" から "進行中" にドラッグすると、Bamboo でブランチ作成スクリプトが起動します。そしてジャジャーン!その課題だけの新規ブランチが Bitbucket レポジトリに現れます。なかなかイケてるでしょう??

この時点で、Bamboo は新しいブランチを自動検出してマスター コード行の CI スキームをコピーし、新しいブランチに適用します。特別なトリックは不要です。Bamboo がそのように動作するのです。開発が進行している間、Bamboo はブランチをビルドしてテストし、ビルドごとにレポジトリの別のブランチからのコードをマージすることもできます。さらにここでもブランチ名に JIRA 課題のキーを使用するとリンクが作成され、JIRA 内でブランチの最新のビルド ステータスを確認できます。(Bamboo をほとんど使用しないが課題の進捗を JIRA でよく確認する関係者や管理職の人たちにとって非常に便利です。)

オープンしたものは必ずクローズを

同様の方法で、JIRA 課題が "レビュー中" から "解決済み" に移行したときにストーリー ブランチをマスターにマージしてクローズできるようにしたいと思います。それを処理する該当のプランを Bamboo でセットアップし、"解決済み" トランジションの事後操でそれを呼び出します。だいたいお分かりいただけたでしょうから、詳細は飛ばしてスクリーンショットをご覧ください。Bamboo ではスクリプト タスクがブランチの削除前にマスターへのマージを試みます。マージの競合が発生した場合、全作業がストップし、Bamboo の通知システムが作動してプロジェクト リーダーに障害の発生を知らせます。(Bamboo の通知で変数を使用できたらどんなにいいでしょうね? そうすれば課題の担当者に直接通知を送信できますし。まあ、これはそのうち・・・。)

ワークフロー トランジションは同じ方法で編集され、ここでも POST 呼び出しを使用してマージ ビルドとプランのクローズを Bamboo キューに追加します。呼び出しはプラン キー ("EVAL-RESOLVE") 以外は同じです。

http://bamboo.atlassiandemo.com:8085/rest/api/1.0/queue/EVAL-RESOLVE?os_authType=basic&os_username=greenhopper&os_password=greenhopper&executeAllStages=true&bamboo.variable.issueKey=%ISSUE_KEY%&bamboo.variable.issueAssignee=%ISSUE_ASSIGNEE%

どのように使うかは皆さん次第

この方法は少しややこしいですか?そうですね。最終的には製品内で対応させたいものです。皆さんのチームで上記のような実装を行っていましたら、どうぞコメントをお寄せください。ベテランの皆さんたちの使用事例を是非お聞かせいただきたいものです。もちろん関心のある事項や感想など一般的な内容についてもどうぞ。これとまったく同じメカニズムを利用して、課題が解決するたびにテスト環境にコードをビルドしてデプロイしたり、課題のステータスが "出荷済み" に移行したときに実稼働環境にデプロイすることができます。または、課題が "進行中" から "要レビュー" にドラッグされたときに Crucible でコード レビューを作成できます。可能性は無限に広がります!

Bamboo をまだお試しでない場合、これをきっかけに是非ご検討ください。他の Atlassian 製品同様、30 日間無料でお試しいただけます。さあ、何も迷うことはありませんよ!

 

(翻訳: Go2Group 株式会社)