1概要

JenkinsはオープンソースのContinuous Integrationサーバーで、特定のタスク/環境用にカスタムプラグインを作成することができます。

この記事では、ビルド出力に統計、つまりクラス数とコード行を追加する拡張機能を作成するプロセス全体について説明します。


2セットアップ

最初にやるべきことは、プロジェクトを設定することです。

幸いなことに、Jenkinsは便利なMavenアーキタイプを

提供しています。

シェルから以下のコマンドを実行するだけです。

mvn archetype:generate -Dfilter=io.jenkins.archetypes:plugin

次のような出力が得られます。

----[INFO]Generating project in Interactive mode[INFO]No archetype defined. Using maven-archetype-quickstart
  (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
Choose archetype:
1: remote -> io.jenkins.archetypes:empty-plugin (Skeleton of
  a Jenkins plugin with a POM and an empty source tree.)
2: remote -> io.jenkins.archetypes:global-configuration-plugin
  (Skeleton of a Jenkins plugin with a POM and an example piece
  of global configuration.)
3: remote -> io.jenkins.archetypes:hello-world-plugin
  (Skeleton of a Jenkins plugin with a POM and an example build step.)
----

それでは、最初のオプションを選択し、対話モードでgroup/artifact/packageを定義してください。その後、

<name> TODO Plugin </name>

などのエントリが含まれているため、

pom.xml

を改良する必要があります。


3 Jenkinsプラグインデザイン


3.1. 拡張ポイント

  • Jenkinsはいくつかの拡張ポイントを提供しています** これらは特定のユースケースの規約を定義し、他のプラグインがそれらを実装することを可能にするインターフェースまたは抽象クラスです。

たとえば、すべてのビルドはいくつかのステップで構成されています。

「VCSからのチェックアウト」、「コンパイル」、「テスト」、「アセンブル」など。Jenkinsは、


hudson。 tasks.BuildStep

__拡張ポイントなので、設定可能なカスタムステップを提供するためにそれを実装できます。

もう1つの例は


hudson.tasks.BuildWrapper


です。これにより、前後のアクションを定義できます。

また、電子メールの受信者に提供できる

hudson.plugins.emailext.plugins.RecipientProvider

拡張ポイントを定義する、非コアのhttps://plugins.jenkins.io/email-ext[Email Extension]プラグインもあります。実装例はこちらから入手できます。

注:プラグインクラスがhttp://javadoc.jenkins-ci.org/hudson/Plugin.html[

hudson.Plugin

]を拡張する必要があるという従来のアプローチがあります。

ただし、

代わりに拡張ポイントを使用することをお勧めします。

** 3.2. プラグインの初期化

Jenkinsに拡張機能とそれをどのようにインスタンス化するかについて伝える必要があります。

まず、プラグイン内に静的な内部クラスを定義し、

hudson.Extension

アノテーションを使用してそれをマークします。

class MyPlugin extends BuildWrapper {
    @Extension
    public static class DescriptorImpl
      extends BuildWrapperDescriptor {

        @Override
        public boolean isApplicable(AbstractProject<?, ?> item) {
            return true;
        }

        @Override
        public String getDisplayName() {
            return "name to show in UI";
        }
    }
}

次に、プラグインのオブジェクトのインスタンス化に使用するコンストラクタを定義し、それに

org.kohsuke.stapler.DataBoundConstructor

アノテーションを付ける必要があります。

パラメータを使用することは可能です。それらはUIに表示され、Jenkinsによって自動的に配信されます。

例えば。

Mavenプラグイン

を検討してください。

@DataBoundConstructor
public Maven(
  String targets,
  String name,
  String pom,
  String properties,
  String jvmOptions,
  boolean usePrivateRepository,
  SettingsProvider settings,
  GlobalSettingsProvider globalSettings,
  boolean injectBuildVariables) { ... }

次のUIにマッピングされています。

リンク:/uploads/maven-settings-1024×581.png%201024w[]

セッターで

org.kohsuke.stapler.DataBoundSetter

アノテーションを使用することも可能です。


4プラグインの実装

ビルド中に基本的なプロジェクト統計を収集するつもりですので、

hudson.tasks.BuildWrapper

がここに行く正しい方法です。

それを実装しましょう:

class ProjectStatsBuildWrapper extends BuildWrapper {

    @DataBoundConstructor
    public ProjectStatsBuildWrapper() {}

    @Override
    public Environment setUp(
      AbstractBuild build,
      Launcher launcher,
      BuildListener listener) {}

    @Extension
    public static class DescriptorImpl extends BuildWrapperDescriptor {

        @Override
        public boolean isApplicable(AbstractProject<?, ?> item) {
            return true;
        }

        @Nonnull
        @Override
        public String getDisplayName() {
            return "Construct project stats during build";
        }

    }
}

さて、今度は実際の機能を実装する必要があります。

プロジェクト統計のドメインクラスを定義しましょう。

class ProjectStats {

    private int classesNumber;
    private int linesNumber;

   //standard constructors/getters
}

そしてデータを構築するコードを書く:

private ProjectStats buildStats(FilePath root)
  throws IOException, InterruptedException {

    int classesNumber = 0;
    int linesNumber = 0;
    Stack<FilePath> toProcess = new Stack<>();
    toProcess.push(root);
    while (!toProcess.isEmpty()) {
        FilePath path = toProcess.pop();
        if (path.isDirectory()) {
            toProcess.addAll(path.list());
        } else if (path.getName().endsWith(".java")) {
            classesNumber++;
            linesNumber += countLines(path);
        }
    }
    return new ProjectStats(classesNumber, linesNumber);
}

最後に、統計をエンドユーザーに表示する必要があります。そのためのHTMLテンプレートを作成しましょう。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>$PROJECT__NAME$</title>
</head>
<body>
Project $PROJECT__NAME$:
<table border="1">
    <tr>
        <th>Classes number</th>
        <th>Lines number</th>
    </tr>
    <tr>
        <td>$CLASSES__NUMBER$</td>
        <td>$LINES__NUMBER$</td>
    </tr>
</table>
</body>
</html>

そしてビルド中にそれを追加します。

public class ProjectStatsBuildWrapper extends BuildWrapper {
    @Override
    public Environment setUp(
      AbstractBuild build,
      Launcher launcher,
      BuildListener listener) {
        return new Environment() {

            @Override
            public boolean tearDown(
              AbstractBuild build, BuildListener listener)
              throws IOException, InterruptedException {

                ProjectStats stats = buildStats(build.getWorkspace());
                String report = generateReport(
                  build.getProject().getDisplayName(),
                  stats);
                File artifactsDir = build.getArtifactsDir();
                String path = artifactsDir.getCanonicalPath() + REPORT__TEMPLATE__PATH;
                File reportFile = new File("path");
               //write report's text to the report's file
            }
        };
    }
}


5使用法

今までに作成したすべてのものを組み合わせて、実行してみましょう。

Jenkinsはローカル環境で稼働していると想定しています。

それ以外の場合は、リンク/jenkins-pipelines[インストールの詳細]を参照してください。


5.1. Jenkins

にプラグインを追加する

それでは、プラグインを作成しましょう。

mvn install

これにより、

target

ディレクトリに

** 。hpi

ファイルが作成されます。それをJenkinsプラグインディレクトリ(デフォルトでは

〜/.jenkins/plugin

)にコピーする必要があります。

cp ./target/jenkins-hello-world.hpi ~/.jenkins/plugins/----

最後に、サーバーを再起動し、プラグインが適用されていることを確認しましょう。

.  __http://localhost:8080__にあるCIダッシュボードを開きます.

.  __Manage Jenkins__に移動します.  __管理プラグイン__ |インストール済み

. 私たちのプラグインを探す

リンク:/uploads/plugin-enabled-768x227.png%20768w[]

[[jenkins-configure]]

====  **  5.2.  Jenkins Job ** を構成する

オープンソースのApache commons-langプロジェクトに新しい仕事を作成し、そこでGitリポジトリへのパスを設定しましょう。

link:/uploads/common-lang-git-1024x359.png%201024w[]

そのためにもプラグインを有効にする必要があります。

リンク:/uploads/enable-for-project-300x218.png%20300w[]

[[check]]

====  **  5.3. 結果を確認する**

これで準備が整いました。動作を確認しましょう。

プロジェクトを構築して結果に移動できます。 __stats.html__ファイルがここにあることがわかります。

link:/uploads/commons-lang-build-1-1024x500.png%201024w[]

それを開きましょう:

link:/uploads/commons-lang-result-300x117.png%20300w[]

それが私たちが期待していたことです -  3行のコードを持つ単一のクラス。

===  **  6. 結論**

このチュートリアルでは、最初から__Jenkins__プラグインを作成し、それが機能することを確認しました。

当然のことながら、私たちはCI拡張機能開発のすべての側面を網羅しているわけではなく、基本的な概要、設計上のアイデア、および初期設定について説明しました。

そしていつものように、ソースコードはhttps://github.com/eugenp/tutorials/tree/master/jenkins/hello-world[over on GitHub]にあります。