decadence

個人のメモ帳

sbt-ci-releaseとtagprを用いたScala libraryのリリースマネジメント

これは何

OSSとしてGitHubで管理するScala libraryの、リリースマネジメント手法について。 今回、以下の2つのツールを使っている。

課題感

Scala libraryをsbtで開発している際のリリースマネジメントとして、以下のような課題があげられる

  • どのようにして、mavenへ本リリースのartifactをpublishするのか
  • どのようにして、開発状態のものをSNAPSHOT artifactとしてmavenへpublishするのか
  • リリースノートやChange Logはどのようにして作成するのか
  • semverを利用するversion設定において、リリース時のversionをどのように設定するのか

これらの対応において、手オペなどを減らして極力自動化されたリリースを行いたい。

成果物

開発時は main branchへのPRを作成する。main branch へmergeされると、以下の操作が行われる。

  • SNAPSHOT artifactがmavenへpublishされる
  • tagpr が次リリースのためのPRを作成する
    • main branch へのPRがmergeされるたびに、リリース用のPRは更新される

github.com

このリリース用PRをマージすると、 main branch上でgit tagが打たれ、maven centralまで本リリースのversionがpublishされる。

また、tagprでは major, minor のようなlabelをPRへ付与することで、打たれるgit tag (リリース時のversion) を変えることができる。

各種設定について

この成果物を実現するために、上記リポジトリではこのような設定をした。

name: tagpr
on:
  push:
    branches: ["main"]
jobs:
  tagpr:
    runs-on: ubuntu-latest
    outputs:
      tagpr-tag: ${{ steps.tagpr.outputs.tag }}
    steps:
    - uses: actions/checkout@v3
    - id: tagpr
      uses: Songmu/tagpr@v1
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  publish:
    needs: tagpr
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
      with:
        fetch-depth: 0
    - uses: olafurpg/setup-scala@v14
    - run: sbt ci-release
      env:
        PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }}
        PGP_SECRET: ${{ secrets.PGP_SECRET }}
        SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
        SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
        CI_COMMIT_TAG: ${{ needs.tagpr.outputs.tagpr-tag }}

基本的にはtagprやsbt-ci-releaseのREADMEにある設定どおりではあるが、今回以下のような変更をしている。

  • sbt-ci-releaseで CI_COMMIT_TAG を明示的に渡す
    • これはsbt ci-releaseにおいて、 vx.x.x のtagが付与された場合にのみmaven centralへ本リリースとしてpublishする機能を利用している
    • リリースPRをmergeしてtagprがtagを作成した時のみこの値が埋まり、それ以外では空が渡されSNAPSHOT作成となる
  • 1つのworkflowの中で、tagprとpublicの処理を実行している
    • GITHUB_PATを使えば異なるworkflowとすることは可能だが、有効期限のあるPATを更新する手間を避けた
  • build.sbt においてversionを明示せず、tagprのversion管理用ファイルとして別途 .version のファイルを置いた
    • tagprの設定ファイルにおいても、このファイルを指定している
    • sbt ci-releaseではgit tagに応じてversionを自動的に導出することが可能

もちろんsbt-ci-releaseなどにおけるmaven centralのアカウント作成といった手間のかかる事前準備は必要なため、初めて行う人は注意されたい。

結果

以下のようなリリースマネジメントが行えるようになった。

  • 次リリースでどのような機能が入るのかリリースPRを見ればわかる
  • リリースPRをmergeするだけで、本リリースが行える
  • github PRのlabelsを設定するだけで次versionを変更出来る
  • main branchにおける最新artifactをSNAPSHOTとして検証出来る
  • 過去リリースにおけるリリースノートが生成される