一、環境依賴
JDK版本要求在1.6以上,Maven官方要求版本在3以上,此處本人使用的是JDK1.8 maven3.5.2
然后呢就是你maven的 setting.xml(此setting文件直接放在了C:\Users\xie_7\.m2下)文件要變成這樣:
<?xml version="1.0" encoding="UTF-8"?> <settings> <!-- 指定本地倉庫的存放地址,可選 --> <localRepository>E:\Jenkins\jar</localRepository> <!-- 下面的東西都不用管知道不,只需要copy就ok --> <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>
二、插件開發
1.創建 插件程序
好了,關於Jenkins的使用怎么就不去做過多解釋了,網上多得是,此處閱讀推薦:
https://blog.csdn.net/shuizhihun07/article/details/80168076
執行如下命令:
mvn -s E:\apache-maven-3.5.3\setting.xml -Uorg.jenkins-ci.tools:maven-hpi-plugin:create
然后會根據上文指定的setting.xml文件,下載到本地倉庫中,下載完成后會提示如下信息
然后cd到指定的文件夾下,執行如下命令:
mvn -s E:\apache-maven-3.5.3\settings-jenkins.xml archetype:generate -DgroupId=com.ydzbinfo -DartifactId=sendActiveMessage -DarchetypeArtifactId=maven-archetype-webapp -DarchetypeCatalog=internal
就會在相應文件夾下面創建項目
但是沒有模板,只是一個空項目
但是如果不寫-DarchetypeCatalog=internal參數,那么就會卡住,如下:
下載archetype-catalog.xml文件,根據以下說明,
archetypeCatalog用來指定maven-archetype-plugin讀取archetype-catalog.xml文件的位置:
internal——maven-archetype-plugin內置的
local——本地的,位置為~/.m2/archetype-catalog.xml
remote——指向Maven中央倉庫的Catalog
將該文件copy到本地倉庫的org\apache\maven\archetype\archetype-catalog\3.2.0文件下,
然后配置-DarchetypeCatalog=internal,但是依然無效,還是報如下信息:
不知道哪里有問題,最后將archetype-catalog.xml文件copy到本地倉庫的根文件夾下,然后設置參數-DarchetypeCatalog=local,一個帶有模板的項目終於創建好了
完整命令如下:
mvn -s E:\apache-maven-3.5.3\settings-jenkins.xml archetype:generate -Dfilter=io.jenkins.archetypes: -DarchetypeCatalog=local
執行結果如下:
選擇第2個hello-world-plugin模板,然后maven自動創建項目,整個項目的結構大致如下:
注意HelloWorldBuilder.java類,就要對應一個resource中的HelloWorldBuilder文件夾
2.開發 插件程序
插件的鈎子應該是可以根據繼承的抽象類(抽象類繼承的接口)的不同,確定插件運行的不同步驟
這里按照教程,在build階段發送一個構建項目是否成功的通知,具體代碼如下:

import cn.hutool.http.HttpUtil; import hudson.Launcher; import hudson.Extension; import hudson.FilePath; import hudson.tasks.BuildStepMonitor; import hudson.tasks.Notifier; 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.IOException; import java.util.HashMap; import java.util.Map; import jenkins.tasks.SimpleBuildStep; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundSetter; public class HelloWorldBuilder extends Builder implements SimpleBuildStep { private String receivers=""; private String amServiceUrl=""; private String projectName = ""; private Boolean noPojectNotify=false;//沒有構建結果 private Boolean successNotify=false; //成功 private Boolean failureNotify=false; //失敗 private Boolean abortedNotify=false;//中斷 private Boolean unstableNotify=false;//不穩定 public String getProjectName() { return projectName; } @DataBoundSetter public void setProjectName(String projectName) { this.projectName = projectName; } public String getAmServiceUrl() { return amServiceUrl; } @DataBoundSetter public void setAmServiceUrl(String amServiceUrl) { this.amServiceUrl = amServiceUrl; } public String getReceivers() { return receivers; } @DataBoundSetter public void setReceivers(String receivers) { this.receivers = receivers; } public Boolean getNoPojectNotify() { return noPojectNotify; } @DataBoundSetter public void setNoPojectNotify(Boolean noPojectNotify) { this.noPojectNotify = noPojectNotify; } public Boolean getSuccessNotify() { return successNotify; } @DataBoundSetter public void setSuccessNotify(Boolean successNotify) { this.successNotify = successNotify; } public Boolean getFailureNotify() { return failureNotify; } @DataBoundSetter public void setFailureNotify(Boolean failureNotify) { this.failureNotify = failureNotify; } public Boolean getAbortedNotify() { return abortedNotify; } @DataBoundSetter public void setAbortedNotify(Boolean abortedNotify) { this.abortedNotify = abortedNotify; } public Boolean getUnstableNotify() { return unstableNotify; } @DataBoundSetter public void setUnstableNotify(Boolean unstableNotify) { this.unstableNotify = unstableNotify; } @DataBoundConstructor public HelloWorldBuilder(String projectName,String receivers,String amServiceUrl) { this.projectName=projectName; this.amServiceUrl=amServiceUrl; this.receivers=receivers; } /*perform 真正開始執行的地方 你所有構建時的任務都將在此內完成 * 在此之內你可以執行 任意想執行的業務操作,Web Service等 */ @Override public void perform(Run<?, ?> build, FilePath workspace, Launcher launcher, TaskListener listener) throws InterruptedException, IOException { String string =""; String displayName = build.getDisplayName(); Boolean isNotify=false; //獲取構建結果 if(build.getResult() == null){ string="no project"; } else{ string= build.getResult().toString(); } int number = build.getNumber(); String resuit = null; if(string.equals("no project")){ resuit="無構建結果"; isNotify = this.noPojectNotify; } if(string.equals("SUCCESS")){ resuit="構建結果:成功"; isNotify = this.successNotify; }else if(string.equals("FAILURE")){ resuit="構建結果:失敗"; isNotify = this.failureNotify; }else if(string.equals("UNSTABLE")){ resuit="構建結果:不穩定"; isNotify = this.unstableNotify; }else if(string.equals("ABORTED")){ resuit="構建結果:中斷構建"; isNotify = this.abortedNotify; } String url = build.getUrl(); String content = displayName + projectName+"任務"+resuit; Map map = new HashMap(); map.put("subject","集成編譯平台編譯通知"); map.put("messageBody",content); map.put("recivers",receivers); if(isNotify) { String post = HttpUtil.post(amServiceUrl, map); listener.getLogger().println("result, " + post + "!"); } else { listener.getLogger().println(isNotify); } } @Override public BuildStepMonitor getRequiredMonitorService() { return BuildStepMonitor.NONE; } @Symbol("greet") @Extension //通過此注解 告訴系統該內部類是作為BuildStepDescriptor的擴展出現 public static final class DescriptorImpl extends BuildStepDescriptor<Builder> { /** * 表示對字段"name"做檢查,"name"被填寫時將會被調用,它的內部通過抽象父類Descriptor執行方法getCheckMethod(String fieldName) ,內部通過反射找到參數名稱對應方法。 * @param value 傳入參數"value"表示字段"name"傳入的值 * @param useFrench 而后的參數useFrench是傳入的同名字段的值 * @throws IOException * @throws ServletException */ public FormValidation doCheckName(@QueryParameter String value, @QueryParameter boolean useFrench) throws IOException, ServletException { if (value.length() == 0) { return FormValidation.error("value.length() == 0"); } if (value.length() < 4) { return FormValidation.warning("value.length() < 4"); } if (!useFrench && value.matches(".*[éáàç].*")) { return FormValidation.warning("else"); } return FormValidation.ok(); } @Override public boolean isApplicable(Class<? extends AbstractProject> aClass) { return true; } //這個步驟的名稱 @Override public String getDisplayName() { return "SendActiveMessage"; } } }
config.jelly配置文件:
<?jelly escape-by-default='true'?> <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"> <f:entry title="任務名稱" field="projectName"> <f:textbox /> </f:entry> <f:entry title="接收人(多個接收人用分號隔開)" field="receivers"> <f:textbox /> </f:entry> <f:entry title="am服務地址" field="amServiceUrl"> <f:textbox default="http://172.20.104.227/sendAmMessage/CICDSendActiveMessage.ashx"/> </f:entry> <f:advanced> <f:entry title="無構建結果通知" field="noPojectNotify"> <f:checkbox checked="true"/> </f:entry> <f:entry title="失敗通知" field="failureNotify"> <f:checkbox checked="true"/> </f:entry> <f:entry title="中斷通知" field="abortedNotify"> <f:checkbox checked="true"/> </f:entry> <f:entry title="不穩定通知" field="unstableNotify"> <f:checkbox checked="true"/> </f:entry> <f:entry title="成功通知" field="successNotify"> <f:checkbox /> </f:entry> </f:advanced> </j:jelly>
然后maven clean package 打包,會在target文件夾下生成一個后綴為.hpi的文件,然后在jenkins的插件管理,采用離線上傳的方式
最后,在需要配置的項目中選擇該插件:
參考文章:
Maven創建項目時出現Generating project in Interactive mode就一直卡住的解決方案
免費的maven的archetype-catalog.xml文件下載