【Flutter】Flutterを使った開発でGitHub Actionsを活用する
CI/CDといえば CircleCI や Bitrise などのサービスが有名ですが、GitHub Actionsを使っているプロジェクトも増えてきています。
今回はFlutterを使った開発でGitHub Actionsを活用する方法を紹介します。
PRを作成、アップデートする度にAnalyzeを走らせる
types: [opened, synchronize] とPRの作成時、修正時に実行されるようにしています。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Flutter_Analyzer | |
| on: | |
| pull_request: | |
| types: [opened, synchronize] | |
| jobs: | |
| flutter_analyze: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v2 | |
| with: | |
| fetch-depth: 1 | |
| - uses: subosito/flutter-action@v1 | |
| with: | |
| channel: 'stable' | |
| - run: flutter pub get | |
| - run: flutter analyze |
ちなみに私が普段使っている analysis_options.yaml は次のとおりです。freezedを使っているので関連するファイルの除外設定をしています。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| include: package:flutter_lints/flutter.yaml | |
| analyzer: | |
| exclude: | |
| - "**/*.g.dart" # for freezed | |
| - "**/*.freezed.dart" # for freezed | |
| errors: | |
| missing_required_param: warning | |
| missing_return: warning | |
| invalid_annotation_target: ignore # for freezed | |
| linter: | |
| rules: | |
| - non_constant_identifier_names |
マージされたときにビルドして Firebase App Distribution にアップロードする
PRがmainブランチにマージされた時を想定していますが 、もちろんyamlファイルを書き換えることでdevelopブランチなど特定のブランチにマージされてときにも対応可能です。
iOS
p12ファイル、プロビジョニングファイルをBASE64化してGitHubActionsのSECRETに設定します。パスワードなども合わせてSECRETにします。
BASE64化する際はmacOSであれば次のように実行することでBASE64化してクリップボードにコピーされるので便利です。
AdHoc.p12 | base64 | pbcopy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: auto build & deploy for iOS | |
| on: | |
| push: | |
| branches: [ main ] | |
| pull_request: | |
| branches: [ main ] | |
| jobs: | |
| build: | |
| runs-on: macos-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/checkout@v2 | |
| with: | |
| fetch-depth: 1 | |
| - name: Import Provisioning Profile | |
| run: | | |
| mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles | |
| echo '${{ secrets.PROVISIONING_PROFILE }}' | openssl base64 -d -out ~/Library/MobileDevice/Provisioning\ Profiles/flutter_app_store.mobileprovision | |
| - name: Import Code-Signing Certificates | |
| uses: Apple-Actions/import-codesign-certs@v1 | |
| with: | |
| p12-file-base64: ${{ secrets.CERTIFICATES_P12 }} | |
| p12-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }} | |
| - name: install flutter | |
| uses: subosito/flutter-action@v1 | |
| with: | |
| channel: 'stable' | |
| - name: flutter dependencies install | |
| run: flutter pub get | |
| - name: build ipa | |
| run: flutter build ios --release --no-codesign | |
| - name: iOS Build Action | |
| uses: yukiarrr/ios-build-action@v1.4.0 | |
| with: | |
| project-path: ios/Runner.xcodeproj | |
| export-method: ad-hoc | |
| p12-base64: ${{ secrets.CERTIFICATES_P12 }} | |
| mobileprovision-base64: ${{ secrets.PROVISIONING_PROFILE }} | |
| code-signing-identity: Apple Distribution | |
| team-id: ${{ secrets.TEAM_ID }} | |
| workspace-path: ios/Runner.xcworkspace | |
| certificate-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }} | |
| output-path: app-release.ipa | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v1.0.0 | |
| with: | |
| name: ios | |
| path: app-release.ipa | |
| deploy: | |
| needs: [build] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@v2 | |
| with: | |
| fetch-depth: 1 | |
| - name: Download artifact | |
| uses: actions/download-artifact@v1.0.0 | |
| with: | |
| name: ios | |
| - name: Firebase App Distribution | |
| uses: wzieba/Firebase-Distribution-Github-Action@v1.3.2 | |
| with: | |
| appId: ${{secrets.FIREBASE_APP_ID_IOS}} | |
| token: ${{secrets.FIREBASE_TOKEN}} | |
| groups: testers | |
| file: ios/app-release.ipa | |
| # Delete it because it is unnecessary after uploading. | |
| - name: Delete artifact | |
| uses: geekyeggo/delete-artifact@v1 | |
| with: | |
| name: ios |
Android
AndroidはKEYSTOREをBASE64化し、パスワード、エイリアス名をSECRETに設定します。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: auto build & deploy for Andorid | |
| on: | |
| push: | |
| branches: [ main ] | |
| pull_request: | |
| branches: [ main ] | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/checkout@v2 | |
| with: | |
| fetch-depth: 1 | |
| - name: install java 8.x | |
| uses: actions/setup-java@v1 | |
| with: | |
| java-version: '8.x' | |
| - name: setup cache | |
| uses: actions/cache@v1 | |
| with: | |
| path: /Users/runner/hostedtoolcache/flutter | |
| key: ${{ runner.OS }}-flutter-install-cache | |
| - name: install flutter | |
| uses: subosito/flutter-action@v1 | |
| with: | |
| channel: 'stable' | |
| - name: flutter dependencies install | |
| run: flutter pub get | |
| - name: build apk | |
| run: | | |
| echo '${{ secrets.KEYSTORE_BASE64 }}' | base64 -d > android/release.keystore | |
| export KEYSTORE_PASSWORD='${{ secrets.KEYSTORE_PASSWORD }}' | |
| export KEY_ALIAS='${{ secrets.KEY_ALIAS }}' | |
| export KEY_PASSWORD='${{ secrets.KEY_PASSWORD }}' | |
| flutter build apk --release | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v1.0.0 | |
| with: | |
| name: android | |
| path: build/app/outputs/flutter-apk/app-release.apk | |
| deploy: | |
| needs: [build] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@v2 | |
| with: | |
| fetch-depth: 1 | |
| - name: Download artifact | |
| uses: actions/download-artifact@v1.0.0 | |
| with: | |
| name: android | |
| - name: upload artifact to Firebase App Distribution | |
| uses: wzieba/Firebase-Distribution-Github-Action@v1.3.2 | |
| with: | |
| appId: ${{secrets.FIREBASE_APP_ID_ANDROID}} | |
| token: ${{secrets.FIREBASE_TOKEN}} | |
| groups: testers | |
| file: android/app-release.apk | |
| # Delete it because it is unnecessary after uploading. | |
| - name: Delete artifact | |
| uses: geekyeggo/delete-artifact@v1 | |
| with: | |
| name: android | |