Fastlane setup for tagging, releasing, and internal testing (#118)

Configures fastlane to automate our current release process of making a git tag, making a git release, building, and pushing to the Play Store internal track and Testflight. See README.md for details on setup and usage.

Co-authored-by: Amanda Bullington <albullington@gmail.com>
This commit is contained in:
Ken-ichi
2022-07-05 18:19:41 -07:00
committed by GitHub
parent 4b4b0f9244
commit 90ff7a59c0
45 changed files with 3065 additions and 1567 deletions

24
.gitignore vendored
View File

@@ -41,17 +41,6 @@ buck-out/
*.keystore
!debug.keystore
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/
*/fastlane/report.xml
*/fastlane/Preview.html
*/fastlane/screenshots
# Bundle artifact
*.jsbundle
@@ -70,5 +59,14 @@ vendor/
# Secrets file
.env
# Fastlane-generated files
*.zip
# Fastlane files
*.zip
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/Appfile
android/keystore.properties
# Apple signing and auth files that fastlane might download
*.cer
*.mobileprovision

View File

@@ -17,20 +17,20 @@ GEM
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.2.0)
aws-partitions (1.573.0)
aws-sdk-core (3.130.0)
aws-partitions (1.602.0)
aws-sdk-core (3.131.2)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.525.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1.0)
aws-sdk-kms (1.55.0)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.57.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.113.0)
aws-sdk-s3 (1.114.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
aws-sigv4 (1.4.0)
aws-sigv4 (1.5.0)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
claide (1.1.0)
@@ -86,7 +86,7 @@ GEM
escape (0.0.4)
ethon (0.15.0)
ffi (>= 1.15.0)
excon (0.92.2)
excon (0.92.3)
faraday (1.10.0)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
@@ -106,8 +106,8 @@ GEM
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-multipart (1.0.3)
multipart-post (>= 1.2, < 3)
faraday-multipart (1.0.4)
multipart-post (~> 2)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
@@ -116,7 +116,7 @@ GEM
faraday_middleware (1.2.0)
faraday (~> 1.0)
fastimage (2.2.6)
fastlane (2.205.1)
fastlane (2.207.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
@@ -159,9 +159,9 @@ GEM
fourflusher (2.3.1)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.18.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-core (0.4.2)
google-apis-androidpublisher_v3 (0.23.0)
google-apis-core (>= 0.6, < 2.a)
google-apis-core (0.7.0)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
@@ -170,19 +170,19 @@ GEM
retriable (>= 2.0, < 4.a)
rexml
webrick
google-apis-iamcredentials_v1 (0.10.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-playcustomapp_v1 (0.7.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-storage_v1 (0.12.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-iamcredentials_v1 (0.12.0)
google-apis-core (>= 0.6, < 2.a)
google-apis-playcustomapp_v1 (0.9.0)
google-apis-core (>= 0.6, < 2.a)
google-apis-storage_v1 (0.16.0)
google-apis-core (>= 0.6, < 2.a)
google-cloud-core (1.6.0)
google-cloud-env (~> 1.0)
google-cloud-errors (~> 1.0)
google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0)
google-cloud-errors (1.2.0)
google-cloud-storage (1.36.1)
google-cloud-storage (1.37.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
@@ -190,7 +190,7 @@ GEM
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
googleauth (1.1.2)
googleauth (1.2.0)
faraday (>= 0.17.3, < 3.a)
jwt (>= 1.4, < 3.0)
memoist (~> 0.16)
@@ -198,14 +198,14 @@ GEM
os (>= 0.9, < 2.0)
signet (>= 0.16, < 2.a)
highline (2.0.3)
http-cookie (1.0.4)
http-cookie (1.0.5)
domain_name (~> 0.5)
httpclient (2.8.3)
i18n (1.10.0)
concurrent-ruby (~> 1.0)
jmespath (1.6.1)
json (2.6.1)
jwt (2.3.0)
json (2.6.2)
jwt (2.4.1)
memoist (0.16.2)
mini_magick (4.11.0)
mini_mime (1.1.2)
@@ -220,9 +220,9 @@ GEM
optparse (0.1.1)
os (1.1.4)
plist (3.6.0)
public_suffix (4.0.6)
public_suffix (4.0.7)
rake (13.0.6)
representable (3.1.1)
representable (3.2.0)
declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
@@ -233,9 +233,9 @@ GEM
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
security (0.1.3)
signet (0.16.1)
signet (0.17.0)
addressable (~> 2.8)
faraday (>= 0.17.5, < 3.0)
faraday (>= 0.17.5, < 3.a)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
simctl (1.6.8)
@@ -256,11 +256,11 @@ GEM
uber (0.1.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.8.1)
unf_ext (0.0.8.2)
unicode-display_width (1.8.0)
webrick (1.7.0)
word_wrap (1.0.0)
xcodeproj (1.21.0)
xcodeproj (1.22.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)

View File

@@ -1,18 +1,22 @@
# iNaturalistReactNative
## Install packages and pods
1. Run `npm install`
1. Run `npx pod-install ios` or `cd ios && pod install` from the root directory
1. `cp env.example .env` and fill in appropriate values. This is not part of the code repo (contains secrets, such as OAuth client ID).
## Set up pre-commit hooks
1. We're using [Husky](https://typicode.github.io/husky/#/) to automatically run `eslint` before each commit. Run `npm run prepare` to install Husky locally.
## Run build
1. Run `npm start -- --reset-cache` (`npm start` works too, but resetting the cache each time makes for a lot less build issues)
2. Run `npm run ios` or `npm run android`
## Tests
```bash
# Run all tests
npm test
@@ -24,7 +28,8 @@ npm test
./node_modules/.bin/jest -t accessibility
```
We currently have two kinds of tests
We currently have two kinds of tests:
1. `tests/integration`: Tests the test the integration of multiple modules, e.g. a list of observation that makes requests to a mocked API, persists the response data in local storage, retrieves the data from local storage and renders components.
1. `tests/unit`: Tests that only test specific modules, like a single component, or a hook.
@@ -33,9 +38,10 @@ We're using [Jest](https://jestjs.io/) and [React Native Testing Library](https:
## Running with Staging Environment
1. Override `API_URL` to a staging API domain - either using a local `.env` file, or overriding the environment variable when calling `npm start` - e.g. `API_URL=http://example.com npm start -- --reset-cache`
# Translations
## Adding New Text
## Translations
### Adding New Text
1. Add new strings in English to `src/i18n/strings.ftl` using [Fluent syntax](https://projectfluent.org/fluent/guide/), e.g.
```Fluent
@@ -61,7 +67,8 @@ We're using [Jest](https://jestjs.io/) and [React Native Testing Library](https:
};
````
## Translating Text
### Translating Text
We manage translations through Crowdin. Actually updating the translation files should be largely automated, but this is what it looks like to do it manually (you must have the [Crowdin CLI](https://github.com/crowdin/crowdin-cli) installed and have an [access token](https://crowdin.com/settings#api-key) associated with a Crowdin user that can post files to the specified project):
```bash
@@ -75,6 +82,47 @@ git add src/i18n/l10n/*
git commit -a -m "Updated translations"
```
## Troubleshooting
1. Run `react-native clean-project`. This will give you options to clean caches, clean builds, reinstall pods, and reinstall node_modules. Using this eliminates a lot of hard-to-diagnose build issues.
## Deploying
We use [fastlane](https://docs.fastlane.tools/) to help automate parts of the deployment process, which requires some additional setup.
### Setting up fastlane
1. Make a [Github personal access token](https://github.com/settings/tokens/) with repo access in the `GITHUB_TOKEN` environmental variable.
1. `cp android/example-keystore.properties android/keystore.properties` and fill in the relevant values provided by another member of iNat staff.
1. `cp fastlane/example-Appfile fastlane/Appfile` and fill in the relevant values provided by another member of iNat staff.
1. Work with iNat staff to either get a new Apple ID or associate an existing one with the iNat Apple development team
1. Sign in to Xcode with your Apple ID
1. Manage Certificates and add an Apple Distribution certificate associated with the iNaturalist team
### Usage
The current expectation is that you we tag to freeze the code, bump the version, and describe the changes represented by the tag. Then we release to make builds and publish on Github. Later, presumably when some of the change logs have been translated, we push builds for internal testing. If that looks ok, we push to public testing, and later to production release.
```zsh
# Make a git tag. This will bump the build number and prompt you to describe
# what changed, which will be used for the eventual github release
# description and changelogs uploaded to the app stores.
fastlane tag
# Make a github release. This will make relevant builds, a github release, and
# add build files to the release
fastlane release
# Upload the build for the latest tag for internal testing
fastlane internal
# Upload the build for the latest tag for public testing (promotes latest
# internal build to open testing)
fastlane beta
# Upload the build for the latest tag to production release. In Android, this
# should just promote the last beta to prod.
fastlane prod
```

View File

@@ -105,21 +105,6 @@ def enableSeparateBuildPerCPUArchitecture = false
*/
def enableProguardInReleaseBuilds = false
def getPassword(String currentUser, String keyChain) {
def stdout = new ByteArrayOutputStream()
def stderr = new ByteArrayOutputStream()
exec {
commandLine 'security', '-q', 'find-generic-password', '-a', currentUser, '-s', keyChain, '-w'
standardOutput = stdout
errorOutput = stderr
ignoreExitValue true
}
//noinspection GroovyAssignabilityCheck
stdout.toString().trim()
}
def pass = getPassword("iNaturalist.org","inaturalist-android")
/**
* The preferred build flavor of JavaScriptCore.
*
@@ -142,6 +127,17 @@ def jscFlavor = 'org.webkit:android-jsc:+'
*/
def enableHermes = project.ext.react.get("enableHermes", true);
// Create a variable called keystorePropertiesFile, and initialize it to your
// keystore.properties file, in the rootProject folder. keystore.properties
// contains values like the local path to your keystore and the password.
def keystorePropertiesFile = rootProject.file("keystore.properties")
// Initialize a new Properties() object called keystoreProperties.
def keystoreProperties = new Properties()
// Load your keystore.properties file into the keystoreProperties object.
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
android {
ndkVersion rootProject.ext.ndkVersion
@@ -151,8 +147,9 @@ android {
applicationId "com.inaturalistreactnative"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 10
versionCode 21
versionName "0.1.1"
setProperty("archivesBaseName", applicationId + "-v" + versionName + "+" + versionCode)
}
splits {
abi {
@@ -170,10 +167,10 @@ android {
keyPassword 'android'
}
release {
storeFile file(INATRN_RELEASE_STORE_FILE)
storePassword pass
keyAlias INATRN_RELEASE_KEY_ALIAS
keyPassword pass
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
}
}
buildTypes {

View File

@@ -13,6 +13,7 @@ import java.util.List;
import com.lugg.ReactNativeConfig.ReactNativeConfigPackage;
import com.facebook.react.bridge.JSIModulePackage;
import com.swmansion.reanimated.ReanimatedJSIModulePackage;
import com.reactnativecommunity.cameraroll.CameraRollPackage;
public class MainApplication extends Application implements ReactApplication {

View File

@@ -1,20 +1,30 @@
import org.apache.tools.ant.taskdefs.condition.Os
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext {
buildToolsVersion = "30.0.2"
buildToolsVersion = "33.0.0"
minSdkVersion = 21
compileSdkVersion = 31
targetSdkVersion = 31
ndkVersion = "20.1.5948944"
kotlinVersion = "1.5.0"
if (System.properties['os.arch'] == "aarch64") {
// For M1 Users we need to use the NDK 24 which added support for aarch64
ndkVersion = "24.0.8215888"
} else {
// Otherwise we default to the side-by-side NDK version from AGP.
ndkVersion = "21.4.7075529"
}
}
repositories {
google()
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:4.2.2")
classpath("com.android.tools.build:gradle:7.0.4")
classpath("com.facebook.react:react-native-gradle-plugin")
classpath("de.undercouch:gradle-download-task:4.1.2")
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files

View File

@@ -0,0 +1,4 @@
storePassword=myStorePassword
keyPassword=mykeyPassword
keyAlias=myKeyAlias
storeFile=myStoreFileLocation

View File

@@ -1,2 +0,0 @@
json_key_file(ENV["JSON_KEY_ANDROID"]) # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
package_name("com.inaturalistreactnative") # e.g. com.krausefx.app

View File

@@ -1,46 +0,0 @@
# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
# https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
# https://docs.fastlane.tools/plugins/available-plugins
#
# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane
default_platform(:android)
platform :android do
desc "Distributes iNaturalistReactNative Android bundle to the Play Store internal track"
lane :internal do
gradle(task: "bundle", build_type: "Release")
upload_to_play_store(
track: "internal",
release_status: "draft",
package_name: ENV["PACKAGE_NAME"],
skip_upload_apk: true
)
slack(
message: "iNaturalistReactNative Android internal build successfully deployed!",
success: true,
slack_url: ENV["SLACK_WEBHOOK"],
default_payloads: [:lane, :test_result, :git_branch, :last_git_commit_hash],
attachment_properties: {
fields: [
{
title: "Version",
value: android_get_version_name(gradle_file: "app/build.gradle")
},
{
title: "Build",
value: android_get_version_code(gradle_file: "app/build.gradle")
}
]
})
end
end

View File

@@ -1,5 +0,0 @@
# Autogenerated by fastlane
#
# Ensure this file is checked in to source control!
gem 'fastlane-plugin-versioning_android'

View File

@@ -30,6 +30,3 @@ FLIPPER_VERSION=0.93.0
# need this to avoid out of memory error on device
# https://stackoverflow.com/questions/57606462/a-failure-occurred-while-executing-com-android-build-gradle-internal-tasks
org.gradle.jvmargs=-Xmx4608m
INATRN_RELEASE_STORE_FILE=inaturalist-android.keystore
INATRN_RELEASE_KEY_ALIAS=inaturalist-android

View File

@@ -1,13 +1,19 @@
rootProject.name = 'iNaturalistReactNative'
include ':@react-native-community_cameraroll'
project(':@react-native-community_cameraroll').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/cameraroll/android')
include ':react-native-exception-handler'
project(':react-native-exception-handler').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-exception-handler/android')
include ':react-native-localize'
project(':react-native-localize').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-localize/android')
include ':react-native-pure-jwt'
project(':react-native-pure-jwt').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-pure-jwt/android')
include ':react-native-pure-jwt'
project(':react-native-pure-jwt').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-pure-jwt/android')
include ':react-native-config'
project(':react-native-config').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-config/android')
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'
includeBuild('../node_modules/react-native-gradle-plugin')
if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") {
include(":ReactAndroid")
project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid')
}

352
fastlane/Fastfile Normal file
View File

@@ -0,0 +1,352 @@
require "fileutils"
appfile_path = File.join( File.expand_path( File.dirname( __FILE__ ) ), "Appfile" )
unless File.exist?( appfile_path )
UI.abort_with_message! <<~NO_APPFILE_ERROR.gsub( /\s+/, " " ).strip
Could not find #{appfile_path}. Copy the example file in that directory to
that path and fill in the relevant values to use Fastlane.
NO_APPFILE_ERROR
end
VERSION = File.open( "../package.json" ) { | f | JSON.parse( f.read )["version"] }
editor_cmd = [
ENV["EDITOR"],
`git config core.editor`,
`which vi`
].map{| e | e.to_s.strip }.detect {| e | !e.empty? }
if editor_cmd.nil?
UI.abort_with_message! <<~NO_EDITOR_ERROR
Could not find an editor, not even vi. Set the EDITOR environmental
variable or the core.editor git config"
NO_EDITOR_ERROR
end
editor_cmd_needs_to_wait = ( editor_cmd =~ /^code / || editor_cmd =~ /^subl / ) && !editor_cmd.include?( "-w" )
EDITOR = editor_cmd_needs_to_wait ? "#{editor_cmd} -w" : editor_cmd
XCODEPROJ = "ios/iNaturalistReactNative.xcodeproj"
PACKAGE_ID = CredentialsManager::AppfileConfig.try_fetch_value( :package_name )
def set_android_version_code( new_version_code )
build_gradle_path = "../android/app/build.gradle"
new_gradle = File.read( build_gradle_path ).sub( /versionCode\s+\d+/, "versionCode #{new_version_code}" )
File.open( build_gradle_path, "w" ) { | f | f.write( new_gradle ) }
end
def set_android_version_name( new_version_name )
build_gradle_path = "../android/app/build.gradle"
new_gradle = File.read( build_gradle_path ).sub( /versionName\s+".+"/, "versionName \"#{VERSION}\"" )
File.open( build_gradle_path, "w" ) { | f | f.write( new_gradle ) }
end
def get_changelog_path( build_number = nil )
build_number ||= get_build_number( xcodeproj: XCODEPROJ )
changelog_dir_path = File.join( "metadata", "android", "en-US", "changelogs" )
FileUtils.mkpath( changelog_dir_path )
File.join( changelog_dir_path, "#{build_number}.txt" )
end
def get_aab_path( build_number = nil )
build_number ||= get_build_number( xcodeproj: XCODEPROJ )
aab_path = File.join(
File.expand_path( File.dirname( __FILE__ ) ),
"..",
"android",
"app",
"build",
"outputs",
"bundle",
"release",
"#{PACKAGE_ID}-v#{VERSION}+#{build_number}-release.aab"
)
end
def get_apk_path( build_number = nil )
build_number ||= get_build_number( xcodeproj: XCODEPROJ )
aab_path = File.join(
File.expand_path( File.dirname( __FILE__ ) ),
"..",
"android",
"app",
"build",
"outputs",
"apk",
"release",
"#{PACKAGE_ID}-v#{VERSION}+#{build_number}-release.apk"
)
end
def get_ipa_path( build_number = nil )
build_number ||= get_build_number( xcodeproj: XCODEPROJ )
aab_path = File.join(
File.expand_path( File.dirname( __FILE__ ) ),
"..",
"ios",
"build",
"#{PACKAGE_ID}-v#{VERSION}+#{build_number}.ipa"
)
end
lane :tag do
desc "Add a new tag with an incremented version"
ensure_git_status_clean
last_tag = last_git_tag
# Increment the iOS build number
increment_build_number( xcodeproj: XCODEPROJ )
build_number = get_build_number( xcodeproj: XCODEPROJ )
# set android/app/build.gradle versionCode to this build_number
set_android_version_code( build_number )
# set android/app/build.gradle versionName to VERSION
set_android_version_name( VERSION )
tag = "v#{VERSION}+#{build_number}"
changes = changelog_from_git_commits( pretty: "# * %h %s (%an, %ai)" )
if last_tag && changes.empty?
UI.abort_with_message! "Nothing has changed since the last tag (#{last_tag})"
end
# Get release notes
# Bit silly but takes advantage of existing syntax highlighting
fname = "COMMIT_EDITMSG"
File.open( fname, "w" ) do | f |
f << <<~INSTRUCTIONS
# Enter notes about what's new in #{tag}. Lines beginning with # will be ignored.
#
# Here's what changed since the last tag:
#{changes}
INSTRUCTIONS
end
system "#{EDITOR} #{fname}", exception: true
release_notes = ""
File.readlines( fname ).each do | line |
release_notes += line unless line[0] == "#"
end
release_notes.strip!
FileUtils.rm( fname )
if release_notes.strip.size == 0
reset_git_repo skip_clean: true
UI.abort_with_message! "You gotta enter release notes!"
end
# Write release notes to a place where they can be translated and add that file to git
changelog_path = get_changelog_path( build_number )
File.open( changelog_path, "w" ) do | f |
f << "#{release_notes}\n"
end
changelog_git_path = File.join( "fastlane", changelog_path )
git_add( path: changelog_git_path )
# commit
commit_version_bump( message: tag, xcodeproj: XCODEPROJ, include: [
"android/app/build.gradle",
changelog_git_path
] )
push_to_git_remote
# Create a tag for this release
add_git_tag( tag: tag )
push_git_tags
end
platform :android do
lane :build do
desc "Build release files for Android"
keystore_properties_path = File.join(
File.expand_path( File.dirname( __FILE__ ) ),
"..",
"android",
"keystore.properties"
)
unless File.exist?( keystore_properties_path )
UI.abort_with_message! <<~NO_KEYSTORE_PROPERTIES_ERROR.gsub( /\s+/, " " ).strip
Could not find #{keystore_properties_path}. Copy the example file in that directory to
that path and fill in the relevant values to build for Android.
NO_KEYSTORE_PROPERTIES_ERROR
end
build_number = get_build_number( xcodeproj: XCODEPROJ )
# Build AAB. This should write
# android/app/build/outputs/bundle/release/PACKAGE_ID-vVERSION_NAME+VERSION_CODE-release.aab
aab_path = get_aab_path( build_number )
if File.exist?( aab_path )
UI.important "AAB already exists at #{aab_path}"
else
gradle( task: "bundle", project_dir: "android" )
end
unless File.exist?( aab_path )
UI.abort_with_message! "Failed to create AAB at #{aab_path}"
end
# Build APK. This should write
# android/app/build/outputs/apk/release/PACKAGE_ID-vVERSION_NAME+VERSION_CODE-release.apk
apk_path = get_apk_path( build_number )
if File.exist?( apk_path )
UI.important "APK already exists at #{apk_path}"
else
gradle( task: "build", project_dir: "android", flags: "-x lint" )
end
unless File.exist?( apk_path )
UI.abort_with_message! "Failed to create APK at #{apk_path}"
end
end
lane :clean do
Dir.glob( File.join( File.dirname( get_aab_path ), "*.aab" ) ).each do | aab_path |
UI.message "Deleting #{aab_path}"
File.delete aab_path
end
Dir.glob( File.join( File.dirname( get_apk_path ), "*.apk" ) ).each do | apk_path |
UI.message "Deleting #{apk_path}"
File.delete apk_path
end
end
end
platform :ios do
lane :build do
desc "Build release files for iOS"
# Build iOS app
get_certificates
get_provisioning_profile
ipa_path = get_ipa_path
if File.exist?( ipa_path )
UI.important "IPA already exists at #{ipa_path}"
else
build_app(
workspace: File.join( "ios", "iNaturalistReactNative.xcworkspace" ),
scheme: "iNaturalistReactNative",
output_directory: File.dirname( ipa_path ),
output_name: File.basename( ipa_path )
)
end
end
lane :clean do
Dir.glob( File.join( File.dirname( get_ipa_path ), "*.ipa" ) ).each do | ipa_path |
UI.message "Deleting #{ipa_path}"
File.delete ipa_path
end
end
end
lane :build do
desc "Build release files for all platforms"
Fastlane::LaneManager.cruise_lane "ios", "build"
Fastlane::LaneManager.cruise_lane "android", "build"
end
lane :clean do
desc "Delete build artifacts"
Fastlane::LaneManager.cruise_lane "ios", "clean"
Fastlane::LaneManager.cruise_lane "android", "clean"
end
lane :release do
desc "Make github release for the latest tag and make builds"
last_tag = last_git_tag
if last_tag.nil? || last_tag.empty?
UI.abort_with_message! "No tags have been added yet. Try starting with `fastlane tag`"
end
original_branch = git_branch
system "git checkout #{last_tag}", exception: true
build_number = get_build_number( xcodeproj: XCODEPROJ )
if build_number.to_s != last_tag.split( "+" ).last
UI.abort_with_message! <<~MSG
The last tag doesn't match the current build number. Either make a new
tag or check out the tag before releasing.
MSG
end
changelog_path = get_changelog_path( build_number )
unless File.exist?( changelog_path )
UI.abort_with_message! <<~MSG
No change log file exists at #{changelog_path}. That should have been
created when you ran `fastlane tag`.
MSG
end
build
apk_path = get_apk_path( build_number )
unless File.exist?( apk_path )
UI.abort_with_message! "Failed to find APK at #{apk_path}"
end
github_release = get_github_release(
url: "inaturalist/iNaturalistReactNative",
version: last_tag,
api_token: ENV["GITHUB_TOKEN"]
)
if github_release
UI.important "Release already exists at #{github_release["url"]}. You need to manually upload any missing assets."
else
set_github_release(
repository_name: "inaturalist/iNaturalistReactNative",
api_token: ENV["GITHUB_TOKEN"],
name: last_tag,
tag_name: last_tag,
description: ( File.read( changelog_path ) rescue nil ),
# This is really just a fallback in case last_tag isn't really a tag
commitish: "main",
upload_assets: [apk_path]
)
end
system "git checkout #{original_branch}", exception: true
end
lane :internal do
desc "Push builds for the latest tag for internal testing"
# Ensure build files exist for the latest tag
aab_path = get_aab_path
unless File.exist?( aab_path )
UI.abort_with_message! "AAB does not exist at #{aab_path}. You may need to run the release lane before making a beta"
end
last_tag = last_git_tag
if last_tag.nil? || last_tag.empty?
UI.abort_with_message! "No tags have been added yet. Try starting with `fastlane tag`"
end
changelog_path = get_changelog_path
unless File.exist?( changelog_path )
UI.abort_with_message! <<~MSG
No change log file exists at #{changelog_path}. That should have been
created when you ran `fastlane tag`.
MSG
end
upload_to_play_store(
aab: aab_path,
track: "internal",
release_status: "draft",
version_name: last_tag
)
upload_to_testflight(
ipa: get_ipa_path,
changelog: ( File.read( changelog_path ) rescue nil )
)
end
lane :beta do
desc "Push builds for the latest tag for public testing"
# Push to play store beta track. In theory some time has elapsed between now
# and creating the release and translators have translated the release
# notes. In theory, and if we configure things correctly,
# upload_to_play_store will grab the appropriate release notes for the
# current version code, even if they aren't actually present for the tag
# the AAB was built from.
upload_to_play_store(
aab: aab_path,
track: "internal"
)
upload_to_play_store(
version_code: build_number,
track: "internal",
track_promote_to: "beta"
)
end
lane :prod do
desc "Push builds for the latest tag to production"
build_number = get_build_number( xcodeproj: XCODEPROJ )
# In theory this will move the release associated with the build_number in
# the beta track to the production track and 100% rollout... but I haven't
# been able to test that yet
upload_to_play_store( version_code: build_number, track: "beta", track_promote_to: "production" )
end

View File

@@ -13,15 +13,103 @@ For _fastlane_ installation instructions, see [Installing _fastlane_](https://do
# Available Actions
## Android
### android internal
### tag
```sh
[bundle exec] fastlane android internal
[bundle exec] fastlane tag
```
Distributes iNaturalistReactNative Android bundle to the Play Store internal track
### build
```sh
[bundle exec] fastlane build
```
### clean
```sh
[bundle exec] fastlane clean
```
### release
```sh
[bundle exec] fastlane release
```
### internal
```sh
[bundle exec] fastlane internal
```
### beta
```sh
[bundle exec] fastlane beta
```
### prod
```sh
[bundle exec] fastlane prod
```
----
## Android
### android build
```sh
[bundle exec] fastlane android build
```
### android clean
```sh
[bundle exec] fastlane android clean
```
----
## iOS
### ios build
```sh
[bundle exec] fastlane ios build
```
### ios clean
```sh
[bundle exec] fastlane ios clean
```
----

8
fastlane/example-Appfile Normal file
View File

@@ -0,0 +1,8 @@
json_key_file("path/to/your/service/acount/key.json")
package_name("org.inaturalist.android")
# Apple
app_identifier("org.inaturalist.iphone") # The bundle identifier of your app
apple_id("your-username@inaturalist.org") # Your Apple email address
itc_team_id("12345") # App Store Connect Team ID
team_id("YOURTEAMID") # Developer Portal Team ID

View File

@@ -0,0 +1 @@
More steps toward getting a release out in Android

View File

@@ -0,0 +1 @@
Several updates toward Android release automation

View File

@@ -0,0 +1 @@
Switch to pushing builds to internal track

View File

@@ -0,0 +1,4 @@
Several updates to release automation, no changes in app functionality
* Upload to TestFlight as a part of pushing internal builds
* Re-arranged some Fastlane code

View File

@@ -0,0 +1 @@
Inserting release notes with vim for fastlane tag.

View File

@@ -0,0 +1 @@
Try again; enter release notes in vim for fastlane tag.

View File

@@ -0,0 +1 @@
Another test of fastlane branch, July 5, 2022.

View File

@@ -0,0 +1 @@
Trying fastlane process again, tag v0.1.1+20.

View File

@@ -0,0 +1,4 @@
Several minor changes to fastlane config
* Ensure we return to the original branch after release, not just to main
* Avoid git clean when release fails

View File

@@ -0,0 +1,5 @@
First release
* Basic log in
* Basic new observation flow
* Basic My Observations, Obs Detail, Obs Edit

View File

@@ -0,0 +1 @@
Not much has changed since the last build

View File

@@ -0,0 +1,10 @@
One of the world&#39;s most popular nature apps, iNaturalist helps you identify the plants and animals around you. Get connected with a community of over 400,000 scientists and naturalists who can help you learn more about nature! What&#39;s more, by recording and sharing your observations, you&#39;ll create research quality data for scientists working to better understand and protect nature. iNaturalist is a joint initiative by the California Academy of Sciences and the National Geographic Society.
KEY FEATURES
• Discover species new to you both near and far
• Record your own observations and share them with the community
• Receive suggestions and crowdsourced identifications of what you&#39;ve seen
• Discuss and help others identify what they&#39;ve seen
• Follow projects comprised of smaller communities and fellow citizen scientists passionate about a particular place and/or species
For more info, check out https://www.inaturalist.org

View File

@@ -0,0 +1 @@
Observe and identify plants and animals with your friends

View File

@@ -0,0 +1 @@
iNaturalist

View File

@@ -209,7 +209,10 @@ GEM
xcpretty (~> 0.2, >= 0.0.7)
PLATFORMS
<<<<<<< HEAD
=======
ruby
>>>>>>> a0f5779a6f509d3a54046c17c19d7e5e7e8355c1
x86_64-darwin-21
DEPENDENCIES

View File

@@ -29,4 +29,5 @@ target 'iNaturalistReactNative' do
# post_install do |installer|
# react_native_post_install(installer)
# end
end

View File

@@ -1,14 +1,14 @@
PODS:
- boost (1.76.0)
- DoubleConversion (1.1.6)
- FBLazyVector (0.67.4)
- FBReactNativeSpec (0.67.4):
- FBLazyVector (0.68.2)
- FBReactNativeSpec (0.68.2):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTRequired (= 0.67.4)
- RCTTypeSafety (= 0.67.4)
- React-Core (= 0.67.4)
- React-jsi (= 0.67.4)
- ReactCommon/turbomodule/core (= 0.67.4)
- RCTRequired (= 0.68.2)
- RCTTypeSafety (= 0.68.2)
- React-Core (= 0.68.2)
- React-jsi (= 0.68.2)
- ReactCommon/turbomodule/core (= 0.68.2)
- fmt (6.2.1)
- glog (0.3.5)
- Permission-LocationWhenInUse (3.3.1):
@@ -24,192 +24,201 @@ PODS:
- DoubleConversion
- fmt (~> 6.2.1)
- glog
- RCTRequired (0.67.4)
- RCTTypeSafety (0.67.4):
- FBLazyVector (= 0.67.4)
- RCTRequired (0.68.2)
- RCTTypeSafety (0.68.2):
- FBLazyVector (= 0.68.2)
- RCT-Folly (= 2021.06.28.00-v2)
- RCTRequired (= 0.67.4)
- React-Core (= 0.67.4)
- React (0.67.4):
- React-Core (= 0.67.4)
- React-Core/DevSupport (= 0.67.4)
- React-Core/RCTWebSocket (= 0.67.4)
- React-RCTActionSheet (= 0.67.4)
- React-RCTAnimation (= 0.67.4)
- React-RCTBlob (= 0.67.4)
- React-RCTImage (= 0.67.4)
- React-RCTLinking (= 0.67.4)
- React-RCTNetwork (= 0.67.4)
- React-RCTSettings (= 0.67.4)
- React-RCTText (= 0.67.4)
- React-RCTVibration (= 0.67.4)
- React-callinvoker (0.67.4)
- React-Core (0.67.4):
- RCTRequired (= 0.68.2)
- React-Core (= 0.68.2)
- React (0.68.2):
- React-Core (= 0.68.2)
- React-Core/DevSupport (= 0.68.2)
- React-Core/RCTWebSocket (= 0.68.2)
- React-RCTActionSheet (= 0.68.2)
- React-RCTAnimation (= 0.68.2)
- React-RCTBlob (= 0.68.2)
- React-RCTImage (= 0.68.2)
- React-RCTLinking (= 0.68.2)
- React-RCTNetwork (= 0.68.2)
- React-RCTSettings (= 0.68.2)
- React-RCTText (= 0.68.2)
- React-RCTVibration (= 0.68.2)
- React-callinvoker (0.68.2)
- React-Codegen (0.68.2):
- FBReactNativeSpec (= 0.68.2)
- RCT-Folly (= 2021.06.28.00-v2)
- RCTRequired (= 0.68.2)
- RCTTypeSafety (= 0.68.2)
- React-Core (= 0.68.2)
- React-jsi (= 0.68.2)
- React-jsiexecutor (= 0.68.2)
- ReactCommon/turbomodule/core (= 0.68.2)
- React-Core (0.68.2):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default (= 0.67.4)
- React-cxxreact (= 0.67.4)
- React-jsi (= 0.67.4)
- React-jsiexecutor (= 0.67.4)
- React-perflogger (= 0.67.4)
- React-Core/Default (= 0.68.2)
- React-cxxreact (= 0.68.2)
- React-jsi (= 0.68.2)
- React-jsiexecutor (= 0.68.2)
- React-perflogger (= 0.68.2)
- Yoga
- React-Core/CoreModulesHeaders (0.67.4):
- React-Core/CoreModulesHeaders (0.68.2):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.67.4)
- React-jsi (= 0.67.4)
- React-jsiexecutor (= 0.67.4)
- React-perflogger (= 0.67.4)
- React-cxxreact (= 0.68.2)
- React-jsi (= 0.68.2)
- React-jsiexecutor (= 0.68.2)
- React-perflogger (= 0.68.2)
- Yoga
- React-Core/Default (0.67.4):
- React-Core/Default (0.68.2):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-cxxreact (= 0.67.4)
- React-jsi (= 0.67.4)
- React-jsiexecutor (= 0.67.4)
- React-perflogger (= 0.67.4)
- React-cxxreact (= 0.68.2)
- React-jsi (= 0.68.2)
- React-jsiexecutor (= 0.68.2)
- React-perflogger (= 0.68.2)
- Yoga
- React-Core/DevSupport (0.67.4):
- React-Core/DevSupport (0.68.2):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default (= 0.67.4)
- React-Core/RCTWebSocket (= 0.67.4)
- React-cxxreact (= 0.67.4)
- React-jsi (= 0.67.4)
- React-jsiexecutor (= 0.67.4)
- React-jsinspector (= 0.67.4)
- React-perflogger (= 0.67.4)
- React-Core/Default (= 0.68.2)
- React-Core/RCTWebSocket (= 0.68.2)
- React-cxxreact (= 0.68.2)
- React-jsi (= 0.68.2)
- React-jsiexecutor (= 0.68.2)
- React-jsinspector (= 0.68.2)
- React-perflogger (= 0.68.2)
- Yoga
- React-Core/RCTActionSheetHeaders (0.67.4):
- React-Core/RCTActionSheetHeaders (0.68.2):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.67.4)
- React-jsi (= 0.67.4)
- React-jsiexecutor (= 0.67.4)
- React-perflogger (= 0.67.4)
- React-cxxreact (= 0.68.2)
- React-jsi (= 0.68.2)
- React-jsiexecutor (= 0.68.2)
- React-perflogger (= 0.68.2)
- Yoga
- React-Core/RCTAnimationHeaders (0.67.4):
- React-Core/RCTAnimationHeaders (0.68.2):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.67.4)
- React-jsi (= 0.67.4)
- React-jsiexecutor (= 0.67.4)
- React-perflogger (= 0.67.4)
- React-cxxreact (= 0.68.2)
- React-jsi (= 0.68.2)
- React-jsiexecutor (= 0.68.2)
- React-perflogger (= 0.68.2)
- Yoga
- React-Core/RCTBlobHeaders (0.67.4):
- React-Core/RCTBlobHeaders (0.68.2):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.67.4)
- React-jsi (= 0.67.4)
- React-jsiexecutor (= 0.67.4)
- React-perflogger (= 0.67.4)
- React-cxxreact (= 0.68.2)
- React-jsi (= 0.68.2)
- React-jsiexecutor (= 0.68.2)
- React-perflogger (= 0.68.2)
- Yoga
- React-Core/RCTImageHeaders (0.67.4):
- React-Core/RCTImageHeaders (0.68.2):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.67.4)
- React-jsi (= 0.67.4)
- React-jsiexecutor (= 0.67.4)
- React-perflogger (= 0.67.4)
- React-cxxreact (= 0.68.2)
- React-jsi (= 0.68.2)
- React-jsiexecutor (= 0.68.2)
- React-perflogger (= 0.68.2)
- Yoga
- React-Core/RCTLinkingHeaders (0.67.4):
- React-Core/RCTLinkingHeaders (0.68.2):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.67.4)
- React-jsi (= 0.67.4)
- React-jsiexecutor (= 0.67.4)
- React-perflogger (= 0.67.4)
- React-cxxreact (= 0.68.2)
- React-jsi (= 0.68.2)
- React-jsiexecutor (= 0.68.2)
- React-perflogger (= 0.68.2)
- Yoga
- React-Core/RCTNetworkHeaders (0.67.4):
- React-Core/RCTNetworkHeaders (0.68.2):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.67.4)
- React-jsi (= 0.67.4)
- React-jsiexecutor (= 0.67.4)
- React-perflogger (= 0.67.4)
- React-cxxreact (= 0.68.2)
- React-jsi (= 0.68.2)
- React-jsiexecutor (= 0.68.2)
- React-perflogger (= 0.68.2)
- Yoga
- React-Core/RCTSettingsHeaders (0.67.4):
- React-Core/RCTSettingsHeaders (0.68.2):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.67.4)
- React-jsi (= 0.67.4)
- React-jsiexecutor (= 0.67.4)
- React-perflogger (= 0.67.4)
- React-cxxreact (= 0.68.2)
- React-jsi (= 0.68.2)
- React-jsiexecutor (= 0.68.2)
- React-perflogger (= 0.68.2)
- Yoga
- React-Core/RCTTextHeaders (0.67.4):
- React-Core/RCTTextHeaders (0.68.2):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.67.4)
- React-jsi (= 0.67.4)
- React-jsiexecutor (= 0.67.4)
- React-perflogger (= 0.67.4)
- React-cxxreact (= 0.68.2)
- React-jsi (= 0.68.2)
- React-jsiexecutor (= 0.68.2)
- React-perflogger (= 0.68.2)
- Yoga
- React-Core/RCTVibrationHeaders (0.67.4):
- React-Core/RCTVibrationHeaders (0.68.2):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.67.4)
- React-jsi (= 0.67.4)
- React-jsiexecutor (= 0.67.4)
- React-perflogger (= 0.67.4)
- React-cxxreact (= 0.68.2)
- React-jsi (= 0.68.2)
- React-jsiexecutor (= 0.68.2)
- React-perflogger (= 0.68.2)
- Yoga
- React-Core/RCTWebSocket (0.67.4):
- React-Core/RCTWebSocket (0.68.2):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default (= 0.67.4)
- React-cxxreact (= 0.67.4)
- React-jsi (= 0.67.4)
- React-jsiexecutor (= 0.67.4)
- React-perflogger (= 0.67.4)
- React-Core/Default (= 0.68.2)
- React-cxxreact (= 0.68.2)
- React-jsi (= 0.68.2)
- React-jsiexecutor (= 0.68.2)
- React-perflogger (= 0.68.2)
- Yoga
- React-CoreModules (0.67.4):
- FBReactNativeSpec (= 0.67.4)
- React-CoreModules (0.68.2):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.67.4)
- React-Core/CoreModulesHeaders (= 0.67.4)
- React-jsi (= 0.67.4)
- React-RCTImage (= 0.67.4)
- ReactCommon/turbomodule/core (= 0.67.4)
- React-cxxreact (0.67.4):
- RCTTypeSafety (= 0.68.2)
- React-Codegen (= 0.68.2)
- React-Core/CoreModulesHeaders (= 0.68.2)
- React-jsi (= 0.68.2)
- React-RCTImage (= 0.68.2)
- ReactCommon/turbomodule/core (= 0.68.2)
- React-cxxreact (0.68.2):
- boost (= 1.76.0)
- DoubleConversion
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-callinvoker (= 0.67.4)
- React-jsi (= 0.67.4)
- React-jsinspector (= 0.67.4)
- React-logger (= 0.67.4)
- React-perflogger (= 0.67.4)
- React-runtimeexecutor (= 0.67.4)
- React-jsi (0.67.4):
- React-callinvoker (= 0.68.2)
- React-jsi (= 0.68.2)
- React-jsinspector (= 0.68.2)
- React-logger (= 0.68.2)
- React-perflogger (= 0.68.2)
- React-runtimeexecutor (= 0.68.2)
- React-jsi (0.68.2):
- boost (= 1.76.0)
- DoubleConversion
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-jsi/Default (= 0.67.4)
- React-jsi/Default (0.67.4):
- React-jsi/Default (= 0.68.2)
- React-jsi/Default (0.68.2):
- boost (= 1.76.0)
- DoubleConversion
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-jsiexecutor (0.67.4):
- React-jsiexecutor (0.68.2):
- DoubleConversion
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-cxxreact (= 0.67.4)
- React-jsi (= 0.67.4)
- React-perflogger (= 0.67.4)
- React-jsinspector (0.67.4)
- React-logger (0.67.4):
- React-cxxreact (= 0.68.2)
- React-jsi (= 0.68.2)
- React-perflogger (= 0.68.2)
- React-jsinspector (0.68.2)
- React-logger (0.68.2):
- glog
- react-native-cameraroll (4.1.2):
- React-Core
@@ -217,7 +226,7 @@ PODS:
- react-native-config/App (= 1.4.5)
- react-native-config/App (1.4.5):
- React-Core
- react-native-geocoder (0.5.0):
- react-native-geocoder-reborn (0.9.0):
- React
- react-native-geolocation-service (5.3.0-beta.4):
- React
@@ -225,7 +234,7 @@ PODS:
- React-Core
- react-native-image-resizer (1.4.5):
- React-Core
- react-native-maps (0.30.1):
- react-native-maps (0.30.2):
- React-Core
- react-native-netinfo (8.3.0):
- React-Core
@@ -237,71 +246,71 @@ PODS:
- ReactCommon/turbomodule/core
- react-native-sensitive-info (6.0.0-alpha.9):
- React-Core
- React-perflogger (0.67.4)
- React-RCTActionSheet (0.67.4):
- React-Core/RCTActionSheetHeaders (= 0.67.4)
- React-RCTAnimation (0.67.4):
- FBReactNativeSpec (= 0.67.4)
- React-perflogger (0.68.2)
- React-RCTActionSheet (0.68.2):
- React-Core/RCTActionSheetHeaders (= 0.68.2)
- React-RCTAnimation (0.68.2):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.67.4)
- React-Core/RCTAnimationHeaders (= 0.67.4)
- React-jsi (= 0.67.4)
- ReactCommon/turbomodule/core (= 0.67.4)
- React-RCTBlob (0.67.4):
- FBReactNativeSpec (= 0.67.4)
- RCTTypeSafety (= 0.68.2)
- React-Codegen (= 0.68.2)
- React-Core/RCTAnimationHeaders (= 0.68.2)
- React-jsi (= 0.68.2)
- ReactCommon/turbomodule/core (= 0.68.2)
- React-RCTBlob (0.68.2):
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/RCTBlobHeaders (= 0.67.4)
- React-Core/RCTWebSocket (= 0.67.4)
- React-jsi (= 0.67.4)
- React-RCTNetwork (= 0.67.4)
- ReactCommon/turbomodule/core (= 0.67.4)
- React-RCTImage (0.67.4):
- FBReactNativeSpec (= 0.67.4)
- React-Codegen (= 0.68.2)
- React-Core/RCTBlobHeaders (= 0.68.2)
- React-Core/RCTWebSocket (= 0.68.2)
- React-jsi (= 0.68.2)
- React-RCTNetwork (= 0.68.2)
- ReactCommon/turbomodule/core (= 0.68.2)
- React-RCTImage (0.68.2):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.67.4)
- React-Core/RCTImageHeaders (= 0.67.4)
- React-jsi (= 0.67.4)
- React-RCTNetwork (= 0.67.4)
- ReactCommon/turbomodule/core (= 0.67.4)
- React-RCTLinking (0.67.4):
- FBReactNativeSpec (= 0.67.4)
- React-Core/RCTLinkingHeaders (= 0.67.4)
- React-jsi (= 0.67.4)
- ReactCommon/turbomodule/core (= 0.67.4)
- React-RCTNetwork (0.67.4):
- FBReactNativeSpec (= 0.67.4)
- RCTTypeSafety (= 0.68.2)
- React-Codegen (= 0.68.2)
- React-Core/RCTImageHeaders (= 0.68.2)
- React-jsi (= 0.68.2)
- React-RCTNetwork (= 0.68.2)
- ReactCommon/turbomodule/core (= 0.68.2)
- React-RCTLinking (0.68.2):
- React-Codegen (= 0.68.2)
- React-Core/RCTLinkingHeaders (= 0.68.2)
- React-jsi (= 0.68.2)
- ReactCommon/turbomodule/core (= 0.68.2)
- React-RCTNetwork (0.68.2):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.67.4)
- React-Core/RCTNetworkHeaders (= 0.67.4)
- React-jsi (= 0.67.4)
- ReactCommon/turbomodule/core (= 0.67.4)
- React-RCTSettings (0.67.4):
- FBReactNativeSpec (= 0.67.4)
- RCTTypeSafety (= 0.68.2)
- React-Codegen (= 0.68.2)
- React-Core/RCTNetworkHeaders (= 0.68.2)
- React-jsi (= 0.68.2)
- ReactCommon/turbomodule/core (= 0.68.2)
- React-RCTSettings (0.68.2):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.67.4)
- React-Core/RCTSettingsHeaders (= 0.67.4)
- React-jsi (= 0.67.4)
- ReactCommon/turbomodule/core (= 0.67.4)
- React-RCTText (0.67.4):
- React-Core/RCTTextHeaders (= 0.67.4)
- React-RCTVibration (0.67.4):
- FBReactNativeSpec (= 0.67.4)
- RCTTypeSafety (= 0.68.2)
- React-Codegen (= 0.68.2)
- React-Core/RCTSettingsHeaders (= 0.68.2)
- React-jsi (= 0.68.2)
- ReactCommon/turbomodule/core (= 0.68.2)
- React-RCTText (0.68.2):
- React-Core/RCTTextHeaders (= 0.68.2)
- React-RCTVibration (0.68.2):
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/RCTVibrationHeaders (= 0.67.4)
- React-jsi (= 0.67.4)
- ReactCommon/turbomodule/core (= 0.67.4)
- React-runtimeexecutor (0.67.4):
- React-jsi (= 0.67.4)
- ReactCommon/turbomodule/core (0.67.4):
- React-Codegen (= 0.68.2)
- React-Core/RCTVibrationHeaders (= 0.68.2)
- React-jsi (= 0.68.2)
- ReactCommon/turbomodule/core (= 0.68.2)
- React-runtimeexecutor (0.68.2):
- React-jsi (= 0.68.2)
- ReactCommon/turbomodule/core (0.68.2):
- DoubleConversion
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-callinvoker (= 0.67.4)
- React-Core (= 0.67.4)
- React-cxxreact (= 0.67.4)
- React-jsi (= 0.67.4)
- React-logger (= 0.67.4)
- React-perflogger (= 0.67.4)
- React-callinvoker (= 0.68.2)
- React-Core (= 0.68.2)
- React-cxxreact (= 0.68.2)
- React-jsi (= 0.68.2)
- React-logger (= 0.68.2)
- React-perflogger (= 0.68.2)
- RealmJS (10.20.0-beta.5):
- React
- RNAudioRecorderPlayer (3.4.0):
@@ -372,6 +381,7 @@ DEPENDENCIES:
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
- React (from `../node_modules/react-native/`)
- React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
- React-Codegen (from `build/generated/ios`)
- React-Core (from `../node_modules/react-native/`)
- React-Core/DevSupport (from `../node_modules/react-native/`)
- React-Core/RCTWebSocket (from `../node_modules/react-native/`)
@@ -383,7 +393,7 @@ DEPENDENCIES:
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
- "react-native-cameraroll (from `../node_modules/@react-native-community/cameraroll`)"
- react-native-config (from `../node_modules/react-native-config`)
- react-native-geocoder (from `../node_modules/react-native-geocoder`)
- react-native-geocoder-reborn (from `../node_modules/react-native-geocoder-reborn`)
- react-native-geolocation-service (from `../node_modules/react-native-geolocation-service`)
- react-native-image-picker (from `../node_modules/react-native-image-picker`)
- react-native-image-resizer (from `../node_modules/react-native-image-resizer`)
@@ -446,6 +456,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/"
React-callinvoker:
:path: "../node_modules/react-native/ReactCommon/callinvoker"
React-Codegen:
:path: build/generated/ios
React-Core:
:path: "../node_modules/react-native/"
React-CoreModules:
@@ -464,8 +476,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/@react-native-community/cameraroll"
react-native-config:
:path: "../node_modules/react-native-config"
react-native-geocoder:
:path: "../node_modules/react-native-geocoder"
react-native-geocoder-reborn:
:path: "../node_modules/react-native-geocoder-reborn"
react-native-geolocation-service:
:path: "../node_modules/react-native-geolocation-service"
react-native-image-picker:
@@ -538,45 +550,46 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
boost: a7c83b31436843459a1961bfd74b96033dc77234
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
FBLazyVector: f7b0632c6437e312acf6349288d9aa4cb6d59030
FBReactNativeSpec: 0f4e1f4cfeace095694436e7c7fcc5bf4b03a0ff
FBLazyVector: a7a655862f6b09625d11c772296b01cd5164b648
FBReactNativeSpec: 81ce99032d5b586fddd6a38d450f8595f7e04be4
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 476ee3e89abb49e07f822b48323c51c57124b572
Permission-LocationWhenInUse: 006c85c8de0c05b5d8be8e8029e4f6b813270293
RCT-Folly: 4d8508a426467c48885f1151029bc15fa5d7b3b8
RCTRequired: 0aa6c1c27e1d65920df35ceea5341a5fe76bdb79
RCTTypeSafety: d76a59d00632891e11ed7522dba3fd1a995e573a
React: ab8c09da2e7704f4b3ebad4baa6cfdfcc852dcb5
React-callinvoker: 216fb96b482da516b8aba4142b145938f6ea92f0
React-Core: af99b93aff83599485e0e0879879aafa35ceae32
React-CoreModules: 137a054ce8c547e81dc3502933b1bc0fd08df05d
React-cxxreact: ec5ee6b08664f5b8ac71d8ad912f54d540c4f817
React-jsi: 3e084c80fd364cee64668d5df46d40c39f7973e1
React-jsiexecutor: cbdf37cebdc4f5d8b3d0bf5ccaa6147fd9de9f3d
React-jsinspector: f4775ea9118cbe1f72b834f0f842baa7a99508d8
React-logger: a1f028f6d8639a3f364ef80419e5e862e1115250
RCTRequired: 3e917ea5377751094f38145fdece525aa90545a0
RCTTypeSafety: c43c072a4bd60feb49a9570b0517892b4305c45e
React: 176dd882de001854ced260fad41bb68a31aa4bd0
React-callinvoker: c2864d1818d6e64928d2faf774a3800dfc38fe1f
React-Codegen: 98b6f97f0a7abf7d67e4ce435c77c05b7a95cf05
React-Core: fdaa2916b1c893f39f02cff0476d1fb0cab1e352
React-CoreModules: fd8705b80699ec36c2cdd635c2ce9d874b9cfdfc
React-cxxreact: 1832d971f7b0cb2c7b943dc0ec962762c90c906e
React-jsi: 72af715135abe8c3f0dcf3b2548b71d048b69a7e
React-jsiexecutor: b7b553412f2ec768fe6c8f27cd6bafdb9d8719e6
React-jsinspector: c5989c77cb89ae6a69561095a61cce56a44ae8e8
React-logger: a0833912d93b36b791b7a521672d8ee89107aff1
react-native-cameraroll: 2957f2bce63ae896a848fbe0d5352c1bd4d20866
react-native-config: 6502b1879f97ed5ac570a029961fc35ea606cd14
react-native-geocoder: 757427682892bb256f3b3745858cc90eba148a8e
react-native-geocoder-reborn: c31cbc630d9307ebbceea1dea2746d0054be35c4
react-native-geolocation-service: c0efb872258ed9240f1003a70fca9e9757e5c785
react-native-image-picker: cffb727cf2f59bd5c0408e30b3dbe0b935f88835
react-native-image-resizer: d9fb629a867335bdc13230ac2a58702bb8c8828f
react-native-maps: d752b0dd0e1951d815b1336332835aab6b4a836f
react-native-maps: df7b9fca1b1c8d356fadbf5b8a63a5f8cf32fc73
react-native-netinfo: 3671b091c4843fda5e153612866ef4024b8f5d62
react-native-safe-area-context: f98b0b16d1546d208fc293b4661e3f81a895afd9
react-native-sensitive-info: d44e909d065f9c0e15734245e5dd6a24b82e3dcd
React-perflogger: 0afaf2f01a47fd0fc368a93bfbb5bd3b26db6e7f
React-RCTActionSheet: 59f35c4029e0b532fc42114241a06e170b7431a2
React-RCTAnimation: aae4f4bed122e78bdab72f7118d291d70a932ce2
React-RCTBlob: f6fb23394b4f28cd86fa7e9f5f6ae45c23669fda
React-RCTImage: 638815cf96124386dd296067246d91441932ae3f
React-RCTLinking: 254dd06283dd6fdb784285f95e7cec8053c3270f
React-RCTNetwork: 8a4c2d4f357268e520b060572d02bc69a9b991fb
React-RCTSettings: 35d44cbb9972ab933bd0a59ea3e6646dcb030ba3
React-RCTText: cc5315df8458cfa7b537e621271ef43273955a97
React-RCTVibration: 3b52a7dced19cdb025b4f88ab26ceb2d85f30ba2
React-runtimeexecutor: a9d3c82ddf7ffdad9fbe6a81c6d6f8c06385464d
ReactCommon: 07d0c460b9ba9af3eaf1b8f5abe7daaad28c9c4e
React-perflogger: a18b4f0bd933b8b24ecf9f3c54f9bf65180f3fe6
React-RCTActionSheet: 547fe42fdb4b6089598d79f8e1d855d7c23e2162
React-RCTAnimation: bc9440a1c37b06ae9ebbb532d244f607805c6034
React-RCTBlob: a1295c8e183756d7ef30ba6e8f8144dfe8a19215
React-RCTImage: a30d1ee09b1334067fbb6f30789aae2d7ac150c9
React-RCTLinking: ffc6d5b88d1cb9aca13c54c2ec6507fbf07f2ac4
React-RCTNetwork: f807a2facab6cf5cf36d592e634611de9cf12d81
React-RCTSettings: 861806819226ed8332e6a8f90df2951a34bb3e7f
React-RCTText: f3fb464cc41a50fc7a1aba4deeb76a9ad8282cb9
React-RCTVibration: 79040b92bfa9c3c2d2cb4f57e981164ec7ab9374
React-runtimeexecutor: b960b687d2dfef0d3761fbb187e01812ebab8b23
ReactCommon: 095366164a276d91ea704ce53cb03825c487a3f2
RealmJS: 772520fb85c19b65c2ea0c8f9aa6e790a905a377
RNAudioRecorderPlayer: 001f01049754e978c43af97162452c8563d5794a
RNCCheckbox: ed1b4ca295475b41e7251ebae046360a703b6eb5
@@ -587,12 +600,12 @@ SPEC CHECKSUMS:
RNGestureHandler: 4f4986408310a43f1606c391f38f76e0d6e790d5
RNLocalize: cbcb55d0e19c78086ea4eea20e03fe8000bbbced
RNPermissions: 34d678157c800b25b22a488e4d8babb57456e796
RNReanimated: 96ab42cfb0e5517293499e0f3f810420eb459f75
RNReanimated: e42de406edd11350af29016cf6802ef16ee364d0
RNScreens: 40a2cb40a02a609938137a1e0acfbf8fc9eebf19
RNVectorIcons: 7923e585eaeb139b9f4531d25a125a1500162a0b
VisionCamera: a4b6e0f84d07c2253f54b96e6d3ee13ebe6536e1
Yoga: d6b6a80659aa3e91aaba01d0012e7edcbedcbecd
VisionCamera: c1c171fcdbf18c438987847f785829c5638f3a4c
Yoga: 99652481fcd320aefa4a7ef90095b95acd181952
PODFILE CHECKSUM: da0f05a708fcf3cbef37e07cf5b19489c9630466
PODFILE CHECKSUM: 51a6b3d8767f92f6783584e73a5acbcb4074e65d
COCOAPODS: 1.11.3

View File

@@ -1,8 +0,0 @@
app_identifier("org.inaturalist.iNatMobileBeta") # The bundle identifier of your app
apple_id("amanda@inaturalist.org") # Your Apple email address
itc_team_id("475606") # App Store Connect Team ID
team_id("N5J7L4P93Z") # Developer Portal Team ID
# For more information about the Appfile, see:
# https://docs.fastlane.tools/advanced/#appfile

View File

@@ -1,42 +0,0 @@
# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
# https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
# https://docs.fastlane.tools/plugins/available-plugins
#
# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane
default_platform(:ios)
platform :ios do
desc "Push a new beta build of iNaturalistReactNative to TestFlight"
lane :beta do
increment_build_number(xcodeproj: "iNaturalistReactNative.xcodeproj")
build_app(workspace: "iNaturalistReactNative.xcworkspace", scheme: "iNaturalistReactNative")
upload_to_testflight
slack(
message: "iNaturalistReactNative iOS beta successfully deployed!",
success: true,
slack_url: ENV["SLACK_WEBHOOK"],
default_payloads: [:lane, :test_result, :git_branch, :last_git_commit_hash],
attachment_properties: {
fields: [
{
title: "Version",
value: lane_context[SharedValues::LATEST_VERSION]
},
{
title: "Build",
value: lane_context[SharedValues::LATEST_BUILD_NUMBER]
}
]
})
end
end

View File

@@ -1,32 +0,0 @@
fastlane documentation
----
# Installation
Make sure you have the latest version of the Xcode command line tools installed:
```sh
xcode-select --install
```
For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
# Available Actions
## iOS
### ios beta
```sh
[bundle exec] fastlane ios beta
```
Push a new beta build to TestFlight
----
This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).

View File

@@ -250,7 +250,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "export NODE_BINARY=/Users/amanda/.nvm/versions/node/v12.13.0/bin/node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
shellScript = "export NODE_BINARY=$(which node)\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
};
1EC8A7F0D8FF77CF01789C19 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
@@ -396,7 +396,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 7;
CURRENT_PROJECT_VERSION = 21;
DEVELOPMENT_TEAM = N5J7L4P93Z;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = iNaturalistReactNative/Info.plist;
@@ -423,7 +423,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 7;
CURRENT_PROJECT_VERSION = 21;
DEVELOPMENT_TEAM = N5J7L4P93Z;
INFOPLIST_FILE = iNaturalistReactNative/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (

View File

@@ -53,7 +53,7 @@ static void InitializeFlipper(UIApplication *application) {
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif

View File

@@ -21,7 +21,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>7</string>
<string>21</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false />
<key>LSRequiresIPhoneOS</key>

View File

@@ -19,6 +19,6 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>7</string>
<string>21</string>
</dict>
</plist>

3316
package-lock.json generated
View File

File diff suppressed because it is too large Load Diff

View File

@@ -19,7 +19,7 @@
"@react-native-community/checkbox": "^0.5.12",
"@react-native-community/datetimepicker": "^6.1.0",
"@react-native-community/netinfo": "^8.2.0",
"@react-native-picker/picker": "^2.4.0",
"@react-native-picker/picker": "^2.4.1",
"@react-navigation/drawer": "^6.3.1",
"@react-navigation/elements": "^1.3.1",
"@react-navigation/native": "^6.0.8",
@@ -39,13 +39,13 @@
"radio-buttons-react-native": "^1.0.4",
"react": "17.0.2",
"react-i18next": "^11.16.1",
"react-native": "^0.67.4",
"react-native": "^0.68.2",
"react-native-audio-recorder-player": "^3.3.4",
"react-native-config": "^1.4.5",
"react-native-device-info": "^8.5.1",
"react-native-dropdown-picker": "^5.3.0",
"react-native-fs": "^2.19.0",
"react-native-geocoder": "^0.5.0",
"react-native-geocoder-reborn": "^0.9.0",
"react-native-geolocation-service": "^5.3.0-beta.4",
"react-native-gesture-handler": "^2.4.1",
"react-native-image-pan-zoom": "^2.1.12",
@@ -53,11 +53,11 @@
"react-native-image-resizer": "^1.4.5",
"react-native-jwt-io": "^1.0.3",
"react-native-localize": "^2.2.1",
"react-native-maps": "^0.30.1",
"react-native-maps": "^0.30.2",
"react-native-modal": "^13.0.1",
"react-native-modal-datetime-picker": "^13.1.0",
"react-native-network-logger": "^1.12.0",
"react-native-paper": "^4.12.1",
"react-native-paper": "^4.12.2",
"react-native-permissions": "^3.3.1",
"react-native-picker-select": "^8.0.4",
"react-native-reanimated": "^2.7.0",

View File

@@ -1,7 +1,7 @@
// @flow
import { useEffect, useState } from "react";
import Geocoder from "react-native-geocoder";
import Geocoder from "react-native-geocoder-reborn";
const useCoords = ( location: string ): Object => {
const [coords, setCoords] = useState( {

View File

@@ -1,6 +1,6 @@
// @flow
import Geocoder from "react-native-geocoder";
import Geocoder from "react-native-geocoder-reborn";
// lifted from SeekReactNative repo
const setPlaceName = ( results: Array<Object> ) => {

View File

@@ -1,7 +1,7 @@
// @flow
import { useEffect, useState } from "react";
import Geocoder from "react-native-geocoder";
import Geocoder from "react-native-geocoder-reborn";
const useLocationName = ( latitude: ?number, longitude: ?number ): ?string => {
const [location, setLocation] = useState( null );