Drone使用技巧-编译Go二进制

Drone使用技巧-编译Go二进制

       今天接到一个需求,需要清理服务器过期的目录,决定用Go开发脚本进行定期清理,但是每次升级代码都要重新打包成二进制文件放到服务器运行,刚好这段时间一直在研究Drone,所以想利用Drone来完成编译二进制文件,不用在本地编译,下面跟大家分享这个过程。

       一、项目代码

       下面我贴出Go项目代码,文件名为main.go

package main

//清理15天前目录

/**
引入扩展
 */
import (
   "time"
   "os"
   "io/ioutil"
)

/**
全局变量
 */
type Config struct {
   FileUrl string //清理目录地址
}

//空配置文件
var configData Config //配置

/**
初始化函数
 */
func init() {
   configData.FileUrl = "/home/Records/"
}

/**
脚本主函数
 */
func main() {
   //获取当前年份
   toDayYear := time.Now().Format("2006")
   //获取去年年份
   lastYear := time.Now().AddDate(-1, 0, 0).Format("2006")
   //获取最近15天日期
   startTime := time.Now().AddDate(0, 0, -15).Format("2006-01-02")
   endTime := time.Now().Format("2006-01-02")
   //获取最近15天所有日期【不删除数据】
   dateTimeList := getBetweenDates(startTime, endTime)
   //清理去年目录
   deleteFile(lastYear, dateTimeList)
   //清理今年的目录
   deleteFile(toDayYear, dateTimeList)
   //获取当前时间
   dateTime := time.Now().Format("2006-01-02 15:04:05")
   //输出
   println(dateTime + ":完成一次目录清理")
}

/**
删除目录
 */
func deleteFile(yearValue string, dateTimeList []string) int {
   //获取当前月份
   toDayMonth := time.Now().Format("01")
   //获取当前年份
   toDayYear := time.Now().Format("2006")
   //打开年份目录
   fileUrl := configData.FileUrl + "/" + yearValue
   fileExitStatus := fileExitStatus(fileUrl)
   //判断是否存在目录,不存在不操作
   if fileExitStatus == 0 {
      return 0
   }
   //循环年份目录下所有目录
   files, _ := ioutil.ReadDir(fileUrl)
   //循环目录
   for _, f := range files {
      //文件路径【主目录/年份/月份】
      filePath := fileUrl + "/" + f.Name()
      //再循环一层【获取月份目录下日目录】
      filesMonth, _ := ioutil.ReadDir(filePath)
      for _, monthKey := range filesMonth {
         //组合文件key【年-月-日】
         fileKey := yearValue + "-" + f.Name() + "-" + monthKey.Name()
         //文件路径【主目录/年份/月份/日】
         filePathUrl := filePath + "/" + monthKey.Name()
         //判断该文件是否是否安全【不在最近15天日期】
         fileWhiteStatus := fileKeyStatus(fileKey, dateTimeList)
         //判断是否需要删除
         if fileWhiteStatus == 0 {
            os.RemoveAll(filePathUrl)
         }
      }
      //判断月份目录是否为空目录且月份不能大于当月【直接删除空目录】
      monthDir, _ := ioutil.ReadDir(filePath)
      if len(monthDir) == 0 && toDayMonth > f.Name() {
         os.RemoveAll(filePath)
      }
   }
   //判断年份目录是否为空目录
   yearDir, _ := ioutil.ReadDir(fileUrl)
   if len(yearDir) == 0 && toDayYear > yearValue {
      os.RemoveAll(fileUrl)
   }
   //返回
   return 1
}

/**
获取最近15天日期
 */
func getBetweenDates(startDate, endDate string) []string {
   d := []string{}
   timeFormatTpl := "2006-01-02 15:04:05"
   if len(timeFormatTpl) != len(startDate) {
      timeFormatTpl = timeFormatTpl[0:len(startDate)]
   }
   date, err := time.Parse(timeFormatTpl, startDate)
   if err != nil {
      // 时间解析,异常
      return d
   }
   date2, err := time.Parse(timeFormatTpl, endDate)
   if err != nil {
      // 时间解析,异常
      return d
   }
   if date2.Before(date) {
      // 如果结束时间小于开始时间,异常
      return d
   }
   // 输出日期格式固定
   timeFormatTpl = "2006-01-02"
   date2Str := date2.Format(timeFormatTpl)
   d = append(d, date.Format(timeFormatTpl))
   for {
      date = date.AddDate(0, 0, 1)
      dateStr := date.Format(timeFormatTpl)
      d = append(d, dateStr)
      if dateStr == date2Str {
         break
      }
   }
   return d
}

/**
判断目录是否存在
 */
func fileExitStatus(file string) int {
   _, err := os.Stat(file)
   if err == nil {
      return 1
   }
   if os.IsNotExist(err) {
      return 0
   }
   return 1
}

/**
判断文件路径是否安全
 */
func fileKeyStatus(file string, fileList []string) int {
   //初始化状态
   status := 0
   //循环获取
   for _, value := range fileList {
      if value == file {
         status = 1
      }
   }
   //获取当前日期
   date := time.Now().Format("2006-01-02")
   //设置时区
   Loc, _ := time.LoadLocation("Asia/Shanghai")
   //日期转时间戳
   fileTime, _ := time.ParseInLocation("2006-01-02", file, Loc)
   limitTime, _ := time.ParseInLocation("2006-01-02", date, Loc)
   //判断文件日期是否大于最大截至日期【防止删错今天之后的目录】
   if fileTime.Unix() >= limitTime.Unix() {
      status = 1
   }
   //返回
   return status
}

       二、获取Gitea密钥

       我们到Gitea管理后台获取API密钥,用于下一步将编译后的二进制文件上传到gitea仓库,操作如下

1.png

Drone提交那个是我刚刚生成的,大家记得保存好。

       三、构建配置文件

       我们在项目目录下创建Drone构建文件.drone.yml,配置如下

kind: pipeline
type: docker
name: clear-call-log

#设置挂载
volumes:
  #Docker环境
  - name: docker
    host:
      path: /var/run/docker.sock
  #Docker配置
  - name: docker-daemon
    host:
      path: /etc/docker/daemon.json
#构建步骤
steps:
#设置缓存
- name: clean
  image: docker:19.03.1
  pull: if-not-exists
  network_mode: host
  # 将宿主机的 docker和配置挂载到运行的 docker 容器中,那么在容器中运行 docker 命令时,等同于在宿主机中运行该docker 命令
  volumes:
    - name: docker
      path: /var/run/docker.sock
    - name: images
      path: /images
    - name: docker-daemon
      path: /etc/docker/daemon.json
#编译二进制文件
- name: build
  image: golang:latest
  pull: if-not-exists
  environment:
    GOPROXY: "https://goproxy.cn,direct"  # 懂的都懂
  commands:
    - CGO_ENABLED=0 go build -o clear-call-log
#推送代码到仓库
- name: push
  image: plugins/gitea-release
  settings:
    api_key: 【gitea密钥】
    base_url: 【gitea地址】
    files: clear-call-log
  when:
    event: tag
#通知发到telegram
- name: telegram
  image: hongzhuangxian/telegram-drone-plugin
  pull: if-not-exists
  settings:
    token:
      from_secret: telegram_token
    chat_id:
      from_secret: telegram_chat_id
  when:
    event: tag
#规定master分支
branches: master

 大家根据自己的情况,将gitea密钥替换成自己的、gitea地址替换成自己的gitea地址(地址不是仓库地址),通知那一步,大家根据自己的情况修改,我是通知到电报。

       四、提交打包编译

       我们先提交一遍代码到仓库

git add .
git commit -m '提交'
git push origin master

确保代码最新后,执行编译

git tag v1.0.0
git push origin v1.0.0

 这样就会交给Drone去帮我们编译成二进制文件。

       五、编译过程

       这是Drone打包二进制过程

2.png

这是通知效果图

3.png

我们到Gitea仓库看看我们版本

4.png

然后我们直接下载二进制文件丢到服务器运行就可以了,不用自己本地打包编译。

0条评论

发表评论