🏷️

V*.*.* から始まる名前で Tag を作成時に GitHub Actions でビルドして GitHub のリリースにアップロードする

2023/09/13に公開

はじめに

V*.*.* から始まる名前で Tag を作成した時に GitHub Actions でビルドして GitHub のリリースにアップロードするための、yaml ファイルの作成方法の紹介です。

それがどんなときに役立つか、活用例を説明します。
例えば、Slack で UNCパスのリンクをクリックして直接ファイルが開けるようになる「Liwing」というツールを開発しているとします。
それをバージョンアップして V1.0.2 をリリースしたいという場合に、「V1.0.2_Liwing」というTagをプッシュすれば、自動的にGitHubのリリースのページに「V1.0.2_Liwing」というリリースが作成され、そこにソースコードをビルドしたプログラムをzip圧縮したファイルが添付されます。
つまり、手動で GitHub のリリースのページを作る手間が省略できます。

yaml ファイルの内容

以下に C# を用いて .NET 6 の環境で開発したデスクトップアプリケーションを対象とした yaml ファイルの例を記します。

name: release

# V*.*.* のタグがPushされた場合にこのワークフローは動作します
on:
  push:
    tags:
      - 'V*.*.*'

jobs:
  build:
    name: release-build
    runs-on: windows-latest
    steps:
      # リポジトリからファイルをチェックアウト
      - name: Checkout
        uses: actions/checkout@v3
        
      # .NET6.0 のセットアップをする
      - name: Setup NuGet
        uses: actions/setup-dotnet@v3
        with:
          dotnet-version: 6.0.x
      
      # solution ファイルの状態を復元する
      # (Windowsを対象とするプロジェクトをビルドする場合はEnableWindowsTargetingをtrueにする)
      - name: Restore dependencies
        run: dotnet restore /p:EnableWindowsTargeting=true
        working-directory: src

      # Releaseビルド実行(XXX.sln は適切なファイルを指定すること)
      - name: Build solution
        run: dotnet build src\XXX.sln -c Release
        
      # Release Zipファイル生成(XXXはリリースに格納したいプロジェクトのフォルダ名を指定すること)
      - name: Zip build file
        run: |
          powershell compress-archive src\XXX\bin\Release\net6.0-windows\* release.zip
      
      # GitHubにReleaseを生成
      # github.refの詳細は以下参照
      # https://docs.github.com/ja/actions/learn-github-actions/contexts#github-context
      - name: Create release
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.ref }}
          release_name: ${{ github.ref }}
          body: "リリースの内容は手動で書いてください。"
          draft: false
          prerelease: false
      
      # 生成したReleaseにZipをアップロード(XXX.zipは任意の名前を記すこと)
      - name: Upload Release Asset
        id: upload-release-asset
        uses: actions/upload-release-asset@v1.0.2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: release.zip
          asset_name: XXX.zip
          asset_content_type: application/zip

yaml ファイルの解説

# V*.*.* のタグがPushされた場合にこのワークフローは動作します
on:
  push:
    tags:
      - 'V*.*.*'

上記の部分で、V*.*.*から始まるtagが作られた時に、開始するようにしています。

      # GitHubにReleaseを生成
      # github.refの詳細は以下参照
      # https://docs.github.com/ja/actions/learn-github-actions/contexts#github-context
      - name: Create release
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.ref }}
          release_name: ${{ github.ref }}
          body: "リリースの内容は手動で書いてください。"
          draft: false
          prerelease: false

上記の uses: actions/create-release@v1 の部分について、何をしているかというと GitHub にリリースを生成するAPIを利用しています。
yamlファイルで actions/*** という記述があった場合は、その文字列で検索すると、そのAPIのリポジトリが見つかります。そのリポジトリの README を読むことで詳細な動作を確認できます。
今回の場合、actions/create-release の文字列で検索すると こちらのリポジトリ が見つかります。
また、body: "リリースの内容は手動で書いてください。" について
GitHub のリリースのページの説明内容だけは、手動で書く想定としています。
(コミットログを自動で入れることはできますが、コミットログでは細か過ぎるため)

      # 生成したReleaseにZipをアップロード(XXX.zipは任意の名前を記すこと)
      - name: Upload Release Asset
        id: upload-release-asset
        uses: actions/upload-release-asset@v1.0.2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: release.zip
          asset_name: XXX.zip
          asset_content_type: application/zip

上記の upload_url: ${{ steps.create_release.outputs.upload_url }} の部分を説明します。
upload_url:****actions/upload-release-asset のAPIでアップロードするurlを指定します。
詳しくは actions/upload-release-assetのREAMDE に書いてあります。

また、上記で指定している値として、${{ steps.<step_id>.outputs.<output_id>}} という記述により、前の step での出力結果を参照しています。
1つ前の step の名前が Create release で、その step で利用している actions/create-release というAPIの upload_url という値を参照しています。
upload_url はアセット(今回の場合はビルドしたプログラムをzip圧縮したファイル)をリリースにアップロードするためのURLです。
詳しくは actions/create-releaseのREADME に書いてあります。

また ${{ steps.<step_id>.outputs.<output_id>}} を用いて前の step の結果を利用することについての詳細は以下の記事を参照ください。

https://rso.hateblo.jp/entry/2019/12/14/102305

まとめ

プロダクトのバージョンアップ時に、自動的に GitHub のリリースを作成したい場合に 本稿の GitHub Actions が活用できます。

ちなみに私はITエンジニア向け情報誌「Software Design」の2022年5月号から「ハピネスチームビルディング」を題材に連載記事を書いています。以下で公開していますので、よろしければ、そちらも参照ください。

https://note.com/kojimadev/m/me68d438e12d4

Twitterでも役立つ情報を発信しますのでフォローしてもらえると嬉しいです → @kojimadev

Discussion