こんにちはEveryDaySoft代表の永田です。
今回はFlutterでGithub Actionsと VScodeのExtension紹介
GitHub Actionsの進捗を確認できる機能です。

VSCodeエディター
iconマークをタップすると、githubにweb遷移します。

GitHubActionsで、FastlaneとDeploygate配信、AppStore配信、GooglePlayConsole配信の紹介をいたします。
FastlaneとDeploygateはローカル上のコマンドでも動作するので、何らかの理由でCIが動かない場合も対応できるので、良いと思いました。
前提
App Store Connect、Google Play Consoleで配信するアプリがあること
iOSで使用する証明書がないこと、ある場合は削除する必要があります。
Gemfile作成
iOSとAndroidのディレクトリー
bundle init
bundle install
iOSとAndroidのディレクトリー
Gemfileのファイル作成
frozen_string_literal: true
source "https://rubygems.org"
gem "fastlane"
iOSとAndroidのデレクトリーで
fastlane init
iOSの場合
2. 👩✈️ Automate beta distribution to TestFlight

Please enter your Apple ID developer credentials
Apple ID Username: Apple IDを入力
Continue by pressing Enter ⏎ Enter を数回繰り返して問題ありません。
fastlaneのディレクトリーが作成されます。

AppfileとFastfileが作成されます。*androidも同様です。

Appfile作成
app_identifier("自動生成") # The bundle identifier of your app
apple_id("自動生成") # Your Apple Developer Portal username
itc_team_id("自動生成") # App Store Connect Team ID
team_id("自動生成") # Developer Portal Team ID
# For more information about the Appfile, see:
# https://docs.fastlane.tools/advanced/#appfile
Matchfile作成
fastlaneのディレクトリーで
fastlane match init
証明書を自動で作成して、連動する目的です。
URL of the Git Repo: GitHubなどのurlを設定願います。

MatchFileが作成されます。*androidも同様です。

解説は自動で英語で記載されてます。

developの場合、証明書が作成されます。 fastlane match development development <-ここをMatchFileのTypeに応じて記載します。
作成以外で使用する場合–readonlyを付与します。
fastlane match development --readonly
成功すると、このようになります。

証明書が既にあり、削除して再作成する必要がある場合は
fastlane match nuke development
iOS_Fastfile作成
App Store Connectのキーを作成画面

fastlane/.envファイル内で作成
api_key
ここから
ASC_KEY_ID="キーID"
ASC_ISSUER_ID="Issuer ID"
ASC_KEY_CONTENT="一度だけダウンロードできる.jsonファイル
ここまで
base64のコマンドを使用して生成
base64 --i pc-api- ~~.json| tr -d "\n" | pbcopy
fastlane/.envファイル内で作成
create_keychain
ここから
MATCH_KEYCHAIN_NAME="キーチェーン名"
MATCH_KEYCHAIN_PASSWORD="pcで使用しているキーチェーンアクセスを解除するパスワード"
ここまで
fastlane/.envファイル内で作成
USERNAME="fastlaneで使用しているメールアドレス"
PERSONAL_GITHUB_ACCESS_TOKEN="個人用アークセストークン"
app_identifierはXcodeのBundleidntifier
default_platform(:ios)
platform :ios do
desc "Push a new release build to the App Store"
lane :release do
api_key = app_store_connect_api_key(
key_id: ENV['ASC_KEY_ID'],
issuer_id: ENV['ASC_ISSUER_ID'],
key_content: ENV['ASC_KEY_CONTENT'],
is_key_content_base64: true,
)
# https://docs.fastlane.tools/actions/create_keychain/
# キーチェーンがないと出力されますが、配信は成功します。
# これがないとfastlaneのupload_to_app_storeが成功しない。
create_keychain(
name: ENV['MATCH_KEYCHAIN_NAME'],
password: ENV['MATCH_KEYCHAIN_PASSWORD'],
default_keychain: true,
unlock: true,
timeout: 3600,
lock_when_sleeps: true
)
username = ENV['USERNAME']
personal_github_access_token = Base64.strict_encode64(ENV['PERSONAL_GITHUB_ACCESS_TOKEN'])
authorization_token_str = "#{username}:#{personal_github_access_token}"
basic_authorization_token = Base64.strict_encode64(authorization_token_str)
# https://docs.fastlane.tools/actions/match/
match(
git_basic_authorization:basic_authorization_token,
api_key: api_key,
app_identifier: ["XcodeのBundleidntifier"],
readonly: false,
type: "appstore", #addhocなどもあります
readonly: is_ci
)
# https://docs.fastlane.tools/actions/build_app/
build_app(
workspace: "Runner.xcworkspace",
scheme: "Runner",
export_options: {
method: "app-store",
},
)
# https://docs.fastlane.tools/actions/upload_to_app_store/
upload_to_app_store(
api_key: api_key,
skip_metadata: true,
skip_screenshots: true,
precheck_include_in_app_purchases: false,
)
end
end
Android_Fastfile作成
app-release.apkとapp-release.aabは事前に作成します。
androidディレクトリーでコマンド実施
./gradlew clean && ./gradlew :app:bundleRelease <-release.apkの作成
flutter build appbundle --no-tree-shake-icons --build-name=1.0.0 --build-number=1. <-aabの作成
release_status: 'draft', <-リリース前、内部公開のためdraft
default_platform(:android)
platform :android do
before_all do |lane, options|
ENV["DEPLOYGATE_API_TOKEN"] = 'DEPLOYGATEに記載してます。'
end
desc "Submit a new Beta Build to Crashlytics Beta"
lane :release do
sh('cd ../../ && flutter build apk --release')
deploygate(
api_token: ENV["DEPLOYGATE_API_TOKEN"],
user: 'DEPLOYGATEのユーザー名',
message: "DeployGate Test配信",
apk: "../build/app/outputs/apk/release/app-release.apk",
)
upload_to_play_store(
track: 'internal',
release_status: 'draft',
aab: "../build/app/outputs/bundle/release/app-release.aab",
skip_upload_metadata: true,
skip_upload_images: true,
skip_upload_screenshots: true
)
end
end
yml作成
Flutterの 7.7.7+0 の 0の数値をGitHubActionsを実行する際は上げてください。

GitHub ActionsのNodeを最新バージョンを設定しています。
iOSのApp Store Connectのビルドは10数分で配信メールが届きます。

- uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '16'
FlutterのTest解析を行うスクリプト
flutter_analyze:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '16'
- uses: subosito/flutter-action@v2
with:
channel: 'stable'
- run: flutter pub get
- run: flutter analyze
- run: flutter test
Flutter、iOSのAppStoreConnect配信スクリプト
secretsの箇所は、GitHub で設定します。
base64のコマンドで作成するもの -> は解説です。 ここから PROVISIONING_PROFILE -> ダウンロードしたAppleのprofile CERTIFICATES_P12 -> キーチェーンアクセスにある使用中の証明書から作成したp12ファイル ASC_API_KEY_CONNECT -> AppStoreConnectユーザとアクセスのキーから一度だけダウンロード可能なjsonファイル SSH_PRIVATE_KEY -> id_ed25519の公開キーをbase64コマンドでコピー base64 --i pc-api- id_ed25519| tr -d "\n" | pbcopy ここまで base64のコマンドで作成しないもの -> は解説です。 ここから CERTIFICATE_PASSWORD -> 作成したp12ファイルに設定したパスワード TEAM_ID -> キーチェーン名の別名(1111111111) MATCH_KEYCHAIN_NAME -> キーチェーン名 MATCH_KEYCHAIN_PASSWORD -> キーチェーンロック解除するパスワード ASC_API_KEY_ID -> キーID ASC_API_ISSUER_ID -> Issuer ID ここまで

GitHubActionsからはssh keyの認証ができないので、
ローカルの.sshディレクトリーで作成
$ ssh-keygen -t ed25519
全て質問はエンター
pbcopy < ~/.ssh/id_ed25519 公開キーをコピー https://github.com/settings/keys 公開キーの登録 秘密キーはgithubのsecrets.箇所で登録
release-ios:
name: Build and release iOS app
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '16'
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- uses: subosito/flutter-action@v2.8.0
with:
flutter-version: '3.7.1'
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2.0'
- run: |
cd ios
bundle install
- name: Install packages
run: flutter pub get
- name: Import Provisioning Profile
env:
PROVISIONING_PROFILE: ${{ secrets.PROVISIONING_PROFILE }}
run: |
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
touch ~/Library/MobileDevice/Provisioning\ Profiles/decoded.mobileprovision
echo -n $PROVISIONING_PROFILE | base64 -d -o ~/Library/MobileDevice/Provisioning\ Profiles/decoded.mobileprovision
- name: Import Code-Signing Certificates
uses: apple-actions/import-codesign-certs@v2
with:
p12-file-base64: ${{ secrets.CERTIFICATES_P12 }}
p12-password: ${{ secrets.CERTIFICATE_PASSWORD }}
# fastlaneで必要なため、SSHキーのセットアップをする.
- name: Setup SSH Keys and known_hosts for fastlane match
run: |
SSH_PATH="$HOME/.ssh"
mkdir -p "$SSH_PATH"
touch "$SSH_PATH/known_hosts"
echo "$PRIVATE_KEY" > "$SSH_PATH/id_ed25519"
chmod 700 "$SSH_PATH"
ssh-keyscan github.com >> ~/.ssh/known_hosts
chmod 600 "$SSH_PATH/known_hosts"
chmod 600 "$SSH_PATH/id_ed25519"
eval $(ssh-agent)
ssh-add "$SSH_PATH/id_ed25519"
env:
PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
- name: Build & upload iOS binary
run: |
cd ios
ls
bundle exec fastlane release
env:
TEAM_ID: ${{ secrets.TEAM_ID }}
MATCH_KEYCHAIN_NAME: ${{ secrets.MATCH_KEYCHAIN_NAME }}
MATCH_KEYCHAIN_PASSWORD: ${{ secrets.MATCH_KEYCHAIN_PASSWORD }}
MATCH_GIT_BASIC_AUTHORIZATION: ${{ secrets.MATCH_GIT_BASIC_AUTHORIZATION }}
ASC_API_KEY_ID: ${{ secrets.ASC_API_KEY_ID }}
ASC_API_ISSUER_ID: ${{ secrets.ASC_API_ISSUER_ID }}
ASC_API_KEY_CONNECT: ${{ secrets.ASC_API_KEY_CONNECT }}
AndroidでGoogle Play ConsoleとDeploygate配信のスクリプト
リリース.apkの作成 android/lib/build.gradle
keytool -genkey -v -keystore keystore名 -alias keyAlias名 -keyalg RSA -keysize 2048 -validity 36500 <-36500は有効期間
キーストアのパスワードを入力してください: keyPassword/storePassword
新規パスワードを再入力してください: keyPassword/storePassword
姓名は何ですか。
[Unknown]: 名前
組織単位名は何ですか。
[Unknown]: 組織名
組織名は何ですか。
[Unknown]: 地域名
都市名または地域名は何ですか。
[Unknown]: Musashino-shi
都道府県名または州名は何ですか。
[Unknown]: Tokyo
この単位に該当する2文字の国コードは何ですか。
[Unknown]: JP
CN=Wataru Yamada, OU=app team, O=org yamacraft, L=Musashino-shi, ST=Tokyo, C=JPでよろしいですか。
[いいえ]: y
signingConfigs {
release {
storeFile file('./keystore名')
storePassword 'パスワード'
keyAlias 'keystorenameファイルを作成時のkeyAlias名'
keyPassword 'パスワード'
}
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.release
}
}
Deploygateに必要な配信設定
GitHub secretsの設定と、Androidディレクトリー内の/fastlane/.envに作成
https://docs.deploygate.com/ja/docs/developer-tools/fastlane/
JSON_KEY_PATHはGCPで作成したJsonキーをbase64化しgithub secrets.登録

Google Cloud Platformで表示


操作セクションからリストを表示


ダウンロードしたjsonはbase64化して、github secrets.登録
release-android:
name: Build and release Android app
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '16'
- uses: subosito/flutter-action@v2.8.0
with:
flutter-version: '3.7.1'
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2.0'
- name: ExportPath
run: |
export PATH=$PATH:${FLUTTER_HOME}/bin/cache/dart-sdk/bin
export PATH=$PATH:${FLUTTER_HOME}/.pub-cache/bin
- name: Building Android AppBundle
run: flutter build appbundle --build-number ${GITHUB_RUN_NUMBER} # build-number
- name: Run builds(fastlane)
run: |
cd android
fastlane deploy
env:
JSON_KEY_PATH: ${{ secrets.JSON_KEY_PATH }}
全体のコード、branchesはプルリクエストをした場合にGitHubActionsが実行されます。
name: GithubActions extension VSCODE
on:
push:
branches: [ test ]
workflow_dispatch:
jobs:
flutter_analyze:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '16'
- uses: subosito/flutter-action@v2
with:
channel: 'stable'
- run: flutter pub get
- run: flutter analyze
- run: flutter test
release-ios:
name: Build and release iOS app
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '16'
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- uses: subosito/flutter-action@v2.8.0
with:
flutter-version: '3.7.1'
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2.0'
- run: |
cd ios
bundle install
- name: Install packages
run: flutter pub get
- name: Import Provisioning Profile
env:
PROVISIONING_PROFILE: ${{ secrets.PROVISIONING_PROFILE }}
run: |
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
touch ~/Library/MobileDevice/Provisioning\ Profiles/decoded.mobileprovision
echo -n $PROVISIONING_PROFILE | base64 -d -o ~/Library/MobileDevice/Provisioning\ Profiles/decoded.mobileprovision
- name: Import Code-Signing Certificates
uses: apple-actions/import-codesign-certs@v2
with:
p12-file-base64: ${{ secrets.CERTIFICATES_P12 }}
p12-password: ${{ secrets.CERTIFICATE_PASSWORD }}
# fastlaneで必要なため、SSHキーのセットアップをする.
- name: Setup SSH Keys and known_hosts for fastlane match
# https://github.com/maddox/actions/blob/master/ssh/entrypoint.sh
run: |
SSH_PATH="$HOME/.ssh"
mkdir -p "$SSH_PATH"
touch "$SSH_PATH/known_hosts"
echo "$PRIVATE_KEY" > "$SSH_PATH/id_ed25519"
chmod 700 "$SSH_PATH"
ssh-keyscan github.com >> ~/.ssh/known_hosts
chmod 600 "$SSH_PATH/known_hosts"
chmod 600 "$SSH_PATH/id_ed25519"
eval $(ssh-agent)
ssh-add "$SSH_PATH/id_ed25519"
env:
PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY2 }}
- name: Build & upload iOS binary
run: |
cd ios
ls
bundle exec fastlane release
env:
TEAM_ID: ${{ secrets.TEAM_ID }}
MATCH_KEYCHAIN_NAME: ${{ secrets.MATCH_KEYCHAIN_NAME }}
MATCH_KEYCHAIN_PASSWORD: ${{ secrets.MATCH_KEYCHAIN_PASSWORD }}
MATCH_GIT_BASIC_AUTHORIZATION: ${{ secrets.MATCH_GIT_BASIC_AUTHORIZATION }}
ASC_API_KEY_ID: ${{ secrets.ASC_API_KEY_ID }}
ASC_API_ISSUER_ID: ${{ secrets.ASC_API_ISSUER_ID }}
ASC_API_KEY_CONNECT: ${{ secrets.ASC_API_KEY_CONNECT }}
release-android:
name: Build and release Android app
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '16'
- uses: subosito/flutter-action@v2.8.0
with:
flutter-version: '3.7.1'
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2.0'
- name: ExportPath
run: |
export PATH=$PATH:${FLUTTER_HOME}/bin/cache/dart-sdk/bin
export PATH=$PATH:${FLUTTER_HOME}/.pub-cache/bin
- name: Building Android AppBundle
run: flutter build appbundle --build-number ${GITHUB_RUN_NUMBER} # build-number
- name: Run builds(fastlane)
run: |
cd android
fastlane deploy
env:
JSON_KEY_PATH: ${{ secrets.JSON_KEY_PATH }}
ローカル対応
iOSディレクトリで
bundle exec fastlane release

Androidはapkとaabをコマンドで事前に作成
androidディレクトリで
bundle exec fastlane deploy

iOSのAppStoreConnectのビルド配信

iOSのAppStoreConnectのTestFlightへのビルド配信

Android,Google Play Consoleの内部配信(リリース済みの場合 製品版も可能)

Android、Deploygate配信(リリースAPK)

No responses yet