// 下階層用テンプレート
#topicpath
----


プロジェクトでJenkinsを使ってますが、ひょんなことから、勉強も兼ねてJenkinsのプラグインを作ってみようと思いました。


//ここにコンテンツを記述します。
#contents


まずは [[Plugin tutorial - 日本語 - Jenkins Wiki>https://wiki.jenkins-ci.org/display/JA/Plugin+tutorial]] に従って、Jenkinsのプラグイン開発を体験してみたいと思います。

**やってみる [#cbc98b72]
環境は Macに [[Mac OS X に maven3 (3.0.5) をインストールする手順 | OSCALOG>http://oscasierra.net/2013/05/install-maven-3-0-mac/]] をつかってMavenなどをインストール済みです。((もしくはMacPortsを使ってインストールでもよいとおもいます。))

***事前の設定 [#q1e08a3e]
 # view ~/.m2/settings.xml
下記のように作成しておきます。
 # cat ~/.m2/settings.xml 
 <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>
 </settings>

*** プロジェクトの作成 [#c13d53c2]
 # mvn -cpu hpi:create
プロジェクト名などを聞かれる。
  <groupId>nu.mine.kino.jenkins.plugins</groupId>
  <artifactId>project-management</artifactId>
こうなるように答えました。

 # cd project-management/
 # mvn -DdownloadSources=true -DdownloadJavadocs=true eclipse:eclipse
Eclipseで利用可能になりました。

 # mvn package
/project-management/target/project-management.hpi というファイルができました。これがプラグインの実体になります。

***ローカルのリポジトリにインストール [#e9b84366]
 # mvn install

*** 動かしてみる。 [#wf780ce2]
 # export MAVEN_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=n"
 # mvn hpi:run

ローカルでJenkinsが起動します。http://localhost:8080/jenkins/ からアクセス可能!
Hello World的なプラグインがインストールされているのが分かります。

#ref(Jenkins_設定.png)
プラグイン全体に関する設定画面 にHello World Builderというプラグインが。

#ref(フ&#12442;ロシ&#12441;ェクトの設定.png)
各プラグインの画面にも設定が追加されている。

#ref(ヒ&#12441;ルト&#12441;のコンソール結果.png)
ビルドを実行した結果でプラグインが動いているのが分かる。

**プロジェクトの構成 [#l3860c2b]
プロジェクトの構成はこんな感じになっています。

#ref(project_setting.png)


***HelloWorldBuilder [#e900c1c7]
HelloWorldBuilder は Builderを拡張しているクラスで、Jenkinsのプロジェクトの「設定 > ビルド」の「ビルド手順の追加」に表示されます。
それで追加するとビルド時にこのクラスのメソッドが呼び出されるようになっています。

実際呼び出されるメソッドは、
    @Override
    public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) {
        // This is where you 'build' the project.
        // Since this is a dummy, we just say 'hello world' and call that a build.
 
        // This also shows how you can consult the global configuration of the builder
        if (getDescriptor().getUseFrench())
            listener.getLogger().println("Bonjour, "+name+"!");
        else
            listener.getLogger().println("Hello, "+name+"!");
        return true;
    }
これです。


***config.jelly [#hbbcec35]
config.jelly は ビルド に追加したときに画面に表示されるUIを制御します。
 <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
   <!--
     This jelly script is used for per-project configuration.
 
     See global.jelly for a general discussion about jelly script.
   -->
 
   <!--
     Creates a text field that shows the value of the "name" property.
     When submitted, it will be passed to the corresponding constructor parameter.
   -->
   <f:entry title="Name" field="name">
     <f:textbox />
   </f:entry>
 </j:jelly>

ここでセットされた値は HelloWorldBuilder のコンストラクタ
 // Fields in config.jelly must match the parameter names in the "DataBoundConstructor"
 @DataBoundConstructor
 public HelloWorldBuilder(String name) {
    this.name = name;
 }
に渡されるようになっています。

***global.jelly [#q178448f]
global.jelly は 「Jenkinsの管理 > システムの設定」に表示されるUIを制御します。config.jelly と同じようにxmlでUIを定義します。

 <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
   <!--
     This Jelly script is used to produce the global configuration option.
 
     Jenkins uses a set of tag libraries to provide uniformity in forms.
     To determine where this tag is defined, first check the namespace URI,
     and then look under $JENKINS/views/. For example, <f:section> is defined
     in $JENKINS/views/lib/form/section.jelly.
 
     It's also often useful to just check other similar scripts to see what
     tags they use. Views are always organized according to its owner class,
     so it should be straightforward to find them.
   -->
   <f:section title="Hello World Builder">
     <f:entry title="French" field="useFrench"
       description="Check if we should say hello in French">
       <f:checkbox />
     </f:entry>
   </f:section>
 </j:jelly>

ここでセットされた値は、自動生成された
 @Extension // This indicates to Jenkins that this is an implementation of an extension point.
  public static final class DescriptorImpl extends BuildStepDescriptor<Builder> {
        @Override
        public boolean configure(StaplerRequest req, JSONObject formData) throws FormException {
            // To persist global configuration information,
            // set that to properties and call save().
            useFrench = formData.getBoolean("useFrench");
            // ^Can also use req.bindJSON(this, formData);
            //  (easier when there are many fields; need set* methods for this, like setUseFrench)
            save();
            return super.configure(req,formData);
        }
  }
ここからアクセス可能なようです。



**関連リンク [#lce0dfb1]
-[[Welcome to Jenkins CI! | Jenkins CI>http://jenkins-ci.org/]]
-[[Plugin tutorial - 日本語 - Jenkins Wiki>https://wiki.jenkins-ci.org/display/JA/Plugin+tutorial]] プラグイン開発の入り口。。
-[[Hudsonプラグイン開発 - wyukawa’s blog>http://d.hatena.ne.jp/wyukawa/20090605/1244210141]]
-[[継続的インテグレーションツール Hudson のプラグインを作成 - なんとなくな Developer のメモ>http://fits.hatenablog.com/entry/20080502/1209726765]]

----
この記事は
#vote(おもしろかった,そうでもない)
- HelloWorldBuilderはどのようにJenkinsに「登録」されるのかよく分からん。どうも DescriptorImpl をちゃんと定義しておく必要がある? -- [[きの]] &new{2014-10-14 (火) 21:03:06};


#comment
#topicpath


SIZE(10){現在のアクセス:&counter;}

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS