tagprで実現するPull Request上で進めるOSSのリリースマネジメント

私の趣味は少し実用的で小さなOSSを書くことです。

今までも多くの小さなOSSを書いてきました。そして、エコシステム的にリリースすべきものはリリースしてきました。

ここで言うリリースと言うのはバージョンをつけてパッケージとしてPublishすることです。 PHPであればpackagist.orgに、Rubyであればrubygems.orgに、JavaScriptであればnpmjs.comにPublishするまでのことを指します。 Goであれば、バージョンのタグをつけてGitHubリポジトリにプッシュすればリリース完了です。必要であればアセットをGitHubのリリースページにアップロードします。

(自分にとって)適当で心地よいリリースマネジメント

私は基本的にすぐにリリースします。修正1つでもバージョンタグを打ってすぐにリリースすることが多いです。

これはリリースされることで初めて各言語のエコシステムに綺麗にのって利用できるようになるからであり、Pull RequestやIssueで貢献してくれた人(私を含む)にできるだけその結果をフィードバックしたいからです。

なのでバージョンが上がることには何も感じずどんどん上げていきます。

と、ここまで「ぽい」ことを書いてきましたが、なかなか上げないこともあり、それは自分でも言語化できていません。なんでだろう?

ようは適当なんだと思います。

関わる人にとって適当で心地よいリリースマネジメント

では私だけではなく関わる人にとって良いリリースマネジメントというのはどういうものか考えてみました。

  • リリースフローが自動化できていて
  • リリース権限を持っている人がいつでもリリースできるようになっていて
  • 自由にリリースして良いことが明らかになっている

なぜこのようなことを考えたかというと、tagprという便利なツールが現れて、かつ、私が作成したOSSに積極的にコントリビュートしてくれる方が現れたからです。前から考えていたわけではなく「なるほどそういうリリースマネジメントがあるのかも」と思ったのでした。

songmu.jp

リリースマネジメントビフォーアフター

さっそく環境を整備してみました。対象はGoのパッケージ/ツールのリリースマネジメントです。

Before

  • リリース ... GoReleaser
  • リリースアセット作成 ... GoReleaser
  • Dockerイメージ作成 ... GoReleaser
  • HomebrewのFormulaの更新 ... GoReleaser
  • CHANGELOG更新 ... ghch
  • 次のバージョン決定 ... git-semv
  • リリース環境 ... ローカル

基本は手元でmakeコマンドを叩いてリリースしていました。

After

  • リリース ... tagpr
  • リリースアセット作成 ... GoReleaser
  • Dockerイメージ作成 ... GoReleaser
  • HomebrewのFormulaの更新 ... maltmillを使ってPull型に
  • CHANGELOG更新 ... tagpr
  • 次のバージョン決定 ... tagpr
  • リリース環境はGitHub Actions

具体的なGitHub Actionsのワークフローは以下のようになっています。なんとなく雰囲気はわかるかと思います。

name: tagpr
on:
  push:
    branches:
      - main

jobs:
  tagpr:
    runs-on: ubuntu-latest
    outputs:
      tagpr-tag: ${{ steps.run-tagpr.outputs.tag }}
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    steps:
      - name: Check out source code
        uses: actions/checkout@v3

      - id: run-tagpr
        name: Run tagpr
        uses: Songmu/tagpr@v1

  release:
    needs: tagpr
    if: needs.tagpr.outputs.tagpr-tag != ''
    runs-on: macos-latest
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    steps:
      - name: Setup docker
        uses: docker-practice/actions-setup-docker@master

      - name: Login to ghcr.io
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Check out source code
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Setup
        run: |
          brew uninstall go@1.17
          brew install go
          brew install goreleaser
          brew install sqlite3
          brew install messense/macos-cross-toolchains/x86_64-unknown-linux-gnu
      - name: Release
        run: |
          make release

結果

思惑通りになったし、tagpr開発者(であるSongmuさん)の思惑通りでもあったみたいです。

環境を整備してよかったです。私も良い体験でした。