Skip to content

Instantly share code, notes, and snippets.

@AlessandroNava
Created January 3, 2020 10:12
Show Gist options
  • Save AlessandroNava/8bd46220d016ef0fc2bcb5cbada7b9d0 to your computer and use it in GitHub Desktop.
Save AlessandroNava/8bd46220d016ef0fc2bcb5cbada7b9d0 to your computer and use it in GitHub Desktop.
Flutter app deploy on Github and Google Play Store
# Miscellaneous
*.class
*.lock
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# Visual Studio Code related
.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.packages
.pub-cache/
.pub/
build/
# Android related
**/key.jks
**/android/**/gradle-wrapper.jar
**/android/.gradle
**/android/captures/
**/android/gradlew
**/android/gradlew.bat
**/android/local.properties
**/android/key.properties
**/android/**/GeneratedPluginRegistrant.java
# iOS/XCode related
**/ios/**/*.mode1v3
**/ios/**/*.mode2v3
**/ios/**/*.moved-aside
**/ios/**/*.pbxuser
**/ios/**/*.perspectivev3
**/ios/**/*sync/
**/ios/**/.sconsign.dblite
**/ios/**/.tags*
**/ios/**/.vagrant/
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata
**/ios/.generated/
**/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/app.flx
**/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/
**/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!**/ios/**/default.mode1v3
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
os: linux
language: generic
dist: xenial
addons:
apt:
packages:
- lib32stdc++6
jdk: oraclejdk8
sudo: false
before_install:
- cd $TRAVIS_BUILD_DIR/$FLUTTER_PROJECT_NAME
install:
- git clone https://github.com/flutter/flutter.git -b stable --depth 1
- export PATH="$PATH:`pwd`/flutter/bin/cache/dart-sdk/bin"
- export PATH="$PATH:`pwd`/flutter/bin"
- flutter doctor -v
- flutter packages get
static_analysis: &static_analysis
name: "Static analysis"
script: flutter analyze --no-pub --no-current-package $TRAVIS_BUILD_DIR/$FLUTTER_PROJECT_NAME/lib $TRAVIS_BUILD_DIR/$FLUTTER_PROJECT_NAME/test
#unit_tests: &unit_tests
# name: "Unit tests"
# script: flutter test --no-pub $TRAVIS_BUILD_DIR/$FLUTTER_PROJECT_NAME/test/
widget_tests: &widget_tests
name: "Widget tests"
script: flutter test --no-pub $TRAVIS_BUILD_DIR/$FLUTTER_PROJECT_NAME/test/widget_test.dart
#integration_tests: &integration_tests
# name: "Integration tests"
# script: flutter drive --target=test_driver/main.dart
build: &build_apk
name: "Build APK"
language: android
jdk:
- oraclejdk8
android:
components:
- tools
- tools
- platform-tools
- build-tools-28.0.3
- android-28
- android-27
before_script:
- echo "$PLAY_STORE_UPLOAD_KEY" | base64 --decode > $TRAVIS_BUILD_DIR/$FLUTTER_PROJECT_NAME/key.jks
- cd $TRAVIS_BUILD_DIR/$FLUTTER_PROJECT_NAME
script:
- flutter build apk --release
deploy:
- provider: releases
api_key: $GITHUB_TOKEN
file: build/app/outputs/apk/release/app-release.apk
skip_cleanup: true
name: $TRAVIS_TAG
on:
tags: true
google_play: &google_play
name: "Google Play"
language: android
jdk:
- oraclejdk8
android:
components:
- tools
- tools
- platform-tools
- build-tools-28.0.3
- android-28
- android-27
install:
- git clone https://github.com/flutter/flutter.git -b stable --depth 1
- export PATH="$PATH:`pwd`/flutter/bin/cache/dart-sdk/bin"
- export PATH="$PATH:`pwd`/flutter/bin"
- flutter doctor -v
- flutter packages get
- gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
- gpg --keyserver hkp://keys.gnupg.net --recv-keys 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
- rvm get stable --auto-dotfiles
- rvm install 2.3.7
- rvm use 2.3.7
- gem update --system
- gem install bundler
- cd $TRAVIS_BUILD_DIR/$FLUTTER_PROJECT_NAME/android
- bundler update --bundler
- bundle install --retry=3 --gemfile=$TRAVIS_BUILD_DIR/$FLUTTER_PROJECT_NAME/android/Gemfile
before_script:
- cd $TRAVIS_BUILD_DIR/$FLUTTER_PROJECT_NAME
- echo "$PLAY_STORE_UPLOAD_KEY" | base64 --decode > $TRAVIS_BUILD_DIR/$FLUTTER_PROJECT_NAME/key.jks
- flutter build appbundle --release
- cd $TRAVIS_BUILD_DIR/$FLUTTER_PROJECT_NAME
- export TRACK=$TRAVIS_BRANCH
- if [[ $TRAVIS_BRANCH == "prod" ]]; then export TRACK=production; fi
- cd $TRAVIS_BUILD_DIR/$FLUTTER_PROJECT_NAME/android
script:
- if [[ $TRAVIS_PULL_REQUEST_BRANCH == beta || $TRAVIS_PULL_REQUEST_BRANCH = alpha || $TRAVIS_PULL_REQUEST_BRANCH = internal ]]; then
bundle exec fastlane promote;
else
bundle exec fastlane release;
fi
jobs:
include:
- <<: *static_analysis
# - <<: *unit_tests
- <<: *widget_tests
# - <<: *integration_tests
- stage: build
<<: *build_apk
- stage: deploy
<<: *google_play
stages:
- name: test
if: (NOT branch =~ /^\d*\.\d*\.\d*$/) OR (NOT branch IN (internal, alpha, beta, prod))
- name: build
if: (NOT branch =~ /^\d*\.\d*\.\d*$/) OR (NOT branch IN (internal, alpha, beta, prod))
- name: deploy
if: (type = push) AND (branch IN (internal, alpha, beta, prod))
cache:
directories:
- "$HOME/.pub-cache"

Flutter app deploy on Github and Google Play Store

Keystore

Generate a .jks for the app with

keytool -genkey -v -keystore $FLUTTER_PROJECT_NAME/key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key

then encode the key with

base64 key.jks

and copy it in an environment variable in Travis-CI named PLAY_STORE_UPLOAD_KEY, add single quotes before and after the variable value.
Also add the password used for the key generation to an environment variable named UPLOAD_KEY_PASSWORD (single quotes here too).

app/build.gradle

Edit the $FLUTTER_PROJECT_NAME/android/app/build.gradle file like this:

...
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}

android {
    ...
    defaultConfig {...}
    signingConfigs {
        release {
            keyAlias keystoreProperties['keyAlias'] != null ? keystoreProperties['keyAlias'] : "key"
            keyPassword keystoreProperties['keyPassword'] != null ? keystoreProperties['keyPassword'] : System.getenv("UPLOAD_KEY_PASSWORD")
            storeFile file("../../key.jks")
            storePassword keystoreProperties['storePassword'] != null ? keystoreProperties['storePassword'] : System.getenv("UPLOAD_KEY_PASSWORD")
        }
    }

    buildTypes {
        release {
            //signingConfig signingConfigs.debug
            signingConfig signingConfigs.release
        }
    }
}
...

key.properties

Add a file at $FLUTTER_PROJECT_NAME/android/key.properties with the following content

storePassword=add_your_password_here
keyPassword=add_your_password_here
keyAlias=key
storeFile=../../key.jks

GitHub token

Generate a new oAuth access token in GitHub here and copy the value in an environment variable named GITHUB_TOKEN.

Deploy to Google Play Store

Install fastlane in your machine using

gem install fastlane -NV

then go to $FLUTTER_PROJECT_NAME/android and run

fastlane init

to setup fastlane in your project, enter the package name exactly as your applicationId in your $FLUTTER_PROJECT_NAME/android/app/build.gradle file.
Then create $FLUTTER_PROJECT_NAME/android/Gemfile with

source "https://rubygems.org"
gem "fastlane"

the run

bundle update

and add both Gemfile and Gemfile.lock to Git.
Then follow this guide to setup fastlane with your Play Console application.
Once completed copy the content of the downloaded JSON file and add it to the Travis-CI environment variables with name GOOGLE_CREDENTIALS (remember the single quotes before and after).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment