GeekFactory

int128.hatenablog.com

Jenkins GitHub PluginをGitBucketで利用する

JenkinsとGitBucketの連携にGitHub Pluginが使えるか調べてみました。GitBucket APIGitHubと互換性があるので、理論上はGitHub Pluginが使えるはずです。

結論

GitHub互換のURL形式でリダイレクトを設定することで、GitHub PluginでもGitBucketのWebhookを受けてジョブを実行できました。

ただし、GitHub PluginでできることはGitBucket Pluginとほぼ同じです。GitHub PluginのメリットはPipelineに対応していること、CIのステータスを設定できることでしょうか。

方法

ジョブ設定のGit URLに https://gitbucket.example.org/user/repo.git の形式を指定します。これによってGitHub PluginがWebhookを認識できるようになります。

実際にはこのURLでgit fetchできないため、GitBucketのフロントにリバースプロキシを入れて、以下のリダイレクトを設定します。

リダイレクト元 リダイレクト先
https://gitbucket.example.org/user/repo.git https://gitbucket.example.org/git/user/repo.git
https://gitbucket.example.org/user/repo.git/... https://gitbucket.example.org/git/user/repo.git/...

Nginxの場合は以下の設定になります。

  location ~ ^/[^/]+/[^/]+\.git.*$ {
    return 301 https://gitbucket.example.org/git$request_uri;
  }
  location / {
    proxy_pass http://gitbucket:8080;
    #client_max_body_size 略
    #proxy_set_header 略
  }

なぜデフォルトでGitHub Pluginが動作しないのか

なぜリダイレクトを設定しないとGitHub Pluginがジョブを実行しないのか調べてみました。

GitBucketからJenkinsへのWebhookの送信は以下の流れで行われます。

  1. GitBucketがpushイベントのWebhookを https://gitbucket.example.org/jenkins/github-webhook/ にPOSTする。
  2. Jenkins GitHub PluginがWebhookを受信する。
  3. Jenkins GitHub PluginはWebhookからリポジトリ情報を取り出す。
  4. Jenkins GitHub Pluginはリポジトリ情報に対応するジョブを探して実行する。

GitHub PluginがGit URLを解析する実装を見ると、以下のように http://host/user/repo の形式になっていました。

    private static final Pattern[] URL_PATTERNS = {
            /**
             * The first set of patterns extract the host, owner and repository names
             * from URLs that include a '.git' suffix, removing the suffix from the
             * repository name.
             */
            Pattern.compile("git@(.+):([^/]+)/([^/]+)\\.git"),
            Pattern.compile("https?://[^/]+@([^/]+)/([^/]+)/([^/]+)\\.git"),
            Pattern.compile("https?://([^/]+)/([^/]+)/([^/]+)\\.git"),
            Pattern.compile("git://([^/]+)/([^/]+)/([^/]+)\\.git"),
            Pattern.compile("ssh://(?:git@)?([^/]+)/([^/]+)/([^/]+)\\.git"),
            /**
             * The second set of patterns extract the host, owner and repository names
             * from all other URLs. Note that these patterns must be processed *after*
             * the first set, to avoid any '.git' suffix that may be present being included
             * in the repository name.
             */
            Pattern.compile("git@(.+):([^/]+)/([^/]+)/?"),
            Pattern.compile("https?://[^/]+@([^/]+)/([^/]+)/([^/]+)/?"),
            Pattern.compile("https?://([^/]+)/([^/]+)/([^/]+)/?"),
            Pattern.compile("git://([^/]+)/([^/]+)/([^/]+)/?"),
            Pattern.compile("ssh://(?:git@)?([^/]+)/([^/]+)/([^/]+)/?")
    };

ということはジョブ設定のGit URLを http://host/user/repo 形式にする必要があります。GitBucketのGit URLは http://host/git/user/repo なのでGitHubと互換性がないのです。

リバースプロキシのレイヤではなくGitBucketのScalatraでリダイレクトできそうな感じです。Jenkinsに限らず、GitHubと同じ形式のURLでgit fetchできることはメリットがあると思います。Pull Requestを送ってみようかな。

もともと解決したかったこと

GitBucket Pluginを使うとPull Requestをマージした契機でジョブが実行されない問題があります。この問題はGitBucket PluginでもGitHub Pluginでも解決できませんでした。そもそもGitBucketはPull Requestをマージした時にpushイベントを投げないようです。

(23:35追記)Multibranch Pipelineを使うと、Pull Requestのマージを契機にジョブを実行できました。ざっくり以下の方法になります。

  • GitHub互換URLでアクセスできるようにリダイレクトを設定する(上述)
  • GitBucketでWebhookを設定する。 https://git.example.org/jenkins/github-webhook/ に対してpushイベントとpull requestイベントを送信する。
  • Jenkinsの設定でGitHub EnterpriseにGitBucket APIhttps://git.example.org/api/v3)を指定する。
  • JenkinsでMultibranch Pipelineジョブを作成し、ブランチソースにGitHubを追加する。その際にAPI endpointにGitBucketを指定する。

詳しくは別の記事にします。

Gradle Swagger Codegen Pluginを書いた

Swaggerのソースコード生成をGradleで利用するためのプラグインを書きました。

github.com

以下のようなビルドスクリプトを実行すると、SwaggerでAPIサーバを自動生成できます。

plugins {
  id 'org.hidetake.swagger.codegen' version '1.0.0'
}

repositories {
  jcenter()
}

dependencies {
  // declare swaggerCodegen to run CLI
  swaggerCodegen 'io.swagger:swagger-codegen-cli:2.2.1'
}

// declare a task to generate code
task generateServer(type: SwaggerCodegen) {
  language = 'spring'
  inputFile = file('petstore.yaml')
  outputDir = file("$buildDir/generated/server")
}

テンプレートのカスタマイズやコード生成クラスの自作にも対応しています。 詳しくはREADME.mdをご覧ください。

チーム開発を始める時に決めること

頭の中を整理するために、新たにチーム開発を始める時に決めることをリストアップしてみました。すべて書き出すと大量になるので、プロセスや開発基盤を中心に書いています。

  • プロジェクト計画
    • ゴール
    • マイルストン
    • スコープ
    • リリース計画
    • プロセス
    • チーム構成
    • リスクと対策
  • プロセス
    • スプリントスケジュール(例:月曜開始の1週間スプリント)
    • 会議体の設定(例:スプリント計画、スプリントレビュー、レトロスペクティブ)
    • 複数チームのワークフロー(例:プロダクトオーナー、UXデザイナー、開発チーム、QAチーム)
    • 仮説検証サイクル(例:仮説設定、リリース、分析)
    • 進捗管理方法(例:リリースバーンダウン)
    • 品質管理方法
    • 障害対応のワークフロー
    • プロセス改善の仕組み(例:レトロスペクティブ結果のバックログ化)
  • プロダクトデザイン(略)
  • ソフトウェアアーキテクチャ(略)
  • インフラアーキテクチャ(略)
  • テスト計画(略)
  • 開発基盤
    • バックログ管理
      • プロジェクト構成
      • 計画から完了までのワークフロー
    • ソースコード管理
      • リポジトリ構成
      • ブランチ戦略
      • 品質ゲート(例:CIステータスチェック)
    • ビルド
      • プロジェクト構成
      • ビルドツール(例:Gradle、Rake、Webpack)
      • 静的解析、メトリクス
      • IDEやエディタの設定管理
    • 開発インフラ
      • 開発環境構成
      • サーバ構成管理(例:Git、Docker Compose、Ansible)
      • iOS/Android構成管理
      • ユーザ管理
      • 新規メンバ対応のワークフロー
    • 継続的インテグレーションと継続的デプロイ
      • 開発、ビルド、デプロイのワークフロー(例:masterブランチを自動デプロイ)
      • 実現方式(例:Jenkins、Circle CI、DeployGate)
      • 設定管理(例:Pipeline、circle.yml)
    • コミュニケーション
      • レビュー対象と方法(例:バックログ、設計、コード)
      • ドキュメント管理
      • Wiki
      • チャット
        • チャンネル構成
        • 外部連携通知(例:バックログ管理、ビルド、デプロイ)
        • BOT通知
      • リモートワーク
  • チームビルディング
    • キックオフ
    • 自己紹介
    • ワークショップ
    • トレーニング
    • 1 on 1

以下の要因によって計画に必要な内容は変わります。例えば、上記には契約やコストの話は入っていません。

  • B2Cサービス、B2Bサービス、自社内システム
  • Webサービス、モバイルアプリ、ソフトウェアパッケージ
  • 受託開発、社内開発
  • 大規模、小規模
  • 階層型組織、フラット組織
  • 新規開発、エンハンス
  • 期限付き、無期限
  • スコープ固定、リリースポイント固定
  • ワンロケ、複数拠点

チームやプロジェクトのレベルでコントロールするのが難しい内容もあるでしょう。例えば、以下が挙げられます。

  • 採用戦略
  • 人事評価
  • 組織構造
  • 技術選択
  • 開発基盤整備

各トピックは互いに依存しているので、整合性が取れるように検討とレビューを繰り返すべきです。例えば、テスト計画と品質管理は密接に関係しています。

これらをチームの立ち上げ時にすべて決めるのは難しいので、優先順位を付けて漸進的に決めていくとよいでしょう。また、チームを取り巻く環境は刻々と変化するので、環境の変化に合わせてルールも見直すべきです。

ざっと書き出してみましたが、一生かけてもすべてに習熟するのは難しい気がします。チーム開発を始める時の計画も、誰か一人にすべてを委ねるのではなく、得意分野を持ち寄ってチームで決めるのが最良かもしれません。

チーム開発実践入門 ~共同作業を円滑に行うツール・メソッド (WEB+DB PRESS plus)

チーム開発実践入門 ~共同作業を円滑に行うツール・メソッド (WEB+DB PRESS plus)

アジャイルサムライ−達人開発者への道−

アジャイルサムライ−達人開発者への道−

アジャイルな見積りと計画づくり ~価値あるソフトウェアを育てる概念と技法~

アジャイルな見積りと計画づくり ~価値あるソフトウェアを育てる概念と技法~

エッセンシャル スクラム

エッセンシャル スクラム

システムテスト自動化 標準ガイド CodeZine BOOKS

システムテスト自動化 標準ガイド CodeZine BOOKS