一.HelloWorldPlugin插件开发

1.配置环境

jdk1.8:https://www.oracle.com/java/technologies/downloads/#java8

maven3.8.3:https://maven.apache.org/download.cgi

使用命令查看环境是否配置成功

jdk:Java -version

maven:mvn -version

2.创建一个插件

选择存储到具有Jenkins插件的目录

mvn -U archetype:generate -Dfilter="io.jenkins.archetypes:"

这里的io.jenkins.archetypes是项目的三层目录 

<span style="color:#212529"><span style="background-color:#fafafa"><code>$ mvn -U archetype:generate -Dfilter="io.jenkins.archetypes:"
…
Choose archetype:
1: local -> io.jenkins.archetypes:empty-plugin (Skeleton of a Jenkins plugin with a POM and an empty source tree.)
2: local -> io.jenkins.archetypes:global-configuration-plugin (Skeleton of a Jenkins plugin with a POM and an example piece of global configuration.)
3: local -> io.jenkins.archetypes:global-shared-library (Uses the Jenkins Pipeline Unit mock library to test the usage of a Global Shared Library)
4: local -> io.jenkins.archetypes:hello-world-plugin (Skeleton of a Jenkins plugin with a POM and an example build step.)
5: local -> io.jenkins.archetypes:scripted-pipeline (Uses the Jenkins Pipeline Unit mock library to test the logic inside a Pipeline script.)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 4
Choose io.jenkins.archetypes:hello-world-plugin version:
1: 1.1
2: 1.2
3: 1.3
4: 1.4
5: 1.5
6: 1.6
7: 1.7
8: 1.8
Choose a number: 8: 8  
[INFO] Using property: groupId = unused
[INFO] Using property: package = io.jenkins.plugins.sample
[INFO] Using property: hostOnJenkinsGitHub = true
Define value for property 'artifactId': HelloWorldPlugin -----项目名称
Define value for property 'version' 1.0-SNAPSHOT: :
Confirm properties configuration:
groupId: unused
package: io.jenkins.plugins.sample
hostOnJenkinsGitHub: true
artifactId: HelloWorldPlugin
version: 1.0-SNAPSHOT
 Y: : y

当出现 success时,创建成功

BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  01:28 min
[INFO] Finished at: 2022-03-04T16:45:23+08:00
[INFO] ------------------------------------------------------------------------

中间可能会出现报错,试试config文件下的setting文件配置

<?xml version="1.0" encoding="UTF-8"?>

<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->

<!--
 | This is the configuration file for Maven. It can be specified at two levels:
 |
 |  1. User Level. This settings.xml file provides configuration for a single user,
 |                 and is normally provided in ${user.home}/.m2/settings.xml.
 |
 |                 NOTE: This location can be overridden with the CLI option:
 |
 |                 -s /path/to/user/settings.xml
 |
 |  2. Global Level. This settings.xml file provides configuration for all Maven
 |                 users on a machine (assuming they're all using the same Maven
 |                 installation). It's normally provided in
 |                 ${maven.conf}/settings.xml.
 |
 |                 NOTE: This location can be overridden with the CLI option:
 |
 |                 -gs /path/to/global/settings.xml
 |
 | The sections in this sample file are intended to give you a running start at
 | getting the most out of your Maven installation. Where appropriate, the default
 | values (values used when the setting is not specified) are provided.
 |
 |-->
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <!-- localRepository
   | The path to the local repository maven will use to store artifacts.
   |
   | Default: ${user.home}/.m2/repository
  <localRepository>/path/to/local/repo</localRepository>
  -->
  <localRepository>D:\apache-maven-3.8.4\repo</localRepository>

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

  <!-- interactiveMode
   | This will determine whether maven prompts you when it needs input. If set to false,
   | maven will use a sensible default value, perhaps based on some other setting, for
   | the parameter in question.
   |
   | Default: true
  <interactiveMode>true</interactiveMode>
  -->

  <!-- offline
   | Determines whether maven should attempt to connect to the network when executing a build.
   | This will have an effect on artifact downloads, artifact deployment, and others.
   |
   | Default: false
  <offline>false</offline>
  -->

  <!-- pluginGroups
   | This is a list of additional group identifiers that will be searched when resolving plugins by their prefix, i.e.
   | when invoking a command line like "mvn prefix:goal". Maven will automatically add the group identifiers
   | "org.apache.maven.plugins" and "org.codehaus.mojo" if these are not already contained in the list.
   |-->
  <!-- proxies
   | This is a list of proxies which can be used on this machine to connect to the network.
   | Unless otherwise specified (by system property or command-line switch), the first proxy
   | specification in this list marked as active will be used.
   |-->
  <proxies>
    <!-- proxy
     | Specification for one proxy, to be used in connecting to the network.
     |
    <proxy>
      <id>optional</id>
      <active>true</active>
      <protocol>http</protocol>
      <username>proxyuser</username>
      <password>proxypass</password>
      <host>proxy.host.net</host>
      <port>80</port>
      <nonProxyHosts>local.net|some.host.com</nonProxyHosts>
    </proxy>
    -->
  </proxies>

  <!-- servers
   | This is a list of authentication profiles, keyed by the server-id used within the system.
   | Authentication profiles can be used whenever maven must make a connection to a remote server.
   |-->
  <servers>
    <!-- server
     | Specifies the authentication information to use when connecting to a particular server, identified by
     | a unique name within the system (referred to by the 'id' attribute below).
     |
     | NOTE: You should either specify username/password OR privateKey/passphrase, since these pairings are
     |       used together.
     |
    <server>
      <id>deploymentRepo</id>
      <username>repouser</username>
      <password>repopwd</password>
    </server>
    -->

    <!-- Another sample, using keys to authenticate.
    <server>
      <id>siteServer</id>
      <privateKey>/path/to/private/key</privateKey>
      <passphrase>optional; leave empty if not used.</passphrase>
    </server>
    -->
  </servers>
  
<mirrors>
  <!-- mirrors
   | This is a list of mirrors to be used in downloading artifacts from remote repositories.
   |
   | It works like this: a POM may declare a repository to use in resolving certain artifacts.
   | However, this repository may have problems with heavy traffic at times, so people have mirrored
   | it to several places.
   |
   | That repository definition will have a unique id, so we can create a mirror reference for that
   | repository, to be used as an alternate download site. The mirror site will be the preferred
   | server for that repository.
   |-->
  
    <!-- mirror
     | Specifies a repository mirror site to use instead of a given repository. The repository that
     | this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
     | for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
     |
    <mirror>
      <id>mirrorId</id>
      <mirrorOf>repositoryId</mirrorOf>
      <name>Human Readable Name for this Mirror.</name>
      <url>http://my.repository.com/repo/path</url>
    </mirror>
     -->
    <mirror>
      <mirrorOf>m.g.o-public</mirrorOf>
      <url>http://repo.jenkins-ci.org/public</url>
      <id>jenkins-ci.org</id>
      <name>Jenkins CI Public</name>
    </mirror>
    
    <mirror>
      <id>alimaven</id>
      <mirrorOf>central</mirrorOf>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
    </mirror>
 
</mirrors>


  <!-- profiles
   | This is a list of profiles which can be activated in a variety of ways, and which can modify
   | the build process. Profiles provided in the settings.xml are intended to provide local machine-
   | specific paths and repository locations which allow the build to work in the local environment.
   |
   | For example, if you have an integration testing plugin - like cactus - that needs to know where
   | your Tomcat instance is installed, you can provide a variable here such that the variable is
   | dereferenced during the build process to configure the cactus plugin.
   |
   | As noted above, profiles can be activated in a variety of ways. One way - the activeProfiles
   | section of this document (settings.xml) - will be discussed later. Another way essentially
   | relies on the detection of a system property, either matching a particular value for the property,
   | or merely testing its existence. Profiles can also be activated by JDK version prefix, where a
   | value of '1.4' might activate a profile when the build is executed on a JDK version of '1.4.2_07'.
   | Finally, the list of active profiles can be specified directly from the command line.
   |
   | NOTE: For profiles defined in the settings.xml, you are restricted to specifying only artifact
   |       repositories, plugin repositories, and free-form properties to be used as configuration
   |       variables for plugins in the POM.
   |
   |-->
   <profiles>
    <profile>
      <id>jenkins</id>
      <activation>
        <activeByDefault>true</activeByDefault> 
      </activation>
      <repositories> 
        <repository>
          <id>repo.jenkins-ci.org</id>
          <url>https://repo.jenkins-ci.org/public/</url>
        </repository>
      </repositories>
      <pluginRepositories>
        <pluginRepository>
          <id>repo.jenkins-ci.org</id>
          <url>https://repo.jenkins-ci.org/public/</url>
        </pluginRepository>
      </pluginRepositories>
    </profile>
   </profiles>
    <!-- profile
     | Specifies a set of introductions to the build process, to be activated using one or more of the
     | mechanisms described above. For inheritance purposes, and to activate profiles via <activatedProfiles/>
     | or the command line, profiles have to have an ID that is unique.
     |
     | An encouraged best practice for profile identification is to use a consistent naming convention
     | for profiles, such as 'env-dev', 'env-test', 'env-production', 'user-jdcasey', 'user-brett', etc.
     | This will make it more intuitive to understand what the set of introduced profiles is attempting
     | to accomplish, particularly when you only have a list of profile id's for debug.
     |
     | This profile example uses the JDK version to trigger activation, and provides a JDK-specific repo.
    <profile>
      <id>jdk-1.4</id>

      <activation>
        <jdk>1.4</jdk>
      </activation>

      <repositories>
        <repository>
          <id>jdk14</id>
          <name>Repository for JDK 1.4 builds</name>
          <url>http://www.myhost.com/maven/jdk14</url>
          <layout>default</layout>
          <snapshotPolicy>always</snapshotPolicy>
        </repository>
      </repositories>
    </profile>
    -->

    <!--
     | Here is another profile, activated by the system property 'target-env' with a value of 'dev',
     | which provides a specific path to the Tomcat instance. To use this, your plugin configuration
     | might hypothetically look like:
     |
     | ...
     | <plugin>
     |   <groupId>org.myco.myplugins</groupId>
     |   <artifactId>myplugin</artifactId>
     |
     |   <configuration>
     |     <tomcatLocation>${tomcatPath}</tomcatLocation>
     |   </configuration>
     | </plugin>
     | ...
     |
     | NOTE: If you just wanted to inject this configuration whenever someone set 'target-env' to
     |       anything, you could just leave off the <value/> inside the activation-property.
     |
    <profile>
      <id>env-dev</id>

      <activation>
        <property>
          <name>target-env</name>
          <value>dev</value>
        </property>
      </activation>

      <properties>
        <tomcatPath>/path/to/tomcat/instance</tomcatPath>
      </properties>
    </profile>
    -->
  <!-- activeProfiles
   | List of profiles that are active for all builds.
   |
  <activeProfiles>
    <activeProfile>alwaysActiveProfile</activeProfile>
    <activeProfile>anotherAlwaysActiveProfile</activeProfile>
  </activeProfiles>
  -->
</settings>

还有一种,就是可能出现下载失败的问题

添加archetype-catalog.xml文件到存储jar包的repo项目下或者maven项目下

archetype-catalog.xml下载 - 软件E线下载站

3.使用idea打开项目(这是个maven项目) 

打开项目,Java目录下的io,jenkins.plugin.sample.HelloWorldBuild对应着resources目录下的io,jenkins.plugin.sample.HelloWorldBuild

先打开maven,在Lifecycle中clean一下,然后package

会在文件夹下生成target文件,在有pom文件的目录下输入cmd指令

mvn hpi:run

记住hpi:run中间不要有空格

运行完成后,进去网站http://localhost:8080/jenkins/(默认的都是这个)

4.HelloWorldPlugin

新建item,创建Freestyle project

进去到里面,点击构建选项

 应用,保存,Build Now

点击Build History里面刚才创建的项目

在编辑信息里可以查看到,即为输出成功

二:访问Url 

在原先HelloWorldPlugin项目上更改

找到resource目录下的Resource Bundle ‘Messages’,该目录作用为封面做准备

多个properties文件是多个国家之间的语言

Builder.DescriptorImpl.DisplayName:-----是指的构建项目下的名称,例如Say hello world

Resource Bundle ‘config’文件对应的是输出路径配置,HelloworldBuilder目录下的config.jelly中的

<f:entry title="${%Name}" field="name">被public HelloWorldBuilder中的name属性映射,记得换参数时,不要忘了更改
public String getName() {
    return name;
}
//<f:*/>(*代表泛指)标签中的field通过类中属性的get方法进行绑定

主要实现功能在perform方法中实现

这里只更改了参数,记得Resource Bundle ‘Messages’文件下的properties文件和Resource Bundle ‘config文件下的properties文件,最重要的时config.jelly文件,Name要改成Path,name要改成path

在这里为了区分,Messages文件下的改成了

Messages.properties: HelloWorldBuilder.DescriptorImpl.DisplayName=Please enter the address

Messages_zh_CN.properties:

HelloWorldBuilder.DescriptorImpl.DisplayName=\u8bf7\u8f93\u5165\u5730\u5740

package io.jenkins.plugins.sample;

import hudson.Launcher;
import hudson.Extension;
import hudson.FilePath;
import hudson.util.FormValidation;
import hudson.model.AbstractProject;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.tasks.Builder;
import hudson.tasks.BuildStepDescriptor;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;

import javax.servlet.ServletException;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import jenkins.tasks.SimpleBuildStep;
import org.jenkinsci.Symbol;
import org.kohsuke.stapler.DataBoundSetter;

public class HelloWorldBuilder extends Builder implements SimpleBuildStep {

    private  String path;
    private boolean useFrench;
    //定义一个userFrench,默认为false
    @DataBoundConstructor
    public HelloWorldBuilder(String path) {
        this.path = path;
    }
        //path属性映射了config.jelly 中 <f:entry title="${%Path}" field="path"> 的field属性
//这个项目的构建操作时在 HelloWorldBuilder.java 就会获得页面的path值,存在关联属性
    public String getPath() {
        return path;
    }
    //<f:*/>(*代表泛指)标签中的field通过类中属性的get方法进行绑定
    public boolean isUseFrench() {
        return useFrench;
    }

    @DataBoundSetter
    public void setUseFrench(boolean useFrench) {
        this.useFrench = useFrench;
    }
    /*perform 真正开始执行的地方 你所有构建时的任务都将在此内完成
     * 在此之内你可以执行 任意想执行的业务操作,Web Service等
     */
    @Override
    public void perform(Run<?, ?> run, FilePath workspace, Launcher launcher, TaskListener listener) throws InterruptedException, IOException {
        listener.getLogger().println(path);
        StringBuilder result = new StringBuilder();
        //创建远程url连接对象
        URL url = new URL(path);
        //通过远程url连接对象打开一个连接,强转成HTTPURLConnection类
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        //设置连接超时时间和读取超时时间
        conn.setConnectTimeout(15000);
        conn.setReadTimeout(60000);
        conn.setRequestProperty("Accept", "application/json");
        //发送请求
        conn.connect();
        //通过conn取得输入流,并使用Reader读取
        if (200 == conn.getResponseCode()){
            InputStream is = conn.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            String line;
            while ((line = br.readLine()) != null){
                result.append(line);
            }
            br.close();
            is.close();
        }
        conn.disconnect();
        listener.getLogger().println(result.toString());

        if (useFrench) {
            listener.getLogger().println("Bonjour");
        } else {
            listener.getLogger().println("Hello");
        }
    }

    @Symbol("greet")
    @Extension
    public static final class DescriptorImpl extends BuildStepDescriptor<Builder> {

        public FormValidation doCheckName(@QueryParameter String value, @QueryParameter boolean useFrench)
                throws IOException, ServletException {
            if (value.length() == 0)
                return FormValidation.error(Messages.HelloWorldBuilder_DescriptorImpl_errors_missingName());
            return FormValidation.ok();
        }

        @Override
        public boolean isApplicable(Class<? extends AbstractProject> aClass) {
            return true;
        }

        @Override
        public String getDisplayName() {
            return Messages.HelloWorldBuilder_DescriptorImpl_DisplayName();
        }

    }

}

然后clean,package,可能会出现问题,多操作几次就行了,这是idea的问题,如果打包时出现问题,可以刷新一下maven

继续在对应的文件夹下输入cmd指令

mvn hpi:run 

在此之前,可以下载个软件,模拟接口,我这里使用的时Apifox,生成连接,发送

进去 

 http://localhost:8080/jenkins/,创建一个自由项目,增加构建步骤,把连接复制进去,Build一下,就可以了。在控制台输出查看结果,如果对应的插件还是HelloWorldPlugin,重启下Jenkins

 

访问seq文件

 HttpResponse<String> response = Unirest.post("http:///")
                .header("Content-Type", "application/json")
                .body("{\r\n    \"path\":\"/testone/TestCases/body/sequence.seq\"\r\n}")
                .asString();

加入即可,另外修改jelly文件,显示可以访问的文件路径

测试报告

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <testFailureIgnore>true</testFailureIgnore>
                    <includes>
                        <include>**/*Test.java</include>
                    </includes>
                    <excludes>
                        <!-- -->
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

运行完代码后导入build,运行maven命令

mvn test
Tests run: 12, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.131 s
[INFO] Finished at: 2022-03-23T11:34:08+08:00
[INFO] ------------------------------------------------------------------------

在**/target/surefire-reports文件下会生成xml和test文件,为测试报告

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐