開發Jenkins Line Notify Plugin(進階篇)
一、前言
Jenkins有豐富的plugins資源提供開發人員使用,但有時候plugin提供的功能並不能完全符合自己的需求,這時候開發人員就必須自行開發符合需求的plugin。
這次將透過開發LINE Notify功能的plugin,來了解plugin開發步驟。
二、運作流程
這個Plunin可以協助每個專案完成建置編譯時,再透過LINE Notify服務通知相關人員,通知建置編譯是完成或是失敗的訊息。讓整個團隊人員隨時都能知道專案的建置編譯狀況。
三、申請LINE Notify權杖
a.進入https://notify-bot.line.me/ => 「登入」。
b.輸入自己的LINE帳號登入。
c.進入「個人頁面」。
d.點擊「發行權杖」。
e.輸入權杖名稱並選擇要接收的聊天室,在按下「發行」。
f.將權杖記下來,後續會使用到。
四、Maven下載
a.到https://maven.apache.org/,下載Maven 3.6.1。
b.將Maven 3.6.1解壓所放置到C:\Program Files目錄下。
五、建立Jenkins Plugin專案
a.在「命令提示字元」下,執行"C:\Program Files\apache-maven-3.6.1\bin\mvn" -U archetype:generate -Dfilter="io.jenkins.archetypes:"指令,並選擇「1」建立空白專案。
b.number選擇「5」,’artifactId’輸入「lineNotify」,最後按下「y」。
c.成功建立空白專案,畫面如下。
六、開發Jenkins Line Notify Plugin
a.使用Eclipse將空白專案匯入,匯入後畫面如下。
b.在package io.jenkins.plugins下建立LineNotify.java,處理將訊息傳送到LINE,程式碼如下。
package io.jenkins.plugins;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.regex.Pattern;
public class LineNotify {
private static final String strEndpoint = "https://notify-api.line.me/api/notify";
public static final String wrap = "%0D%0A";
public boolean sendMessage(String token, String message, boolean encoded) {
message = replaceProcess(message);
if (!encoded) {
try {
message = URLEncoder.encode(message, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return callEvent(token, message);
}
private boolean callEvent(String token, String message) {
boolean result = false;
try {
String strUrl = strEndpoint;
URL url = new URL(strUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.addRequestProperty("Authorization", "Bearer " + token);
connection.setRequestMethod("POST");
connection.addRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setDoOutput(true);
String parameterString = new String("message=" + message);
PrintWriter printWriter = new PrintWriter(connection.getOutputStream());
printWriter.print(parameterString);
printWriter.close();
connection.connect();
int statusCode = connection.getResponseCode();
if (statusCode == 200) {
result = true;
} else {
throw new Exception("Error:(StatusCode)" + statusCode + ", " + connection.getResponseMessage());
}
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
private String replaceProcess(String txt) {
txt = replaceAllRegex(txt, "\\\\", "¥"); // \
return txt;
}
private String replaceAllRegex(String value, String regex, String replacement) {
if (value == null || value.length() == 0 || regex == null || regex.length() == 0 || replacement == null)
return "";
return Pattern.compile(regex).matcher(value).replaceAll(replacement);
}
}
c. 在package io.jenkins.plugins下建立LineNotifyNotifier.java,Jenkins會執行此物件來進行LINE Notify動作,程式碼如下:
package io.jenkins.plugins;
import java.io.IOException;
import java.net.URLEncoder;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.jenkinsci.Symbol;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;
import hudson.Extension;
import hudson.FilePath;
import hudson.Launcher;
import hudson.model.AbstractProject;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.BuildStepMonitor;
import hudson.tasks.Notifier;
import hudson.tasks.Publisher;
import jenkins.tasks.SimpleBuildStep;
public class LineNotifyNotifier extends Notifier implements SimpleBuildStep {
private String token;
private String remark;
@DataBoundConstructor
public LineNotifyNotifier(String token) {
this.token = token;
}
@DataBoundSetter
public void setRemark(String remark) {
this.remark = remark;
}
public String getToken() {
return token;
}
public String getRemark() {
return remark;
}
@Override
public void perform(Run<?, ?> run, FilePath workspace, Launcher launcher, TaskListener listener)
throws InterruptedException, IOException {
// TODO Auto-generated method stub
LineNotify l = new LineNotify();
StringBuffer message = new StringBuffer();
message.append(LineNotify.wrap + LineNotify.wrap);
message.append(
URLEncoder.encode("專案名稱:" + ("".equals(run.getParent().getDisplayName()) ? run.getParent().getName()
: run.getParent().getDisplayName()), "UTF-8"));
message.append(LineNotify.wrap + LineNotify.wrap);
message.append(URLEncoder.encode("狀態:" + (run.getResult() == null ? "" : run.getResult().toString()), "UTF-8"));
message.append(LineNotify.wrap + LineNotify.wrap);
message.append(URLEncoder.encode("建置歷程:" + run.getNumber(), "UTF-8"));
message.append(LineNotify.wrap + LineNotify.wrap);
long diff = System.currentTimeMillis() - run.getStartTimeInMillis();
long minutes = diff / (1000 * 60);
long seconds = (diff / 1000) - (minutes * 60);
message.append(URLEncoder.encode("建置時間:" + minutes + "分" + seconds + "秒", "UTF-8"));
message.append(LineNotify.wrap + LineNotify.wrap);
message.append(URLEncoder.encode("備註:" + remark, "UTF-8"));
l.sendMessage(token, message.toString(), true);
}
@Extension
public static class DescriptorImpl extends BuildStepDescriptor<Publisher> {
@Override
public boolean isApplicable(@SuppressWarnings("rawtypes") Class<? extends AbstractProject> jobType) {
return true;
}
@Override
public String getDisplayName() {
return "LINE Notify";
}
}
@Override
public BuildStepMonitor getRequiredMonitorService() {
return BuildStepMonitor.NONE;
}
}
七、建立UI元件
a.在resources目錄下建立io\jenkins\plugins\LineNotifyNotifier目錄,如下圖。
b.在io\jenkins\plugins\LineNotifyNotifier目錄下,建立一個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="token">
<f:textbox />
</f:entry>
<f:entry title="備註" field="remark">
<f:textbox />
</f:entry>
</j:jelly>
八、執行Jenkins Line Notify Plugin
a.在「lineNotify」上按右鍵 => 「Run as」=> 「Run Configurations」。
b.執行參數設定如下:
c.等待出現「資訊: Jenkins is fully up and running」,如下圖。
d.在瀏覽器中,進入http://127.0.0.1:8080/jenkins/如下圖,進入「新增作業」。
e.輸入相關作業資訊。
f.進入「建置後動作」=>「新增建置後動作」=>「LINE Notify」。
g.輸入權杖與備註後,按「儲存」。
h.按下「馬上建置」,就可以收到LINE Notify。
九、通知畫面
筆者的LINE就會收到訊息如下。
十、封裝成Jenkins Plugin安裝檔
a.設定如下,在按下「Run」:
b.在「target」目錄下可以找到封裝完成「lineNotify.hpi」檔案。
十、安裝Jenkins Plugin檔案
在「管理 Jenkins」->「外掛程式管理」內,來上傳剛剛完成的lineNotify.hpi檔案。