暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

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

935

 

今天接到一个需求,需要清理服务器过期的目录,决定用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仓库,操作如下

    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打包二进制过程

          这是通知效果图

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

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


          【图】来源于网络

          【文】https://hongzx.cn/home/blogShow/244

          Follow

          佛布朗斯基博客

          (佛布朗斯基)我是一只热爱编程的码农,已从事后端开发5年以上,也正因此,在日常工作学习中,会遇到蛮多问题需要解决,我希望透过记录,真实地将问题以及解决方法保存下来,更为高效地解决问题是我的初衷。


           

          文章转载自程序员技术笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

          评论