Flutterプロジェクトに設定しておくと楽になるGitHub Actions

by dicekest,

main.ymlの基本設定

プロジェクトのコードに対して静的チェックを行います。
この中でやることは以下の4つです。

  1. flutter analyze でエラーがないこと
  2. flutter format でエラーがないこと
  3. flutter test でエラーがないこと
  4. grindで作ったスクリプトのエラーがないこと

grindで作ったスクリプトはプロジェクト内の画像ファイルが コード上呼び出しがあるかどうかを検索して回るスクリプトです。
flutter analyze では画像ファイルが実際に使われているかどうかをチェックする機能がなく、 実は使われなくなった画像ファイルなどがいつまでも残り続けてしまう問題が起きないように用意しています。

name: app
on: [pull_request]
jobs:
  test:
    name: Test on ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest]
    steps:
    # Set up Flutter and add it to the path.
    - uses: actions/setup-java@v1
      with:
        java-version: '12.x'
    - uses: subosito/flutter-action@v1
      with:
        flutter-version: '3.3.10'

    - name: Clone the app repository.
      uses: actions/checkout@v2
      with:
        path: 'code'

    - name: Get packages for the Flutter project.
      run: flutter pub get
      working-directory: code/app
    - name: Analyze the project's Dart code.
      run: flutter analyze
      working-directory: code/app
    - name: Ensure the Dart code is formatted correctly.
      run: flutter format --set-exit-if-changed --dry-run ./lib/
      working-directory: code/app
    - name: Run Flutter unit tests.
      run: flutter test
      working-directory: code/app

    # Run custom scripts defined in `tool/grind.dart`.
    - name: Analyze asset files are all in use.
      run: flutter pub run grinder analyze-asset-use
      working-directory: code/app

コードレビュアーを自動でアサインする機能

kentaro-m さんのGitHub Actionを利用しています。
アプリチームは3名とメンバーが少ないこともあり空いている人にレビューをお願いする方針で開発していたのですが、 いくつか面倒な要素が増えてきたので自動でアサインするようにしました。
ランダムではあるので多少レビューのアサインに偏りが出てしまうことはありますが、そこはその時に別途調整したりして開発をしています。

  • 開発ラインが複数になったこと
  • メンバーが4人になってお互いの把握が難しくなってきたこと
  • スプリント開始前の見積もりでコードレビューの分の見積もりをやめたい
name: 'Auto Assign'
on:
  pull_request:
    types: [opened, ready_for_review]

jobs:
  add-reviews:
    runs-on: ubuntu-latest
    steps:
      - uses: kentaro-m/auto-assign-action@v1.2.1
        with:
          configuration-path: '.github/auto_assign.yml'

auto-assign.yml に幾つかの設定を追記するだけで完了します。
今回はチームメンバーと skipKeywords にレビューしないための設定を追加しているので プロジェクトによって少しいじるだけですぐ使い始めることができます

# Set to true to add reviewers to pull requests
addReviewers: true

# Set to true to add assignees to pull requests
addAssignees: author


# A list of reviewers to be added to pull requests (GitHub user name)
reviewers:
  - rydein1
  - rydein2
  - rydein3

# A number of reviewers added to the pull request
# Set 0 to add all the reviewers (default: 0)
numberOfReviewers: 1

runOnDraft: false

skipKeywords:
  - Release

develop -> mainのPRを作成する機能

最後にGitHubのリリースノートを作成するための機能です。
先ほどのPRにラベルを付与したものを利用してラベルごとに分類したリリースノートを作成します。

name: git-pr-release
on:
  push:
    branches:
    - develop
jobs:
  git-pr-release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0 # git-pr-release needs the git histories
      - uses: actions/setup-ruby@v1
        with:
          ruby-version: 3.1
      - run: gem install --no-document git-pr-release
      - run: git-pr-release
        env:
          GIT_PR_RELEASE_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GIT_PR_RELEASE_BRANCH_PRODUCTION: main
          GIT_PR_RELEASE_BRANCH_STAGING: develop
          GIT_PR_RELEASE_LABELS: pr-release
          TZ: Asia/Tokyo
          GIT_PR_RELEASE_TEMPLATE: .github/git-pr-release.erb

ブランチ名のprefixからPRにラベルを付与する機能

スプリントの開発を終えてアプリリリースする際にリリースノートなどで何をやったのかまとめて見たいことが出てくると思います。
そこで、ブランチを作成する際によくつけられるであろう feature/hoge , fix/fuga などの命名ルールを利用してPRにラベルを付与していきます。
後述するリリースノートを作成する機能で、PRのラベルごとにやったことを分類して一覧で確認することができるようになります。

プロジェクトにあった運用に変更したい場合は Get label name の項目でよく使うprefixやラベルに合わせて設定を変更すればすぐOKです。
日々の開発ではあまり目立たないパフォーマンスの改善、リファクタも分類して見えるようにしておくことでモチベーションにもつながる気がします。

name: Automatically labeling pull request.

on:
  pull_request:
    types: [opened]

jobs:
  auto-labeling-pr:
    runs-on: ubuntu-latest

    env:
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

    steps:
      - uses: actions/checkout@v2

      # ラベル名を取得する
      - name: Get label name
        id: label_name
        run: |
          branch_type=$(echo ${{github.head_ref}} | cut -d "/" -f1)
          if [ $branch_type == 'feature' ]; then
            label_name=$(echo "feature")
          elif [ $branch_type == 'fix' ] || [ $branch_type == 'bugfix' ]; then
            label_name=$(echo "bugfix")
          elif [ $branch_type == 'hotfix' ]; then
            label_name=$(echo "hotfix")
          elif [ $branch_type == 'breaking-change' ]; then
            label_name=$(echo "breaking-change")
          elif [ $branch_type == 'performance' ]; then
            label_name=$(echo "performance")
          elif [ $branch_type == 'refactor' ]; then
            label_name=$(echo "refactor")
          else
            label_name=""
          fi
          echo "::set-output name=label_name::$label_name"
      # PRにラベルを付与する
      - name: Auto labeling
        if: ${{ steps.label_name.outputs.label_name }}
        run: |
          number=$(echo $GITHUB_REF | sed -e 's/[^0-9]//g')
          gh pr edit $number --add-label ${{ steps.label_name.outputs.label_name }}

タグをpushしたらGitHubのリリースノートを作成する機能

現在のプロジェクトではCodemagicを利用して開発版のアプリの配信、AppStore等のストアへのアップロード処理を行なっています。
Codemagicにはストア配信用のワークフローが作成されており、リポジトリに特定のタグをpushした時に処理が実行されるように設定して運用しています。
ストアへのアプリのアップロードを行う際には v1.0.0 のようなバージョンのタグを切ってpushすることで下記のActionが動作します。
指定したタグ名を取得しリリースノートのタイトルを指定しています。

name: Create release note

on:
  push:
    tags:
      - "v*.*.*"

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Get the version
        id: get_version
        run: echo ::set-output name=VERSION::${GITHUB_REF#refs/tags/}
      - name: Release
        uses: softprops/action-gh-release@v1
        with:
          name: Release ${{ steps.get_version.outputs.VERSION }}
          generate_release_notes: true

リリースノートのテンプレートを以下のように設定しており、 PRに付与してラベルに応じてタイトルが設定され分類されて見えるようになります。
リリースノートにも表示されるようになるのでコミットメッセージやPRタイトルはわかりやすいテキストを設定しましょう。

changelog:
  exclude:
    labels:
      - ignore-for-release
    authors:
      - octocat
  categories:
    - title: Breaking Changes 🛠
      labels:
        - breaking-change
    - title: Exciting New Features 🎉
      labels:
        - feature
    - title: Refactor & Performance Improvements ⚡️
      labels:
        - performance
        - refactor
    - title: Critical Bugs 🚨
      labels:
        - hotfix
    - title: Other Changes
      labels:
        - "*"

dependabotの設定

pubパッケージのdependabotは現時点ではベータですが、プロジェクトで利用しているパッケージを最新にメンテし続けるのは大変なので スプリントの開発に合わせてアップデートしていける環境を用意しています。
更新のタイミングは週次で、PRのマージ先は develop と指定しています。 特にパッケージ間でバージョンの依存があるようなもの(Firebaseとか)は諸々合わせてパッケージの更新をしてくれるのでかなり便利になる印象です。

version: 2
enable-beta-ecosystems: true
updates:
  - package-ecosystem: "pub"
    directory: "/"
    schedule:
      interval: "weekly"
    target-branch: develop