Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android build playstore #2333

Merged
merged 21 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
72b5835
Update Android deployment workflow and configuration for Fastlane
Mozart299 Dec 13, 2024
6f4d47c
Add trigger for Android deployment workflow on push to android-build-…
Mozart299 Dec 13, 2024
6b2484b
Update Android deployment workflow to use Ruby 2.6 and remove push tr…
Mozart299 Dec 13, 2024
4fe1465
Update excon gem version to 1.2.2 in Gemfile.lock
Mozart299 Dec 13, 2024
6872e7d
Downgrade excon gem version to 0.112.0 in Gemfile.lock
Mozart299 Dec 13, 2024
4668b5b
Update Android deployment workflow to use Ruby 3.3.6 and change worki…
Mozart299 Dec 13, 2024
d87b9fd
Update Android deployment workflow to use Ruby 2.6
Mozart299 Dec 13, 2024
b450ed8
Update excon gem version to 1.0.0 in Gemfile.lock
Mozart299 Dec 13, 2024
09673da
Update Android deployment workflow to use Ruby 3.3.6
Mozart299 Dec 13, 2024
f0f578c
Update Android deployment workflow to use Ruby 3.1.0
Mozart299 Dec 13, 2024
65669cb
Add changelog directory and default changelog file for Android deploy…
Mozart299 Dec 13, 2024
bb5f9e9
Add initial release notes for version 2.1.3 in deployment workflow
Mozart299 Dec 13, 2024
28c447a
Update release notes to reflect app version 3.0.2 in deployment workflow
Mozart299 Dec 13, 2024
98d32f9
Add Fastlane lanes for Play Store deployment and Firebase App Distrib…
Mozart299 Dec 13, 2024
06e6528
Add Fastlane plugin for Firebase App Distribution and update Gemfile
Mozart299 Dec 13, 2024
2073a10
Load release keystore properties from prod-key.properties file in bui…
Mozart299 Dec 13, 2024
c32f400
Add Google Maps API key configuration and product flavors for airqo a…
Mozart299 Dec 13, 2024
9b2e6e0
Load application properties from key.properties file in build.gradle
Mozart299 Dec 13, 2024
179c7d9
Update dependencies in pubspec.lock to latest versions
Mozart299 Dec 13, 2024
a7c0eae
Update flutter_sticky_header and value_layout_builder dependencies to…
Mozart299 Dec 13, 2024
6db65ba
Add environment-specific .env files for production and development
Mozart299 Dec 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions .github/workflows/deploy-android-to-play-store.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
if: inputs.android == true
defaults:
run:
working-directory: mobile
working-directory: mobile-v3
steps:
- name: Checkout
uses: "actions/checkout@v4"
Expand Down Expand Up @@ -64,8 +64,8 @@ jobs:
- name: Setup Fastlane
uses: ruby/[email protected]
with:
ruby-version: "2.6"
working-directory: mobile/android
ruby-version: "3.1.0"
working-directory: mobile-v3/android

- name: Install bundle
run: |
Expand All @@ -78,6 +78,13 @@ jobs:
cd android/
echo $MOBILE_ANDROID_PLAYSTORE_SA > play-store-service-account.json
bundle exec fastlane supply init
mkdir -p fastlane/metadata/android/en-US/changelogs
touch fastlane/metadata/android/en-US/changelogs/default.txt

if [ ! -f fastlane/release_notes.txt ]; then
echo "App release version 3.0.2" > fastlane/release_notes.txt
fi

cat fastlane/release_notes.txt > fastlane/metadata/android/en-US/changelogs/default.txt
bundle exec fastlane android play_store
env:
Expand Down
4 changes: 4 additions & 0 deletions mobile-v3/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,7 @@ app.*.map.json
.env
.env.*
*.env

/android/google-services.json
/android/play-store-service-account.json
/android/fastlane/metadata
Comment on lines +74 to +76
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Additional sensitive files need to be ignored

Found an exposed Google Maps API key in iOS configuration and several configuration files that should be considered for gitignore:

  • Add /ios/Runner/AppDelegate.swift to gitignore as it contains an exposed API key
  • Consider adding the following configuration files:
    • /ios/Flutter/*.xcconfig
    • /android/app/src/main/res/xml/network_security_config.xml

While the current additions are good, these additional sensitive files should also be protected to prevent accidental commits of credentials or configuration.

🔗 Analysis chain

Good security practice! Properly ignoring sensitive configuration files.

The additions to .gitignore for google-services.json, play-store-service-account.json, and Fastlane metadata are essential for security. However, let's verify if we're catching all sensitive files.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any potentially sensitive files that might have been committed
rg -l "AIza[0-9A-Za-z-_]{35}" # Search for Google API keys
rg -l "BEGIN PRIVATE KEY" # Search for private key files

Length of output: 95


Script:

#!/bin/bash
# Let's check the content of the file that might contain sensitive information
cat mobile/ios/Runner/AppDelegate.swift

# Also check for any other potential sensitive files in the mobile directories
fd -t f "(google-services|credentials|key|secret|auth|config)" mobile/

Length of output: 1479

6 changes: 6 additions & 0 deletions mobile-v3/android/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
source "https://rubygems.org"

gem "fastlane"

plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
eval_gemfile(plugins_path) if File.exist?(plugins_path)
229 changes: 229 additions & 0 deletions mobile-v3/android/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.7)
base64
nkf
rexml
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
artifactory (3.0.17)
atomos (0.1.3)
aws-eventstream (1.3.0)
aws-partitions (1.1022.0)
aws-sdk-core (3.214.0)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
aws-sigv4 (~> 1.9)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.96.0)
aws-sdk-core (~> 3, >= 3.210.0)
aws-sigv4 (~> 1.5)
aws-sdk-s3 (1.176.1)
aws-sdk-core (~> 3, >= 3.210.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
aws-sigv4 (1.10.1)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
base64 (0.2.0)
claide (1.1.0)
colored (1.2)
colored2 (3.1.2)
commander (4.6.0)
highline (~> 2.0.0)
declarative (0.0.20)
digest-crc (0.6.5)
rake (>= 12.0.0, < 14.0.0)
domain_name (0.6.20240107)
dotenv (2.8.1)
emoji_regex (3.2.3)
excon (0.112.0)
faraday (1.10.4)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0)
faraday-multipart (~> 1.0)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.0)
faraday-patron (~> 1.0)
faraday-rack (~> 1.0)
faraday-retry (~> 1.0)
ruby2_keywords (>= 0.0.4)
faraday-cookie_jar (0.0.7)
faraday (>= 0.8.0)
http-cookie (~> 1.0.0)
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-multipart (1.0.4)
multipart-post (~> 2)
faraday-net_http (1.0.2)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday-rack (1.0.0)
faraday-retry (1.0.3)
faraday_middleware (1.2.1)
faraday (~> 1.0)
fastimage (2.3.1)
fastlane (2.226.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
aws-sdk-s3 (~> 1.0)
babosa (>= 1.0.3, < 2.0.0)
bundler (>= 1.12.0, < 3.0.0)
colored (~> 1.2)
commander (~> 4.6)
dotenv (>= 2.1.1, < 3.0.0)
emoji_regex (>= 0.1, < 4.0)
excon (>= 0.71.0, < 1.0.0)
faraday (~> 1.0)
faraday-cookie_jar (~> 0.0.6)
faraday_middleware (~> 1.0)
fastimage (>= 2.1.0, < 3.0.0)
fastlane-sirp (>= 1.0.0)
gh_inspector (>= 1.1.2, < 2.0.0)
google-apis-androidpublisher_v3 (~> 0.3)
google-apis-playcustomapp_v1 (~> 0.1)
google-cloud-env (>= 1.6.0, < 2.0.0)
google-cloud-storage (~> 1.31)
highline (~> 2.0)
http-cookie (~> 1.0.5)
json (< 3.0.0)
jwt (>= 2.1.0, < 3)
mini_magick (>= 4.9.4, < 5.0.0)
multipart-post (>= 2.0.0, < 3.0.0)
naturally (~> 2.2)
optparse (>= 0.1.1, < 1.0.0)
plist (>= 3.1.0, < 4.0.0)
rubyzip (>= 2.0.0, < 3.0.0)
security (= 0.1.5)
simctl (~> 1.6.3)
terminal-notifier (>= 2.0.0, < 3.0.0)
terminal-table (~> 3)
tty-screen (>= 0.6.3, < 1.0.0)
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
xcodeproj (>= 1.13.0, < 2.0.0)
xcpretty (~> 0.4.0)
xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
fastlane-plugin-firebase_app_distribution (0.9.1)
google-apis-firebaseappdistribution_v1 (~> 0.3.0)
google-apis-firebaseappdistribution_v1alpha (~> 0.2.0)
fastlane-sirp (1.0.0)
sysrandom (~> 1.0)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.54.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-core (0.11.3)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
mini_mime (~> 1.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.a)
rexml
google-apis-firebaseappdistribution_v1 (0.3.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-firebaseappdistribution_v1alpha (0.2.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-iamcredentials_v1 (0.17.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-playcustomapp_v1 (0.13.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-storage_v1 (0.31.0)
google-apis-core (>= 0.11.0, < 2.a)
google-cloud-core (1.7.1)
google-cloud-env (>= 1.0, < 3.a)
google-cloud-errors (~> 1.0)
google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0)
google-cloud-errors (1.4.0)
google-cloud-storage (1.47.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
google-apis-storage_v1 (~> 0.31.0)
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
googleauth (1.8.1)
faraday (>= 0.17.3, < 3.a)
jwt (>= 1.4, < 3.0)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (>= 0.16, < 2.a)
highline (2.0.3)
http-cookie (1.0.8)
domain_name (~> 0.5)
httpclient (2.8.3)
jmespath (1.6.2)
json (2.9.0)
jwt (2.9.3)
base64
mini_magick (4.13.2)
mini_mime (1.1.5)
multi_json (1.15.0)
multipart-post (2.4.1)
nanaimo (0.4.0)
naturally (2.2.1)
nkf (0.2.0)
optparse (0.6.0)
os (1.1.4)
plist (3.7.1)
public_suffix (6.0.1)
rake (13.2.1)
representable (3.2.0)
declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
rexml (3.3.9)
rouge (3.28.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
security (0.1.5)
signet (0.19.0)
addressable (~> 2.8)
faraday (>= 0.17.5, < 3.a)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
simctl (1.6.10)
CFPropertyList
naturally
sysrandom (1.0.5)
terminal-notifier (2.0.0)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
trailblazer-option (0.1.2)
tty-cursor (0.7.1)
tty-screen (0.8.2)
tty-spinner (0.9.3)
tty-cursor (~> 0.7)
uber (0.1.0)
unicode-display_width (2.6.0)
word_wrap (1.0.0)
xcodeproj (1.27.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.4.0)
rexml (>= 3.3.6, < 4.0)
xcpretty (0.4.0)
rouge (~> 3.28.0)
xcpretty-travis-formatter (1.0.1)
xcpretty (~> 0.2, >= 0.0.7)

PLATFORMS
x64-mingw-ucrt

DEPENDENCIES
fastlane
fastlane-plugin-firebase_app_distribution

BUNDLED WITH
2.5.22
51 changes: 50 additions & 1 deletion mobile-v3/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ secrets {
ignoreList.add("sdk.*") // Ignore all keys matching the regexp "sdk.*"
}


def appProperties = new Properties()
def appPropertiesFile = rootProject.file('key.properties')
if (appPropertiesFile.exists()) {
appPropertiesFile.withReader('UTF-8') { reader ->
appProperties.load(reader)
}
}

def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
Expand All @@ -30,6 +39,16 @@ if (localPropertiesFile.exists()) {
}
}

def googleMapApiKey = appProperties.getProperty('google.maps.key')
if (googleMapApiKey == null) {
throw new GradleException("Google Maps Key not found. Define google.maps.key in the key.properties file.")
}

def googleMapApiKeyDev = appProperties.getProperty('google.maps.key.dev')
if (googleMapApiKeyDev == null) {
throw new GradleException("Google Maps Key not found. Define google.maps.key_dev in the key.properties file.")
}
Comment on lines +47 to +50
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Correct the property key name in the exception message

There's an inconsistency between the property key you're accessing and the one mentioned in the exception message. The property key is 'google.maps.key.dev', but the exception message refers to 'google.maps.key_dev'. Ensure both use the same key name for clarity and correctness.

Apply this diff to correct the exception message:

- throw new GradleException("Google Maps Key not found. Define google.maps.key_dev in the key.properties file.")
+ throw new GradleException("Google Maps Key not found. Define google.maps.key.dev in the key.properties file.")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def googleMapApiKeyDev = appProperties.getProperty('google.maps.key.dev')
if (googleMapApiKeyDev == null) {
throw new GradleException("Google Maps Key not found. Define google.maps.key_dev in the key.properties file.")
}
def googleMapApiKeyDev = appProperties.getProperty('google.maps.key.dev')
if (googleMapApiKeyDev == null) {
throw new GradleException("Google Maps Key not found. Define google.maps.key.dev in the key.properties file.")
}


def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
Expand All @@ -40,6 +59,12 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0'
}

def releaseKeystoreProperties = new Properties()
def releaseKeystorePropertiesFile = rootProject.file('prod-key.properties')
if (releaseKeystorePropertiesFile.exists()) {
releaseKeystoreProperties.load(new FileInputStream(releaseKeystorePropertiesFile))
}
Comment on lines +65 to +66
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Ensure proper resource management when loading properties

The FileInputStream used to load releaseKeystoreProperties isn't closed, which can lead to resource leaks. Consider using withInputStream to automatically manage the resource.

Apply this diff to use withInputStream:

- releaseKeystoreProperties.load(new FileInputStream(releaseKeystorePropertiesFile))
+ releaseKeystorePropertiesFile.withInputStream { stream ->
+     releaseKeystoreProperties.load(stream)
+ }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
releaseKeystoreProperties.load(new FileInputStream(releaseKeystorePropertiesFile))
}
releaseKeystorePropertiesFile.withInputStream { stream ->
releaseKeystoreProperties.load(stream)
}
}


android {
namespace "com.airqo.app"
compileSdk 34
Expand Down Expand Up @@ -69,11 +94,35 @@ android {
versionName flutterVersionName
}

flavorDimensions "airqo"
productFlavors {
airqo {
dimension "airqo"
manifestPlaceholders = [googleMapsKey:googleMapApiKey]
}

airqodev {
dimension "airqo"
applicationIdSuffix ".dev"
manifestPlaceholders = [googleMapsKey:googleMapApiKeyDev]
}

}

signingConfigs {
release {
keyAlias releaseKeystoreProperties['keyAlias']
keyPassword releaseKeystoreProperties['keyPassword']
storeFile releaseKeystoreProperties['storeFile'] ? file(releaseKeystoreProperties['storeFile']) : null
storePassword releaseKeystoreProperties['storePassword']
}
}

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.debug
signingConfig signingConfigs.release
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions mobile-v3/android/fastlane/Appfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
json_key_file("play-store-service-account.json") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
package_name("com.airqo.app") # e.g. com.krausefx.app
Loading
Loading