Goreleaser + TraivsCI 发布 gopo 项目

本贴最后更新于 1121 天前,其中的信息可能已经物是人非

GoreleaserTraivsCI 这边就不再过多介绍,可以去它们官网上了解。这边主要是介绍 gopo 以及如何把它发布出去供人使用。那这篇文章也相应的分为两个部分。

gopo

gopo 说白了就是解析 go 中的结构体,生成对应的结构体字段常量表。也就是说:

type SomeTable struct{
        Id       int     `gorm:"primary_key" json:"id"` //记录id
    	Height   float32 `json:"height"`                //身高
    	Weight   float32 `json:"weight"`                //体重
}

解析以上结构体后,生成如下代码:

// 自动生成
const (
	SomeTableTableName = "cms.some_table"
	
	SomeTableId = "id"
	SomeTableHeight = "height"
	SomeTableWeight = "weight"
)

可以看到,生成了这个结构体中每个字段对应的常量值,这样有什么作用呢?主要是在一些 ORM 框架中,虽然杜绝了直接写 SQL,但也会有写死字段名的情况,如下例所示:

func FindHeight(id int){
    // 只取这两个字段
    db.Select("id","height").Find(&SomeTable{},id)
}
func FindWeight(id int){
    db.Select("id","weight").Find(&SomeTable{},id)
}
// 这种通用的Select就更难管理了
func FindBy(id int,selects []string){
    db.Select(selects).Find(&SomeTable{},id)
}

可以看到,假如我只想去两个字段,还得把字段名写死在代码中。如果是大型的项目,这就有些不好管理了,万一出现一些改名、删字段的极端情况,还得去代码中搜索,也容易遗漏。所以我们最好能把这个数据库字段名提取出来作为常量,利用 IDE 管理起来就很方便了。

a := FindBy(1,[]string{SomeTableId,SomeTableHeight})

这样,即保证了灵活性,也不担心项目里到处都是写死的数据库字段名。那么对于表多、字段多的情况,使用 gopo 自动生成就很方便了。

gopo 的原理也很简单,就是解析 go 的 AST 语法树,然后生成对应的代码,实现的思路和代码都借鉴了 swaggo/swag,这是一个很牛逼的项目,在此表示感谢。

gopo 的使用也很简单,提供了很多可选参数,最简单用法就是:

$ gopo

那么它就会自动在当前目录下寻找 go 文件,收集里面的所有结构体,并为每个结构体生成对应的常量表。更多用法在项目的 README.md 中有说明,也可以通过 --help 去查看此命令的帮助文档。

[Goreleaser&TraivsCI]

进入本文的压轴,其实对 go 语言来说,还有一块很适合的应用就是编写一些命令行程序,简直不要太方便。代码编写完成后,打包直接能生成 Liunx\Mac\Windows 三大平台的可执行文件,也不需要考虑安装环境、语言版本等问题,比 Python、Java 什么的方便太多。当然这里不是想挑起语言之争,只是单说在打包、编译方面,go 做的比较好。

那么如果加上 goreleaser 和 CI,代码一推上去直接打包完毕同时更新到 homebrew、scoop 等包管理软件上,就更加的便捷了。这个项目的 .goreleaser.yml.traivs.yml 这两个配置,基本上其他的 go 语言编写的命令行程序也可以直接拿来使用,有需要者自取即可。

简单介绍一下这整个流程:

  1. TraivsCI 检测到代码提交,自动运行打包任务
  2. 打包任务调用 goreleaser 进行打包
  3. 通过 .goreleaser.yml 中的配置,goreleaser 命令会自动打包并发到 github 的 release 模块,并且推送到 homebrew 或者 scoop 等包管理工具上。

这里要注意的就是两点:

  1. TravisCI 中需要设置 github 的 personal access token,因为 goreleaser 需要往 github 上推包。

image

在图片上红圈标注的位置点击 Setting,然后在 Environment Variables 中加一项 GITHUB_TOKEN 即可。

  1. .goreleaser.yml 会自动建立 homebrewscoop 的 repo,如果直接拿过来是不行的(这是我的账号下的配置),需要一定的修改:
before:
  hooks:
    # You may remove this if you don't use go modules.
    - go mod download
builds:
  - env:
      - CGO_ENABLED=0
    main: cmd/main.go
    goos:
      - linux
      - darwin
      - windows
    goarch:
      - 386
      - amd64
archives:
  - name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
    replacements:
      darwin: Darwin
      linux: Linux
      windows: Windows
      386: i386
      amd64: x86_64
checksum:
  name_template: 'checksums.txt'
snapshot:
  name_template: "{{ .Tag }}-next"
changelog:
  sort: asc
  filters:
    exclude:
      - '^docs:'
      - '^test:'
brews:
  -
    # 项目名
    name: gopo

    # Github repository 需要改成自己的
    tap:
      owner: HYY-yu
      name: homebrew-tap

    # 需要改成自己的
    url_template: "https://github.com/HYY-yu/gopo/releases/download/{{ .Tag }}/{{ .ArtifactName }}"

    # Git author used to commit to the repository.
    # Defaults are shown.
    commit_author:
      name: goreleaserbot
      email: goreleaser@carlosbecker.com

    # Folder inside the repository to put the formula.
    # Default is the root folder.
    folder: Formula

    # Caveats for the user of your binary.
    # Default is empty.
    caveats: "gopo -v"

    # Your app's homepage.
    # Default is empty.
    # homepage: "https://example.com/"

    # Your app's description.
    # Default is empty.
    description: "Gopo"

    # Specify for packages that run as a service.
    # Default is empty.
    plist: |
      <?xml version="1.0" encoding="UTF-8"?>
      ...

    # Custom install script for brew.
    # Default is 'bin.install "program"'.
    install: |
      system "rm -f #{bin}/gopo"
      bin.install "gopo"
scoop:
  # 需要改成自己的
  url_template: "https://github.com/HYY-yu/gopo/releases/download/{{ .Tag }}/{{ .ArtifactName }}"

  # Repository to push the app manifest to.
  bucket:
    owner: HYY-yu
    name: scoop-bucket

  # Git author used to commit to the repository.
  # Defaults are shown.
  commit_author:
    name: goreleaserbot
    email: goreleaser@carlosbecker.com

  # The project name and current git tag are used in the format string.
  commit_msg_template: "Scoop update for {{ .ProjectName }} version {{ .Tag }}"

  # Persist data between application updates
  persist:
    - "data"
    - "config.toml"

总结

那么 Goreleaser+TraivsCI 整个流程基本也介绍完毕了,现在只需要为 master 分支打一个 tag,比如 v0.2.0,那么直接就会生成对应版本的可执行文件,并发布出去。

使用者利用 brew upgrade gopo 更新即可。

  • TraivsCI
    1 引用
  • 开源

    Open Source, Open Mind, Open Sight, Open Future!

    393 引用 • 3380 回帖
  • GitHub

    GitHub 于 2008 年上线,目前,除了 Git 代码仓库托管及基本的 Web 管理界面以外,还提供了订阅、讨论组、文本渲染、在线文件编辑器、协作图谱(报表)、代码片段分享(Gist)等功能。正因为这些功能所提供的便利,又经过长期的积累,GitHub 的用户活跃度很高,在开源世界里享有深远的声望,并形成了社交化编程文化(Social Coding)。

    207 引用 • 2031 回帖
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    491 引用 • 1383 回帖 • 370 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...