用Go开发Drone插件

用Go开发Drone插件

      最近发现了PushDeer这个项目,可以简单的请求推送API,将消息推送到我们的手机设备。最近刚好在捣鼓docker自动化部署(Drone),Drone又支持我们开发插件,所以有了一个想法,就是自定义一个通知插件,通过PushDeer将构建成功后推送消息到我们的设备。

      Drone自定义插件过程也是非常简单,我们只要将插件打包成镜像,在.drone文件中直接使用就可以,并且支持多种语言去开发插件,这里我选择用Go来开发插件。

      一、设计插件接口

      Drone在启动我们的镜像的时候会把settings字段下的参数以前缀为PLUGIN_的全大写环境变量的方式传入给插件。

比如有如下配置文件:

...
settings:
names: [ john, tom]

那么传递的参数是下面这样的:

PLUGIN_NAMES=john,tom

      二、开发插件

      我们先创建一个项目pushdeerDrone,创建一个main.go文件,代码如下:

package main

//引入包
import (
   "strings"
   "strconv"
   "net/http"
   "fmt"
   "time"
   "os"
)

//初始化参数
var pushKey string
var text string
var apiUrl string
var messageType string
var desp string

/**
程序初始化
 */
func init() {
   pushKey = os.Getenv("PLUGIN_PUSHKEY")  //推送Key
   text = os.Getenv("PLUGIN_CONTENT")     //推送内容
   apiUrl = os.Getenv("PLUGIN_URL")       //推送链接
   messageType = os.Getenv("PLUGIN_TYPE") //推送类型
   desp = os.Getenv("PLUGIN_DESP")        //推送内容(markdown)
}

/**
主函数
 */
func main() {
   //处理时间函数
   text = dealTime(text)
   //获取发送体
   payloadParams := dealMessageType(messageType, text, pushKey, desp)
   //组合参数
   payload := strings.NewReader(payloadParams)
   //调用
   _, err := http.Post(apiUrl, "application/x-www-form-urlencoded", payload)
   //判断是否调用失败
   if err != nil {
      fmt.Print(err)
      return
   }
   //输出成功
   fmt.Print("发送成功")
}

/**
处理发送体
 */
func dealMessageType(messageType, text, pushKey, desp string) string {
   //初始化发送请求体
   sendMessage := ""
   //逻辑判断
   switch {
   case messageType == "text": //发送文字
      sendMessage = "pushkey=" + pushKey + "&text=" + text + "&type=text"
   case messageType == "image": //发送图片
      sendMessage = "pushkey=" + pushKey + "&text=" + text + "&type=image"
   case messageType == "markdown": //发送markdown
      sendMessage = "pushkey=" + pushKey + "&text=" + text + "&desp=" + desp + "&type=markdown"
   default: //发送文字
      sendMessage = "pushkey=" + pushKey + "&text=" + text + "&type=image"
   }
   //返回
   return sendMessage
}

/**
处理时间【处理成秒数】
 */
func dealTime(text string) string {
   //扫描结束时间特殊标
   startTimeIndex := strings.Index(text, "%0B")
   if startTimeIndex >= 0 {
      //提取结束时间
      startTime, _ := strconv.ParseInt(text[startTimeIndex+3:startTimeIndex+13], 10, 64)
      //获取当前时间戳
      endTime := time.Now().Unix()
      //获取秒
      seconds := endTime - startTime
      //拼接替换
      replaceString := "%0B" + text[startTimeIndex+3:startTimeIndex+13]
      //秒数转换
      secondsString := dealSeconds(seconds)
      //替换
      text = strings.Replace(text, replaceString, secondsString, -1)
   }
   //返回
   return text
}

/**
处理时间
 */
func dealSeconds(seconds int64) string {
   //秒数转换
   minute := seconds / 60
   second := seconds - minute*60
   //判断文案
   if second > 0 {
      return strconv.FormatInt(minute, 10) + "分" + strconv.FormatInt(second, 10) + "秒"
   } else {
      return strconv.FormatInt(minute, 10) + "分"
   }
}

然后我们初始化mod

go mod init

      三、打包二进制文件

      记住结尾不要留空格,不然会报错。

set GOOS=linux
set GOARCH=amd64
set CGO_ENABLED=0
go build -o pushdeer-drone-plugin

      四、发布镜像

      我这里镜像是托管在docker镜像仓库,所以需要提前创建好镜像仓库,名字为hongzhuangxian/pushdeer-drone-plugin。

      我们输入以下命令行进行打包发布镜像

docker build -t hongzhuangxian/pushdeer-drone-plugin .
docker push hongzhuangxian/pushdeer-drone-plugin

      五、使用插件

      发布完镜像后,我们在.drone中使用我们自己自定义的插件

#通知到手机里
- name: pushdeer
  image: hongzhuangxian/pushdeer-drone-plugin
  settings:
    pushkey: 自己手机的pushkey
    url: https://api2.pushdeer.com/message/push
    type: text
    content:  >
       自动化部署成功%0A

       仓库:${DRONE_REPO_NAME}%0A

       版本:${DRONE_BUILD_NUMBER}%0A

       提交者:${DRONE_COMMIT_AUTHOR_NAME}%0A

       耗时:%0B${DRONE_BUILD_STARTED}%0A

       提交分支:${DRONE_COMMIT_BRANCH}%0A

我们这里的推送服务直接使用PushDeer提供的推送地址,pushkey需要改成我们自己手机对应的pushkey。

      最终构建完成后推送效果如下

WX20220212-103928@2x.png

      目前插件还在完善过程中,第一版本已经可以实现推送图片、文字、markdown格式,大家通过type传值进行不同格式的推送,以下分享几个小技巧

1、如果需要换行可以直接带入以下
%0A
2、如果需要获取构建耗时,可以像这样
%0B${DRONE_BUILD_STARTED}

      项目代码大家可以到pushdeerDrone进行查看,插件镜像可以直接通过以下命令拉取

docker pull hongzhuangxian/pushdeer-drone-plugin

      大家也可以根据自己的情况进行改造,今天先跟大家分享到这里。

0条评论

发表评论