2014年9月12日金曜日

改めてJenkinsのプラグインを開発する方法をまとめてみた

概要

過去にEclipseとMavenを使ってサンプルのプラグインを動作させる方法を紹介しました
JenkinsのプラグインはRubyでも書けるようになったようでいろいろと変わっていることもあるかなーと思い再びプラグインの作成方法をまとめてみました
でもまた、Java+Mavenで作っています
環境マシンはMacですが、Javaが動けばWindowsでもLinuxでも同様に開発はできるかと思います

環境準備

  • Mac
    Mac OS X 10.8.5
  • Java
    1.6.0_65
  • Maven
    3.2.3

プラグイン開発

Java+Mavenでプラグインの開発するための流れを紹介していきます

Mavenの設定

ユーザごとの設定を記述する~/.m2/settings.xmlに以下を追記します
ない場合は作成しちゃってください
すでにファイルがあり<settings>タグや<pluginGrups>タグがある場合は適切な場所に設定を追記してください

<settings>
  <pluginGroups>
    <pluginGroup>org.jenkins-ci.tools</pluginGroup>
  </pluginGroups>

  <profiles>
    <!-- Give access to Jenkins plugins -->
    <profile>
      <id>jenkins</id>
      <activation>
        <activeByDefault>true</activeByDefault> <!-- change this to false, if you don't like to have it on per default -->
      </activation>
      <repositories>
        <repository>
          <id>repo.jenkins-ci.org</id>
          <url>http://repo.jenkins-ci.org/public/</url>
        </repository>
      </repositories>
      <pluginRepositories>
        <pluginRepository>
          <id>repo.jenkins-ci.org</id>
          <url>http://repo.jenkins-ci.org/public/</url>
        </pluginRepository>
      </pluginRepositories>
    </profile>
  </profiles>
  <mirrors>
    <mirror>
      <id>repo.jenkins-ci.org</id>
      <url>http://repo.jenkins-ci.org/public/</url>
      <mirrorOf>m.g.o-public</mirrorOf>
    </mirror>
  </mirrors>
</settings>

詳しい内容はよくわかりません
Jenkinsのプラグインを作成するためのおまじない程度に認識しとけばOKだと思います

プロジェクトの作成

コマンド一発です

mvn -U org.jenkins-ci.tools:maven-hpi-plugin:create

いろいろなダウンロードが始まりますので完了するまで待ちます
完了するとgroupIdとartifaceIdを入力するように促されるので適当に入力します(以下ではgroupIdはデフォルトでartifaceIdは「test」としています)

Enter the groupId of your plugin [org.jenkins-ci.plugins]: 
Enter the artifactId of your plugin (normally without '-plugin' suffix): test

とりあえずビルド

cd test
mvn clean package

またものすごい勢いでダウンロードが始まります
ダウンロードが完了するとコンパイルしテストが実行され、その後プラグインの実体となるhpiファイルを作成してくれます

ls -ltr target/test.hpi
-rw-r--r-- 1 user staff 8176  9 10 14:48 target/test.hpi

サンプルの実行

せっかくビルドできてhpiファイルもできたので早速プラグインがJenkins上で動作するか試してみましょう

mvnDebug hpi:run

8080番でJenkinsが立ち上がります
Jenkins is fully up and running と表示されば起動完了です
ブラウザでhttp://localhost:8080/jenkinsにアクセスしてみましょう
当たり前ですが、8080番がすでに使われているとエラーになるのでnetstat等で使われていないことを確認してから実行してください
か、-Djetty.port=8090オプションを指定することでポートを変更することも可能です
そしてあまり関係ないが起動するJenkinsのバージョンがやや古い

このサンプルはビルド手順に「Say hello world」を追加し、ビルド時に指定した文字列を受け取って「Hello hogehoge!」という出力をコンソールに出すことができます
なので適当にジョブを作成してビルド手順に「Say hello world」を指定すればプラグインの動作を確認することができます
plugin-test.png

サンプルの拡張

せっかくなんでサンプルを使って独自の機能も追加してみます
修正するファイルは
src/main/java/org/jenkinsci/plugins/test/HelloWorldBuilder.java

src/main/resources/org/jenkinsci/plugins/test/HelloWorldBuilder/config.jelly
になります
config.jellyでUIを定義し定義したUIの部品をJavaで操作する感じです
global.jellyというファイルもありますが、これはJenkinsの管理 -> システムの設定に設定項目を表示するためのファイルとなります

すごい簡単な拡張ですが、名前以外に年齢も入力させてビルド結果に出力できるようにしてみましょう

UI拡張

まず、UIを拡張します
config.jellyに以下を追加します

<f:entry title="Age" field="age">
  <f:textbox />
</f:entry>

Nameと同様に1つテキストフォームを増やす命令となります
とりあえずこの状態だけ修正してUIを確認してもフォームが増えていることは確認できます

ロジック修正

次に、HelloWorldBuilder.javaを修正してUIから取得した値を表示させるようにします
内容的には年齢を表示するようのフィールドを宣言して、それに対するGetterの追加とコンストラクタの修正をします
あとはperformというBulderクラスから継承したメソッドで宣言したフィールド情報を表示します
部分的にですが、HelloWorldBuilder.javaに追記、修正した部分を記載します

  • フィールド追加
    フィールドを定義している箇所に以下を追加してください
private final String age;
  • コンストラクタ修正
    既存のコンストラクタを以下のように修正してください
@DataBoundConstructor
public HelloWorldBuilder(String name, String age) {
    this.name = name;
    this.age = age;
}
  • Getter追加
    Getterを定義している箇所に以下のGetterを追加してください
public String getAge() {
    return age;
}
  • perform追加
    既存のperformメソッド内でprintlnしている箇所に以下を追加してください
listener.getLogger().println(name +" is " + age + " years old.");

さらにAgeは数字だけを入力するように制限してみたいと思います
以下のバリデーションチェック用のメソッドを追記してください

public FormValidation doCheckAge(@QueryParameter String value) throws IOException, ServletException {
    if (value.length() == 0)
        return FormValidation.error("Please set a age");
    try {
        Integer.parseInt(value);
    } catch (NumberFormatException e) {
        return FormValidation.error("Isn't the type of int?");
    }
    return FormValidation.ok();
}

チェックしているのは文字数が0以上かと数字かどうかを判断しています
バリデーションエラーの場合は警告ではなく、エラーとしています

ビルド&実行

さて、作ったものを動かしてみましょう

mvn clean package
mvnDebug hpi:run

でビルド&実行します
動いている場合はCtrl+cで停止してから上記を実行してください
ジョブの設定で「ビルド手順の追加」を確認するとAgeが入力できるようになっています
Ageを指定して実行するとビルド結果にAgeの情報も出力されます
またフォーマットチェックも実装したので数字以外だとエラーが表示されることがわかると思います(ただ、エラーでもジョブの設定保存自体はできてしまうので飾りみたいな感じです)

完成版の実行イメージは以下の通りです

  • ビルド手順の追加にAgeが追加されている
    adding_parameter_age.png

  • 入力されたパラメータが数字でない場合エラーを表示する
    check_parameter_age.png

  • 実行結果にAgeの情報が追加されている
    age_appear_in_result.png

とりあえず今回はサンプルの実行と簡単な拡張方法を紹介しました
あとは作成したhpiファイルを稼働中のJenkinsに組み込む方法やJenkinsCIに取り込んでもらい一般公開する方法などやることはありますが、それはまた機会があれば紹介したいと思います

今回紹介した方法は基本中の基本の部分なのであとはリファレンスを読んだりググったりしながら独自のプラグインを開発してみてください
それでも開発につまる場合はGithubで公開されているプラグインのコードを見れください

参考リンク

0 件のコメント:

コメントを投稿