Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e5db3758a | ||
|
|
47012b8c07 | ||
|
|
3b46d837ae | ||
|
|
94e89f65bc | ||
|
|
ca04e28df1 | ||
|
|
91039e89b0 | ||
|
|
661b6bc4bd | ||
|
|
2e4321483a | ||
|
|
b04cddd54c | ||
|
|
4b78f7dc8d | ||
|
|
808d06305e | ||
|
|
42acb2997a | ||
|
|
44df616c45 | ||
|
|
4c6b97093c | ||
|
|
9108585f12 | ||
|
|
0fed3a2469 | ||
|
|
00955fb9a3 | ||
|
|
380f24f46b | ||
|
|
875a37290d | ||
|
|
718bc363ad | ||
|
|
fa22e7fcba | ||
|
|
b49b43298b | ||
|
|
0ce2494246 | ||
|
|
b19788fba2 | ||
|
|
57d97b6667 | ||
|
|
723a911ec2 | ||
|
|
89139cf776 | ||
|
|
6632dae48e | ||
|
|
4f6a856052 | ||
|
|
9deb5dbf56 | ||
|
|
18252c1be6 | ||
|
|
24591328a0 | ||
|
|
05773c06ee | ||
|
|
66911f43d4 | ||
|
|
9c672323f3 | ||
|
|
cab969647d | ||
|
|
904d8cf96a | ||
|
|
6660224eb1 | ||
|
|
2e953baa67 | ||
|
|
4cee364958 | ||
|
|
a967239d69 | ||
|
|
7593a144c4 | ||
|
|
02d8209131 | ||
|
|
d3193fd958 | ||
|
|
043b254480 | ||
|
|
0997fb3ba4 | ||
|
|
c4328e6a30 | ||
|
|
66664692a6 | ||
|
|
03c16dd251 | ||
|
|
da923fe04e | ||
|
|
2fbf6518e7 | ||
|
|
a9c0427758 | ||
|
|
e9824a28bd | ||
|
|
7f6a5cb31f | ||
|
|
1a289d4ec7 | ||
|
|
156d27e8e1 | ||
|
|
392ecf7fdd | ||
|
|
a1469f8eb2 | ||
|
|
edcc107ec3 | ||
|
|
d54b5cc080 | ||
|
|
c188d840c5 | ||
|
|
dd253af0bb | ||
|
|
1c8c8fd7b1 | ||
|
|
34f8642fd8 | ||
|
|
f40fc9c6f1 | ||
|
|
c9b5496ec9 | ||
|
|
3256feee7c | ||
|
|
796bd4ac45 | ||
|
|
873db44f2e | ||
|
|
1ffd5a33a4 | ||
|
|
bb13230ba5 | ||
|
|
d19514fe09 | ||
|
|
b8d588a0ec | ||
|
|
ccc7b9b324 | ||
|
|
86b2cdc76a | ||
|
|
df58bed557 | ||
|
|
76c38f4092 | ||
|
|
c32bf4b827 | ||
|
|
ebd4b696f5 | ||
|
|
046b5ac9cf | ||
|
|
18aa57fb8e | ||
|
|
088f4c2de9 | ||
|
|
4ac9524398 | ||
|
|
5fb3d02921 | ||
|
|
a625a35e16 | ||
|
|
4ed84b1846 | ||
|
|
14ea177f9c | ||
|
|
bc7ef61855 | ||
|
|
43b598ee72 | ||
|
|
21a4016aa4 | ||
|
|
5baeffca8e | ||
|
|
d0ab22ab7e | ||
|
|
b200e90bcc | ||
|
|
bcaadc62f1 | ||
|
|
44931c642b | ||
|
|
5c262bcddb | ||
|
|
42739665fc | ||
|
|
097c16931e | ||
|
|
df87828d80 | ||
|
|
889027fffe | ||
|
|
8eee5fc318 | ||
|
|
317b54ad69 | ||
|
|
ada8f35cc3 | ||
|
|
7b12f2acae | ||
|
|
06750e92be | ||
|
|
d5ca9b6bbe | ||
|
|
6635ff42f2 | ||
|
|
3b22d0fb43 | ||
|
|
0702b9af79 | ||
|
|
b26ab3460e | ||
|
|
bcef86fee2 |
@@ -1,7 +1,7 @@
|
||||
status-im.utils.build/warning-handler
|
||||
status-im.utils.build/get-current-sha
|
||||
status-im2.constants/spacing-char
|
||||
status-im2.constants/arg-wrapping-char
|
||||
status-im.chat.constants/spacing-char
|
||||
status-im.chat.constants/arg-wrapping-char
|
||||
status-im.ios.core/init
|
||||
status-im.ui.components.camera/aspects
|
||||
status-im.ui.components.camera/capture-targets
|
||||
@@ -12,11 +12,11 @@ status-im.chat.models.message-content/actions
|
||||
status-im.chat.models.message-content/blank-string
|
||||
status-im.chat.models.message-content/sorted-ranges
|
||||
status-im.ethereum.mnemonic/words->passphrase
|
||||
native-module.core/listener
|
||||
native-module.core/multiaccount-reset
|
||||
native-module.core/extract-group-membership-signatures
|
||||
native-module.core/sign-group-membership
|
||||
native-module.core/update-mailservers
|
||||
status-im.native-module.core/listener
|
||||
status-im.native-module.core/multiaccount-reset
|
||||
status-im.native-module.core/extract-group-membership-signatures
|
||||
status-im.native-module.core/sign-group-membership
|
||||
status-im.native-module.core/update-mailservers
|
||||
status-im.ethereum.abi-spec/bytes-to-hex
|
||||
status-im.android.core/init
|
||||
status-im.chat.models.message/transport-keys
|
||||
@@ -46,8 +46,8 @@ status-im.utils.handlers/logged-in
|
||||
status-im.multiaccounts.model/credentials
|
||||
status-im.multiaccounts.login.core/contract-fleet?
|
||||
status-im.multiaccounts.login.core/fetch-nodes
|
||||
status-im2.config/rpc-networks-only?
|
||||
status-im2.config/waku-enabled?
|
||||
status-im.utils.config/rpc-networks-only?
|
||||
status-im.utils.config/waku-enabled?
|
||||
status-im.utils.pairing/has-paired-installations?
|
||||
status-im.tribute-to-talk.core-test/user-cofx
|
||||
quo.gesture-handler/tap-gesture-handler
|
||||
@@ -154,40 +154,40 @@ status-im.ethereum.ens/name-hash
|
||||
status-im.ethereum.ens/ABI-hash
|
||||
status-im.ethereum.ens/pubkey-hash
|
||||
status-im.network.core/get-network
|
||||
status-im2.constants/desktop-content-types
|
||||
status-im2.constants/blocks-per-hour
|
||||
status-im2.constants/one-earth-day
|
||||
status-im2.constants/left-pane-min-width
|
||||
status-im2.constants/system
|
||||
status-im2.constants/contact-discovery
|
||||
status-im2.constants/send-transaction-failed-parse-response
|
||||
status-im2.constants/send-transaction-failed-parse-params
|
||||
status-im2.constants/send-transaction-no-account-selected
|
||||
status-im2.constants/send-transaction-invalid-tx-sender
|
||||
status-im2.constants/web3-get-logs
|
||||
status-im2.constants/web3-transaction-receipt
|
||||
status-im2.constants/web3-new-filter
|
||||
status-im2.constants/web3-new-pending-transaction-filter
|
||||
status-im2.constants/web3-new-block-filter
|
||||
status-im2.constants/web3-uninstall-filter
|
||||
status-im2.constants/web3-get-filter-changes
|
||||
status-im2.constants/web3-shh-post
|
||||
status-im2.constants/web3-shh-new-identity
|
||||
status-im2.constants/web3-shh-has-identity
|
||||
status-im2.constants/web3-shh-new-group
|
||||
status-im2.constants/web3-shh-add-to-group
|
||||
status-im2.constants/web3-shh-new-filter
|
||||
status-im2.constants/web3-shh-uninstall-filter
|
||||
status-im2.constants/web3-shh-get-filter-changes
|
||||
status-im2.constants/web3-shh-get-messages
|
||||
status-im2.constants/status-create-address
|
||||
status-im2.constants/event-transfer-hash
|
||||
status-im2.constants/regx-rtl-characters
|
||||
status-im2.constants/desktop-msg-chars-hard-limit
|
||||
status-im2.constants/debug-metrics
|
||||
status-im2.constants/scan-qr-code
|
||||
status-im2.constants/ipfs-proto-code
|
||||
status-im2.constants/swarm-proto-code
|
||||
status-im.constants/desktop-content-types
|
||||
status-im.constants/blocks-per-hour
|
||||
status-im.constants/one-earth-day
|
||||
status-im.constants/left-pane-min-width
|
||||
status-im.constants/system
|
||||
status-im.constants/contact-discovery
|
||||
status-im.constants/send-transaction-failed-parse-response
|
||||
status-im.constants/send-transaction-failed-parse-params
|
||||
status-im.constants/send-transaction-no-account-selected
|
||||
status-im.constants/send-transaction-invalid-tx-sender
|
||||
status-im.constants/web3-get-logs
|
||||
status-im.constants/web3-transaction-receipt
|
||||
status-im.constants/web3-new-filter
|
||||
status-im.constants/web3-new-pending-transaction-filter
|
||||
status-im.constants/web3-new-block-filter
|
||||
status-im.constants/web3-uninstall-filter
|
||||
status-im.constants/web3-get-filter-changes
|
||||
status-im.constants/web3-shh-post
|
||||
status-im.constants/web3-shh-new-identity
|
||||
status-im.constants/web3-shh-has-identity
|
||||
status-im.constants/web3-shh-new-group
|
||||
status-im.constants/web3-shh-add-to-group
|
||||
status-im.constants/web3-shh-new-filter
|
||||
status-im.constants/web3-shh-uninstall-filter
|
||||
status-im.constants/web3-shh-get-filter-changes
|
||||
status-im.constants/web3-shh-get-messages
|
||||
status-im.constants/status-create-address
|
||||
status-im.constants/event-transfer-hash
|
||||
status-im.constants/regx-rtl-characters
|
||||
status-im.constants/desktop-msg-chars-hard-limit
|
||||
status-im.constants/debug-metrics
|
||||
status-im.constants/scan-qr-code
|
||||
status-im.constants/ipfs-proto-code
|
||||
status-im.constants/swarm-proto-code
|
||||
status-im.multiaccounts.update.publisher/publish-update!
|
||||
status-im.utils.async/task-queue
|
||||
status-im.utils.async/async-periodic-run!
|
||||
|
||||
@@ -14,21 +14,6 @@
|
||||
clojure.set set
|
||||
clojure.walk walk
|
||||
taoensso.timbre log}}
|
||||
:shadowed-var {:level :error
|
||||
;; We temporarily use :include to define an
|
||||
;; allowlist of core Clojure vars. In the
|
||||
;; future, as we progressively fix shadowed
|
||||
;; vars, we should be able to delete this
|
||||
;; option and lint all vars.
|
||||
:include [comparator
|
||||
count
|
||||
identity
|
||||
iter
|
||||
key
|
||||
str
|
||||
symbol
|
||||
time
|
||||
val]}
|
||||
:invalid-arity {:skip-args [status-im.utils.fx/defn utils.re-frame/defn]}
|
||||
;; TODO remove number when this is fixed
|
||||
;; https://github.com/borkdude/clj-kondo/issues/867
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
module.exports = {
|
||||
"testRunner": "jest",
|
||||
"testRegex": "\\.visual\\.js$",
|
||||
"runner-config": "visual-test/config.json",
|
||||
"devices": {
|
||||
"simulator": {
|
||||
"type": "ios.simulator",
|
||||
"device": {
|
||||
"type": "iPhone 11 Pro"
|
||||
}
|
||||
}
|
||||
},
|
||||
"apps": {
|
||||
"ios.release": {
|
||||
"name": "StatusIm",
|
||||
"type": "ios.app",
|
||||
"binaryPath": "ios/build/Build/Products/Release-iphonesimulator/StatusIm.app",
|
||||
"build": "make release-ios"
|
||||
},
|
||||
"ios.debug": {
|
||||
"name": "StatusIm",
|
||||
"type": "ios.app",
|
||||
"binaryPath": process.env.TEST_BINARY_PATH,
|
||||
"build": "make run-ios SIMULATOR='iPhone 11 Pro'"
|
||||
}
|
||||
},
|
||||
"configurations": {
|
||||
"ios.sim.release": {
|
||||
"device": "simulator",
|
||||
"app": "ios.release"
|
||||
},
|
||||
"ios.sim.debug": {
|
||||
"device": "simulator",
|
||||
"app": "ios.debug"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ KEYCARD_TEST_MENU=0
|
||||
QR_READ_TEST_MENU=1
|
||||
ENABLE_ROOT_ALERT=1
|
||||
ENABLE_QUO_PREVIEW=1
|
||||
MAX_IMAGES_BATCH=5
|
||||
APN_TOPIC=im.status.ethereum.pr
|
||||
COMMUNITIES_ENABLED=1
|
||||
DATABASE_MANAGEMENT_ENABLED=1
|
||||
|
||||
@@ -21,6 +21,7 @@ COMMANDS_ENABLED=1
|
||||
KEYCARD_TEST_MENU=1
|
||||
QR_READ_TEST_MENU=1
|
||||
ENABLE_ROOT_ALERT=0
|
||||
MAX_IMAGES_BATCH=5
|
||||
APN_TOPIC=im.status.ethereum.pr
|
||||
VERIFY_TRANSACTION_CHAIN_ID=5
|
||||
VERIFY_ENS_CHAIN_ID=5
|
||||
|
||||
@@ -26,6 +26,7 @@ VERIFY_TRANSACTION_CHAIN_ID=5
|
||||
VERIFY_ENS_CHAIN_ID=5
|
||||
TEST_STATEOFUS=1
|
||||
BLANK_PREVIEW=0
|
||||
MAX_IMAGES_BATCH=5
|
||||
DATABASE_MANAGEMENT_ENABLED=1
|
||||
COMMUNITIES_ENABLED=1
|
||||
COMMUNITIES_MANAGEMENT_ENABLED=1
|
||||
|
||||
@@ -17,6 +17,7 @@ RPC_NETWORKS_ONLY=0
|
||||
PARTITIONED_TOPIC=0
|
||||
CONTRACT_NODES=1
|
||||
ENABLE_ROOT_ALERT=1
|
||||
MAX_IMAGES_BATCH=5
|
||||
BLANK_PREVIEW=0
|
||||
COMMUNITIES_ENABLED=1
|
||||
DATABASE_MANAGEMENT_ENABLED=1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: '@react-native-community',
|
||||
};
|
||||
root: true,
|
||||
extends: '@react-native-community',
|
||||
};
|
||||
|
||||
@@ -43,4 +43,4 @@ As a <user|developer|...>, I want to <task> so that <goal>.
|
||||
[comment]: # (if on Android please replicate bug whilst running adb logcat)
|
||||
```
|
||||
...
|
||||
```
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
name: MVPBug Report
|
||||
about: MVPBug Report
|
||||
name: Bug Report
|
||||
about: Bug Report
|
||||
title: ''
|
||||
labels: 'E:Mobile Bugfixes MVP'
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
@@ -22,7 +22,8 @@ assignees: ''
|
||||
|
||||
### Reproduction
|
||||
|
||||
1.
|
||||
1) Open Status
|
||||
2)
|
||||
|
||||
### Additional Information
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
---
|
||||
name: Wont fix Report
|
||||
about: to facilitate future handling, identify and address non-urgent issues that won't be prioritized in the near future
|
||||
title: ''
|
||||
labels: likely_wont_fix
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Problem
|
||||
|
||||
|
||||
#### Expected behavior
|
||||
|
||||
|
||||
#### Actual behavior
|
||||
|
||||
|
||||
### Reproduction
|
||||
|
||||
1.
|
||||
|
||||
### Additional Information
|
||||
|
||||
- Status version: release
|
||||
- Operating System: Android, iOS
|
||||
|
||||
|
||||
[comment]: # (Please, add logs/notes if necessary)
|
||||
|
||||
@@ -5,6 +5,7 @@ project-board:
|
||||
min-reviewers: 1
|
||||
tested-pr-label-name: 'Tested - Issues'
|
||||
contributor-column-name: 'CONTRIBUTOR'
|
||||
to-rebase-column-name: 'TO REBASE'
|
||||
review-column-name: 'REVIEW'
|
||||
test-column-name: 'E2E Tests'
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
# Xcode
|
||||
#
|
||||
/ios/.xcode.env.local
|
||||
/component-spec
|
||||
result/
|
||||
build/
|
||||
@@ -101,8 +100,9 @@ Statusgo.xcframework
|
||||
|
||||
#ios
|
||||
/ios/Pods/
|
||||
/ios/logs/
|
||||
/ios/StatusIm.xcworkspace
|
||||
/ios/react-native-xcode.log
|
||||
/ios/set_xcode_version.log
|
||||
.ruby-version
|
||||
status-e2e/
|
||||
|
||||
@@ -183,10 +183,4 @@ test/appium/tests/users.py
|
||||
/.calva/
|
||||
|
||||
## component-tests
|
||||
*.log
|
||||
|
||||
## local xcode env introduced in react-native 0.69
|
||||
.xcode.env.local
|
||||
|
||||
## git hooks
|
||||
lefthook.yml
|
||||
*.log
|
||||
@@ -1,9 +0,0 @@
|
||||
*
|
||||
!*.js
|
||||
!*/
|
||||
*.clj-kondo
|
||||
*.shadow-cljs
|
||||
modules
|
||||
result
|
||||
target
|
||||
component-spec
|
||||
@@ -1,9 +1,7 @@
|
||||
module.exports = {
|
||||
arrowParens: 'always',
|
||||
printWidth: 120,
|
||||
semi: true,
|
||||
singleQuote: true,
|
||||
tabWidth: 2,
|
||||
trailingComma: 'all',
|
||||
useTabs: false,
|
||||
bracketSpacing: false,
|
||||
bracketSameLine: true,
|
||||
singleQuote: true,
|
||||
trailingComma: 'all',
|
||||
tabWidth: 4,
|
||||
};
|
||||
|
||||
@@ -16,11 +16,7 @@
|
||||
|
||||
;; respect blank line
|
||||
;; https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-bl
|
||||
:respect-bl
|
||||
|
||||
;; hang multiline left-hand-thing
|
||||
;; https://github.com/kkinnear/zprint/issues/273
|
||||
:multi-lhs-hang]
|
||||
:respect-bl]
|
||||
:fn-map
|
||||
{"reg-sub" :arg1-pair
|
||||
"h/describe" :arg1-body
|
||||
@@ -30,7 +26,6 @@
|
||||
"list-comp" :binding
|
||||
"defview" :arg1-body
|
||||
"letsubs" :binding
|
||||
"with-let" "let"
|
||||
"testing" :arg1-body
|
||||
"deftest-sub" :arg1-body
|
||||
"wait-for" :arg1-body
|
||||
|
||||
@@ -14,17 +14,17 @@ WHITE := $(shell tput -Txterm setaf 7)
|
||||
YELLOW := $(shell tput -Txterm setaf 3)
|
||||
RESET := $(shell tput -Txterm sgr0)
|
||||
HELP_FUN = \
|
||||
%help; \
|
||||
while(<>) { push @{$$help{$$2 // 'options'}}, [$$1, $$3] if /^([a-zA-Z\-]+)\s*:.*\#\#(?:@([a-zA-Z\-]+))?\s(.*)$$/ }; \
|
||||
print "Usage: make [target]\n\nSee STARTING_GUIDE.md for more info.\n\n"; \
|
||||
for (sort keys %help) { \
|
||||
print "${WHITE}$$_:${RESET}\n"; \
|
||||
for (@{$$help{$$_}}) { \
|
||||
$$sep = " " x (32 - length $$_->[0]); \
|
||||
print " ${YELLOW}$$_->[0]${RESET}$$sep${GREEN}$$_->[1]${RESET}\n"; \
|
||||
}; \
|
||||
print "\n"; \
|
||||
}
|
||||
%help; \
|
||||
while(<>) { push @{$$help{$$2 // 'options'}}, [$$1, $$3] if /^([a-zA-Z\-]+)\s*:.*\#\#(?:@([a-zA-Z\-]+))?\s(.*)$$/ }; \
|
||||
print "Usage: make [target]\n\nSee STARTING_GUIDE.md for more info.\n\n"; \
|
||||
for (sort keys %help) { \
|
||||
print "${WHITE}$$_:${RESET}\n"; \
|
||||
for (@{$$help{$$_}}) { \
|
||||
$$sep = " " x (32 - length $$_->[0]); \
|
||||
print " ${YELLOW}$$_->[0]${RESET}$$sep${GREEN}$$_->[1]${RESET}\n"; \
|
||||
}; \
|
||||
print "\n"; \
|
||||
}
|
||||
HOST_OS := $(shell uname | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
# This can come from Jenkins
|
||||
@@ -42,7 +42,7 @@ export NODE_OPTIONS += --openssl-legacy-provider
|
||||
export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore
|
||||
|
||||
# Our custom config is located in nix/nix.conf
|
||||
export NIX_USER_CONF_FILES = $(PWD)/nix/nix.conf
|
||||
export NIX_CONF_DIR = $(PWD)/nix
|
||||
# Location of symlinks to derivations that should not be garbage collected
|
||||
export _NIX_GCROOTS = /nix/var/nix/gcroots/per-user/$(USER)/status-mobile
|
||||
# Defines which variables will be kept for Nix pure shell, use semicolon as divider
|
||||
@@ -81,10 +81,6 @@ nix-gc-protected:
|
||||
@echo -e "$(YELLOW)The following paths are protected:$(RESET)" && \
|
||||
ls -1 $(_NIX_GCROOTS) | sed 's/^/ - /'
|
||||
|
||||
nix-upgrade: SHELL := /bin/sh
|
||||
nix-upgrade: ##@nix Upgrade Nix interpreter to current version.
|
||||
nix/scripts/upgrade.sh
|
||||
|
||||
nix-gc: export TARGET := nix
|
||||
nix-gc: nix-gc-protected ##@nix Garbage collect all packages older than 20 days from /nix/store
|
||||
nix-store --gc
|
||||
@@ -159,7 +155,7 @@ pod-install: ##@prepare Run 'pod install' to install podfiles and update Podfile
|
||||
|
||||
update-fleets: ##@prepare Download up-to-date JSON file with current fleets state
|
||||
curl -s https://fleets.status.im/ \
|
||||
| sed 's/"warning": "/"warning": "DO NOT EDIT! /' \
|
||||
| jq --indent 4 --sort-keys . \
|
||||
> resources/config/fleets.json
|
||||
|
||||
$(KEYSTORE_PATH): export TARGET := keytool
|
||||
@@ -222,18 +218,23 @@ release-android: keystore build-android ##@build Build signed Android APK
|
||||
|
||||
release-ios: export TARGET := ios
|
||||
release-ios: export BUILD_ENV ?= prod
|
||||
release-ios: watchman-clean ios-clean jsbundle ##@build Build release for iOS release
|
||||
xcodebuild \
|
||||
-scheme StatusIm \
|
||||
-configuration Release \
|
||||
-workspace ios/StatusIm.xcworkspace \
|
||||
-destination 'generic/platform=iOS' \
|
||||
-UseModernBuildSystem=N clean archive
|
||||
release-ios: watchman-clean ##@build Build release for iOS release
|
||||
@git clean -dxf -f target/ios && \
|
||||
$(MAKE) jsbundle-ios && \
|
||||
xcodebuild -workspace ios/StatusIm.xcworkspace -scheme StatusIm -configuration Release -destination 'generic/platform=iOS' -UseModernBuildSystem=N clean archive
|
||||
|
||||
jsbundle: SHELL := /bin/sh
|
||||
jsbundle: export BUILD_ENV ?= prod
|
||||
jsbundle: ##@build Build JavaScript and Clojurescript bundle for iOS and Android
|
||||
nix/scripts/build.sh targets.mobile.jsbundle
|
||||
jsbundle-android: SHELL := /bin/sh
|
||||
jsbundle-android: export TARGET := android
|
||||
jsbundle-android: export BUILD_ENV ?= prod
|
||||
jsbundle-android: ##@jsbundle Compile JavaScript and Clojurescript into app directory
|
||||
# Call nix-build to build the 'targets.mobile.android.jsbundle' attribute and copy the.js files to the project root
|
||||
nix/scripts/build.sh targets.mobile.android.jsbundle && \
|
||||
mv result/*.js ./
|
||||
|
||||
jsbundle-ios: export TARGET := ios
|
||||
jsbundle-ios: export BUILD_ENV ?= prod
|
||||
jsbundle-ios: ##@jsbundle Compile JavaScript and Clojure into index.ios.js
|
||||
yarn shadow-cljs release mobile
|
||||
|
||||
#--------------
|
||||
# status-go lib
|
||||
@@ -272,7 +273,7 @@ run-android: export TARGET := android
|
||||
run-android: ##@run Build Android APK and start it on the device
|
||||
npx react-native run-android --appIdSuffix debug
|
||||
|
||||
SIMULATOR=iPhone 11 Pro
|
||||
SIMULATOR=iPhone 13
|
||||
run-ios: export TARGET := ios
|
||||
run-ios: ##@run Build iOS app and start it in a simulator/device
|
||||
ifneq ("$(SIMULATOR)", "")
|
||||
@@ -281,43 +282,23 @@ else
|
||||
npx react-native run-ios
|
||||
endif
|
||||
|
||||
show-ios-devices: export TARGET := ios
|
||||
show-ios-devices: ##@other shows connected ios device and its name
|
||||
xcrun xctrace list devices
|
||||
|
||||
run-ios-device: export TARGET := ios
|
||||
run-ios-device: ##@run iOS app and start it on a connected device by its name
|
||||
ifndef DEVICE_NAME
|
||||
$(error Usage: make run-ios-device DEVICE_NAME=your-device-name)
|
||||
endif
|
||||
react-native run-ios --device "$(DEVICE_NAME)"
|
||||
|
||||
#--------------
|
||||
# Tests
|
||||
#--------------
|
||||
|
||||
# Get all clojure files, including untracked, excluding removed
|
||||
define find_all_clojure_files
|
||||
$$(comm -23 <(sort <(git ls-files --cached --others --exclude-standard)) <(sort <(git ls-files --deleted)) | grep -e \.clj$$ -e \.cljs$$ -e \.cljc$$ -e \.edn)
|
||||
endef
|
||||
|
||||
lint: export TARGET := clojure
|
||||
lint: export TARGET := default
|
||||
lint: ##@test Run code style checks
|
||||
@sh scripts/lint-re-frame-in-quo-components.sh && \
|
||||
sh scripts/lint-re-frame-in-quo-components.sh && \
|
||||
clj-kondo --config .clj-kondo/config.edn --cache false --lint src && \
|
||||
ALL_CLOJURE_FILES=$(call find_all_clojure_files) && \
|
||||
zprint '{:search-config? true}' -sfc $$ALL_CLOJURE_FILES && \
|
||||
sh scripts/lint-trailing-newline.sh && \
|
||||
yarn prettier
|
||||
ALL_CLOJURE_FILE=$$(git ls-files | grep -e \.clj$$ -e \.cljs$$ -e \.cljc$$ -e \.edn$$) && \
|
||||
zprint '{:search-config? true}' -sfc $$ALL_CLOJURE_FILE
|
||||
|
||||
# NOTE: We run the linter twice because of https://github.com/kkinnear/zprint/issues/271
|
||||
lint-fix: export TARGET := clojure
|
||||
lint-fix: export TARGET := default
|
||||
lint-fix: ##@test Run code style checks and fix issues
|
||||
ALL_CLOJURE_FILES=$(call find_all_clojure_files) && \
|
||||
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
|
||||
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
|
||||
sh scripts/lint-trailing-newline.sh --fix && \
|
||||
yarn prettier
|
||||
ALL_CLOJURE_FILE=$$(git ls-files | grep -e \.clj$$ -e \.cljs$$ -e \.cljc$$ -e \.edn$$) && \
|
||||
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILE && \
|
||||
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILE
|
||||
|
||||
|
||||
shadow-server: export TARGET := clojure
|
||||
shadow-server:##@ Start shadow-cljs in server mode for watching
|
||||
@@ -344,6 +325,14 @@ test: ##@test Run tests once in NodeJS
|
||||
yarn shadow-cljs compile test && \
|
||||
node --require ./test-resources/override.js target/test/test.js
|
||||
|
||||
|
||||
run-visual-test-ios: export TARGET := clojure
|
||||
run-visual-test-ios: XCODE_DERIVED_DATA := $(HOME)/Library/Developer/Xcode/DerivedData
|
||||
run-visual-test-ios: APPLICATION_NAME := StatusIm-brfnruzfrkkycpbndmdoeyrigthc
|
||||
run-visual-test-ios: export TEST_BINARY_PATH := $(XCODE_DERIVED_DATA)/$(APPLICATION_NAME)/Build/Products/Debug-iphonesimulator/StatusIm.app
|
||||
run-visual-test-ios: ##@test Run tests once in NodeJS
|
||||
detox test --configuration ios.sim.debug
|
||||
|
||||
component-test-watch: export TARGET := clojure
|
||||
component-test-watch: export COMPONENT_TEST := true
|
||||
component-test-watch: export BABEL_ENV := test
|
||||
@@ -354,12 +343,12 @@ component-test-watch: ##@ Watch tests and re-run no changes to cljs files
|
||||
component-test: export TARGET := clojure
|
||||
component-test: export COMPONENT_TEST := true
|
||||
component-test: export BABEL_ENV := test
|
||||
component-test: ##@test Run component tests once in NodeJS
|
||||
component-test: ##@test Run tests once in NodeJS
|
||||
# Here we create the gyp bindings for nodejs
|
||||
yarn install
|
||||
yarn shadow-cljs compile component-test && \
|
||||
jest --config=test/jest/jest.config.js
|
||||
|
||||
#--------------
|
||||
# Other
|
||||
#--------------
|
||||
|
||||
@@ -368,10 +357,6 @@ geth-connect: ##@other Connect to Geth on the device
|
||||
adb forward tcp:8545 tcp:8545 && \
|
||||
build/bin/geth attach http://localhost:8545
|
||||
|
||||
ios-clean: SHELL := /bin/sh
|
||||
ios-clean: ##@prepare Clean iOS build artifacts
|
||||
git clean -dxf -f target/ios
|
||||
|
||||
android-clean: export TARGET := gradle
|
||||
android-clean: ##@prepare Clean Gradle state
|
||||
git clean -dxf -f ./android/app/build; \
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png" alt="Get it on Google Play" height="80"/>](https://play.google.com/store/apps/details?id=im.status.ethereum)
|
||||
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" alt="Get it on F-Droid" height="80"/>](https://f-droid.org/packages/im.status.ethereum/)
|
||||
|
||||
|
||||
[Get it on Github](https://github.com/status-im/status-mobile/releases)
|
||||
[<img src="doc/github_badge.png" alt="Get it on Github" height="80"/>](https://github.com/status-im/status-mobile/releases)
|
||||
|
||||
Join us in creating a browser, messenger, and gateway to a decentralized world. Status is a free (libre) open source mobile client targeting Android & iOS built entirely on [Ethereum](https://ethereum.org/) technologies. That's right, no middle men and `go-ethereum` running directly on your device.
|
||||
|
||||
@@ -22,31 +20,31 @@ If this interests you, **help us make Status a reality** - anyone can contribute
|
||||
|
||||
## How to Contribute?
|
||||
|
||||
Go straight to the [docs](doc/) and choose what interests you:
|
||||
Go straight to the [docs](https://status.im/docs) or [join our chat](https://join.status.im/chat/public/status) and choose what interests you:
|
||||
|
||||
- **Developer** Developers are the heart of software and to keep Status beating
|
||||
we need all the help we can get! If you're looking to code in ClojureScript or
|
||||
Golang then Status is the project for you! We use React Native and there is even
|
||||
some Java/Objective-C too! Want to learn more about it? Start by reading our
|
||||
[Developer Introduction](doc/starting-guide.md) which guides you
|
||||
[Developer Introduction](https://status.im/developer_tools/) which guides you
|
||||
through the technology stack and start browsing [beginner
|
||||
issues](https://github.com/status-im/status-mobile/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22good%20first%20issue%22%20).
|
||||
Then you can read how to [Build
|
||||
Status](doc/starting-guide.md), which talks about managing
|
||||
project dependencies, coding guidelines and testing procedures.
|
||||
Check out our [coding guidelines](doc/new-guidelines.md).
|
||||
Status](https://status.im/technical/build_status/), which talks about managing
|
||||
project dependencies, coding guidelines and testing procedures. The [doc/](doc/)
|
||||
directory also has valuable information for contributors.
|
||||
|
||||
- **Community Management**
|
||||
Metcalfe's law states that the value of a network is proportional to the square of the number of connected users of the system - without community Status is meaningless. We're looking to create a positive, fun environment to explore new ideas, experiment and grow the Status community. Building a community takes a lot of work but the people you'll meet and long lasting relationships you form will be well worth it, check out our [Mission and Community Principles](https://status.im/about)
|
||||
|
||||
- **Specification / Documentation**
|
||||
John Dewey once said "Education is not preparation for life; education is life *itself* ". Developers & Designers need guidance and it all starts from documentation and specifications. Our software is only as good as its documentation, check out our [docs](doc/) and see how you can improve what we have.
|
||||
John Dewey once said "Education is not preparation for life; education is life *itself* ". Developers & Designers need guidance and it all starts from documentation and specifications. Our software is only as good as its documentation, head over to our [docs](https://status.im/docs) and see how you can improve what we have.
|
||||
|
||||
- **Blog Writing**
|
||||
Content is King, keeping our blog up to date and informing the community of news helps keep everyone on the same page.
|
||||
Content is King, keeping our blog up to date and informing the community of news helps keep everyone on the same page. [Jump into our chat](https://join.status.im/chat/public/status) and discuss with the team how you can contribute!
|
||||
|
||||
- **Testers**
|
||||
It's bug hunting season! Status is currently under active development and there is sure to be a bunch of learning, [build status from scratch](doc/starting-guide.md) or if an android user check out our [nightly builds](https://status.im/nightly). You can shake your phone to submit bug reports, or start browsing our [Github Issues](https://github.com/status-im/status-mobile/issues). Every bug you find brings Status closer to stable, usable software for everyone to enjoy!
|
||||
It's bug hunting season! Status is currently under active development and there is sure to be a bunch of learning, [build status from scratch](https://status.im/technical/build_status/) or if an android user check out our [nightly builds](https://status.im/nightly). You can shake your phone to submit bug reports, or start browsing our [Github Issues](https://github.com/status-im/status-mobile/issues). Every bug you find brings Status closer to stable, usable software for everyone to enjoy!
|
||||
|
||||
- **Security**
|
||||
Status is a visual interface to make permanent changes on the Blockchain, it handles crypto-tokens that have real value and allows 3rd party code execution. Security is paramount to its success. You are given permission to break Status as hard as you can, as long as you share your findings with the community!
|
||||
@@ -54,6 +52,9 @@ Status is a visual interface to make permanent changes on the Blockchain, it han
|
||||
- **Evangelism**
|
||||
Help us spread the word! Tell a friend *right now*, in fact tell **everyone** - yell from a mountain if you have to, every person counts! If you've got a great story to tell or have some interesting way you've spread the word about Status let us know about it in our [chat](https://join.status.im/chat/public/status)
|
||||
|
||||
## Status API
|
||||
View our [API Docs](https://status.im/developer_tools/status_web_api.html) and learn how to integrate your DApp into Status. You can read more about how to add your DApp to Status [here](https://status.im/developer_tools/add_your_dapp.html).
|
||||
|
||||
## Give me Binaries!
|
||||
|
||||
You can get our Beta builds for both Android and iOS on our [website](https://status.im), through our [nightly builds](https://status.im/nightly/) or by [building it yourself](https://status.im/technical/build_status/).
|
||||
@@ -67,8 +68,12 @@ Without the dedication of these outstanding individuals, Status would not exist.
|
||||
|
||||
## Contact us
|
||||
|
||||
Feel free to email us at [support@status.im](mailto:support@status.im).
|
||||
Feel free to email us at [support@status.im](mailto:support@status.im) or better yet, [join our chat](https://join.status.im/chat/public/status).
|
||||
|
||||
## License
|
||||
|
||||
Licensed under the [Mozilla Public License v2.0](https://github.com/status-im/status-mobile/blob/develop/LICENSE.md)
|
||||
|
||||
## Testing Supported by
|
||||
|
||||
[](https://www.browserstack.com/automate/public-build/SFBWQ3k5R2tnT2t6UGsxU1h1U0g3VFlCNnoxVTRHYWNoTDhsb1laaTJZWT0tLUZMUm5sSVFBSU9qSWM1RUJvK1I3Z3c9PQ==--ad15ae7992b432b33743749d40318952415bd98f)
|
||||
|
||||
@@ -94,10 +94,6 @@ project.ext.react = [
|
||||
enableHermes: !disableHermes,
|
||||
/* Disable 'The first definition was here.' warnings */
|
||||
hermesFlagsRelease: ["-w"],
|
||||
/* FIXME: Workaround for crash caused by missing libhermes-executor-release.so.
|
||||
* https://github.com/facebook/react-native/issues/32928 */
|
||||
deleteDebugFilesForVariant: { false },
|
||||
enableVmCleanup: false,
|
||||
bundleInPr: true,
|
||||
inputExcludes: ["android/**", "ios/**", "react-native/**", "src/**", "test/**"]
|
||||
]
|
||||
@@ -136,14 +132,6 @@ def jscFlavor = 'org.webkit:android-jsc:+'
|
||||
*/
|
||||
def enableHermes = project.ext.react.get("enableHermes", false);
|
||||
|
||||
/**
|
||||
* Architectures to build native code for.
|
||||
*/
|
||||
def reactNativeArchitectures() {
|
||||
def value = project.getProperties().get("reactNativeArchitectures")
|
||||
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
|
||||
}
|
||||
|
||||
def getCommitHash = { ->
|
||||
if (project.hasProperty("commitHash")) {
|
||||
return project.commitHash
|
||||
@@ -173,7 +161,7 @@ def getVersionName = { ->
|
||||
}
|
||||
/* Necessary because Android Studio uses wrong PWD.
|
||||
* Is actually absolute directory path of this file. */
|
||||
def configDir = project.projectDir.toString()
|
||||
def configDir = project.projectDir.toString()
|
||||
version = new File(configDir + '/../../VERSION').text
|
||||
return version.replaceAll("\\s","")
|
||||
}
|
||||
@@ -195,13 +183,11 @@ def getEnvOrConfig = { varName ->
|
||||
}
|
||||
|
||||
android {
|
||||
ndkVersion rootProject.ext.ndkVersion
|
||||
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
@@ -219,70 +205,7 @@ android {
|
||||
abiFilters getEnvOrConfig('ANDROID_ABI_INCLUDE').split(";")
|
||||
}
|
||||
}
|
||||
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
||||
|
||||
if (isNewArchitectureEnabled()) {
|
||||
// We configure the NDK build only if you decide to opt-in for the New Architecture.
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
arguments "APP_PLATFORM=android-21",
|
||||
"APP_STL=c++_shared",
|
||||
"NDK_TOOLCHAIN_VERSION=clang",
|
||||
"GENERATED_SRC_DIR=$buildDir/generated/source",
|
||||
"PROJECT_BUILD_DIR=$buildDir",
|
||||
"REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
|
||||
"REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build",
|
||||
"NODE_MODULES_DIR=$rootDir/../node_modules"
|
||||
cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
|
||||
cppFlags "-std=c++17"
|
||||
// Make sure this target name is the same you specify inside the
|
||||
// src/main/jni/Android.mk file for the `LOCAL_MODULE` variable.
|
||||
targets "rndiffapp_appmodules"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isNewArchitectureEnabled()) {
|
||||
// We configure the NDK build only if you decide to opt-in for the New Architecture.
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
path "$projectDir/src/main/jni/Android.mk"
|
||||
}
|
||||
}
|
||||
def reactAndroidProjectDir = project(':ReactAndroid').projectDir
|
||||
def packageReactNdkDebugLibs = tasks.register("packageReactNdkDebugLibs", Copy) {
|
||||
dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck")
|
||||
from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
|
||||
into("$buildDir/react-ndk/exported")
|
||||
}
|
||||
def packageReactNdkReleaseLibs = tasks.register("packageReactNdkReleaseLibs", Copy) {
|
||||
dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck")
|
||||
from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
|
||||
into("$buildDir/react-ndk/exported")
|
||||
}
|
||||
afterEvaluate {
|
||||
// If you wish to add a custom TurboModule or component locally,
|
||||
// you should uncomment this line.
|
||||
// preBuild.dependsOn("generateCodegenArtifactsFromSchema")
|
||||
preDebugBuild.dependsOn(packageReactNdkDebugLibs)
|
||||
preReleaseBuild.dependsOn(packageReactNdkReleaseLibs)
|
||||
|
||||
// Due to a bug inside AGP, we have to explicitly set a dependency
|
||||
// between configureNdkBuild* tasks and the preBuild tasks.
|
||||
// This can be removed once this is solved: https://issuetracker.google.com/issues/207403732
|
||||
configureNdkBuildRelease.dependsOn(preReleaseBuild)
|
||||
configureNdkBuildDebug.dependsOn(preDebugBuild)
|
||||
reactNativeArchitectures().each { architecture ->
|
||||
tasks.findByName("configureNdkBuildDebug[${architecture}]")?.configure {
|
||||
dependsOn("preDebugBuild")
|
||||
}
|
||||
tasks.findByName("configureNdkBuildRelease[${architecture}]")?.configure {
|
||||
dependsOn("preReleaseBuild")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Arbitrary project metadata
|
||||
* https://docs.gradle.org/current/dsl/org.gradle.api.plugins.ExtraPropertiesExtension.html
|
||||
@@ -385,15 +308,26 @@ android {
|
||||
dependencies {
|
||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
implementation "com.facebook.react:react-native:+" // From node_modules
|
||||
implementation 'com.facebook.soloader:soloader:0.10.3+'
|
||||
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
|
||||
implementation "androidx.core:core-splashscreen:1.0.0"
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.facebook.fbjni'
|
||||
}
|
||||
// TODO Uncomment once Flipper does not cause webview crashes in Debug mode
|
||||
// debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
|
||||
// exclude group:'com.facebook.flipper'
|
||||
// }
|
||||
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.facebook.flipper'
|
||||
}
|
||||
|
||||
if (enableHermes) {
|
||||
//noinspection GradleDynamicVersion
|
||||
implementation("com.facebook.react:hermes-engine:+") { // From node_modules
|
||||
exclude group: 'com.facebook.fbjni' }
|
||||
} else {
|
||||
def hermesPath = "../../node_modules/hermes-engine/android/";
|
||||
debugImplementation files(hermesPath + "hermes-debug.aar")
|
||||
releaseImplementation files(hermesPath + "hermes-release.aar")
|
||||
prImplementation files(hermesPath + "hermes-release.aar")
|
||||
} else {
|
||||
implementation jscFlavor
|
||||
}
|
||||
|
||||
@@ -411,25 +345,9 @@ dependencies {
|
||||
implementation project(':react-native-status')
|
||||
implementation project(':react-native-status-keycard')
|
||||
implementation 'com.github.status-im:function:0.0.1'
|
||||
implementation 'com.facebook.fresco:fresco:2.5.0'
|
||||
implementation 'com.facebook.fresco:animated-gif:2.5.0'
|
||||
implementation "com.squareup.okhttp3:okhttp-tls:4.9.2"
|
||||
}
|
||||
|
||||
if (isNewArchitectureEnabled()) {
|
||||
// If new architecture is enabled, we let you build RN from source
|
||||
// Otherwise we fallback to a prebuilt .aar bundled in the NPM package.
|
||||
// This will be applied to all the imported transtitive dependency.
|
||||
configurations.all {
|
||||
resolutionStrategy.dependencySubstitution {
|
||||
substitute(module("com.facebook.react:react-native"))
|
||||
.using(project(":ReactAndroid"))
|
||||
.because("On New Architecture we're building React Native from source")
|
||||
substitute(module("com.facebook.react:hermes-engine"))
|
||||
.using(project(":ReactAndroid:hermes-engine"))
|
||||
.because("On New Architecture we're building Hermes from source")
|
||||
}
|
||||
}
|
||||
implementation 'com.facebook.fresco:fresco:2.2.0'
|
||||
implementation 'com.facebook.fresco:animated-gif:2.2.0'
|
||||
implementation "com.squareup.okhttp3:okhttp-tls:3.12.12"
|
||||
}
|
||||
|
||||
def getLocalNDKDir = { ->
|
||||
@@ -465,11 +383,3 @@ task hemroidBuild(type: Exec) {
|
||||
preBuild.dependsOn hemroidBuild
|
||||
|
||||
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
|
||||
|
||||
def isNewArchitectureEnabled() {
|
||||
// To opt-in for the New Architecture, you can either:
|
||||
// - Set `newArchEnabled` to true inside the `gradle.properties` file
|
||||
// - Invoke gradle with `-newArchEnabled=true`
|
||||
// - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
|
||||
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
|
||||
}
|
||||
|
||||
@@ -7,7 +7,5 @@
|
||||
<!-- Remove licensing permission since we don't license our app and it blocks F-Droid submissions. -->
|
||||
<uses-permission tools:node="remove" android:name="com.android.vending.CHECK_LICENSE"/>
|
||||
|
||||
<application tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" android:usesCleartextTraffic="true" >
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" android:exported="false" />
|
||||
</application>
|
||||
<application tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" android:usesCleartextTraffic="true" />
|
||||
</manifest>
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
|
||||
* directory of this source tree.
|
||||
*/
|
||||
package im.status.ethereum;
|
||||
|
||||
import android.content.Context;
|
||||
import com.facebook.flipper.android.AndroidFlipperClient;
|
||||
import com.facebook.flipper.android.utils.FlipperUtils;
|
||||
import com.facebook.flipper.core.FlipperClient;
|
||||
import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
|
||||
import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.inspector.DescriptorMapping;
|
||||
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
|
||||
// import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
|
||||
// import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.react.ReactFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.modules.network.NetworkingModule;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
public class ReactNativeFlipper {
|
||||
public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
|
||||
if (FlipperUtils.shouldEnableFlipper(context)) {
|
||||
final FlipperClient client = AndroidFlipperClient.getInstance(context);
|
||||
|
||||
client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
|
||||
client.addPlugin(new ReactFlipperPlugin());
|
||||
client.addPlugin(new DatabasesFlipperPlugin(context));
|
||||
client.addPlugin(new SharedPreferencesFlipperPlugin(context));
|
||||
client.addPlugin(CrashReporterPlugin.getInstance());
|
||||
|
||||
// TODO Uncomment once Flipper does not cause webview crashes in Debug mode
|
||||
// NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
|
||||
// NetworkingModule.setCustomClientBuilder(
|
||||
// new NetworkingModule.CustomClientBuilder() {
|
||||
// @Override
|
||||
// public void apply(OkHttpClient.Builder builder) {
|
||||
// builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
|
||||
// }
|
||||
// });
|
||||
// client.addPlugin(networkFlipperPlugin);
|
||||
client.start();
|
||||
|
||||
// Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
|
||||
// Hence we run if after all native modules have been initialized
|
||||
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
|
||||
if (reactContext == null) {
|
||||
reactInstanceManager.addReactInstanceEventListener(
|
||||
new ReactInstanceManager.ReactInstanceEventListener() {
|
||||
@Override
|
||||
public void onReactContextInitialized(ReactContext reactContext) {
|
||||
reactInstanceManager.removeReactInstanceEventListener(this);
|
||||
reactContext.runOnNativeModulesQueueThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
client.addPlugin(new FrescoFlipperPlugin());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
client.addPlugin(new FrescoFlipperPlugin());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,22 +29,18 @@
|
||||
android:allowBackup="false"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:theme="@style/Theme.AppSplash"
|
||||
android:theme="@style/AppTheme"
|
||||
android:name=".MainApplication"
|
||||
android:largeHeap="true"
|
||||
android:usesCleartextTraffic="true"
|
||||
android:extractNativeLibs="true">
|
||||
<!-- After upgrading Android Gradle Plugin to 4.2.0 and above we must get rid of `extractNativeLibs="true"`
|
||||
and use`useLegacyPackaging` flag in our app's `build.gradle`-->
|
||||
android:usesCleartextTraffic="true">
|
||||
<meta-data android:name="commitHash" android:value="${commitHash}"/>
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/Theme.AppSplash"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
|
||||
android:resizeableActivity="false"
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
|
||||
@@ -21,7 +21,6 @@ import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.provider.Settings;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import com.facebook.react.ReactActivityDelegate;
|
||||
import com.facebook.react.ReactRootView;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
@@ -29,10 +28,10 @@ import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
|
||||
|
||||
import com.facebook.react.ReactFragmentActivity;
|
||||
import com.reactnativenavigation.NavigationActivity;
|
||||
import com.facebook.react.modules.core.PermissionListener;
|
||||
import androidx.core.splashscreen.SplashScreen;
|
||||
import com.facebook.react.ReactActivity;
|
||||
import org.devio.rn.splashscreen.SplashScreen;
|
||||
|
||||
import java.util.Properties;
|
||||
import im.status.ethereum.module.StatusThreadPoolExecutor;
|
||||
@@ -43,8 +42,6 @@ public class MainActivity extends NavigationActivity
|
||||
|
||||
|
||||
@Nullable private PermissionListener mPermissionListener;
|
||||
private boolean keepSplash = true;
|
||||
private final int SPLASH_DELAY = 3200;
|
||||
|
||||
private static void registerUncaughtExceptionHandler(final Context context) {
|
||||
final Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
|
||||
@@ -124,8 +121,21 @@ public class MainActivity extends NavigationActivity
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
SplashScreen splashScreen = SplashScreen.installSplashScreen(this);
|
||||
setTheme(R.style.DarkTheme);
|
||||
|
||||
switch (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) {
|
||||
case Configuration.UI_MODE_NIGHT_YES:
|
||||
setTheme(R.style.DarkTheme);
|
||||
SplashScreen.show(this, R.style.DarkTheme, R.id.lottie);
|
||||
break;
|
||||
case Configuration.UI_MODE_NIGHT_NO:
|
||||
setTheme(R.style.LightTheme);
|
||||
SplashScreen.show(this, R.style.LightTheme, R.id.lottie);
|
||||
break;
|
||||
default:
|
||||
setTheme(R.style.LightTheme);
|
||||
SplashScreen.show(this, R.style.LightTheme, R.id.lottie);
|
||||
}
|
||||
SplashScreen.setAnimationFinished(true);
|
||||
// Make sure we get an Alert for every uncaught exceptions
|
||||
registerUncaughtExceptionHandler(MainActivity.this);
|
||||
|
||||
@@ -187,11 +197,6 @@ public class MainActivity extends NavigationActivity
|
||||
}
|
||||
};
|
||||
|
||||
splashScreen.setKeepOnScreenCondition(() -> keepSplash);
|
||||
|
||||
Handler handler = new Handler();
|
||||
handler.postDelayed(() -> keepSplash = false, SPLASH_DELAY);
|
||||
|
||||
StatusThreadPoolExecutor.getInstance().execute(r);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package im.status.ethereum;
|
||||
|
||||
import androidx.multidex.MultiDexApplication;
|
||||
import android.util.Log;
|
||||
import android.content.Context;
|
||||
import android.webkit.WebView;
|
||||
import im.status.ethereum.newarchitecture.MainApplicationReactNativeHost;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import com.facebook.react.PackageList;
|
||||
|
||||
@@ -14,10 +14,9 @@ import com.facebook.react.ReactNativeHost;
|
||||
import com.reactnativenavigation.NavigationApplication;
|
||||
import com.reactnativenavigation.react.NavigationReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.config.ReactFeatureFlags;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.modules.network.OkHttpClientProvider;
|
||||
import com.reactnativecommunity.blurview.BlurViewPackage;
|
||||
import com.cmcewen.blurview.BlurViewPackage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -39,7 +38,6 @@ public class MainApplication extends NavigationApplication {
|
||||
|
||||
@Override
|
||||
protected List<ReactPackage> getPackages() {
|
||||
|
||||
StatusPackage statusPackage = new StatusPackage(RootUtil.isDeviceRooted());
|
||||
|
||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||
@@ -62,26 +60,48 @@ public class MainApplication extends NavigationApplication {
|
||||
}
|
||||
};
|
||||
|
||||
private final ReactNativeHost mNewArchitectureNativeHost = new MainApplicationReactNativeHost(this);
|
||||
|
||||
@Override
|
||||
public ReactNativeHost getReactNativeHost() {
|
||||
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
||||
return mNewArchitectureNativeHost;
|
||||
} else {
|
||||
return mReactNativeHost;
|
||||
}
|
||||
return mReactNativeHost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
// If you opted-in for the New Architecture, we enable the TurboModule system
|
||||
ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
|
||||
|
||||
OkHttpClientProvider.setOkHttpClientFactory(new StatusOkHttpClientFactory());
|
||||
|
||||
WebView.setWebContentsDebuggingEnabled(BuildConfig.DEBUG_WEBVIEW == "1");
|
||||
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||
}
|
||||
/**
|
||||
* Loads Flipper in React Native templates. Call this in the onCreate method with something like
|
||||
* initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||
*
|
||||
* @param context
|
||||
* @param reactInstanceManager
|
||||
*/
|
||||
private static void initializeFlipper(
|
||||
Context context, ReactInstanceManager reactInstanceManager) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
try {
|
||||
/*
|
||||
We use reflection here to pick up the class that initializes Flipper,
|
||||
since Flipper library is not available in release mode
|
||||
*/
|
||||
Class<?> aClass = Class.forName("im.status.ethereum.ReactNativeFlipper");
|
||||
aClass
|
||||
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
|
||||
.invoke(null, context, reactInstanceManager);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,58 +20,25 @@ import java.security.cert.X509Certificate;
|
||||
import im.status.ethereum.module.StatusPackage;
|
||||
|
||||
class StatusOkHttpClientFactory implements OkHttpClientFactory {
|
||||
|
||||
private static final String TAG = "StatusOkHttpClientFactory";
|
||||
|
||||
public OkHttpClient createNewNetworkModuleClient() {
|
||||
X509Certificate cert = null;
|
||||
HandshakeCertificates clientCertificates;
|
||||
String certPem = "";
|
||||
String certPem = StatusPackage.getImageTLSCert();
|
||||
X509Certificate cert;
|
||||
|
||||
// Get TLS PEM certificate from status-go
|
||||
try {
|
||||
// induce half second sleep because sometimes a cert is not immediately available
|
||||
// TODO : remove sleep if App no longer crashes on Android 10 devices with
|
||||
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
|
||||
Thread.sleep(500);
|
||||
certPem = StatusPackage.getImageTLSCert();
|
||||
} catch(Exception e) {
|
||||
Log.e(TAG, "Could not getImageTLSCert",e);
|
||||
}
|
||||
// Convert PEM certificate string to X509Certificate object
|
||||
try {
|
||||
// induce half second sleep because sometimes a cert is not immediately available
|
||||
// TODO : remove sleep if App no longer crashes on Android 10 devices
|
||||
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
|
||||
Thread.sleep(500);
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certPem.getBytes()));
|
||||
} catch(Exception e) {
|
||||
Log.e(TAG, "Could not parse certificate",e);
|
||||
}
|
||||
// Create HandshakeCertificates object with our certificate
|
||||
try {
|
||||
// induce half second sleep because sometimes a cert is not immediately available
|
||||
// TODO : remove sleep if App no longer crashes on Android 10 devices
|
||||
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
|
||||
Thread.sleep(500);
|
||||
clientCertificates = new HandshakeCertificates.Builder()
|
||||
.addPlatformTrustedCertificates()
|
||||
.addTrustedCertificate(cert)
|
||||
.build();
|
||||
} catch(Exception e) {
|
||||
Log.e(TAG, "Could not build HandshakeCertificates", e);
|
||||
return null;
|
||||
Log.e("StatusOkHttpClientFactory", "Could not parse certificate");
|
||||
cert = null;
|
||||
}
|
||||
|
||||
// Create OkHttpClient with custom SSL socket factory and trust manager
|
||||
try {
|
||||
return OkHttpClientProvider.createClientBuilder()
|
||||
.sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager())
|
||||
.build();
|
||||
} catch(Exception e) {
|
||||
Log.e(TAG, "Could not create OkHttpClient", e);
|
||||
return null;
|
||||
}
|
||||
HandshakeCertificates clientCertificates = new HandshakeCertificates.Builder()
|
||||
.addPlatformTrustedCertificates()
|
||||
.addTrustedCertificate(cert)
|
||||
.build();
|
||||
|
||||
return OkHttpClientProvider.createClientBuilder()
|
||||
.sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
package im.status.ethereum.newarchitecture;
|
||||
import android.app.Application;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.facebook.react.PackageList;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
|
||||
import com.facebook.react.bridge.JSIModulePackage;
|
||||
import com.facebook.react.bridge.JSIModuleProvider;
|
||||
import com.facebook.react.bridge.JSIModuleSpec;
|
||||
import com.facebook.react.bridge.JSIModuleType;
|
||||
import com.facebook.react.bridge.JavaScriptContextHolder;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.UIManager;
|
||||
import com.facebook.react.fabric.ComponentFactory;
|
||||
import com.facebook.react.fabric.CoreComponentsRegistry;
|
||||
import com.facebook.react.fabric.FabricJSIModuleProvider;
|
||||
import com.facebook.react.fabric.ReactNativeConfig;
|
||||
import com.facebook.react.uimanager.ViewManagerRegistry;
|
||||
import im.status.ethereum.BuildConfig;
|
||||
import im.status.ethereum.newarchitecture.components.MainComponentsRegistry;
|
||||
import im.status.ethereum.newarchitecture.modules.MainApplicationTurboModuleManagerDelegate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
/**
|
||||
* A {@link ReactNativeHost} that helps you load everything needed for the New Architecture, both
|
||||
* TurboModule delegates and the Fabric Renderer.
|
||||
*
|
||||
* <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
|
||||
* `newArchEnabled` property). Is ignored otherwise.
|
||||
*/
|
||||
public class MainApplicationReactNativeHost extends ReactNativeHost {
|
||||
public MainApplicationReactNativeHost(Application application) {
|
||||
super(application);
|
||||
}
|
||||
@Override
|
||||
public boolean getUseDeveloperSupport() {
|
||||
return BuildConfig.DEBUG;
|
||||
}
|
||||
@Override
|
||||
protected List<ReactPackage> getPackages() {
|
||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||
// Packages that cannot be autolinked yet can be added manually here, for example:
|
||||
// packages.add(new MyReactNativePackage());
|
||||
// TurboModules must also be loaded here providing a valid TurboReactPackage implementation:
|
||||
// packages.add(new TurboReactPackage() { ... });
|
||||
// If you have custom Fabric Components, their ViewManagers should also be loaded here
|
||||
// inside a ReactPackage.
|
||||
return packages;
|
||||
}
|
||||
@Override
|
||||
protected String getJSMainModuleName() {
|
||||
return "index";
|
||||
}
|
||||
@NonNull
|
||||
@Override
|
||||
protected ReactPackageTurboModuleManagerDelegate.Builder
|
||||
getReactPackageTurboModuleManagerDelegateBuilder() {
|
||||
// Here we provide the ReactPackageTurboModuleManagerDelegate Builder. This is necessary
|
||||
// for the new architecture and to use TurboModules correctly.
|
||||
return new MainApplicationTurboModuleManagerDelegate.Builder();
|
||||
}
|
||||
@Override
|
||||
protected JSIModulePackage getJSIModulePackage() {
|
||||
return new JSIModulePackage() {
|
||||
@Override
|
||||
public List<JSIModuleSpec> getJSIModules(
|
||||
final ReactApplicationContext reactApplicationContext,
|
||||
final JavaScriptContextHolder jsContext) {
|
||||
final List<JSIModuleSpec> specs = new ArrayList<>();
|
||||
// Here we provide a new JSIModuleSpec that will be responsible of providing the
|
||||
// custom Fabric Components.
|
||||
specs.add(
|
||||
new JSIModuleSpec() {
|
||||
@Override
|
||||
public JSIModuleType getJSIModuleType() {
|
||||
return JSIModuleType.UIManager;
|
||||
}
|
||||
@Override
|
||||
public JSIModuleProvider<UIManager> getJSIModuleProvider() {
|
||||
final ComponentFactory componentFactory = new ComponentFactory();
|
||||
CoreComponentsRegistry.register(componentFactory);
|
||||
// Here we register a Components Registry.
|
||||
// The one that is generated with the template contains no components
|
||||
// and just provides you the one from React Native core.
|
||||
MainComponentsRegistry.register(componentFactory);
|
||||
final ReactInstanceManager reactInstanceManager = getReactInstanceManager();
|
||||
ViewManagerRegistry viewManagerRegistry =
|
||||
new ViewManagerRegistry(
|
||||
reactInstanceManager.getOrCreateViewManagers(reactApplicationContext));
|
||||
return new FabricJSIModuleProvider(
|
||||
reactApplicationContext,
|
||||
componentFactory,
|
||||
ReactNativeConfig.DEFAULT_CONFIG,
|
||||
viewManagerRegistry);
|
||||
}
|
||||
});
|
||||
return specs;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package im.status.ethereum.newarchitecture.components;
|
||||
import com.facebook.jni.HybridData;
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
import com.facebook.react.fabric.ComponentFactory;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
/**
|
||||
* Class responsible to load the custom Fabric Components. This class has native methods and needs a
|
||||
* corresponding C++ implementation/header file to work correctly (already placed inside the jni/
|
||||
* folder for you).
|
||||
*
|
||||
* <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
|
||||
* `newArchEnabled` property). Is ignored otherwise.
|
||||
*/
|
||||
@DoNotStrip
|
||||
public class MainComponentsRegistry {
|
||||
static {
|
||||
SoLoader.loadLibrary("fabricjni");
|
||||
}
|
||||
@DoNotStrip private final HybridData mHybridData;
|
||||
@DoNotStrip
|
||||
private native HybridData initHybrid(ComponentFactory componentFactory);
|
||||
@DoNotStrip
|
||||
private MainComponentsRegistry(ComponentFactory componentFactory) {
|
||||
mHybridData = initHybrid(componentFactory);
|
||||
}
|
||||
@DoNotStrip
|
||||
public static MainComponentsRegistry register(ComponentFactory componentFactory) {
|
||||
return new MainComponentsRegistry(componentFactory);
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package im.status.ethereum.newarchitecture.modules;
|
||||
import com.facebook.jni.HybridData;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
import java.util.List;
|
||||
/**
|
||||
* Class responsible to load the TurboModules. This class has native methods and needs a
|
||||
* corresponding C++ implementation/header file to work correctly (already placed inside the jni/
|
||||
* folder for you).
|
||||
*
|
||||
* <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
|
||||
* `newArchEnabled` property). Is ignored otherwise.
|
||||
*/
|
||||
public class MainApplicationTurboModuleManagerDelegate
|
||||
extends ReactPackageTurboModuleManagerDelegate {
|
||||
private static volatile boolean sIsSoLibraryLoaded;
|
||||
protected MainApplicationTurboModuleManagerDelegate(
|
||||
ReactApplicationContext reactApplicationContext, List<ReactPackage> packages) {
|
||||
super(reactApplicationContext, packages);
|
||||
}
|
||||
protected native HybridData initHybrid();
|
||||
native boolean canCreateTurboModule(String moduleName);
|
||||
public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder {
|
||||
protected MainApplicationTurboModuleManagerDelegate build(
|
||||
ReactApplicationContext context, List<ReactPackage> packages) {
|
||||
return new MainApplicationTurboModuleManagerDelegate(context, packages);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected synchronized void maybeLoadOtherSoLibraries() {
|
||||
if (!sIsSoLibraryLoaded) {
|
||||
// If you change the name of your application .so file in the Android.mk file,
|
||||
// make sure you update the name here as well.
|
||||
SoLoader.loadLibrary("status-im_appmodules");
|
||||
sIsSoLibraryLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
THIS_DIR := $(call my-dir)
|
||||
include $(REACT_ANDROID_DIR)/Android-prebuilt.mk
|
||||
# If you wish to add a custom TurboModule or Fabric component in your app you
|
||||
# will have to include the following autogenerated makefile.
|
||||
# include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_PATH := $(THIS_DIR)
|
||||
# You can customize the name of your application .so file here.
|
||||
LOCAL_MODULE := rndiffapp_appmodules
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)
|
||||
LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp)
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
|
||||
# If you wish to add a custom TurboModule or Fabric component in your app you
|
||||
# will have to uncomment those lines to include the generated source
|
||||
# files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni)
|
||||
#
|
||||
# LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
|
||||
# LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp)
|
||||
# LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
|
||||
# Here you should add any native library you wish to depend on.
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libfabricjni \
|
||||
libfbjni \
|
||||
libfolly_runtime \
|
||||
libglog \
|
||||
libjsi \
|
||||
libreact_codegen_rncore \
|
||||
libreact_debug \
|
||||
libreact_nativemodule_core \
|
||||
libreact_render_componentregistry \
|
||||
libreact_render_core \
|
||||
libreact_render_debug \
|
||||
libreact_render_graphics \
|
||||
librrc_view \
|
||||
libruntimeexecutor \
|
||||
libturbomodulejsijni \
|
||||
libyoga
|
||||
LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 -Wall
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
@@ -1,20 +0,0 @@
|
||||
#include "MainApplicationModuleProvider.h"
|
||||
#include <rncore.h>
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
std::shared_ptr<TurboModule> MainApplicationModuleProvider(
|
||||
const std::string moduleName,
|
||||
const JavaTurboModule::InitParams ¶ms) {
|
||||
// Here you can provide your own module provider for TurboModules coming from
|
||||
// either your application or from external libraries. The approach to follow
|
||||
// is similar to the following (for a library called `samplelibrary`:
|
||||
//
|
||||
// auto module = samplelibrary_ModuleProvider(moduleName, params);
|
||||
// if (module != nullptr) {
|
||||
// return module;
|
||||
// }
|
||||
// return rncore_ModuleProvider(moduleName, params);
|
||||
return rncore_ModuleProvider(moduleName, params);
|
||||
}
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <ReactCommon/JavaTurboModule.h>
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
std::shared_ptr<TurboModule> MainApplicationModuleProvider(
|
||||
const std::string moduleName,
|
||||
const JavaTurboModule::InitParams ¶ms);
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -1,38 +0,0 @@
|
||||
#include "MainApplicationTurboModuleManagerDelegate.h"
|
||||
#include "MainApplicationModuleProvider.h"
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
jni::local_ref<MainApplicationTurboModuleManagerDelegate::jhybriddata>
|
||||
MainApplicationTurboModuleManagerDelegate::initHybrid(
|
||||
jni::alias_ref<jhybridobject>) {
|
||||
return makeCxxInstance();
|
||||
}
|
||||
void MainApplicationTurboModuleManagerDelegate::registerNatives() {
|
||||
registerHybrid({
|
||||
makeNativeMethod(
|
||||
"initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid),
|
||||
makeNativeMethod(
|
||||
"canCreateTurboModule",
|
||||
MainApplicationTurboModuleManagerDelegate::canCreateTurboModule),
|
||||
});
|
||||
}
|
||||
std::shared_ptr<TurboModule>
|
||||
MainApplicationTurboModuleManagerDelegate::getTurboModule(
|
||||
const std::string name,
|
||||
const std::shared_ptr<CallInvoker> jsInvoker) {
|
||||
// Not implemented yet: provide pure-C++ NativeModules here.
|
||||
return nullptr;
|
||||
}
|
||||
std::shared_ptr<TurboModule>
|
||||
MainApplicationTurboModuleManagerDelegate::getTurboModule(
|
||||
const std::string name,
|
||||
const JavaTurboModule::InitParams ¶ms) {
|
||||
return MainApplicationModuleProvider(name, params);
|
||||
}
|
||||
bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule(
|
||||
std::string name) {
|
||||
return getTurboModule(name, nullptr) != nullptr ||
|
||||
getTurboModule(name, {.moduleName = name}) != nullptr;
|
||||
}
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -1,30 +0,0 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <ReactCommon/TurboModuleManagerDelegate.h>
|
||||
#include <fbjni/fbjni.h>
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
class MainApplicationTurboModuleManagerDelegate
|
||||
: public jni::HybridClass<
|
||||
MainApplicationTurboModuleManagerDelegate,
|
||||
TurboModuleManagerDelegate> {
|
||||
public:
|
||||
// Adapt it to the package you used for your Java class.
|
||||
static constexpr auto kJavaDescriptor =
|
||||
"Lcom/rndiffapp/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;";
|
||||
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject>);
|
||||
static void registerNatives();
|
||||
std::shared_ptr<TurboModule> getTurboModule(
|
||||
const std::string name,
|
||||
const std::shared_ptr<CallInvoker> jsInvoker) override;
|
||||
std::shared_ptr<TurboModule> getTurboModule(
|
||||
const std::string name,
|
||||
const JavaTurboModule::InitParams ¶ms) override;
|
||||
/**
|
||||
* Test-only method. Allows user to verify whether a TurboModule can be
|
||||
* created by instances of this class.
|
||||
*/
|
||||
bool canCreateTurboModule(std::string name);
|
||||
};
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -1,48 +0,0 @@
|
||||
#include "MainComponentsRegistry.h"
|
||||
#include <CoreComponentsRegistry.h>
|
||||
#include <fbjni/fbjni.h>
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
|
||||
#include <react/renderer/components/rncore/ComponentDescriptors.h>
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {}
|
||||
std::shared_ptr<ComponentDescriptorProviderRegistry const>
|
||||
MainComponentsRegistry::sharedProviderRegistry() {
|
||||
auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry();
|
||||
// Custom Fabric Components go here. You can register custom
|
||||
// components coming from your App or from 3rd party libraries here.
|
||||
//
|
||||
// providerRegistry->add(concreteComponentDescriptorProvider<
|
||||
// AocViewerComponentDescriptor>());
|
||||
return providerRegistry;
|
||||
}
|
||||
jni::local_ref<MainComponentsRegistry::jhybriddata>
|
||||
MainComponentsRegistry::initHybrid(
|
||||
jni::alias_ref<jclass>,
|
||||
ComponentFactory *delegate) {
|
||||
auto instance = makeCxxInstance(delegate);
|
||||
auto buildRegistryFunction =
|
||||
[](EventDispatcher::Weak const &eventDispatcher,
|
||||
ContextContainer::Shared const &contextContainer)
|
||||
-> ComponentDescriptorRegistry::Shared {
|
||||
auto registry = MainComponentsRegistry::sharedProviderRegistry()
|
||||
->createComponentDescriptorRegistry(
|
||||
{eventDispatcher, contextContainer});
|
||||
auto mutableRegistry =
|
||||
std::const_pointer_cast<ComponentDescriptorRegistry>(registry);
|
||||
mutableRegistry->setFallbackComponentDescriptor(
|
||||
std::make_shared<UnimplementedNativeViewComponentDescriptor>(
|
||||
ComponentDescriptorParameters{
|
||||
eventDispatcher, contextContainer, nullptr}));
|
||||
return registry;
|
||||
};
|
||||
delegate->buildRegistryFunction = buildRegistryFunction;
|
||||
return instance;
|
||||
}
|
||||
void MainComponentsRegistry::registerNatives() {
|
||||
registerHybrid({
|
||||
makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid),
|
||||
});
|
||||
}
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
#include <ComponentFactory.h>
|
||||
#include <fbjni/fbjni.h>
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorRegistry.h>
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
class MainComponentsRegistry
|
||||
: public facebook::jni::HybridClass<MainComponentsRegistry> {
|
||||
public:
|
||||
// Adapt it to the package you used for your Java class.
|
||||
constexpr static auto kJavaDescriptor =
|
||||
"Lcom/rndiffapp/newarchitecture/components/MainComponentsRegistry;";
|
||||
static void registerNatives();
|
||||
MainComponentsRegistry(ComponentFactory *delegate);
|
||||
private:
|
||||
static std::shared_ptr<ComponentDescriptorProviderRegistry const>
|
||||
sharedProviderRegistry();
|
||||
static jni::local_ref<jhybriddata> initHybrid(
|
||||
jni::alias_ref<jclass>,
|
||||
ComponentFactory *delegate);
|
||||
};
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -1,10 +0,0 @@
|
||||
#include <fbjni/fbjni.h>
|
||||
#include "MainApplicationTurboModuleManagerDelegate.h"
|
||||
#include "MainComponentsRegistry.h"
|
||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
||||
return facebook::jni::initialize(vm, [] {
|
||||
facebook::react::MainApplicationTurboModuleManagerDelegate::
|
||||
registerNatives();
|
||||
facebook::react::MainComponentsRegistry::registerNatives();
|
||||
});
|
||||
}
|
||||
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
@@ -2,6 +2,4 @@
|
||||
<resources>
|
||||
<color name="alert_background">#ffffff</color>
|
||||
<color name="alert_text">#000000</color>
|
||||
<color name="splash_background">#09101C</color>
|
||||
<color name="splash_status_bar_color">#ffffff</color>
|
||||
</resources>
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<style name="Theme.AppSplash" parent="Theme.SplashScreen">
|
||||
<item name="windowSplashScreenBackground">@color/splash_background</item>
|
||||
<item name="windowSplashScreenAnimatedIcon">@drawable/splash_logo</item>
|
||||
<item name="windowSplashScreenAnimationDuration">1000</item>
|
||||
|
||||
<!-- Status bar and Nav bar configs -->
|
||||
<item name="android:statusBarColor" tools:targetApi="l">@color/splash_background</item>
|
||||
<item name="android:windowLightStatusBar">false</item>
|
||||
|
||||
<item name="postSplashScreenTheme">@style/DarkTheme</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -1,30 +1,16 @@
|
||||
import org.apache.tools.ant.taskdefs.condition.Os
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
/**
|
||||
* Project-wide gradle configuration properties for use by all modules
|
||||
*/
|
||||
ext {
|
||||
// kotlin_version is needed for react-native-camera-kit library
|
||||
kotlin_version = project.kotlinVersion
|
||||
RNNKotlinVersion = "1.6.20"
|
||||
RNGH_kotlinVersion = "1.6.20"
|
||||
RNNKotlinVersion = "1.4.31"
|
||||
buildToolsVersion = project.buildToolsVersion
|
||||
minSdkVersion = Integer.valueOf(project.minSdkVersion)
|
||||
compileSdkVersion = Integer.valueOf(project.compileSdkVersion)
|
||||
targetSdkVersion = Integer.valueOf(project.targetSdkVersion)
|
||||
supportLibVersion = project.supportLibVersion
|
||||
gradlePluginVersion = project.gradlePluginVersion
|
||||
kotlinPluginVersion = project.kotlinPluginVersion
|
||||
|
||||
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"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
buildscript {
|
||||
@@ -34,10 +20,8 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${project.ext.kotlinPluginVersion}"
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.31"
|
||||
classpath "com.android.tools.build:gradle:${project.ext.gradlePluginVersion}"
|
||||
classpath("com.facebook.react:react-native-gradle-plugin")
|
||||
classpath("de.undercouch:gradle-download-task:5.0.1")
|
||||
// WARNING: Do not place your application dependencies here!
|
||||
// They belong in the individual module build.gradle files.
|
||||
}
|
||||
@@ -66,20 +50,6 @@ allprojects {
|
||||
}
|
||||
|
||||
repositories {
|
||||
exclusiveContent {
|
||||
// We get React Native's Android binaries exclusively through npm,
|
||||
// from a local Maven repo inside node_modules/react-native/.
|
||||
// (The use of exclusiveContent prevents looking elsewhere like Maven Central
|
||||
// and potentially getting a wrong version.)
|
||||
filter {
|
||||
includeGroup "com.facebook.react"
|
||||
}
|
||||
forRepository {
|
||||
maven {
|
||||
url "$rootDir/../node_modules/react-native/android"
|
||||
}
|
||||
}
|
||||
}
|
||||
mavenLocal()
|
||||
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
||||
maven { url("$rootDir/../node_modules/react-native/android") }
|
||||
@@ -91,7 +61,6 @@ allprojects {
|
||||
google()
|
||||
jcenter() // Required for @react-native-community/blur:3.6.1, can be removed after updating to 3.6.1+
|
||||
mavenCentral()
|
||||
// maven { url "https://www.jitpack.io" }
|
||||
maven { url 'https://mvnrepository.com/artifact/com.github.gundy/semver4j'}
|
||||
maven { url "https://www.jitpack.io" }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,15 +21,14 @@
|
||||
# $keytool -genkey -v -keystore ./status-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias status
|
||||
|
||||
# Version requirements used throughout the Gradle scripts
|
||||
kotlinVersion=1.6.20
|
||||
kotlinVersion=1.3.50
|
||||
minSdkVersion=23
|
||||
compileSdkVersion=31
|
||||
targetSdkVersion=31
|
||||
buildToolsVersion=31.0.0
|
||||
supportLibVersion=28.0.0
|
||||
# This should match version from nix/mobile/android/maven-and-npm-deps/maven/default.nix
|
||||
gradlePluginVersion=7.2.2
|
||||
kotlinPluginVersion=1.6.20
|
||||
gradlePluginVersion=3.5.4
|
||||
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
@@ -49,9 +48,5 @@ org.gradle.jvmargs=-Xmx8704M
|
||||
versionCode=9999
|
||||
commitHash=unknown
|
||||
|
||||
# Use this property to enable support to the new architecture.
|
||||
# This will allow you to use TurboModules and the Fabric render in
|
||||
# your application. You should enable this flag either if you want
|
||||
# to write custom TurboModules/Fabric components OR use libraries that
|
||||
# are providing them.
|
||||
newArchEnabled=false
|
||||
# Flipper
|
||||
FLIPPER_VERSION=0.54.0
|
||||
|
||||
@@ -20,10 +20,3 @@ include ':react-native-status-keycard'
|
||||
project(':react-native-status-keycard').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-status-keycard/android')
|
||||
include ':react-native-blur'
|
||||
project(':react-native-blur').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/blur/android')
|
||||
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')
|
||||
include(":ReactAndroid:hermes-engine")
|
||||
project(":ReactAndroid:hermes-engine").projectDir = file('../node_modules/react-native/ReactAndroid/hermes-engine')
|
||||
}
|
||||
|
||||
@@ -1,19 +1,24 @@
|
||||
module.exports = {
|
||||
presets: ['module:metro-react-native-babel-preset'],
|
||||
plugins: ['react-native-reanimated/plugin'],
|
||||
env: {
|
||||
test: {
|
||||
presets: [
|
||||
'@babel/preset-react',
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
node: '14',
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
"presets": [
|
||||
"module:metro-react-native-babel-preset"
|
||||
],
|
||||
"plugins": [
|
||||
"react-native-reanimated/plugin"
|
||||
],
|
||||
"env": {
|
||||
"test": {
|
||||
"presets": [
|
||||
'@babel/preset-react',
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
node: '14',
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-jenkins-lib@v1.6.3'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux && x86_64 && nix-2.14' }
|
||||
agent { label 'linux && x86_64 && nix-2.11' }
|
||||
|
||||
options {
|
||||
timestamps()
|
||||
@@ -41,12 +40,16 @@ pipeline {
|
||||
BUILD_ENV = 'prod'
|
||||
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
|
||||
FASTLANE_DISABLE_COLORS = 1
|
||||
/* coverage report identification */
|
||||
COVERALLS_SERVICE_NAME = "jenkins"
|
||||
COVERALLS_SERVICE_JOB_ID = "${JOB_NAME}#${BUILD_NUMBER}"
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Prep') {
|
||||
steps {
|
||||
script {
|
||||
utils.doGitRebasePR()
|
||||
utils.symlinkEnv()
|
||||
println("Build Number: ${utils.genBuildNumber()}")
|
||||
}
|
||||
@@ -72,12 +75,20 @@ pipeline {
|
||||
stage('Upload') {
|
||||
steps { script {
|
||||
def urls = apks.collect { s3.uploadArtifact(it) }
|
||||
if (urls.size() > 1) { /* Return only the universal APK. */
|
||||
/* return only the universal APK */
|
||||
if (urls.size() > 1) {
|
||||
env.PKG_URL = urls.find { it.contains('universal') }
|
||||
} else { /* If no universal is available pick first. */
|
||||
} else { /* if no universal is available pick first */
|
||||
env.PKG_URL = urls.first()
|
||||
}
|
||||
jenkins.setBuildDesc(APK: env.PKG_URL)
|
||||
/* e2e builds get tested in SauceLabs */
|
||||
if (utils.isE2EBuild()) {
|
||||
env.SAUCE_URL = android.uploadToSauceLabs()
|
||||
}
|
||||
if (utils.isNightlyBuild()) {
|
||||
env.DIAWI_URL = android.uploadToDiawi()
|
||||
}
|
||||
} }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-jenkins-lib@v1.6.3'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
@@ -9,8 +8,6 @@ pipeline {
|
||||
disableConcurrentBuilds()
|
||||
/* Prevent Jenkins jobs from running forever */
|
||||
timeout(time: 40, unit: 'MINUTES')
|
||||
/* Allow copying of artifacts from this job. */
|
||||
copyArtifactPermission('/status-mobile/e2e/*')
|
||||
/* Limit builds retained */
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '10',
|
||||
@@ -20,7 +17,7 @@ pipeline {
|
||||
}
|
||||
|
||||
/* WARNING: Defining parameters here with the ?: trick causes them to remember last value. */
|
||||
parameters {
|
||||
parameters {
|
||||
choice(
|
||||
name: 'BUILD_TYPE',
|
||||
description: 'Makefile target to build. Optional Parameter.',
|
||||
@@ -108,7 +105,7 @@ pipeline {
|
||||
e2eApk = utils.getEnv(apke2e, 'SAUCE_URL')
|
||||
build(
|
||||
job: 'status-mobile/e2e/status-app-nightly',
|
||||
parameters: [string(name: 'APK_URL', value: e2eApk)],
|
||||
parameters: [string(name: 'APK_NAME', value: e2eApk)],
|
||||
wait: false
|
||||
)
|
||||
} }
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-jenkins-lib@v1.6.3'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
pipeline {
|
||||
agent { label 'macos && arm64 && nix-2.14 && xcode-14.3' }
|
||||
agent { label 'macos && x86_64 && nix-2.11 && xcode-13.4' }
|
||||
|
||||
parameters {
|
||||
string(
|
||||
@@ -49,6 +48,7 @@ pipeline {
|
||||
stage('Prep') {
|
||||
steps {
|
||||
script {
|
||||
utils.doGitRebasePR()
|
||||
utils.symlinkEnv()
|
||||
println("Build Number: ${utils.genBuildNumber()}")
|
||||
}
|
||||
@@ -63,11 +63,6 @@ pipeline {
|
||||
steps {
|
||||
script { api = ios.bundle() }
|
||||
}
|
||||
post {
|
||||
failure {
|
||||
archiveArtifacts 'ios/logs/*'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Parallel Upload') {
|
||||
parallel {
|
||||
@@ -77,11 +72,15 @@ pipeline {
|
||||
}
|
||||
}
|
||||
stage('Upload') {
|
||||
when { expression { !utils.isReleaseBuild() } }
|
||||
steps { script {
|
||||
env.DIAWI_URL = ios.uploadToDiawi()
|
||||
env.PKG_URL = env.DIAWI_URL
|
||||
env.PKG_URL = s3.uploadArtifact(api)
|
||||
jenkins.setBuildDesc(IPA: env.PKG_URL)
|
||||
/* e2e builds get tested in SauceLabs */
|
||||
if (utils.isE2EBuild()) {
|
||||
env.SAUCE_URL = ios.uploadToSauceLabs()
|
||||
} else if (!utils.isReleaseBuild()) {
|
||||
env.DIAWI_URL = ios.uploadToDiawi()
|
||||
}
|
||||
} }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-jenkins-lib@v1.6.3'
|
||||
|
||||
pipeline {
|
||||
agent { label params.AGENT_LABEL }
|
||||
@@ -29,7 +28,7 @@ pipeline {
|
||||
timestamps()
|
||||
disableConcurrentBuilds()
|
||||
/* Prevent Jenkins jobs from running forever */
|
||||
timeout(time: 120, unit: 'MINUTES')
|
||||
timeout(time: 300, unit: 'MINUTES')
|
||||
/* Limit builds retained */
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '20',
|
||||
@@ -42,19 +41,18 @@ pipeline {
|
||||
steps { script {
|
||||
nix.shell('nix-env -i openssh', sandbox: false, pure: false)
|
||||
/* some build targets don't build on MacOS */
|
||||
os = sh(script: 'uname', returnStdout: true)
|
||||
arch = sh(script: 'arch', returnStdout: true)
|
||||
uname = sh(script: 'uname', returnStdout: true)
|
||||
} }
|
||||
}
|
||||
stage('Build status-go') {
|
||||
steps { script {
|
||||
def platforms = ['mobile.android', 'mobile.ios', 'library']
|
||||
if (os != 'Darwin') { platforms.removeAll { it == 'mobile.ios' } }
|
||||
/* FIXME: Remove this when #16237 is merged. */
|
||||
if (arch == 'arm64') { platforms.removeAll { it == 'mobile.android' } }
|
||||
def platforms = ['mobile.android', 'mobile.ios']
|
||||
if (uname != "Darwin") {
|
||||
platforms.removeAll { it == "ios" }
|
||||
}
|
||||
platforms.each { os ->
|
||||
nix.build(
|
||||
attr: "targets.status-go.${os}",
|
||||
attr: "targets.status-go.${os}.buildInputs",
|
||||
sandbox: false,
|
||||
link: false
|
||||
)
|
||||
@@ -63,9 +61,10 @@ pipeline {
|
||||
}
|
||||
stage('Build android jsbundle') {
|
||||
steps { script {
|
||||
/* Build/fetch deps required for jsbundle build. */
|
||||
/* build/fetch things required to produce a js-bundle for android
|
||||
* (e.g. maven and node repos) */
|
||||
nix.build(
|
||||
attr: 'targets.mobile.jsbundle',
|
||||
attr: 'targets.mobile.android.jsbundle',
|
||||
sandbox: false,
|
||||
pure: false,
|
||||
link: false
|
||||
@@ -74,7 +73,7 @@ pipeline {
|
||||
}
|
||||
stage('Build android deps') {
|
||||
steps { script {
|
||||
/* Build/fetch deps required to build android release. */
|
||||
/* build/fetch things required to build jsbundle and android */
|
||||
nix.build(
|
||||
attr: 'targets.mobile.android.release.buildInputs',
|
||||
sandbox: false,
|
||||
@@ -85,16 +84,12 @@ pipeline {
|
||||
}
|
||||
stage('Build nix shell deps') {
|
||||
steps { script {
|
||||
def shells = ['android', 'ios', 'fastlane', 'keytool', 'clojure', 'gradle']
|
||||
if (os != "Darwin") { shells.removeAll { it == 'ios' } }
|
||||
/* Build/fetch deps required to start default Nix shell. */
|
||||
shells.each { shell ->
|
||||
nix.build(
|
||||
attr: "shells.${shell}.buildInputs",
|
||||
sandbox: false,
|
||||
link: false
|
||||
)
|
||||
}
|
||||
/* build/fetch things required to instantiate shell.nix for TARGET=all */
|
||||
nix.build(
|
||||
attr: 'shells.default.buildInputs',
|
||||
sandbox: false,
|
||||
link: false
|
||||
)
|
||||
} }
|
||||
}
|
||||
stage('Upload') {
|
||||
@@ -1,16 +1,15 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-jenkins-lib@v1.6.3'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux && x86_64 && nix-2.14' }
|
||||
agent { label 'linux && x86_64 && nix-2.11' }
|
||||
|
||||
options {
|
||||
timestamps()
|
||||
/* Prevent Jenkins jobs from running forever */
|
||||
timeout(time: 15, unit: 'MINUTES')
|
||||
timeout(time: 10, unit: 'MINUTES')
|
||||
/* Limit builds retained */
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '10',
|
||||
@@ -42,6 +41,13 @@ pipeline {
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Prep') {
|
||||
steps {
|
||||
script {
|
||||
utils.doGitRebasePR()
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Checks') {
|
||||
parallel {
|
||||
stage('Lint') {
|
||||
@@ -62,14 +68,6 @@ pipeline {
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Component Tests') {
|
||||
steps {
|
||||
sh """#!/bin/bash
|
||||
set -eo pipefail
|
||||
make component-test 2>&1 | tee -a ${LOG_FILE}
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('Upload') {
|
||||
steps {
|
||||
script {
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
|
||||
pipeline {
|
||||
|
||||
agent { label 'linux' }
|
||||
|
||||
parameters {
|
||||
string(
|
||||
name: 'APK_URL',
|
||||
description: 'URL of APK uploaded to SauceLabs.',
|
||||
name: 'APK_NAME',
|
||||
description: 'Filename of APK uploaded to SauceLabs.',
|
||||
)
|
||||
string(
|
||||
name: 'KEYWORD_EXPRESSION',
|
||||
@@ -21,20 +18,8 @@ pipeline {
|
||||
disableConcurrentBuilds()
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Fetch') {
|
||||
when { expression { !params.APK_URL } }
|
||||
steps { script {
|
||||
copyArtifacts(
|
||||
projectName: "status-mobile/nightly",
|
||||
filter: '*-x86.apk',
|
||||
/* WARNING: This copies the latest available artifact. */
|
||||
selector: lastWithArtifacts(),
|
||||
)
|
||||
apk_path = "${env.WORKSPACE}/${utils.findFile('*-x86.apk')}"
|
||||
} }
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Setup') {
|
||||
steps { script {
|
||||
dir('test/appium') {
|
||||
@@ -42,7 +27,6 @@ pipeline {
|
||||
}
|
||||
} }
|
||||
}
|
||||
|
||||
stage('Test') {
|
||||
steps {
|
||||
withCredentials([
|
||||
@@ -74,13 +58,13 @@ pipeline {
|
||||
sh 'cp -f $TEST_ETH_ACCOUNTS_FILE users.py'
|
||||
sh """
|
||||
python3 -m pytest \
|
||||
--numprocesses 6 \
|
||||
--numprocesses 9 \
|
||||
--rerun_count=2 \
|
||||
--testrail_report=True \
|
||||
-m testrail_id \
|
||||
-m \"new_ui_critical or new_ui_medium\" \
|
||||
-k \"${params.KEYWORD_EXPRESSION}\" \
|
||||
--apk=${params.APK_URL ?: apk_path}
|
||||
--apk=${params.APK_NAME}
|
||||
"""
|
||||
}
|
||||
}
|
||||
@@ -104,8 +88,5 @@ pipeline {
|
||||
)
|
||||
}
|
||||
}
|
||||
cleanup {
|
||||
sh 'make purge'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-jenkins-lib@v1.6.3'
|
||||
|
||||
pipeline {
|
||||
|
||||
@@ -11,14 +10,20 @@ pipeline {
|
||||
description: 'Name of the branch to checkout and build.',
|
||||
defaultValue: 'develop',
|
||||
)
|
||||
/* Commented to use TEST_MARKERS values from job params
|
||||
string(
|
||||
name: 'TEST_MARKERS',
|
||||
description: 'Marker expression for matching tests to run.',
|
||||
defaultValue: 'new_ui_critical',
|
||||
) */
|
||||
string(
|
||||
name: 'APK_NAME',
|
||||
description: 'Filename of APK uploaded to SauceLabs, path, or URL.',
|
||||
)
|
||||
string(
|
||||
name: 'PR_ID',
|
||||
description: 'ID of the Pull Request triggering this build.',
|
||||
)
|
||||
string(
|
||||
name: 'APK_URL',
|
||||
description: 'Optional, set if job require APK to be downloaded from URL.',
|
||||
)
|
||||
string(
|
||||
name: 'KEYWORD_EXPRESSION',
|
||||
description: 'This will run tests which contain names that match the given string expression (Optional)',
|
||||
@@ -29,48 +34,19 @@ pipeline {
|
||||
description: 'IDs of the TestRail case, separated by a comma (Optional)',
|
||||
defaultValue: '',
|
||||
)
|
||||
/* FIXME: Remove this no longer relevant argument */
|
||||
string(
|
||||
name: 'APK_NAME',
|
||||
description: 'OBSOLETE ARGUMENT TO BE REMOVED',
|
||||
defaultValue: 'DUMMY',
|
||||
)
|
||||
/* Commented to use TEST_MARKERS values from job params
|
||||
string(
|
||||
name: 'TEST_MARKERS',
|
||||
description: 'Marker expression for matching tests to run.',
|
||||
defaultValue: 'new_ui_critical',
|
||||
)
|
||||
*/
|
||||
}
|
||||
|
||||
options {
|
||||
disableConcurrentBuilds()
|
||||
timeout(time: 90, unit: 'MINUTES')
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Prep') {
|
||||
stage('Checks') {
|
||||
steps { script {
|
||||
currentBuild.displayName = "PR-${params.PR_ID}"
|
||||
if (params.PR_ID == null) {
|
||||
error("PR_ID parameter not set!")
|
||||
}
|
||||
if (params.APK_NAME == null) { error("APK_NAME parameter not set!") }
|
||||
if (params.PR_ID == null) { error("PR_ID parameter not set!") }
|
||||
} }
|
||||
}
|
||||
|
||||
stage('Fetch') {
|
||||
when { expression { !params.APK_URL } }
|
||||
steps { script {
|
||||
copyArtifacts(
|
||||
projectName: "status-mobile/prs/android-e2e/PR-${params.PR_ID}",
|
||||
/* WARNING: This copies the latest available artifact. */
|
||||
selector: lastWithArtifacts(),
|
||||
)
|
||||
apk_path = "${env.WORKSPACE}/${utils.findFile('result/*.apk')}"
|
||||
} }
|
||||
}
|
||||
|
||||
stage('Setup') {
|
||||
steps { script {
|
||||
dir('test/appium') {
|
||||
@@ -78,9 +54,9 @@ pipeline {
|
||||
}
|
||||
} }
|
||||
}
|
||||
|
||||
stage('Test') {
|
||||
steps { script {
|
||||
currentBuild.displayName = "PR-${params.PR_ID}"
|
||||
/* for managing optional arguments */
|
||||
def extraPytestOpts = ''
|
||||
if (params.TR_CASE_IDS != '') {
|
||||
@@ -123,11 +99,11 @@ pipeline {
|
||||
sh 'cp -f $TEST_ETH_ACCOUNTS_FILE users.py'
|
||||
sh """
|
||||
python3 -m pytest \
|
||||
--numprocesses 6 \
|
||||
--numprocesses 9 \
|
||||
--rerun_count=2 \
|
||||
--testrail_report=True \
|
||||
-k \"${params.KEYWORD_EXPRESSION}\" \
|
||||
--apk=${params.APK_URL ?: apk_path} \
|
||||
--apk=${params.APK_NAME} \
|
||||
--build=PR-${params.PR_ID}-${utils.timestamp()} \
|
||||
--pr_number=${params.PR_ID} \
|
||||
${extraPytestOpts}
|
||||
@@ -137,9 +113,4 @@ pipeline {
|
||||
} }
|
||||
}
|
||||
}
|
||||
post {
|
||||
cleanup {
|
||||
sh 'make purge'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
|
||||
pipeline {
|
||||
|
||||
agent { label 'linux' }
|
||||
|
||||
parameters {
|
||||
string(
|
||||
name: 'APK_URL',
|
||||
description: 'URL of APK to be tested(base for upgrade, usually release build)',
|
||||
name: 'APK_NAME',
|
||||
description: 'Filename of APK uploaded to SauceLabs (base for upgrade, usually release build)',
|
||||
)
|
||||
string(
|
||||
name: 'APK_URL_UPGRADE',
|
||||
description: 'URL of APK of upgraded application (installed on top of base)',
|
||||
name: 'APK_NAME_UPGRADE',
|
||||
description: 'Filename of APK of upgraded application (installed on top of base)',
|
||||
)
|
||||
string(
|
||||
name: 'KEYWORD_EXPRESSION',
|
||||
@@ -32,17 +29,6 @@ pipeline {
|
||||
|
||||
|
||||
stages {
|
||||
stage('Prep') {
|
||||
steps { script {
|
||||
if (params.APK_URL == null) {
|
||||
error("APK_URL parameter not set!")
|
||||
}
|
||||
if (params.APK_URL_UPGRADE == null) {
|
||||
error("APK_URL_UPGRADE parameter not set!")
|
||||
}
|
||||
} }
|
||||
}
|
||||
|
||||
stage('Setup') {
|
||||
steps { script {
|
||||
dir('test/appium') {
|
||||
@@ -50,7 +36,6 @@ pipeline {
|
||||
}
|
||||
} }
|
||||
}
|
||||
|
||||
stage('Test') {
|
||||
steps { script {
|
||||
/* for managing optional arguments */
|
||||
@@ -89,11 +74,11 @@ pipeline {
|
||||
python3 -m pytest \
|
||||
-m "upgrade" \
|
||||
-k \"${params.KEYWORD_EXPRESSION}\" \
|
||||
--numprocesses 4 \
|
||||
--numprocesses 15 \
|
||||
--rerun_count=2 \
|
||||
--testrail_report=True \
|
||||
--apk=${params.APK_URL} \
|
||||
--apk_upgrade=${params.APK_URL_UPGRADE} \
|
||||
--apk=${params.APK_NAME} \
|
||||
--apk_upgrade=${params.APK_NAME_UPGRADE} \
|
||||
${extraPytestOpts}
|
||||
"""
|
||||
}
|
||||
@@ -118,8 +103,5 @@ pipeline {
|
||||
)
|
||||
}
|
||||
}
|
||||
cleanup {
|
||||
sh 'make purge'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-jenkins-lib@v1.6.3'
|
||||
|
||||
pipeline {
|
||||
agent { label 'macos' }
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-jenkins-lib@v1.6.3'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env groovy
|
||||
/**
|
||||
* This job runs daily and executes `pod repo update` on MacOS
|
||||
* This is done to avoid issues with out of date repo causing errors like:
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
|
||||
pipeline {
|
||||
agent {
|
||||
label 'linux'
|
||||
}
|
||||
|
||||
triggers {
|
||||
cron('H 5 * * *')
|
||||
}
|
||||
|
||||
options {
|
||||
timestamps()
|
||||
/* Prevent Jenkins jobs from running forever */
|
||||
timeout(time: 15, unit: 'MINUTES')
|
||||
/* Disable concurrent jobs */
|
||||
disableConcurrentBuilds()
|
||||
/* Don't keep more than 50 builds */
|
||||
buildDiscarder(logRotator(numToKeepStr: '10'))
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Get Nodes') {
|
||||
steps { script {
|
||||
stagePerNode = nodesByLabel('macos').collectEntries {
|
||||
["${it}" : generateNodeCleanupStage(it)]
|
||||
}
|
||||
} }
|
||||
}
|
||||
|
||||
stage('Clean Xcode') {
|
||||
steps { script {
|
||||
parallel stagePerNode
|
||||
} }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def generateNodeCleanupStage(nodeLabel) {
|
||||
return { stage(nodeLabel) {
|
||||
node(nodeLabel) {
|
||||
dir('/Users/jenkins/Library/Developer/Xcode') {
|
||||
sh 'rm -fr Archives DerivedData'
|
||||
}
|
||||
}
|
||||
} }
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Export icons
|
||||
|
||||

|
||||

|
||||
|
||||
1. Export from figma 2 pngs 2x and 3x put them in `./resources/images/icons`
|
||||
2. if necessary, rename file so that filename contains only lower case chars, e.g. `"Icon-Name@2x.png"` should be renamed to `"icon_name@2x.png"`.
|
||||
@@ -33,13 +33,13 @@ See https://cursive-ide.com/userguide/index.html
|
||||
- https://gist.github.com/Samyoul/f71a0593ba7a12d24dd0d5ef986ebbec
|
||||
- Right click and "add as leiningen project"
|
||||
|
||||
<img src="images/ide-setup/1_fake_project_file.png" width=75% />
|
||||
<img src="images/IDE_SETUP/1_fake_project_file.png" width=75% />
|
||||
|
||||
## I get a lot of `cannot be resolved`
|
||||
|
||||
Are you getting problems where you get a lot of `cannot be resolved` on everything?
|
||||
|
||||
<img src="images/ide-setup/2_resolve.jpeg" width=75% />
|
||||
<img src="images/IDE_SETUP/2_resolve.jpeg" width=75% />
|
||||
|
||||
See https://cursive-ide.com/userguide/macros.html
|
||||
|
||||
@@ -56,21 +56,21 @@ I had a number of problems connecting to REPL, the solution is as follows:
|
||||
|
||||
At the top of IntelliJ IDEA click on the `Add Configuration...` option:
|
||||
|
||||
<img src="images/ide-setup/3_REPL_1.png" width=75% />
|
||||
<img src="images/IDE_SETUP/3_REPL_1.png" width=75% />
|
||||
|
||||
This will load the following menu:
|
||||
|
||||
<img src="images/ide-setup/4_REPL_2.png" width=75% />
|
||||
<img src="images/IDE_SETUP/4_REPL_2.png" width=75% />
|
||||
|
||||
Click on the `+` icon in the top left corner of the menu.
|
||||
|
||||
Select `Clojure REPL > Remote`
|
||||
|
||||
<img src="images/ide-setup/5_REPL_3.png" width=75% />
|
||||
<img src="images/IDE_SETUP/5_REPL_3.png" width=75% />
|
||||
|
||||
Which will load the following menu
|
||||
|
||||
<img src="images/ide-setup/6_REPL_4.png" width=75% />
|
||||
<img src="images/IDE_SETUP/6_REPL_4.png" width=75% />
|
||||
|
||||
Enter the below options:
|
||||
|
||||
@@ -81,14 +81,14 @@ Enter the below options:
|
||||
- Host = 127.0.0.1
|
||||
- Port = 7888
|
||||
|
||||
<img src="images/ide-setup/7_REPL_5.png" width=75% />
|
||||
<img src="images/IDE_SETUP/7_REPL_5.png" width=75% />
|
||||
|
||||
Press `OK`
|
||||
|
||||
Now the below option will be visible.
|
||||
Press the green run button
|
||||
|
||||
<img src="images/ide-setup/8_REPL_6.png" width=75% />
|
||||
<img src="images/IDE_SETUP/8_REPL_6.png" width=75% />
|
||||
|
||||
You should now see an dialog with the following message:
|
||||
|
||||
@@ -113,7 +113,7 @@ Which should output
|
||||
|
||||
See below:
|
||||
|
||||
<img src="images/ide-setup/9_REPL_7.png" width=75% />
|
||||
<img src="images/IDE_SETUP/9_REPL_7.png" width=75% />
|
||||
|
||||
#### Connecting REPL and IntelliJ to `status-mobile`
|
||||
|
||||
@@ -138,7 +138,7 @@ Next go back to the REPL input and enter the following commands:
|
||||
|
||||
See Below
|
||||
|
||||
<img src="images/ide-setup/10_REPL_8.png" width="75%" />
|
||||
<img src="images/IDE_SETUP/10_REPL_8.png" width="75%" />
|
||||
|
||||
Which should switch the clj file type target to cljs as shown above
|
||||
|
||||
@@ -146,13 +146,13 @@ Finally you are ready to test REPL.
|
||||
|
||||
Create a sample function to evaluate something simple like `(prn "I'm working")`, move your cursor to one of the outer parentheses. Right or `control` click and select the `REPL` option. From there select `Sync files in REPL` and then `Send '...' to REPL'`.
|
||||
|
||||
<img src="images/ide-setup/11_REPL_9.png" width="75%" />
|
||||
<img src="images/IDE_SETUP/11_REPL_9.png" width="75%" />
|
||||
|
||||
Alternatively you can use the shortcut commands `⇧⌘M` to sync your files and `⇧⌘P` to send the statement to REPL. You may also need to switch the REPL namespace to match the current file, which can be done manually from the dialogue box or using the `⇧⌘N` shortcut key.
|
||||
|
||||
Following the above should give you the below result:
|
||||
|
||||
<img src="images/ide-setup/12_REPL_10.png" width="75%" />
|
||||
<img src="images/IDE_SETUP/12_REPL_10.png" width="75%" />
|
||||
|
||||
🎉 Tada! Working! 🎉
|
||||
|
||||
@@ -169,7 +169,7 @@ For VS Code users.
|
||||
### Start and connect the REPL
|
||||
|
||||
1. Open the `status-mobile` folder.
|
||||
1. Start [Status development](starting-guide.md#development) (Starting the `run-clojure` and `run-metro` jobs in split view in the VS Code integrated terminal works great.)
|
||||
1. Start [Status development](STARTING_GUIDE.md#development) (Starting the `run-clojure` and `run-metro` jobs in split view in the VS Code integrated terminal works great.)
|
||||
1. Run the VS Code command: **Calva: Connect to a running REPL Server in the project**
|
||||
1. Select the project type `shadow-cljs`
|
||||
1. Accept the suggested connection `host:port`
|
||||
@@ -1,54 +0,0 @@
|
||||
## Getting Started
|
||||
|
||||
[Starting Guide](starting-guide.md)
|
||||
|
||||
[IDE Setup](ide-setup.md)
|
||||
|
||||
|
||||
|
||||
## Development Process
|
||||
|
||||
[Coding guidelines](new-guidelines.md)
|
||||
|
||||
[Release Checklist](release-checklist.md)
|
||||
|
||||
[Release Guide](release-guide.md)
|
||||
|
||||
[Merging PR process](merging-pr-process.md)
|
||||
|
||||
[PR Review Policy](pr-review-policy.md)
|
||||
|
||||
[Working on PR together with QA team](pipeline_process.md)
|
||||
|
||||
[Debugging](debugging.md)
|
||||
|
||||
[Patching](patching.md)
|
||||
|
||||
[Creating a pixel perfect UI](pixel-perfection.md)
|
||||
|
||||
## Testing
|
||||
|
||||
[How to run local tests](testing.md)
|
||||
|
||||
[End-to-end tests (e2e) overview](how-to-launch-e2e.md)
|
||||
|
||||
[Component tests (jest) overview](component-tests-overview.md)
|
||||
|
||||
|
||||
|
||||
## Misc
|
||||
|
||||
[Importing icons from Figma into project](export-icons.md)
|
||||
|
||||
[Updating Status APK builds for the F-Droid Android application catalogue](fdroid.md)
|
||||
|
||||
[Troubleshooting for known errors](troubleshooting.md)
|
||||
|
||||
|
||||
|
||||
## Outdated:
|
||||
|
||||
[Old guidelines](codebase-structure-and-guidelines.md)
|
||||
|
||||
[Post mortem analysis](post-mortem.md)
|
||||
|
||||
@@ -28,30 +28,11 @@ You need to have an emulator like [AVD](https://developer.android.com/studio/run
|
||||
|
||||
### iOS
|
||||
|
||||
#### Running on a simulator
|
||||
|
||||
We highly recommend using the `iPhone 11 Pro` simulator as its screen dimensions match with our design.
|
||||
|
||||
If you have Xcode `v12.x` (and above) installed in your system, you need to follow the below steps to add `iPhone 11 Pro` simulator:
|
||||
|
||||
1. Open Xcode
|
||||
2. Menu `>` Window `>` Devices and Simulators
|
||||
3. Tap `+` button on bottom left
|
||||
4. Select **Device Type** as `iPhone 11 Pro`
|
||||
5. Leave the **Simulator Name** empty and tap on **Create**
|
||||
|
||||
##### NOTE ⚠️
|
||||
|
||||
Running `make run-ios` will target `iPhone 11 Pro` by default.
|
||||
|
||||
If you need to run on any other simulator, you can specify the simulator type by adding the `SIMULATOR` flag:
|
||||
You can specify the simulator type by adding the `SIMULATOR` flag:
|
||||
```sh
|
||||
make run-ios SIMULATOR="iPhone 11 Pro"
|
||||
```
|
||||
|
||||
#### Running on a physical device
|
||||
|
||||
Some manual steps are necessary for [developing on a physical iOS Device](#physical-ios-device).
|
||||
Some manual steps are necesary for [developing on a physical iOS Device](#physical-ios-device).
|
||||
|
||||
# Build release
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# Testing
|
||||
|
||||
### Unit & integration tests
|
||||
|
||||
To run tests:
|
||||
|
||||
```
|
||||
make test
|
||||
```
|
||||
|
||||
|
||||
To watch the tests:
|
||||
|
||||
```
|
||||
make test-watch
|
||||
```
|
||||
|
||||
To run test in REPL
|
||||
|
||||
```
|
||||
make test
|
||||
yarn shadow-cljs cljs-repl test # or start the REPL in your editor
|
||||
```
|
||||
|
||||
Then start the test process with
|
||||
|
||||
```
|
||||
node --require ./test-resources/override.js target/test/test.js --repl
|
||||
```
|
||||
|
||||
You can run single test in REPL like this
|
||||
|
||||
```clojure
|
||||
(require 'cljs.test)
|
||||
(cljs.test/test-var #'status-im.data-store.chats-test/normalize-chat-test)
|
||||
```
|
||||
|
||||
|
||||
|
||||
Tests will use the bindings in `modules/react-native-status/nodejs`, if you make any changes to these you will need to restart the watcher.
|
||||
@@ -1,27 +1,6 @@
|
||||
## `yarn add` is not working
|
||||
# [DEPRECATED] Undefined is not an object evaluating `register_handler_fx`
|
||||
|
||||
While running any yarn add command like `yarn add react-native-share@7.0.2`, it is showing error
|
||||
|
||||
```
|
||||
error status-mobile/node_modules/better-sqlite3: Command failed.
|
||||
```
|
||||
|
||||
### Cause
|
||||
|
||||
Local `node` version can be different from the one needed by Status project.
|
||||
|
||||
### Solution
|
||||
|
||||
Before running `yarn add`, nix shell should be started:
|
||||
|
||||
```
|
||||
make shell
|
||||
```
|
||||
|
||||
|
||||
## [DEPRECATED] Undefined is not an object evaluating `register_handler_fx`
|
||||
|
||||
### Deprecation note
|
||||
## Deprecation note
|
||||
|
||||
This type of error should not occur anymore now that we require the namespace in the `fx.cljs` file.
|
||||
|
||||
@@ -35,7 +14,7 @@ That way you don't need to use any magical call like `find-ns` or inline `requir
|
||||
|
||||
You also want to make sure users are using the macro by using a aliased namespace defined in require statement rather than require-macro and refer to the macro directly. Otherwise it won't require the cljs file and the require statement of the namespace in the macroexpension might not be there.
|
||||
|
||||
### Stacktrace
|
||||
## Stacktrace
|
||||
|
||||
```
|
||||
13:25:22, Requiring: hi-base32
|
||||
@@ -55,19 +34,19 @@ _callTimer@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false
|
||||
_callImmediatesPass@http://localhost:8081/index.bundle?pla<…>
|
||||
```
|
||||
|
||||
### Cause
|
||||
## Cause
|
||||
|
||||
- stacktrace mentions `register_handler_fx`,
|
||||
- common cause is when requires have been cleaned up and a require of `status-im.utils.handlers` namespace was removed because it looked like it was unused but was actually used through a fx/defn macro
|
||||
|
||||
### Solution
|
||||
## Solution
|
||||
|
||||
go through known faulty commit looking for deleted requires
|
||||
|
||||
|
||||
## Git "unable to access" errors during `yarn install`
|
||||
# Git "unable to access" errors during `yarn install`
|
||||
|
||||
### Description
|
||||
## Description
|
||||
Developer updates `package.json` file with a new dependency using a GitHub URL. So it looks like this:
|
||||
```
|
||||
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#feature/exportKeyWithPath",
|
||||
@@ -81,10 +60,10 @@ fatal: unable to access 'https://github.com/status-im/react-native-status-keycar
|
||||
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
|
||||
```
|
||||
|
||||
### Cause
|
||||
## Cause
|
||||
`yarn.lock` is not updated to be in sync with `package.json`.
|
||||
|
||||
### Solution
|
||||
## Solution
|
||||
Update yarn.lock file. In order to do this, perform the following steps on a clean `status-mobile` repo:
|
||||
```
|
||||
cd status-mobile
|
||||
@@ -93,9 +72,9 @@ yarn install
|
||||
and don't forget to commit updated `yarn.lock` together with `package.json`.
|
||||
|
||||
|
||||
## adb server/client version mismatch errors
|
||||
# adb server/client version mismatch errors
|
||||
|
||||
### Description
|
||||
## Description
|
||||
Running some adb commands, e.g. `adb devices` or `make android-ports` (in turn invokes `adb reverse`/`adb forward` commands) may display the following message:
|
||||
```
|
||||
adb server version (40) doesn't match this client (41); killing...
|
||||
@@ -111,10 +90,10 @@ This might cause all kinds of difficult-to-debug errors, e.g.:
|
||||
- `make run-android` throwing `- Error: Command failed: ./gradlew app:installDebug -PreactNativeDevServerPort=8081 Unable to install /status-mobile/android/app/build/outputs/apk/debug/app-debug.apk com.android.ddmlib.InstallException: EOF`
|
||||
- dropped CLJS repl connections (that have been enabled previously with the help of `make android-ports`)
|
||||
|
||||
### Cause
|
||||
## Cause
|
||||
System's local adb and Nix's adb differ. As adb include of server/client processes, this can cause subtle version errors that cause adb to kill mismatching server processes.
|
||||
|
||||
### Solution
|
||||
## Solution
|
||||
Always use respective `make` commands, e.g. `make android-ports`, `make android-devices`, etc.
|
||||
|
||||
Alternatively, run adb commands only from `make shell TARGET=android` shell. Don't forget the `TARGET=android` env var setting - otherwise `adb` will still be selected from the system's default location. You can double-check this by running `which adb`.
|
||||
@@ -146,4 +125,4 @@ For x86 CPU architecture Android Devices, Hermes is creating the issue and the a
|
||||
### Solution
|
||||
Disable Hermes while building the app
|
||||
|
||||
`make run-android DISABLE_HERMES=true`
|
||||
`make run-android DISABLE_HERMES=true`
|
||||
@@ -91,11 +91,30 @@ These guidelines make db.cljs namespaces the place to go when making changes to
|
||||
|
||||
- If manual QA is not needed but all tests don't pass, you can ping @churik or @Serhy to confirm that failed E2E tests are not unrelated.
|
||||
|
||||
## Enabling debug logs
|
||||
Calls to `log/debug` will not be printed to the console by default. It can be enabled under "Advanced settings" in the app:
|
||||
|
||||

|
||||
|
||||
## Translations
|
||||
The app relies on system locale to select a language from the [list of supported languages](https://github.com/status-im/status-mobile/blob/bda73867471cf2bb8a68b1cc27c9f94b92d9a58b/src/status_im/i18n_resources.cljs#L9). It falls back to English in cash the system locale is not supported.
|
||||
|
||||
We use Lokalise App to manage [translations](https://translate.status.im/). In case you need to add/remove a key to translations, you only need to change `en.json`. Missing keys fallback to `en.json`. The actual translations will be added by Lokalise.
|
||||
|
||||
## re-frisk
|
||||
re-frisk is a state visualization tool written by our very own Andrey (@flexsurfer). To start re-frisk, execute the following command:
|
||||
```bash
|
||||
$ yarn shadow-cljs run re-frisk-remote.core/start
|
||||
```
|
||||
|
||||
or you can also use make:
|
||||
|
||||
```bash
|
||||
$ make run-re-frisk
|
||||
```
|
||||
|
||||
A server will be started at http://localhost:4567. It might show "not connected" at first. Don't worry and just start using the app. The events and state will populate.
|
||||
|
||||
## Merging approved PRs
|
||||
|
||||
We don't Github's UI to merge. Instead `./scripts/merge-pr.sh` is used to sign and merge PR to `develop`. You first need to enable [GPG signing on you commits](https://github.com/status-im/status-mobile/blob/develop/STARTING_GUIDE.md#configure-gpg-keys-for-signing-commits).
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
# Component Tests
|
||||
|
||||
The component tests are using React Native Testing Library - https://callstack.github.io/react-native-testing-library/
|
||||
and Jest - https://jestjs.io/
|
||||
|
||||
|
||||
It is highly recommended to read some advice from Kent C.Dodds on how to write tests and use these tools correctly.
|
||||
|
||||
|
||||
https://kentcdodds.com/blog/common-mistakes-with-react-testing-library
|
||||
|
||||
https://www.youtube.com/watch?v=ahrvE062Kv4
|
||||
|
||||
Both of these links are showing it for React-Testing-Library (not Native) however the approach is for the most part considered the same.
|
||||
|
||||
## Running the tests
|
||||
To run these tests there are two methods.
|
||||
|
||||
`make component-test`
|
||||
setups and runs the test suite once.
|
||||
|
||||
`make component-test-watch`
|
||||
setups and runs the test suite and watches for code changes will then retrigger the test suite.
|
||||
|
||||
## Writing Tests
|
||||
New test files will need their namespace added to either the file "src/quo2/core_spec.cljs" or "src/status_im2/core_spec.cljs. These locations may update overtime but it is dependent on the entrypoint in shadow-cljs config discussed below.
|
||||
|
||||
|
||||
### Best practices
|
||||
For the moment we will keep best practices for tests in our other guidelines document:
|
||||
|
||||
To that point these guidelines will follow the conventions of Jest and React Native Testing Library recommendations and Status mobile will just stack their preferences on top.
|
||||
|
||||
### Utilities
|
||||
There is a file of utility functions defined in "src/test_helpers/component.cljs" and "src/test_helpers/component.clj". It will be great to use these utilities and to add any common testing tools to these files as it should make writing tests easier and faster.
|
||||
|
||||
|
||||
## Configuration
|
||||
Status Mobile has a bespoke tech stack, as such there is more complexities to configuring the tests.
|
||||
|
||||
### Shadow-CLJS
|
||||
the configuration for compiling our tests are defined in the "shadow-cljs.edn" file.
|
||||
The three main parts of this are
|
||||
`:target :npm-module`
|
||||
Needed for the configuration we are using
|
||||
`:entries`
|
||||
a vector of entry points for the test files.
|
||||
and the `ns-regexp` to specify what tests to find. Since we have multiple forms of tests we decided that "component-spec" is the least likely to detect the wrong file type.
|
||||
|
||||
It's worth knowing that our tests are compiled to JS and then run in the temporary folder `component-tests`.
|
||||
|
||||
### Jest
|
||||
There is also further configuration for Jest in "test/jest". There is a jest config file which has some mostly standard configuration pieces, where the tests live, what environment variables are set etc. This is documented by Jest here: https://jestjs.io/docs/configuration
|
||||
|
||||
There is also a setup file which is used to set some global and default values. Additionally this file is used to mock some of the react native (among other) dependencies
|
||||
@@ -1,64 +0,0 @@
|
||||
# Debugging
|
||||
|
||||
## Inspecting re-frame with re-frisk
|
||||
`re-frisk` is a state visualization tool written by our very own Andrey (@flexsurfer). With its help you can inspect the current state of app-db, watch event, etc.
|
||||
|
||||

|
||||
|
||||
To start `re-frisk`, execute the following command:
|
||||
```bash
|
||||
$ yarn shadow-cljs run re-frisk-remote.core/start
|
||||
```
|
||||
|
||||
or you can also use make:
|
||||
|
||||
```bash
|
||||
$ make run-re-frisk
|
||||
```
|
||||
|
||||
A server will be started at http://localhost:4567. It might show "not connected" at first. Don't worry and just start using the app. The events and state will populate.
|
||||
|
||||
More details about re-frisk are on the [project page](https://github.com/flexsurfer/re-frisk).
|
||||
|
||||
## Enabling debug logs
|
||||
Calls to `log/debug` will not be printed to the console by default. It can be enabled under "Advanced settings" in the app:
|
||||
|
||||

|
||||
|
||||
|
||||
## Checking status-go logs
|
||||
While status mobile works it saves logs from `status-go` to `geth.log` file.
|
||||
|
||||
|
||||
### Checking logs from physical device
|
||||
To obtain `geth.log` from physical device you need to shake it and in an opened menu select "Share logs".
|
||||
|
||||

|
||||
|
||||
|
||||
### Checking logs from iOS Simulator
|
||||
When developing with iOS simulator it is more convenient to see the `geth.log` updates in real-time.
|
||||
To do this:
|
||||
- open Activity Monitor
|
||||
- find the "StatusIm" app and doubleclick it
|
||||
- in the opened window select "Open files and ports" and find the full path to `geth.log` (note that it won't appear until you login to Status app)
|
||||
|
||||

|
||||
|
||||
|
||||
## Tips
|
||||
### From @ilmotta:
|
||||
|
||||
Something I find extremely convenient for Android is to use `adb` to tail logs. I don't use macOS so I don't know if the iOS simulator offers a CLI interface with the same capabilities.
|
||||
|
||||
But here's what I use for example:
|
||||
|
||||
```
|
||||
adb shell tail -n 10 -f /storage/emulated/0/Android/data/im.status.ethereum.debug/files/Download/geth.log | grep 'waku.relay'
|
||||
```
|
||||
|
||||
Also to inspect logs in a more flexible manner, instead of the strict output from `make run-metro`, I prefer `adb logcat`. Combined with enabling status-mobile logs in debug by default plus filtering the logs to only what I care during development, I find this helps me inspect the app without running re-frisk because with the debug log level I can already see which events are dispatched (one of the features I like the most from re-frisk).
|
||||
|
||||
```
|
||||
adb logcat | grep 'ReactNativeJS\|StatusModule\|GoLog'
|
||||
```
|
||||
@@ -45,4 +45,4 @@ The `State` field in the Pivotal story is used to track the progress of a Pivota
|
||||
| 5 points | 2 - 3 days |
|
||||
| 8 points | ~1 week |
|
||||
|
||||
We should avoid 8 point stories by breaking them down into smaller stories as much as possible.
|
||||
We should avoid 8 point stories by breaking them down into smaller stories as much as possible.
|
||||
@@ -1,31 +0,0 @@
|
||||
# 0014. Team-structure
|
||||
|
||||
| Date | Tags |
|
||||
|---|---|
|
||||
| 2023-06-16 | wallet team |
|
||||
|
||||
## Status
|
||||
|
||||
Proposed
|
||||
|
||||
## Context:
|
||||
|
||||
In order to try out vertical team, which is a structure that is wanted by the company, we will be creating a wallet team within the mobile team.
|
||||
Some member of the mobile team will join the current wallet team, which is composed by developers from desktop and lead by @alaibe, on a voluntary basis.
|
||||
The responsibilities of the team are to implement the new wallet UI, with the support of the current wallet team, which will be assisting with the status-go work.
|
||||
|
||||
## Decision
|
||||
|
||||
Some team members have already expressed interest and some have been asked and accepted to join the wallet team, these team members are:
|
||||
|
||||
- @rasom
|
||||
- @OmarBasem
|
||||
- @vkjr
|
||||
- @J-Son89
|
||||
- @briansztamfater
|
||||
- @smohamedjavid
|
||||
- @ulisesmac
|
||||
|
||||
# Follow-up Actions
|
||||
|
||||
- We still need 3/4 team members to join the wallet team
|
||||
@@ -1,46 +0,0 @@
|
||||
# 0015. Team-structure
|
||||
|
||||
| Date | Tags |
|
||||
|---|---|
|
||||
| 2023-06-16 | changes in team structure |
|
||||
|
||||
## Status
|
||||
|
||||
Proposed/partially implemented
|
||||
|
||||
## Context:
|
||||
|
||||
Currently, there is only a single team lead in the mobile development team, and after a meeting with the design team, it has been identified that the mobile app lacks polishness. One of the main issues identified is a lack of oversight in certain areas. To address this problem, it has been decided to create an additional role within the team. For each section of the mobile app (communities, syncing & onboarding, activity center & shell, wallet, messaging), a person will be selected to fulfill the responsibilities outlined below.
|
||||
|
||||
## Decision
|
||||
|
||||
The decision is to create an additional role within the mobile development team for each section. The individuals selected for these roles will have the following responsibilities:
|
||||
|
||||
- Ensure GitHub issues are created for new features/designs of the section.
|
||||
- Ensure issues are adequately described and linked as best as possible.
|
||||
- Ensure issues have a grooming session where other developers can provide their feedback before working on the set of issues.
|
||||
- Ensure all relevant parties are invited, such as designers, QA, Product Owner, leads, etc., as needed (including the designer who created the feature).
|
||||
- Ensure there is consensus among the developers working on the section about the decided strategy approach. Ideally, this consensus should be documented.
|
||||
- Ensure UI quality by organizing designer reviews and guaranteeing pixel perfection.
|
||||
- Ensure overall implementation is satisfactory based on the predefined requirements.
|
||||
- Ensure alignment between desktop, web, and mobile versions for the respective section in collaboration with the mobile developers and design team.
|
||||
- Act as a point of contact for the design team with respect to the section.
|
||||
- Ensure that someone goes through the designs once they are created with the respective designer.
|
||||
- Assist the design team with technical feasibility analysis and address any product concerns.
|
||||
- Facilitate the growth of the next team member into the role.
|
||||
|
||||
The people identified for each sections are as follow:
|
||||
|
||||
- Messaging @flexsurfer, followed by @alwx
|
||||
- Syncing & Onboarding @siddarthkay
|
||||
- Communities @ilmotta
|
||||
- Activity Center & Shell @J-Son89, followed by @Parveshdhull
|
||||
- Wallet (once the vertical team is created) @J-Son89, followed by @briansztamfater
|
||||
|
||||
This will be a rotating post, every 4 months it will go to the next in line.
|
||||
|
||||
The wallet team might have longer times for rotation, as stability might be more important. That's still to be decided.
|
||||
|
||||
# Follow-up Actions
|
||||
|
||||
- Find suitable next in line for Messaging, Onboarding, Communities
|
||||
|
Before Width: | Height: | Size: 231 KiB After Width: | Height: | Size: 231 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
@@ -1,103 +0,0 @@
|
||||
How to Launch E2E
|
||||
===
|
||||
|
||||
## Overview for how automated test structured for Status app
|
||||
|
||||
As a part of CI for Status mobile app and in order to ensure there are no regressions appear after the changes in code (bug fix, new/updated feature) we are using automated tests (e2e tests).
|
||||
|
||||
- Automated tests written on Python 3.9 and pytest.
|
||||
- Appium (server) and Selenium WebDriver (protocol) are the base of test automation framework.
|
||||
|
||||
TestRail is a test case management system tool where we have test cases.
|
||||
|
||||
|
||||
Each of the test case gets a priority (Critical/High/Medium)
|
||||
|
||||
**SauceLabs** - is a cloud based mobile application test platform. We are using Android emulators (Android 10.0) for test script execution there. We have 16 session be running at the same time max.
|
||||
For now we support e2e for Android only.
|
||||
|
||||
## What's happening when any e2e job is running
|
||||
Whenever we need to push set of test scripts we create 16 parallel sessions (max, but depending on amount of cases that are included in job) and each thread: 1) uploads Android .apk file to SauceLabs -> 2) runs through the test steps -> 3) receives results whether test failed on particular step or succeeded with no errors -> 3) Parse test results and push them as a Github comment (if the suite ran against respective PR) and into TestRail.
|
||||
|
||||
We push **whole automation test suite (currently 155, amout is changing)** against each nightly build (if the nightly builds job succeeded). Results of the test run are saved in TestRail.
|
||||
And also we push set of autotests whenever PR with successful builds got moved in to `E2E Tests` column from [Pipeline for QA dashboard ](https://github.com/status-im/status-react/projects/7).
|
||||
In that case we save results in TestRail as well and push a comment with test results in a respective PR.
|
||||
|
||||
For example: https://github.com/status-im/status-react/pull/9147#issuecomment-540008770
|
||||
|
||||

|
||||
|
||||
|
||||
The test_send_stt_from_wallet opens link in TestRail https://ethstatus.testrail.net/index.php?/tests/view/890885 where performed steps could be found
|
||||
List of all runs performed by test jobs could be found here https://ethstatus.testrail.net/index.php?/runs/overview/14
|
||||
|
||||
**For credentials for TestRail to see results ping Chu in DM**:
|
||||
|
||||
Opening any test run navigates you to list of test cases with results:
|
||||

|
||||
|
||||
|
||||
## What about launching e2e manually
|
||||
|
||||
To manage e2e there are several jobs in https://ci.status.im/job/status-mobile/job/e2e :
|
||||
1) [nightly](https://ci.status.im/job/status-mobile/job/e2e/job/status-app-nightly/) - running automatically after building nightly apk e2e build. QA running it manually for results of e2e when testing release.
|
||||
2) [upgrade](https://ci.status.im/job/status-mobile/job/e2e/job/status-app-upgrade/) - running manually by QA in release testing for smoke upgrade tests.
|
||||
3) [prs](https://ci.status.im/job/status-mobile/job/e2e/job/status-app-prs/) - running **only automatically** when PR moves into `e2e column`
|
||||
4) [prs-rerun](https://ci.status.im/job/status-mobile/job/e2e/job/status-app-prs-rerun/) - for manual run, can be run on request by anyone. **If you need to launch e2e against your build, use this job.**
|
||||
Params to specify:
|
||||
|
||||
- apk: [url_to_apk_build_here]
|
||||
- pr_id: pull request number (e.g. 1234)
|
||||
- branch: branch name from which the test are taken (in most of cases `develop`)
|
||||
- keyword expression: tests by area (let's say `ens` or `chat`, thay can be combined`ens or chat or send_tx`. All keywords can be found in testrail, ping Chu for details)
|
||||
- test_marks: tests by priorities (by default: `critical or high or medium`, which corresponds the whole suite; to lauch the same suite as in PRs, use `critical or high`)
|
||||
- testrail_case_id: here is the list of test cases which you may find in test rail (4-digit value)
|
||||
|
||||
For easier access you can hit `Rerun tests` in GH comment and testrail_case_id/ apk_name/ pr_id will be filled automatically. For making sure that tests are being rerun on most recent e2e build it is recommended to paste link to the last e2e build in apk_name field. The list of PR builds can be found in Jenkins Builds block on PR page.
|
||||

|
||||
And then hit ‘Build’.
|
||||
Once the job starts it picks up specified tests, runs them against provided apk and sends results to pull request.
|
||||
|
||||
Even we have 16 parallel sessions for testing it’s a time consuming operation (whole test suite we have automated at the moment takes ~140 minutes to finish).
|
||||
So for PRs we pick only set of `critical or high` (you can also use this in TEST_MARKS param for job)
|
||||
tests (otherwise some PRs could wait their turn of the scheduled Jenkins job till the next day).
|
||||
|
||||
## Analysing test results (and why test fails to pass)
|
||||
|
||||
After automated test run finished test results could be found in GH comment (if the test suite ran agaist PR) and TestRail. There are two states of the test: Passed and Failed. Test failure happens when certain condition of test step has not met or automated test can not proceed execution because it can not find the respective element on screen it expects should be there.
|
||||
|
||||
Several examples of when test fails to succeed:
|
||||
|
||||
- Test clicked on element which should load new screen (or pop-up) and awaits some element on this screen. But test did not wait enough allowing the new screen to appear and so it fails with “Could not find element XYZ” (this case is more app issue in our opinion rather then test issue, but we just can not spend our and dev time with too specific random places which happens once causing app lags in different moments)
|
||||
|
||||
- Test sent transaction to address but it was not mined in time (we have a limit to wait until balance is changed on recipient side up to ~6 mins now). We classify this as False Fail, because it’s not the app issue but more network issue.
|
||||
|
||||
- Test infrastructure issues, - anything related to infrastructure including SauceLabs side issues (apk failed to install - rare case, or LTE connection was set by default instead WiFi or unexpected pop-up appeared preventing test to going further)
|
||||
|
||||
- Failure due to changed feature which has not been taken into account in some test after code merge (for instance: some element on screen has been removed, and we want to locate another element on this screen via XPath which is different now)
|
||||
|
||||
- **Valid issue in the automated test scripts** - that's what we're looking for
|
||||
|
||||
Example: here is the test results https://github.com/status-im/status-react/pull/13015#issuecomment-1016495043 where one test failed.
|
||||
1. Open the test in TestRail and open session recorded for this test in SauceLabs
|
||||

|
||||
|
||||
|
||||
In TestRail you may find all the steps performed by the test.
|
||||
In SauceLabs testrun page you may find useful: video of the session, step logs, logcat.log of the session
|
||||
2. Analyze step where test was failed
|
||||
For particular example it was failed on `Recover access(password:qwerty, keycard:False)` and unexpected error appeared.
|
||||
|
||||
## Limits for e2e tests coverage
|
||||
Not all features of the app could be covered by e2e at the moment:
|
||||
|
||||
- Colours or place of an element on UI.
|
||||
- Real ETH/token transactions. That’s the main reason we have separate .apk build for automation needs - it defaults to Goerli network. Also it has enabled keycard test menu, ENS names and chat commands are also on Goerli network (the same in PR builds, but not in nightlies / release)
|
||||
- Autologin/Biometric related actions (autologin available when device meets certain conditions like the it has set unlock password and device is not rooted: all emulators are rooted in SauceLabs)
|
||||
|
||||
## Brief flow for test to be automated
|
||||
|
||||
Whenever there is a need to have a new test:
|
||||
1) Create a test scenario in TestRail.
|
||||
2) If certain item could be checked in scope of existing test case we update existing one (otherwise we may have thousands of test cases which is overkill to manage in TestRail as well as in automated test scripts). And also complex autotests increase probability to not catch regressions by stopping test execution (due to valid bug or changed feature) keeping the rest test steps uncovered. So here we need to balance when it makes sense to update existing test case with more checks.
|
||||
3) Then we create test script based on the test case, ensure test passes for the build and pushing the changes to repo.
|
||||
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 439 KiB After Width: | Height: | Size: 439 KiB |
|
Before Width: | Height: | Size: 285 KiB After Width: | Height: | Size: 285 KiB |
|
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 180 KiB |
|
Before Width: | Height: | Size: 290 KiB After Width: | Height: | Size: 290 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 655 KiB After Width: | Height: | Size: 655 KiB |
|
Before Width: | Height: | Size: 203 KiB After Width: | Height: | Size: 203 KiB |
|
Before Width: | Height: | Size: 583 KiB After Width: | Height: | Size: 583 KiB |
|
Before Width: | Height: | Size: 585 KiB After Width: | Height: | Size: 585 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 255 KiB |
|
Before Width: | Height: | Size: 308 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 68 KiB |