Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09f95dcdf9 | ||
|
|
d0e40699b9 | ||
|
|
d8be02d9a9 | ||
|
|
632a578721 | ||
|
|
647c1e42c4 | ||
|
|
616e5ed80f | ||
|
|
574cf9c64b | ||
|
|
21922e0434 | ||
|
|
e21a400b4c | ||
|
|
5e6c164c9d | ||
|
|
962402bd74 | ||
|
|
e685c3bb39 | ||
|
|
b90ecf5004 | ||
|
|
5915936863 |
@@ -1,7 +1,8 @@
|
||||
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.ethereum.resolver/name
|
||||
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 +13,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
|
||||
@@ -30,7 +31,7 @@ reagent.dom/dom-node
|
||||
reagent.dom/force-update-all
|
||||
status-im.multiaccounts.create.core/get-new-key-code
|
||||
status-im.ethereum.decode/string
|
||||
status-im.ui.screens.network.views/mainnet?
|
||||
status-im.network.ui.views/mainnet?
|
||||
status-im.data-store.chats/event->string
|
||||
status-im.mailserver.constants/seven-days
|
||||
status-im.mailserver.constants/connection-timeout
|
||||
@@ -46,8 +47,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
|
||||
@@ -64,7 +65,7 @@ mocks.js-dependencies/emoji-picker
|
||||
mocks.js-dependencies/i18n
|
||||
mocks.js-dependencies/qr-code
|
||||
mocks.js-dependencies/svg
|
||||
mocks.js-dependencies/icons
|
||||
mocks.js-dependencies/vector-icons
|
||||
mocks.js-dependencies/webview
|
||||
mocks.js-dependencies/desktop-linking
|
||||
mocks.js-dependencies/desktop-shortcuts
|
||||
@@ -154,40 +155,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!
|
||||
@@ -200,7 +201,7 @@ status-im.utils.platform/isMacOs?
|
||||
status-im.utils.platform/isNix?
|
||||
status-im.utils.platform/isWin?
|
||||
status-im.utils.platform/android-version>=
|
||||
utils.debounce/clear-all
|
||||
status-im.utils.debounce/clear-all
|
||||
status-im.transport.db/create-chat
|
||||
status-im.utils.priority-map/priority-map
|
||||
status-im.utils.priority-map/priority-map-by
|
||||
|
||||
@@ -1,23 +1,12 @@
|
||||
{:lint-as {status-im.utils.views/defview clojure.core/defn
|
||||
status-im.utils.views/letsubs clojure.core/let
|
||||
reagent.core/with-let clojure.core/let
|
||||
status-im.utils.fx/defn clj-kondo.lint-as/def-catch-all
|
||||
utils.re-frame/defn clj-kondo.lint-as/def-catch-all
|
||||
quo.react/with-deps-check clojure.core/fn
|
||||
quo.previews.preview/list-comp clojure.core/for
|
||||
status-im.utils.styles/def clojure.core/def
|
||||
status-im.utils.styles/defn clojure.core/defn
|
||||
test-helpers.unit/deftest-sub clojure.core/defn
|
||||
taoensso.tufte/defnp clojure.core/defn}
|
||||
:linters {:consistent-alias {:level :error
|
||||
:aliases {clojure.string string
|
||||
clojure.set set
|
||||
clojure.walk walk
|
||||
taoensso.timbre log}}
|
||||
: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
|
||||
:unresolved-symbol {:exclude [PersistentPriorityMap.EMPTY
|
||||
number
|
||||
status-im.test-helpers/restore-app-db]}}
|
||||
:config-in-ns {mocks.js-dependencies {:linters {:clojure-lsp/unused-public-var {:level :off}}}}}
|
||||
{:lint-as {status-im.utils.views/defview clojure.core/defn
|
||||
status-im.utils.views/letsubs clojure.core/let
|
||||
status-im.utils.fx/defn clj-kondo.lint-as/def-catch-all
|
||||
quo.react/with-deps-check clojure.core/fn
|
||||
quo.previews.preview/list-comp clojure.core/for
|
||||
status-im.utils.styles/def clojure.core/def
|
||||
status-im.utils.styles/defn clojure.core/defn
|
||||
taoensso.tufte/defnp clojure.core/defn}
|
||||
:linters {:invalid-arity {:skip-args [status-im.utils.fx/defn]}
|
||||
;;TODO remove number when this is fixed
|
||||
;;https://github.com/borkdude/clj-kondo/issues/867
|
||||
:unresolved-symbol {:exclude [PersistentPriorityMap.EMPTY number]}}}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,10 @@ CACHED_WEBVIEWS_ENABLED=1
|
||||
DEBUG_WEBVIEW=1
|
||||
DEFAULT_NETWORK=mainnet_rpc
|
||||
DEV_BUILD=1
|
||||
ERC20_CONTRACT_WARNINGS=0
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
FLEET=status.prod
|
||||
FLEET=eth.prod
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=info
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||
@@ -21,15 +22,9 @@ STATUS_GO_ENABLE_NIMBUS=0
|
||||
KEYCARD_TEST_MENU=0
|
||||
QR_READ_TEST_MENU=1
|
||||
ENABLE_ROOT_ALERT=1
|
||||
ENABLE_REFERRAL_INVITE=1
|
||||
ENABLE_QUO_PREVIEW=1
|
||||
MAX_IMAGES_BATCH=5
|
||||
APN_TOPIC=im.status.ethereum.pr
|
||||
COMMUNITIES_ENABLED=1
|
||||
DATABASE_MANAGEMENT_ENABLED=1
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
COLLECTIBLES_ENABLED=1
|
||||
COMMANDS_ENABLED=1
|
||||
TWO_MINUTES_SYNCING=1
|
||||
SWAP_ENABLED=1
|
||||
STICKERS_TEST_ENABLED=1
|
||||
LOCAL_PAIRING_ENABLED=1
|
||||
COMMUNITIES_MANAGEMENT_ENABLED=1
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
DEBUG_WEBVIEW=1
|
||||
DEFAULT_NETWORK=goerli_rpc
|
||||
DEFAULT_NETWORK=testnet_rpc
|
||||
ERC20_CONTRACT_WARNINGS=1
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
FLEET=status.prod
|
||||
FLEET=eth.staging
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=debug
|
||||
LOG_LEVEL=info
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=0
|
||||
PAIRING_POPUP_DISABLED=1
|
||||
PFS_ENCRYPTION_ENABLED=1
|
||||
@@ -21,15 +22,9 @@ COMMANDS_ENABLED=1
|
||||
KEYCARD_TEST_MENU=1
|
||||
QR_READ_TEST_MENU=1
|
||||
ENABLE_ROOT_ALERT=0
|
||||
ENABLE_REFERRAL_INVITE=1
|
||||
MAX_IMAGES_BATCH=5
|
||||
APN_TOPIC=im.status.ethereum.pr
|
||||
VERIFY_TRANSACTION_CHAIN_ID=5
|
||||
VERIFY_ENS_CHAIN_ID=5
|
||||
TEST_STATEOFUS=1
|
||||
DATABASE_MANAGEMENT_ENABLED=1
|
||||
VERIFY_TRANSACTION_CHAIN_ID=3
|
||||
COMMUNITIES_ENABLED=1
|
||||
COMMUNITIES_MANAGEMENT_ENABLED=1
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
TWO_MINUTES_SYNCING=1
|
||||
STICKERS_TEST_ENABLED=1
|
||||
LOCAL_PAIRING_ENABLED=1
|
||||
COMMUNITIES_MANAGEMENT_ENABLED=0
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
CACHED_WEBVIEWS_ENABLED=1
|
||||
DEBUG_WEBVIEW=1
|
||||
DEFAULT_NETWORK=goerli_rpc
|
||||
DEFAULT_NETWORK=mainnet_rpc
|
||||
ERC20_CONTRACT_WARNINGS=0
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
FLEET=status.prod
|
||||
FLEET=eth.prod
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=debug
|
||||
LOG_LEVEL=info
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||
MAINNET_WARNING_ENABLED=1
|
||||
PFS_ENCRYPTION_ENABLED=1
|
||||
@@ -17,21 +18,13 @@ RPC_NETWORKS_ONLY=0
|
||||
PARTITIONED_TOPIC=0
|
||||
CONTRACT_NODES=1
|
||||
STATUS_GO_ENABLE_NIMBUS=0
|
||||
COMMANDS_ENABLED=1
|
||||
KEYCARD_TEST_MENU=0
|
||||
ENABLE_ROOT_ALERT=1
|
||||
ENABLE_REFERRAL_INVITE=1
|
||||
DISABLE_WALLET_ON_MOBILE_NETWORK=1
|
||||
APN_TOPIC=im.status.ethereum.pr
|
||||
VERIFY_TRANSACTION_CHAIN_ID=5
|
||||
VERIFY_ENS_CHAIN_ID=5
|
||||
TEST_STATEOFUS=1
|
||||
BLANK_PREVIEW=0
|
||||
MAX_IMAGES_BATCH=5
|
||||
DATABASE_MANAGEMENT_ENABLED=1
|
||||
GOOGLE_FREE=0
|
||||
COMMUNITIES_ENABLED=1
|
||||
COMMUNITIES_MANAGEMENT_ENABLED=1
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
TWO_MINUTES_SYNCING=1
|
||||
ENABLE_QUO_PREVIEW=1
|
||||
STICKERS_TEST_ENABLED=1
|
||||
LOCAL_PAIRING_ENABLED=1
|
||||
COMMUNITIES_MANAGEMENT_ENABLED=0
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
DEBUG_WEBVIEW=1
|
||||
DEFAULT_NETWORK=mainnet_rpc
|
||||
ERC20_CONTRACT_WARNINGS=0
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
FLEET=status.prod
|
||||
FLEET=eth.prod
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=info
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||
@@ -12,13 +13,11 @@ PFS_TOGGLE_VISIBLE=1
|
||||
POW_TARGET=0.002
|
||||
POW_TIME=1
|
||||
SNOOPY=0
|
||||
KEYCARD_TEST_MENU=0
|
||||
RPC_NETWORKS_ONLY=0
|
||||
PARTITIONED_TOPIC=0
|
||||
CONTRACT_NODES=1
|
||||
ENABLE_ROOT_ALERT=1
|
||||
ENABLE_REFERRAL_INVITE=0
|
||||
MAX_IMAGES_BATCH=5
|
||||
BLANK_PREVIEW=0
|
||||
COMMUNITIES_ENABLED=1
|
||||
DATABASE_MANAGEMENT_ENABLED=1
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
DEBUG_WEBVIEW=0
|
||||
DEFAULT_NETWORK=mainnet_rpc
|
||||
ERC20_CONTRACT_WARNINGS=0
|
||||
ETHEREUM_DEV_CLUSTER=0
|
||||
EXTENSIONS=0
|
||||
FLEET=status.prod
|
||||
FLEET=eth.prod
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||
@@ -12,10 +13,8 @@ PFS_TOGGLE_VISIBLE=0
|
||||
POW_TARGET=0.002
|
||||
POW_TIME=1
|
||||
SNOOPY=0
|
||||
KEYCARD_TEST_MENU=0
|
||||
RPC_NETWORKS_ONLY=1
|
||||
PARTITIONED_TOPIC=0
|
||||
ENABLE_ROOT_ALERT=1
|
||||
MAX_IMAGES_BATCH=1
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
COLLECTIBLES_ENABLED=1
|
||||
ENABLE_REFERRAL_INVITE=0
|
||||
|
||||
@@ -94,4 +94,4 @@ suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||
|
||||
[version]
|
||||
^0.122.0
|
||||
^0.105.0
|
||||
|
||||
@@ -8,9 +8,10 @@ These are just guidelines, not rules. Use your best judgment, and feel free to p
|
||||
|
||||
#### What should I know before I get started?
|
||||
|
||||
* [Mission and Principles](https://status.im/about)
|
||||
* [Mission and Core Values](https://status.im/contribute)
|
||||
* [Principles](https://status.im/contribute/our_principles.html)
|
||||
* [Read our FAQ](https://status.im/docs/FAQs.html)
|
||||
* [Join our Chat](http://join.status.im/chat/public/status-core-dev)
|
||||
* [Developer Introduction](https://status.im/developer_tools/)
|
||||
* [Build Status Yourself](https://status.im/technical/build_status)
|
||||
* [Build Status Yourself](https://status.im/build_status)
|
||||
* [Find issues to work on](https://github.com/status-im/)
|
||||
|
||||
@@ -9,27 +9,46 @@ assignees: ''
|
||||
|
||||
# Bug Report
|
||||
|
||||
## Problem
|
||||
|
||||
## Problem
|
||||
[comment]: # (A problem description)
|
||||
|
||||
An overview of the background required to understand the problem.
|
||||
A problem description.
|
||||
|
||||
#### Expected behavior
|
||||
|
||||
[comment]: # (Describe what you expected to happen. Please include designs if possible.)
|
||||
|
||||
#### Actual behavior
|
||||
|
||||
[comment]: # (Describe what actually happened. Please include screenshots if possible.)
|
||||
|
||||
#### Notes
|
||||
|
||||
For the developer who will be investigating. Is it related to another PR? Tips on where to start?
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
Rules for the future PR to be accepted.
|
||||
|
||||
### Reproduction
|
||||
|
||||
1) Open Status
|
||||
2)
|
||||
[comment]: # (Describe how we can replicate the bug step by step.)
|
||||
|
||||
- Open Status
|
||||
- ...
|
||||
- Step 3, etc.
|
||||
|
||||
### Additional Information
|
||||
|
||||
- Status version: nightly
|
||||
- Operating System: Android, iOS
|
||||
[comment]: # (Please do your best to fill this out.)
|
||||
- Status version: ...
|
||||
[comment]: # (Android or iOS.)
|
||||
- Operating System: <Android|iOS>
|
||||
|
||||
#### Logs
|
||||
|
||||
[comment]: # (Please, add logs/notes if necessary)
|
||||
[comment]: # (if on Android please replicate bug whilst running adb logcat)
|
||||
|
||||
```
|
||||
...
|
||||
```
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
---
|
||||
name: Release umbrella issue
|
||||
about: Release Issue
|
||||
title: 'Mobile release '
|
||||
labels: release
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
Issue to manage mobile release <version>
|
||||
|
||||
### Scope
|
||||
[comment]: # (Add milestone from github)
|
||||
https://github.com/status-im/status-mobile/milestone/
|
||||
|
||||
- release notes:
|
||||
- release branch:
|
||||
|
||||
|
||||
### Testing info
|
||||
[comment]: # (TestRail info, added by QA)
|
||||
Main test suite:
|
||||
Upgrade (e2e):
|
||||
|
||||
### Builds in TestFlight and PlayStore to push as a release
|
||||
[comment]: # (Will be added by QA after testing approving of build)
|
||||
|
||||
### Process
|
||||
#### 1) Kick-off
|
||||
- [ ] 1. Translation PRs is merged before cutting branch (Jinho)
|
||||
- [ ] 2. Prepare scope of visible changes based on commits history, started from previous release branch cut ([guide](https://notes.status.im/how-to-prepare-release-notes))
|
||||
- [ ] 3. Update [RELEASES.md](https://github.com/status-im/status-mobile/blob/develop/RELEASES.md) with release notes (make PR based on previous step)
|
||||
- [ ] 4. Create release branch using this [guide](https://github.com/status-im/status-mobile/blob/develop/doc/RELEASE_GUIDE.md), bump VERSION (merge created PR ([example](https://github.com/status-im/status-mobile/pull/12504) ) to develop) and get successful release builds (so, testing can be started)
|
||||
- [ ] 5. Based on release scope, ask for comms (Jonny)
|
||||
- [ ] 6. Make sure that assets (screenshots, video) in stores are up-to-date, more info [here](https://notes.status.im/how-to-update-assets)
|
||||
|
||||
#### 2) Testing
|
||||
[comment]: # (Section will be maintained by QA)
|
||||
- [ ] Dogfooding (add notes, if it was held)
|
||||
- [ ] Regression testing for release candidate build
|
||||
- [ ] Upgrade tests
|
||||
- [ ] Fix known blocker(s) found during regression testing
|
||||
|
||||
##### Blockers
|
||||
[comment]: # (Section for blocker issues; should be fixed and merged by release-manager. Remove if no blockers found)
|
||||
- [ ] 1 blocker:
|
||||
|
||||
=============================================================================================
|
||||
|
||||
- [ ] Cherry-pick fix(es) to the release branch
|
||||
- [ ] Verify fix(es) on new release candidate build
|
||||
- [ ] Retest
|
||||
- [ ] Keep release build forever (button in Jenkins)
|
||||
|
||||
#### 3) Submission
|
||||
|
||||
- [ ] 1. Prepare PR for F-droid build ([instruction]( https://github.com/status-im/status-mobile/blob/develop/doc/FDROID.md))
|
||||
- [ ] 2. Release notes written and added (500 character limit for updates (Android) and PR for [RELEASES.md](https://github.com/status-im/status-mobile/blob/develop/RELEASES.md) is ready to be merged (from 1.3 step)
|
||||
- [ ] 3. Submit beta version for Android (Open Testing in Play Store)
|
||||
- [ ] 4. Submit iOS build to Apple review ([instruction](https://drive.google.com/file/d/10Cl7PBB7TFPkZiVbfzdFGpfMRP9bxXuq/view?usp=sharing), be careful - low quality of audio)
|
||||
- [ ] 5. Play store content reviewed and updated
|
||||
- [ ] 6. Privacy policy reviewed and updated (ask in channel)
|
||||
- [ ] 7. Countries to be excluded (ask in channel)
|
||||
- [ ] 8. Changes to our FAQ made (should be checked and if any changes needed, ask Jakub to made them)
|
||||
|
||||
|
||||
#### 4) Before publishing
|
||||
- [ ] 1. Translations for comms available (marketing, ask in the channel)
|
||||
- [ ] 2. Promotional content ready (marketing, ask in channel)
|
||||
- [ ] 3. Upload builds for DO store, https://dev.status.im/ (Jakub)
|
||||
|
||||
#### 5) At time of publishing
|
||||
- [ ] 1. Notify marketing to push comms and blog post (Jonny + get review on blog from QA team)
|
||||
- [ ] 2. Publish release to app store and playstore
|
||||
- [ ] 3. Final push to update prod site https://status.im/, [instructions](https://github.com/status-im/infra-docs/blob/master/articles/status_release_upload.md) (Jakub - requires credentials to upload)
|
||||
- [ ] 4. Add the link to the post about the release and publish the release: https://github.com/status-im/status-mobile/releases (Jakub)
|
||||
- [ ] 5. Merge PR for updating [RELEASES.md](https://github.com/status-im/status-mobile/blob/develop/RELEASES.md) (from 1.3 step)
|
||||
|
||||
@@ -9,8 +9,8 @@ project-board:
|
||||
test-column-name: 'E2E Tests'
|
||||
|
||||
automated-tests:
|
||||
repo-full-name: 'status-im/status-mobile'
|
||||
job-full-name: 'status-mobile/e2e/status-app-prs'
|
||||
repo-full-name: 'status-im/status-react'
|
||||
job-full-name: 'end-to-end-tests/status-app-prs'
|
||||
kickoff-column-name: 'E2E Tests'
|
||||
|
||||
github-team:
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
name: Zenhub integration assigned
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- assigned
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: status-im/zenhub-automations@master
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
ZENHUB_API_KEY: ${{ secrets.ZENHUB_TOKEN }}
|
||||
INPROG_COLUMN: Z2lkOi8vcmFwdG9yL1BpcGVsaW5lLzMyODI1Mg
|
||||
REVIEW_COLUMN: Z2lkOi8vcmFwdG9yL1BpcGVsaW5lLzIyNjk0MTA
|
||||
@@ -0,0 +1,14 @@
|
||||
name: Zenhub integration branch
|
||||
on:
|
||||
create:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: status-im/zenhub-automations@master
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
ZENHUB_API_KEY: ${{ secrets.ZENHUB_TOKEN }}
|
||||
INPROG_COLUMN: Z2lkOi8vcmFwdG9yL1BpcGVsaW5lLzMyODI1Mg
|
||||
REVIEW_COLUMN: Z2lkOi8vcmFwdG9yL1BpcGVsaW5lLzIyNjk0MTA
|
||||
@@ -0,0 +1,19 @@
|
||||
name: Zenhub integration PR
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ develop ]
|
||||
types:
|
||||
- ready_for_review
|
||||
- opened
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: status-im/zenhub-automations@master
|
||||
if: github.event.pull_request.draft == false
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
ZENHUB_API_KEY: ${{ secrets.ZENHUB_TOKEN }}
|
||||
INPROG_COLUMN: Z2lkOi8vcmFwdG9yL1BpcGVsaW5lLzMyODI1Mg
|
||||
REVIEW_COLUMN: Z2lkOi8vcmFwdG9yL1BpcGVsaW5lLzIyNjk0MTA
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
# Xcode
|
||||
#
|
||||
/ios/.xcode.env.local
|
||||
/component-spec
|
||||
result/
|
||||
build/
|
||||
*.pbxuser
|
||||
@@ -41,8 +39,8 @@ local.properties
|
||||
.tags*
|
||||
|
||||
# VS Code
|
||||
.vscode/
|
||||
workspace.code-workspace
|
||||
.vscode/ipch/
|
||||
.vscode/settings.json
|
||||
|
||||
# node.js
|
||||
#
|
||||
@@ -97,12 +95,12 @@ doo-index.html
|
||||
|
||||
# Status
|
||||
Statusgo.framework
|
||||
Statusgo.xcframework
|
||||
|
||||
#ios
|
||||
/ios/Pods/
|
||||
/ios/logs/
|
||||
/ios/StatusIm.xcworkspace
|
||||
/ios/react-native-xcode.log
|
||||
/ios/set_xcode_version.log
|
||||
.ruby-version
|
||||
status-e2e/
|
||||
|
||||
@@ -167,26 +165,3 @@ trace.edn
|
||||
|
||||
/app/
|
||||
project.clj
|
||||
|
||||
##appium
|
||||
test/appium/report/
|
||||
result.xml
|
||||
test/appium/tests/users.py
|
||||
|
||||
##node bindings
|
||||
/bin/
|
||||
/lib/
|
||||
|
||||
## visual tests
|
||||
/artifacts
|
||||
|
||||
/.calva/
|
||||
|
||||
## component-tests
|
||||
*.log
|
||||
|
||||
## local xcode env introduced in react-native 0.69
|
||||
.xcode.env.local
|
||||
|
||||
## git hooks
|
||||
lefthook.yml
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
module.exports = {
|
||||
bracketSpacing: false,
|
||||
bracketSameLine: true,
|
||||
jsxBracketSameLine: true,
|
||||
singleQuote: true,
|
||||
trailingComma: 'all',
|
||||
tabWidth: 4,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"*.android": "groovy",
|
||||
"*.ios": "groovy",
|
||||
"*.linux": "groovy",
|
||||
"*.macos": "groovy",
|
||||
"*.windows": "groovy",
|
||||
"*.nix-cache": "groovy",
|
||||
},
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
;; -*- mode: clojure -*-
|
||||
;; vi: ft=clojure
|
||||
{:width 105
|
||||
:style [;; community style
|
||||
;; https://github.com/kkinnear/zprint/blob/main/doc/reference.md#community
|
||||
:community
|
||||
|
||||
;; no comma in map
|
||||
:no-comma
|
||||
|
||||
:custom-justify
|
||||
|
||||
;; respect all newlines
|
||||
;; https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-nl
|
||||
:respect-nl
|
||||
|
||||
;; 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]
|
||||
:fn-map
|
||||
{"reg-sub" :arg1-pair
|
||||
"h/describe" :arg1-body
|
||||
"h/test" :arg1-body
|
||||
"global.describe" :arg1-body
|
||||
"global.test" :arg1-body
|
||||
"list-comp" :binding
|
||||
"defview" :arg1-body
|
||||
"letsubs" :binding
|
||||
"with-let" "let"
|
||||
"testing" :arg1-body
|
||||
"deftest-sub" :arg1-body
|
||||
"wait-for" :arg1-body
|
||||
"with-deps-check" :arg1-body
|
||||
"->" [:noarg1-body
|
||||
{:list {:constant-pair? false :force-nl? false}
|
||||
:next-inner-restore [[:list :constant-pair?]]}]
|
||||
"set!" "reset!"
|
||||
"assoc-when" "assoc"
|
||||
"assoc-some" "assoc"
|
||||
"conj-when" "conj"
|
||||
"conj-some" "conj"}
|
||||
:remove {:fn-force-nl #{:noarg1-body}}
|
||||
:style-map
|
||||
{:no-comma {:map {:comma? false}}
|
||||
:custom-justify
|
||||
{:doc "Justify everything using pre-1.1.2 approach"
|
||||
:binding {:justify? true :justify {:max-variance 1000}}
|
||||
:map {:justify? true :justify {:max-variance 1000}}
|
||||
:pair {:justify? true :justify {:max-variance 1000}}}}}
|
||||
@@ -131,9 +131,9 @@ TODO: update once bug is fixed for Android that causes crash when app is back fr
|
||||
## "react-native-shake": "^3.3.1"
|
||||
|
||||
used to send email to support when phone is shaked
|
||||
## "react-native-lottie-splash-screen": "^1.0.1"
|
||||
## "react-native-splash-screen": "^3.2.0"
|
||||
|
||||
used to make splash screen with lottie animation during initial loading for android, also used as replacement of "react-native-splash-screen" for iOS
|
||||
used to make splash screen during initial loading
|
||||
|
||||
## "react-native-status-keycard": "^2.5.7"
|
||||
|
||||
@@ -157,10 +157,6 @@ used for browser
|
||||
used for native navigation
|
||||
fixed because even bugfix version upgrade causes runtime errors with current version of react-native
|
||||
|
||||
## "rn-emoji-keyboard": "https://github.com/status-im/rn-emoji-keyboard"
|
||||
## "web3-utils": "^1.2.1"
|
||||
|
||||
Used for taking emoji input, for custom emoji thumbnails for community channels
|
||||
|
||||
## "react-native-draggable-flatlist": "https://github.com/computerjazz/react-native-draggable-flatlist"
|
||||
|
||||
A drag-and-drop-enabled FlatList component for React Native
|
||||
used for some abi encoding primitives
|
||||
@@ -1,4 +1,4 @@
|
||||
.PHONY: nix-add-gcroots clean nix-clean run-metro test release _list _fix-node-perms _tmpdir-rm
|
||||
.PHONY: nix-add-gcroots clean nix-clean run-metro test release _list _fix-node-perms _tmpdir-mk _tmpdir-rm
|
||||
|
||||
help: SHELL := /bin/sh
|
||||
help: ##@other Show this help
|
||||
@@ -32,23 +32,19 @@ ifndef BUILD_TAG
|
||||
export BUILD_TAG := $(shell git rev-parse --short HEAD)
|
||||
endif
|
||||
|
||||
# We don't want to use /run/user/$UID because it runs out of space too easilly.
|
||||
export TMPDIR = /tmp/tmp-status-mobile-$(BUILD_TAG)
|
||||
# This has to be specified for both the Node.JS server process and the Qt process.
|
||||
# We don't want to use /run/user/$UID because it runs out of space too easilly
|
||||
export TMPDIR = /tmp/tmp-status-react-$(BUILD_TAG)
|
||||
# this has to be specified for both the Node.JS server process and the Qt process
|
||||
export REACT_SERVER_PORT ?= 5001
|
||||
# Fix for ERR_OSSL_EVP_UNSUPPORTED error.
|
||||
export NODE_OPTIONS += --openssl-legacy-provider
|
||||
# The path can be anything, but home is usually safest.
|
||||
export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore
|
||||
|
||||
# Our custom config is located in 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
|
||||
export _NIX_GCROOTS = /nix/var/nix/gcroots/per-user/$(USER)/status-react
|
||||
# Defines which variables will be kept for Nix pure shell, use semicolon as divider
|
||||
export _NIX_KEEP ?= TMPDIR,BUILD_ENV,STATUS_GO_SRC_OVERRIDE
|
||||
export _NIX_KEEP ?= TMPDIR,BUILD_ENV,STATUS_GO_SRC_OVERRIDE,NIMBUS_SRC_OVERRIDE
|
||||
|
||||
# Useful for Android release builds
|
||||
# Useful for Andoird release builds
|
||||
TMP_BUILD_NUMBER := $(shell ./scripts/version/gen_build_no.sh | cut -c1-10)
|
||||
|
||||
# MacOS root is read-only, read nix/README.md for details
|
||||
@@ -61,10 +57,13 @@ endif
|
||||
# Nix targets
|
||||
#----------------
|
||||
|
||||
# WARNING: This has to be located right before all the targets.
|
||||
# WARNING: This has to be located right before the targets
|
||||
ifdef IN_NIX_SHELL
|
||||
SHELL := env bash
|
||||
else
|
||||
SHELL := ./nix/scripts/shell.sh
|
||||
endif
|
||||
|
||||
shell: export TARGET ?= default
|
||||
shell: ##@prepare Enter into a pre-configured shell
|
||||
ifndef IN_NIX_SHELL
|
||||
@ENTER_NIX_SHELL
|
||||
@@ -86,7 +85,7 @@ nix-gc: nix-gc-protected ##@nix Garbage collect all packages older than 20 days
|
||||
nix-store --gc
|
||||
|
||||
nix-clean: export TARGET := default
|
||||
nix-clean: ##@nix Remove all status-mobile build artifacts from /nix/store
|
||||
nix-clean: ##@nix Remove all status-react build artifacts from /nix/store
|
||||
nix/scripts/clean.sh
|
||||
|
||||
nix-purge: SHELL := /bin/sh
|
||||
@@ -118,22 +117,16 @@ _fix-node-perms: ##@prepare Fix permissions so that directory can be cleaned
|
||||
$(shell test -d node_modules && chmod -R 744 node_modules)
|
||||
$(shell test -d node_modules.tmp && chmod -R 744 node_modules.tmp)
|
||||
|
||||
$(TMPDIR): SHELL := /bin/sh
|
||||
$(TMPDIR): ##@prepare Create a TMPDIR for temporary files
|
||||
_tmpdir-mk: SHELL := /bin/sh
|
||||
_tmpdir-mk: ##@prepare Create a TMPDIR for temporary files
|
||||
@mkdir -p "$(TMPDIR)"
|
||||
# Make sure TMPDIR exists every time make is called
|
||||
_tmpdir-mk: $(TMPDIR)
|
||||
-include _tmpdir-mk
|
||||
|
||||
_tmpdir-rm: SHELL := /bin/sh
|
||||
_tmpdir-rm: ##@prepare Remove TMPDIR
|
||||
rm -fr "$(TMPDIR)"
|
||||
|
||||
_install-hooks: SHELL := /bin/sh
|
||||
_install-hooks: ##@prepare Create prepare-commit-msg git hook symlink
|
||||
@ln -s -f ../../scripts/hooks/prepare-commit-msg .git/hooks
|
||||
-include _install-hooks
|
||||
|
||||
# Remove directories and ignored files
|
||||
clean: SHELL := /bin/sh
|
||||
clean: _fix-node-perms _tmpdir-rm ##@prepare Remove all output folders
|
||||
@@ -147,7 +140,7 @@ purge: _fix-node-perms _tmpdir-rm ##@prepare Remove all output folders
|
||||
|
||||
watchman-clean: export TARGET := watchman
|
||||
watchman-clean: ##@prepare Delete repo directory from watchman
|
||||
watchman watch-del $${STATUS_MOBILE_HOME}
|
||||
watchman watch-del $${STATUS_REACT_HOME}
|
||||
|
||||
pod-install: export TARGET := ios
|
||||
pod-install: ##@prepare Run 'pod install' to install podfiles and update Podfile.lock
|
||||
@@ -155,81 +148,49 @@ 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
|
||||
$(KEYSTORE_PATH):
|
||||
keystore: export TARGET := keytool
|
||||
keystore: export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore
|
||||
keystore: ##@prepare Generate a Keystore for signing Android APKs
|
||||
@./scripts/generate-keystore.sh
|
||||
|
||||
keystore: $(KEYSTORE_PATH) ##@prepare Generate a Keystore for signing Android APKs
|
||||
|
||||
fdroid-max-watches: SHELL := /bin/sh
|
||||
fdroid-max-watches: ##@prepare Bump max_user_watches to avoid ENOSPC errors
|
||||
sysctl fs.inotify.max_user_watches=524288
|
||||
|
||||
fdroid-nix-dir: SHELL := /bin/sh
|
||||
fdroid-nix-dir: ##@prepare Create /nix directory for F-Droid Vagrant builders
|
||||
mkdir -m 0755 /nix
|
||||
chown vagrant /nix
|
||||
|
||||
fdroid-fix-tmp: SHELL := /bin/sh
|
||||
fdroid-fix-tmp: ##@prepare Fix TMPDIR permissions so Vagrant user is the owner
|
||||
chown -R vagrant "$(TMPDIR)"
|
||||
|
||||
fdroid-build-env: fdroid-max-watches fdroid-nix-dir fdroid-fix-tmp ##@prepare Setup build environment for F-Droud build
|
||||
|
||||
fdroid-pr: export TARGET := android-sdk
|
||||
fdroid-pr: ##@prepare Create F-Droid release PR
|
||||
ifndef APK
|
||||
$(error APK env var not defined)
|
||||
endif
|
||||
scripts/fdroid-pr.sh "$(APK)"
|
||||
|
||||
xcode-clean: SHELL := /bin/sh
|
||||
xcode-clean: XCODE_HOME := $(HOME)/Library/Developer/Xcode
|
||||
xcode-clean: ##@prepare Clean XCode derived data and archives
|
||||
rm -fr $(XCODE_HOME)/DerivedData/StatusIm-* $(XCODE_HOME)/Archives/*/StatusIm*
|
||||
|
||||
#----------------
|
||||
# Release builds
|
||||
#----------------
|
||||
release: release-android release-ios ##@build Build release for Android and iOS
|
||||
release: release-android release-ios ##@build build release for Android and iOS
|
||||
|
||||
build-fdroid: export BUILD_ENV = prod
|
||||
build-fdroid: export BUILD_TYPE = release
|
||||
build-fdroid: export ANDROID_ABI_SPLIT = false
|
||||
build-fdroid: export ANDROID_ABI_INCLUDE = armeabi-v7a;arm64-v8a;x86;x86_64
|
||||
build-fdroid: ##@build Build release for F-Droid
|
||||
@scripts/build-android.sh
|
||||
|
||||
build-android: export BUILD_ENV ?= prod
|
||||
build-android: export BUILD_TYPE ?= nightly
|
||||
build-android: export BUILD_NUMBER ?= $(TMP_BUILD_NUMBER)
|
||||
build-android: export ANDROID_ABI_SPLIT ?= false
|
||||
build-android: export ANDROID_ABI_INCLUDE ?= armeabi-v7a;arm64-v8a;x86
|
||||
build-android: ##@build Build unsigned Android APK
|
||||
@scripts/build-android.sh
|
||||
|
||||
release-android: export TARGET := keytool
|
||||
release-android: export TARGET := default
|
||||
release-android: export BUILD_ENV ?= prod
|
||||
release-android: export BUILD_TYPE ?= nightly
|
||||
release-android: export BUILD_NUMBER ?= $(TMP_BUILD_NUMBER)
|
||||
release-android: export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore
|
||||
release-android: keystore build-android ##@build Build signed Android APK
|
||||
@scripts/sign-android.sh result/app-release-unsigned.apk
|
||||
release-android: export ANDROID_APK_SIGNED ?= true
|
||||
release-android: export ANDROID_ABI_SPLIT ?= false
|
||||
release-android: export ANDROID_ABI_INCLUDE ?= armeabi-v7a;arm64-v8a;x86
|
||||
release-android: keystore ##@build build release for Android
|
||||
scripts/release-android.sh
|
||||
|
||||
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/* ./
|
||||
|
||||
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
|
||||
@@ -243,10 +204,6 @@ status-go-ios: SHELL := /bin/sh
|
||||
status-go-ios: ##@status-go Compile status-go for iOS app
|
||||
nix/scripts/build.sh targets.status-go.mobile.ios
|
||||
|
||||
status-go-library: SHELL := /bin/sh
|
||||
status-go-library: ##@status-go Compile status-go for node-js
|
||||
nix/scripts/build.sh targets.status-go.library
|
||||
|
||||
#--------------
|
||||
# Watch, Build & Review changes
|
||||
#--------------
|
||||
@@ -268,7 +225,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=
|
||||
run-ios: export TARGET := ios
|
||||
run-ios: ##@run Build iOS app and start it in a simulator/device
|
||||
ifneq ("$(SIMULATOR)", "")
|
||||
@@ -277,123 +234,62 @@ 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 := default
|
||||
lint: export TARGET := clojure
|
||||
lint: ##@test Run code style checks
|
||||
@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
|
||||
yarn clj-kondo --confg .clj-kondo/config.edn --lint src && \
|
||||
clojure -Sdeps '{:deps {cljfmt {:mvn/version "0.6.7"}}}' \
|
||||
-m cljfmt.main check $$(git diff --diff-filter=d --cached --name-only src && echo src) \
|
||||
--indents indentation.edn
|
||||
|
||||
# NOTE: We run the linter twice because of https://github.com/kkinnear/zprint/issues/271
|
||||
lint-fix: export TARGET := default
|
||||
lint-fix: export TARGET := clojure
|
||||
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
|
||||
|
||||
|
||||
shadow-server: export TARGET := clojure
|
||||
shadow-server:##@ Start shadow-cljs in server mode for watching
|
||||
yarn shadow-cljs server
|
||||
|
||||
test-watch: export TARGET := clojure
|
||||
test-watch: ##@ Watch tests and re-run no changes to cljs files
|
||||
yarn install
|
||||
nodemon --exec 'yarn shadow-cljs compile mocks && yarn shadow-cljs compile test && node --require ./test-resources/override.js target/test/test.js' -e cljs
|
||||
|
||||
test-watch-for-repl: export TARGET := clojure
|
||||
test-watch-for-repl: ##@ Watch tests and support REPL connections
|
||||
yarn install
|
||||
rm -f target/test/test.js
|
||||
concurrently --kill-others --prefix-colors 'auto' --names 'build,repl' \
|
||||
'yarn shadow-cljs compile mocks && yarn shadow-cljs watch test --verbose' \
|
||||
'until [ -f ./target/test/test.js ] ; do sleep 1 ; done ; node --require ./test-resources/override.js ./target/test/test.js --repl'
|
||||
clojure -Sdeps '{:deps {cljfmt {:mvn/version "0.6.7"}}}' \
|
||||
-m cljfmt.main fix src \
|
||||
--indents indentation.edn
|
||||
|
||||
test: export TARGET := clojure
|
||||
test: ##@test Run tests once in NodeJS
|
||||
# Here we create the gyp bindings for nodejs
|
||||
yarn install
|
||||
yarn shadow-cljs compile mocks && \
|
||||
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
|
||||
component-test-watch: ##@ Watch tests and re-run no changes to cljs files
|
||||
yarn install
|
||||
nodemon --exec 'yarn shadow-cljs compile component-test && jest --config=test/jest/jest.config.js' -e cljs
|
||||
|
||||
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
|
||||
yarn install
|
||||
yarn shadow-cljs compile component-test && \
|
||||
jest --config=test/jest/jest.config.js
|
||||
coverage: ##@test Run tests once in NodeJS generating coverage
|
||||
@scripts/run-coverage.sh
|
||||
|
||||
#--------------
|
||||
# Other
|
||||
#--------------
|
||||
|
||||
geth-connect: export TARGET := android-sdk
|
||||
geth-connect: export TARGET := android-env
|
||||
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; \
|
||||
[[ -d android/.gradle ]] && cd android && ./gradlew clean
|
||||
|
||||
android-ports: export TARGET := android-sdk
|
||||
android-ports: export TARGET := android-env
|
||||
android-ports: ##@other Add proxies to Android Device/Simulator
|
||||
adb reverse tcp:8081 tcp:8081 && \
|
||||
adb reverse tcp:3449 tcp:3449 && \
|
||||
adb reverse tcp:4567 tcp:4567 && \
|
||||
adb forward tcp:5561 tcp:5561
|
||||
|
||||
android-devices: export TARGET := android-sdk
|
||||
android-devices: export TARGET := android-env
|
||||
android-devices: ##@other Invoke adb devices
|
||||
adb devices
|
||||
|
||||
android-logcat: export TARGET := android-sdk
|
||||
android-logcat: ##@other Read status-mobile logs from Android phone using adb
|
||||
android-logcat: export TARGET := android-env
|
||||
android-logcat: ##@other Read status-react logs from Android phone using adb
|
||||
adb logcat | grep -e RNBootstrap -e ReactNativeJS -e ReactNative -e StatusModule -e StatusNativeLogs -e 'F DEBUG :' -e 'Go :' -e 'GoLog :' -e 'libc :'
|
||||
|
||||
android-install: export TARGET := android-sdk
|
||||
android-install: export TARGET := android-env
|
||||
android-install: export BUILD_TYPE ?= release
|
||||
android-install: ##@other Install APK on device using adb
|
||||
adb install result/app-$(BUILD_TYPE).apk
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
# Status - a Mobile Ethereum Operating System
|
||||
|
||||
[<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/)
|
||||
[<img src="doc/github_badge.png" alt="Get it on Github" height="80"/>](https://github.com/status-im/status-mobile/releases)
|
||||
# Status - a Mobile Ethereum Operating System
|
||||
|
||||
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.
|
||||
|
||||
@@ -10,11 +7,11 @@ Join us in creating a browser, messenger, and gateway to a decentralized world.
|
||||
|
||||
## Why?
|
||||
|
||||
We believe in a medium of pure free trade, economies with fair, permission-less access and a world without intermediaries. We want to create policies that can exist between friends or scale globally, we want to communicate securely and be uninhibited by legacy systems.
|
||||
We believe in a medium of pure free trade, economies with fair, permission-less access and a world without intermediaries. We want to create policies that can exist between friends or scale globally, we want to communicate securely and be uninhibited by legacy systems.
|
||||
|
||||
We want to take responsibility for our data, the way we conduct ourselves privately and promote this way of life to a mass audience.
|
||||
|
||||
We want deep insights into our own economies so we can make informed, data-driven decisions on how to make our lives better. The Ethereum blockchain, Smart Contracts, Swarm and Whisper provides us a path forward.
|
||||
We want deep insights into our own economies so we can make informed, data-driven decisions on how to make our lives better. The Ethereum blockchain, Smart Contracts, Swarm and Whisper provides us a path forward.
|
||||
|
||||
If this interests you, **help us make Status a reality** - anyone can contribute and we need everyone at any skill level to participate.
|
||||
|
||||
@@ -22,37 +19,29 @@ If this interests you, **help us make Status a reality** - anyone can contribute
|
||||
|
||||
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](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](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.
|
||||
- **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](https://status.im/developer_tools/) which guides you through the technology stack and start browsing [beginner issues](https://github.com/status-im/status-react/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](https://status.im/technical/build_status/), which talks about managing project dependencies, coding guidelines and testing procedures.
|
||||
|
||||
- **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)
|
||||
- **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 [Community Principles](https://status.im/contribute/our_principles.html)
|
||||
|
||||
- **Specification / Documentation**
|
||||
- **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, head over to our [docs](https://status.im/docs) and see how you can improve what we have.
|
||||
|
||||
- **Blog Writing**
|
||||
- **Blog Writing**
|
||||
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](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!
|
||||
- **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](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-react/issues). Every bug you find brings Status closer to stable, usable software for everyone to enjoy!
|
||||
|
||||
- **Security**
|
||||
- **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!
|
||||
|
||||
- **Evangelism**
|
||||
- **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
|
||||
## 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!
|
||||
@@ -72,8 +61,10 @@ Feel free to email us at [support@status.im](mailto:support@status.im) or better
|
||||
|
||||
## License
|
||||
|
||||
Licensed under the [Mozilla Public License v2.0](https://github.com/status-im/status-mobile/blob/develop/LICENSE.md)
|
||||
Licensed under the [Mozilla Public License v2.0](https://github.com/status-im/status-react/blob/develop/LICENSE.md)
|
||||
|
||||
## Testing Supported by
|
||||
|
||||
[](https://www.browserstack.com/automate/public-build/SFBWQ3k5R2tnT2t6UGsxU1h1U0g3VFlCNnoxVTRHYWNoTDhsb1laaTJZWT0tLUZMUm5sSVFBSU9qSWM1RUJvK1I3Z3c9PQ==--ad15ae7992b432b33743749d40318952415bd98f)
|
||||
|
||||
[](https://coveralls.io/github/status-im/status-react)
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
# Description
|
||||
|
||||
This document explains some of the steps that are involved in relseases.
|
||||
|
||||
## PlayStore Metadata Updates
|
||||
|
||||
You can update Play Store releae metadata using `fastlane android upload_metadata`.
|
||||
|
||||
But that requires credentials necessary for accessing Play Store API. The simpler way is to edit files contained within [`fastlane/metadata`](metadata) and run the following CI job:
|
||||
|
||||
https://ci.status.im/job/status-tools/job/update-playstore-metadata/
|
||||
@@ -25,7 +25,7 @@ QA process was focused on account creation and login with keycard, and this bug
|
||||
|
||||
# Missing labels for en translation
|
||||
|
||||
https://github.com/status-im/status-mobile/issues/9003
|
||||
https://github.com/status-im/status-react/issues/9003
|
||||
|
||||
## Cause
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
# Description
|
||||
|
||||
This document provides information on how to start developing Status App.
|
||||
|
||||
# Getting Started
|
||||
|
||||
To start developing start a shell for platform you are interested in.
|
||||
```
|
||||
make shell TARGET=android
|
||||
```
|
||||
This step will take a while the first time as it will download all dependencies.
|
||||
|
||||
To build the app, your can simply run on of the following:
|
||||
```
|
||||
make release-android
|
||||
make release-ios
|
||||
```
|
||||
For more `make` targets run `make help`.
|
||||
|
||||
# Development
|
||||
|
||||
There are three steps necessary to start development, in this case for Android:
|
||||
|
||||
1. `make run-clojure` - Compiles Clojure into JavaScript, watches for changes on cljs files, and hot-reloads code in the app
|
||||
2. `make run-metro` - Starts metro bundler and watches JavaScript code
|
||||
3. `make run-android` - Builds the Android app and starts it on the device
|
||||
|
||||
The first two will continue watching for changes and keep re-building the app. They need to be ready first.
|
||||
The last one will exit once the app is up and ready.
|
||||
|
||||
# Manual Steps
|
||||
|
||||
There are a few manual steps you might want to do in order to start contributing.
|
||||
|
||||
## Genymotion Virtualization
|
||||
|
||||
Optionally set up Genymotion if you don't want to use Android Virtual Device:
|
||||
|
||||
https://www.genymotion.com
|
||||
|
||||
## Android Development Environment
|
||||
|
||||
You can also setup Android Development Environment + Simulator:
|
||||
|
||||
https://facebook.github.io/react-native/docs/getting-started.html
|
||||
|
||||
## Configure GitHub Account
|
||||
|
||||
The optimal way of pushing to GitHubis using SSH instead of user/pass auth.
|
||||
|
||||
It's recommented that you [add your public SSH key to your GitHub account](https://help.github.com/en/github/authenticating-to-github/adding-a-new-ssh-key-to-your-github-account).
|
||||
|
||||
## Configure GPG Keys for signing commits
|
||||
|
||||
In order to increase security we require all commits in `status-react` repo to be signed with a GPG key.
|
||||
|
||||
Steps:
|
||||
1. [Generate a new GPG key](https://help.github.com/en/github/authenticating-to-github/generating-a-new-gpg-key)
|
||||
2. [Setup Git to use your GPG key](https://help.github.com/en/github/authenticating-to-github/telling-git-about-your-signing-key)
|
||||
3. [Setup Git to sign commits](https://help.github.com/en/github/authenticating-to-github/signing-commits)
|
||||
4. [Setup GitHub to validate commits](https://help.github.com/en/github/authenticating-to-github/adding-a-new-gpg-key-to-your-github-account)
|
||||
@@ -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,21 +60,21 @@ 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
|
||||
Update yarn.lock file. In order to do this, perform the following steps on a clean `status-mobile` repo:
|
||||
## Solution
|
||||
Update yarn.lock file. In order to do this, perform the following steps on a clean `status-react` repo:
|
||||
```
|
||||
cd status-mobile
|
||||
cd status-react
|
||||
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...
|
||||
@@ -108,42 +87,13 @@ adb server version (41) doesn't match this client (40); killing...
|
||||
This might cause all kinds of difficult-to-debug errors, e.g.:
|
||||
- not being able to find the device through `adb devices`
|
||||
- `make run-android` throwing `com.android.builder.testing.api.DeviceException: com.android.ddmlib.InstallException: device 'device-id' not found.`
|
||||
- `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`
|
||||
- `make run-android` throwing `- Error: Command failed: ./gradlew app:installDebug -PreactNativeDevServerPort=8081 Unable to install /status-react/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`.
|
||||
|
||||
# Hot Reloading Crashes
|
||||
## APP Crashes on reloading changes
|
||||
|
||||
### Cause
|
||||
Status-mobile uses `shadow-cljs` for hot reloading changes and uses its own [reloader](https://github.com/status-im/status-mobile/blob/develop/src/status_im/reloader.cljs) for updating them in the running app. If react-native's fast refresh is also enabled then it creates conflicts and crashes the app.
|
||||
|
||||
### Solution
|
||||
Open react native's [In-App Developer Menu](https://reactnative.dev/docs/debugging#accessing-the-in-app-developer-menu) and press "Disable Fast Refresh" or "Disable Hot Reloading"
|
||||
|
||||
## App Crashes after few reloads
|
||||
|
||||
### Cause
|
||||
For x86 CPU architecture Android Devices, Hermes is creating the issue and the app crashes after a few reloads.
|
||||
([Original Issue](https://github.com/status-im/status-mobile/issues/14031))
|
||||
|
||||
<details>
|
||||
<summary>How to Find CPU architecture</summary>
|
||||
|
||||
CPU architecture of android device can be found using
|
||||
- `adb shell uname -m` or
|
||||
- `adb shell getprop ro.product.cpu.abilist`
|
||||
|
||||
</details>
|
||||
|
||||
### Solution
|
||||
Disable Hermes while building the app
|
||||
|
||||
`make run-android DISABLE_HERMES=true`
|
||||
@@ -76,28 +76,15 @@ import com.sun.org.apache.xalan.internal.xsltc.compiler.Copy
|
||||
* extraPackagerArgs: []
|
||||
* ]
|
||||
*/
|
||||
|
||||
/*
|
||||
Enabling Hermes on x86 devices is crashing the app after a few reloads,
|
||||
this flag can be used to disable Hermes while building app.
|
||||
https://github.com/status-im/status-mobile/issues/14031
|
||||
*/
|
||||
|
||||
def disableHermes = System.getenv('DISABLE_HERMES') == 'true'
|
||||
|
||||
project.ext.react = [
|
||||
nodeExecutableAndArgs: ["node", "--max-old-space-size=16384"],
|
||||
entryFile: "index.js",
|
||||
/* NOTE: Hermes engine is required for Android 64-bit builds running on 64 devices,
|
||||
* to guard against a hang in the UI thread after invoking status-go.
|
||||
* Also a clean and rebuild is required when changing this. */
|
||||
enableHermes: !disableHermes,
|
||||
enableHermes: true,
|
||||
/* 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/**"]
|
||||
]
|
||||
@@ -137,19 +124,9 @@ def jscFlavor = 'org.webkit:android-jsc:+'
|
||||
def enableHermes = project.ext.react.get("enableHermes", false);
|
||||
|
||||
/**
|
||||
* Architectures to build native code for.
|
||||
* Exclude google library so we can publish to external android stores
|
||||
*/
|
||||
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
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
def googleFree = project.env.get("GOOGLE_FREE", false)
|
||||
|
||||
def getVersionCode = { ->
|
||||
new ByteArrayOutputStream().withStream { stdOut ->
|
||||
@@ -171,10 +148,7 @@ def getVersionName = { ->
|
||||
if (project.hasProperty("releaseVersion")) {
|
||||
return project.releaseVersion
|
||||
}
|
||||
/* Necessary because Android Studio uses wrong PWD.
|
||||
* Is actually absolute directory path of this file. */
|
||||
def configDir = project.projectDir.toString()
|
||||
version = new File(configDir + '/../../VERSION').text
|
||||
version = new File('../VERSION').text
|
||||
return version.replaceAll("\\s","")
|
||||
}
|
||||
}
|
||||
@@ -195,13 +169,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 {
|
||||
@@ -212,77 +184,13 @@ android {
|
||||
versionCode getVersionCode()
|
||||
versionName getVersionName()
|
||||
missingDimensionStrategy 'react-native-camera', 'general'
|
||||
manifestPlaceholders = [commitHash: getCommitHash()]
|
||||
/* this needs to be empty if we want APKs split by ABIs */
|
||||
if (!getEnvOrConfig('ANDROID_ABI_SPLIT').toBoolean()) {
|
||||
ndk {
|
||||
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
|
||||
@@ -318,6 +226,23 @@ android {
|
||||
jumboMode true
|
||||
javaMaxHeapSize "8g"
|
||||
}
|
||||
signingConfigs {
|
||||
debug {
|
||||
storeFile file('debug.keystore')
|
||||
storePassword 'android'
|
||||
keyAlias 'androiddebugkey'
|
||||
keyPassword 'android'
|
||||
}
|
||||
/* Caution! In production, you need to generate your own keystore file.
|
||||
* See: https://facebook.github.io/react-native/docs/signed-apk-android */
|
||||
release {
|
||||
/* environment variables take precedence over gradle.properties file */
|
||||
storeFile file(getEnvOrConfig('KEYSTORE_PATH').replaceAll("~", System.properties['user.home']))
|
||||
storePassword getEnvOrConfig('KEYSTORE_PASSWORD')
|
||||
keyAlias getEnvOrConfig('KEYSTORE_ALIAS')
|
||||
keyPassword getEnvOrConfig('KEYSTORE_KEY_PASSWORD')
|
||||
}
|
||||
}
|
||||
splits {
|
||||
abi {
|
||||
reset()
|
||||
@@ -326,26 +251,20 @@ android {
|
||||
universalApk true
|
||||
}
|
||||
}
|
||||
signingConfigs {
|
||||
debug {
|
||||
storeFile file('debug.keystore')
|
||||
storePassword 'android'
|
||||
keyAlias 'androiddebugkey'
|
||||
keyPassword 'android'
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
debug {
|
||||
applicationIdSuffix ".debug"
|
||||
debuggable true
|
||||
versionNameSuffix "-SNAPSHOT"
|
||||
resValue "string", "build_config_package", "im.status.ethereum"
|
||||
signingConfig signingConfigs.debug
|
||||
resValue "string", "build_config_package", "im.status.ethereum"
|
||||
}
|
||||
release {
|
||||
minifyEnabled enableProguardInReleaseBuilds
|
||||
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
||||
signingConfig null
|
||||
if (getEnvOrConfig('ANDROID_APK_SIGNED').toBoolean()) {
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
pr {
|
||||
initWith release
|
||||
@@ -385,9 +304,8 @@ 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'
|
||||
@@ -401,10 +319,11 @@ dependencies {
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -414,7 +333,6 @@ dependencies {
|
||||
|
||||
implementation 'androidx.multidex:multidex:2.0.1' // only needed if minSdkVersion is less than 21 (https://developer.android.com/studio/build/multidex)
|
||||
implementation project(':react-native-dialogs')
|
||||
implementation project(':react-native-blur')
|
||||
// Force using exact RN version instead of relying on gradle dependency resolution
|
||||
// https://docs.gradle.org/current/userguide/introduction_dependency_management.html#sec:dependency_resolution
|
||||
// NOTE: Uncomment if building RN from a fork
|
||||
@@ -422,25 +340,8 @@ 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.2.0'
|
||||
implementation 'com.facebook.fresco:animated-gif:2.2.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.0.0'
|
||||
implementation 'com.facebook.fresco:animated-gif:2.0.0'
|
||||
}
|
||||
|
||||
def getLocalNDKDir = { ->
|
||||
@@ -462,7 +363,7 @@ task hemroidBuild(type: Exec) {
|
||||
def localNdkDir = getLocalNDKDir()
|
||||
def ndkDir = System.env.ANDROID_NDK_ROOT
|
||||
if (localNdkDir != null) {
|
||||
ndkDir = localNdkDir
|
||||
ndkDir = localNdkDir
|
||||
}
|
||||
|
||||
def execPath = "$ndkDir/ndk-build"
|
||||
@@ -476,11 +377,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"
|
||||
}
|
||||
|
||||
@@ -64,15 +64,3 @@
|
||||
-dontwarn java.nio.file.*
|
||||
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
|
||||
-dontwarn okio.**
|
||||
|
||||
# fast-image
|
||||
|
||||
-keep public class com.dylanvann.fastimage.* {*;}
|
||||
-keep public class com.dylanvann.fastimage.** {*;}
|
||||
-keep public class * implements com.bumptech.glide.module.GlideModule
|
||||
-keep public class com.bumptech.glide.annotation.GlideModule
|
||||
-keep public class * extends com.bumptech.glide.module.AppGlideModule
|
||||
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
|
||||
**[] $VALUES;
|
||||
public *;
|
||||
}
|
||||
@@ -2,12 +2,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<!-- These are added by React Native for debug mode, but actually aren't needed in release mode -->
|
||||
<uses-permission tools:node="remove" android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||
<!-- 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"/>
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||
|
||||
<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>
|
||||
|
||||
@@ -17,34 +17,34 @@
|
||||
<uses-feature android:name="android.hardware.camera" />
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="28" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
|
||||
<uses-permission android:name="com.android.vending.BILLING" />
|
||||
|
||||
<!-- these permissions should be removed -->
|
||||
<!-- React Native unnecessary permissions (https://github.com/facebook/react-native/issues/5886) -->
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove"/>
|
||||
|
||||
<application
|
||||
tools:replace="android:allowBackup"
|
||||
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`-->
|
||||
<meta-data android:name="commitHash" android:value="${commitHash}"/>
|
||||
android:requestLegacyExternalStorage="true">
|
||||
<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>
|
||||
@@ -74,7 +74,8 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
|
||||
<service android:name="im.status.ethereum.pushnotifications.ForegroundService"></service>
|
||||
<service android:name="im.status.ethereum.module.ForegroundService"></service>
|
||||
<service android:name="im.status.ethereum.module.LocalNotificationsService" />
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.provider"
|
||||
|
||||
@@ -21,30 +21,23 @@ 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;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
|
||||
|
||||
import com.reactnativenavigation.NavigationActivity;
|
||||
import com.facebook.react.modules.core.PermissionListener;
|
||||
import androidx.core.splashscreen.SplashScreen;
|
||||
import com.facebook.react.ReactFragmentActivity;
|
||||
import com.facebook.react.ReactActivity;
|
||||
import com.facebook.react.modules.core.PermissionListener;
|
||||
import org.devio.rn.splashscreen.SplashScreen;
|
||||
|
||||
import java.util.Properties;
|
||||
import im.status.ethereum.module.StatusThreadPoolExecutor;
|
||||
import im.status.ethereum.MainApplication;
|
||||
|
||||
public class MainActivity extends NavigationActivity
|
||||
public class MainActivity extends ReactFragmentActivity
|
||||
implements ActivityCompat.OnRequestPermissionsResultCallback{
|
||||
|
||||
|
||||
@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();
|
||||
@@ -104,16 +97,6 @@ public class MainActivity extends NavigationActivity
|
||||
return intent;
|
||||
}
|
||||
|
||||
private void tryToEmit(String eventName, WritableMap event) {
|
||||
try {
|
||||
((MainApplication) getApplication()).getReactNativeHost()
|
||||
.getReactInstanceManager()
|
||||
.getCurrentReactContext()
|
||||
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
||||
.emit("url", event);
|
||||
} catch(Exception e) {/* we expect NPE on first start, which is OK because we have a fallback */}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewIntent(final Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
@@ -124,8 +107,18 @@ 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);
|
||||
|
||||
break;
|
||||
case Configuration.UI_MODE_NIGHT_NO:
|
||||
setTheme(R.style.LightTheme);
|
||||
break;
|
||||
default:
|
||||
setTheme(R.style.LightTheme);
|
||||
}
|
||||
// Make sure we get an Alert for every uncaught exceptions
|
||||
registerUncaughtExceptionHandler(MainActivity.this);
|
||||
|
||||
@@ -134,7 +127,7 @@ public class MainActivity extends NavigationActivity
|
||||
Log.v("RNBootstrap", "Available system memory "+getAvailableMemory(activityManager).availMem + ", maximum usable application memory " + activityManager.getLargeMemoryClass()+"M");
|
||||
|
||||
setSecureFlag();
|
||||
|
||||
SplashScreen.show(this, true);
|
||||
// NOTE: Try to not restore the state https://github.com/software-mansion/react-native-screens/issues/17
|
||||
super.onCreate(null);
|
||||
|
||||
@@ -174,24 +167,9 @@ public class MainActivity extends NavigationActivity
|
||||
@Override
|
||||
public void run() {
|
||||
System.loadLibrary("status-logs");
|
||||
|
||||
// when app is started but the Activity has been destroyed, the deep linking url event is
|
||||
// not emitted when coming back to foreground. This is a workaround. If the problem is
|
||||
// resolved in react-native this code should be removed
|
||||
if (getIntent().getData() != null) {
|
||||
WritableMap event = Arguments.createMap();
|
||||
event.putString("url", getIntent().getDataString());
|
||||
// on first start emit will (silently) fail, but the regular deep linking handler will work
|
||||
tryToEmit("url", event);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
splashScreen.setKeepOnScreenCondition(() -> keepSplash);
|
||||
|
||||
Handler handler = new Handler();
|
||||
handler.postDelayed(() -> keepSplash = false, SPLASH_DELAY);
|
||||
|
||||
StatusThreadPoolExecutor.getInstance().execute(r);
|
||||
}
|
||||
|
||||
@@ -200,7 +178,14 @@ public class MainActivity extends NavigationActivity
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of the main component registered from JavaScript.
|
||||
* This is used to schedule rendering of the component.
|
||||
*/
|
||||
@Override
|
||||
protected String getMainComponentName() {
|
||||
return "StatusIm";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
@@ -257,4 +242,14 @@ public class MainActivity extends NavigationActivity
|
||||
mPermissionListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReactActivityDelegate createReactActivityDelegate() {
|
||||
return new ReactActivityDelegate(this, getMainComponentName()) {
|
||||
@Override
|
||||
protected ReactRootView createRootView() {
|
||||
return new RNGestureHandlerEnabledRootView(MainActivity.this);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,28 @@
|
||||
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;
|
||||
|
||||
import com.aakashns.reactnativedialogs.ReactNativeDialogsPackage;
|
||||
import com.facebook.react.ReactApplication;
|
||||
import cl.json.RNSharePackage;
|
||||
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.soloader.SoLoader;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.modules.network.OkHttpClientProvider;
|
||||
import com.reactnativecommunity.blurview.BlurViewPackage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import im.status.ethereum.keycard.RNStatusKeycardPackage;
|
||||
import im.status.ethereum.module.StatusPackage;
|
||||
import im.status.ethereum.pushnotifications.PushNotificationPackage;
|
||||
import im.status.ethereum.StatusOkHttpClientFactory;
|
||||
|
||||
import com.facebook.react.bridge.JSIModulePackage;
|
||||
import com.swmansion.reanimated.ReanimatedJSIModulePackage;
|
||||
public class MainApplication extends MultiDexApplication implements ReactApplication {
|
||||
|
||||
public class MainApplication extends NavigationApplication {
|
||||
|
||||
private final ReactNativeHost mReactNativeHost = new NavigationReactNativeHost(this) {
|
||||
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
|
||||
@Override
|
||||
public boolean getUseDeveloperSupport() {
|
||||
return BuildConfig.DEBUG;
|
||||
@@ -39,7 +30,6 @@ public class MainApplication extends NavigationApplication {
|
||||
|
||||
@Override
|
||||
protected List<ReactPackage> getPackages() {
|
||||
|
||||
StatusPackage statusPackage = new StatusPackage(RootUtil.isDeviceRooted());
|
||||
|
||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||
@@ -47,7 +37,6 @@ public class MainApplication extends NavigationApplication {
|
||||
packages.add(new ReactNativeDialogsPackage());
|
||||
packages.add(new RNStatusKeycardPackage());
|
||||
packages.add(new PushNotificationPackage());
|
||||
packages.add(new BlurViewPackage());
|
||||
return packages;
|
||||
}
|
||||
|
||||
@@ -55,34 +44,19 @@ public class MainApplication extends NavigationApplication {
|
||||
protected String getJSMainModuleName() {
|
||||
return "index";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSIModulePackage getJSIModulePackage() {
|
||||
return new ReanimatedJSIModulePackage();
|
||||
}
|
||||
};
|
||||
|
||||
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());
|
||||
|
||||
SoLoader.init(this, /* native exopackage */ false);
|
||||
WebView.setWebContentsDebuggingEnabled(BuildConfig.DEBUG_WEBVIEW == "1");
|
||||
//initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||
}
|
||||
/**
|
||||
* Loads Flipper in React Native templates. Call this in the onCreate method with something like
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
package im.status.ethereum;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.facebook.react.modules.network.OkHttpClientFactory;
|
||||
import com.facebook.react.modules.network.OkHttpClientProvider;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.tls.HandshakeCertificates;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.lang.RuntimeException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.cert.CertificateFactory;
|
||||
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 = "";
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 |
|
After Width: | Height: | Size: 482 B |
|
Before Width: | Height: | Size: 272 B |
|
Before Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 975 B |
|
Before Width: | Height: | Size: 495 B |
|
Before Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 826 B |
|
Before Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 826 B |
|
Before Width: | Height: | Size: 4.2 KiB |
@@ -1,21 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/backgroundColor">
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/lottie"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="fitCenter"
|
||||
android:adjustViewBounds="true"
|
||||
app:lottie_rawRes="@raw/launching_animation"
|
||||
app:lottie_autoPlay="true"
|
||||
app:lottie_loop="true"
|
||||
/>
|
||||
</FrameLayout>
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/launch_logo"/>
|
||||
|
||||
</FrameLayout>
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="alert_background">#141414</color>
|
||||
<color name="alert_text">#ffffff</color>
|
||||
</resources>
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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>
|
||||
@@ -8,7 +8,6 @@
|
||||
<item name="android:forceDarkAllowed">true</item>
|
||||
<item name="android:windowTranslucentStatus">false</item>
|
||||
<item name="android:statusBarColor">?attr/backgroundColor</item>
|
||||
<item name="android:alertDialogTheme">@style/AlertDialogTheme</item>
|
||||
</style>
|
||||
|
||||
<style name="LightTheme" parent="AppTheme">
|
||||
@@ -22,10 +21,4 @@
|
||||
<item name="backgroundColor">#000000</item>
|
||||
<item name="android:windowLightStatusBar">false</item>
|
||||
</style>
|
||||
|
||||
<style name="AlertDialogTheme" parent="Theme.AppCompat.DayNight.Dialog.Alert">
|
||||
<item name="android:textColor">@color/alert_text</item>
|
||||
<item name="android:textColorPrimary">@color/alert_text</item>
|
||||
<item name="android:background">@color/alert_background</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
@@ -3,7 +3,5 @@
|
||||
|
||||
<!-- These are added by React Native for debug mode, but actually aren't needed in release mode -->
|
||||
<uses-permission tools:node="remove" android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||
<!-- 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"/>
|
||||
|
||||
</manifest>
|
||||
|
||||
@@ -3,7 +3,5 @@
|
||||
|
||||
<!-- These are added by React Native for debug mode, but actually aren't needed in release mode -->
|
||||
<uses-permission tools:node="remove" android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||
<!-- 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"/>
|
||||
|
||||
</manifest>
|
||||
</manifest>
|
||||
@@ -1,41 +1,25 @@
|
||||
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 {
|
||||
RNNKotlinVersion = "1.6.20"
|
||||
RNGH_kotlinVersion = "1.6.20"
|
||||
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 {
|
||||
repositories {
|
||||
flatDir { dirs "libs", "${rootDir}/app/libs" }
|
||||
google()
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${project.ext.kotlinPluginVersion}"
|
||||
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.
|
||||
}
|
||||
@@ -58,38 +42,27 @@ subprojects {
|
||||
|
||||
allprojects {
|
||||
beforeEvaluate {
|
||||
if (System.env.STATUS_GO_ANDROID_LIBDIR == null || System.env.STATUS_GO_ANDROID_LIBDIR == "") {
|
||||
throw new GradleException('STATUS_GO_ANDROID_LIBDIR environment variable is not valid!')
|
||||
}
|
||||
if (System.env.STATUS_GO_ANDROID_LIBDIR == null || System.env.STATUS_GO_ANDROID_LIBDIR == "") {
|
||||
throw new GradleException('STATUS_GO_ANDROID_LIBDIR environment variable is not valid!')
|
||||
}
|
||||
}
|
||||
|
||||
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") }
|
||||
// Android JSC is installed from npm
|
||||
maven { url("$rootDir/../node_modules/jsc-android/dist") }
|
||||
// For geth, function, and status-go
|
||||
flatDir { dirs "libs", System.env.STATUS_GO_ANDROID_LIBDIR }
|
||||
// Everything Else
|
||||
maven {
|
||||
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
||||
url("$rootDir/../node_modules/react-native/android")
|
||||
}
|
||||
maven {
|
||||
// Android JSC is installed from npm
|
||||
url("$rootDir/../node_modules/jsc-android/dist")
|
||||
}
|
||||
|
||||
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'}
|
||||
jcenter()
|
||||
|
||||
// for geth, function, and status-go
|
||||
flatDir { dirs "libs", System.env.STATUS_GO_ANDROID_LIBDIR }
|
||||
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
|
||||
compileSdkVersion=29
|
||||
targetSdkVersion=29
|
||||
buildToolsVersion=29.0.2
|
||||
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.3
|
||||
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
@@ -43,20 +42,12 @@ KEYSTORE_KEY_PASSWORD=password
|
||||
ANDROID_ABI_SPLIT=false
|
||||
# Some platforms are excluded though
|
||||
ANDROID_ABI_INCLUDE=armeabi-v7a;arm64-v8a;x86
|
||||
# F-Droid builds need to be unsigned
|
||||
ANDROID_APK_SIGNED=true
|
||||
|
||||
org.gradle.jvmargs=-Xmx8704M
|
||||
|
||||
versionCode=9999
|
||||
commitHash=unknown
|
||||
|
||||
# Flipper
|
||||
FLIPPER_VERSION=0.54.0
|
||||
|
||||
|
||||
|
||||
# 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_VERSION=0.35.0
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
pluginManagement {
|
||||
include ':react-native-share'
|
||||
project(':react-native-share').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-share/android')
|
||||
repositories {
|
||||
mavenLocal() // Let's prioritize local Maven repos so that Nix can provide them offline
|
||||
gradlePluginPortal()
|
||||
@@ -18,12 +16,3 @@ include ':react-native-status'
|
||||
project(':react-native-status').projectDir = new File(rootProject.projectDir, '../modules/react-native-status/android')
|
||||
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,24 +0,0 @@
|
||||
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',
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
{
|
||||
"variables": {
|
||||
"module_name%": "status_nodejs_addon",
|
||||
"module_path%": "./lib/binding/"
|
||||
},
|
||||
"targets": [{
|
||||
"target_name": "<(module_name)",
|
||||
"sources": [
|
||||
"./modules/react-native-status/nodejs/status.cpp"
|
||||
],
|
||||
"xcode_settings": {
|
||||
"MACOSX_DEPLOYMENT_TARGET": "10.7"
|
||||
},
|
||||
"libraries": [
|
||||
"<!(pwd)/result/libstatus.a"
|
||||
],
|
||||
"conditions": [
|
||||
["OS=='mac'", {
|
||||
"libraries": [
|
||||
"-framework IOKit",
|
||||
"-framework CoreFoundation",
|
||||
"-framework CoreServices",
|
||||
"-framework Security"
|
||||
]
|
||||
}]
|
||||
]
|
||||
}, {
|
||||
"target_name": "action_after_build",
|
||||
"type": "none",
|
||||
"dependencies": ["<(module_name)"],
|
||||
"copies": [
|
||||
{
|
||||
"files": [ "<(PRODUCT_DIR)/<(module_name).node" ],
|
||||
"destination": "<(module_path)"
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
||||
@@ -1,15 +1,12 @@
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
library 'status-react-jenkins@v1.2.8'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux && x86_64 && nix-2.11' }
|
||||
agent { label 'linux' }
|
||||
|
||||
options {
|
||||
timestamps()
|
||||
/* Prevent Jenkins jobs from running forever */
|
||||
timeout(time: 30, unit: 'MINUTES')
|
||||
timeout(time: 20, unit: 'MINUTES')
|
||||
/* Limit builds retained */
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '10',
|
||||
@@ -17,11 +14,7 @@ pipeline {
|
||||
artifactNumToKeepStr: '10',
|
||||
))
|
||||
/* Allows combined build to copy */
|
||||
copyArtifactPermission('/status-mobile/*')
|
||||
/* Abort old PR builds. */
|
||||
disableConcurrentBuilds(
|
||||
abortPrevious: isPRBuild
|
||||
)
|
||||
copyArtifactPermission('/status-react/*')
|
||||
}
|
||||
|
||||
parameters {
|
||||
@@ -36,29 +29,59 @@ pipeline {
|
||||
LANG = "en_US.UTF-8"
|
||||
LC_ALL = "en_US.UTF-8"
|
||||
LANGUAGE = "en_US.UTF-8"
|
||||
TARGET = "android${utils.isE2EBuild() ? "-e2e" : ""}"
|
||||
TARGET = 'android'
|
||||
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.symlinkEnv()
|
||||
println("Build Number: ${utils.genBuildNumber()}")
|
||||
btype = utils.getBuildType()
|
||||
print "Running ${btype} build!"
|
||||
jenkins.abortPreviousRunningBuilds()
|
||||
/* Cleanup and Prep */
|
||||
commonPrep(btype)
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Bundle') {
|
||||
steps {
|
||||
script { apks = android.bundle() }
|
||||
}
|
||||
}
|
||||
stage('Sign') {
|
||||
steps {
|
||||
script { apks = android.sign(apks) }
|
||||
stage('Parallel Assemble') {
|
||||
parallel {
|
||||
stage('Checks') { stages {
|
||||
stage('Lint') {
|
||||
steps {
|
||||
script {
|
||||
/* We want the build result to be uploaded */
|
||||
catchError(
|
||||
message: 'Linting check failed!',
|
||||
buildResult: 'FAILURE',
|
||||
stageResult: 'FAILURE'
|
||||
) {
|
||||
sh 'make lint'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Tests') {
|
||||
steps {
|
||||
script {
|
||||
sh 'make test'
|
||||
}
|
||||
}
|
||||
}
|
||||
} }
|
||||
stage('Build') { stages {
|
||||
stage('Bundle') {
|
||||
steps {
|
||||
script { apks = android.bundle() }
|
||||
}
|
||||
}
|
||||
} }
|
||||
}
|
||||
}
|
||||
stage('Parallel Upload') {
|
||||
@@ -69,22 +92,37 @@ pipeline {
|
||||
} }
|
||||
}
|
||||
stage('Upload') {
|
||||
steps { script {
|
||||
def urls = apks.collect { s3.uploadArtifact(it) }
|
||||
if (urls.size() > 1) { /* Return only the universal APK. */
|
||||
env.PKG_URL = urls.find { it.contains('universal') }
|
||||
} else { /* If no universal is available pick first. */
|
||||
env.PKG_URL = urls.first()
|
||||
steps {
|
||||
script {
|
||||
def urls = apks.collect { s3.uploadArtifact(it) }
|
||||
/* 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 */
|
||||
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()
|
||||
}
|
||||
}
|
||||
jenkins.setBuildDesc(APK: env.PKG_URL)
|
||||
} }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Cleanup') {
|
||||
steps {
|
||||
sh 'make purge'
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
success { script { github.notifyPR(true) } }
|
||||
failure { script { github.notifyPR(false) } }
|
||||
always { sh 'make purge' }
|
||||
always { sh 'make _fix-node-perms' }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-react-jenkins@v1.2.8'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
@@ -8,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',
|
||||
@@ -18,24 +16,10 @@ pipeline {
|
||||
))
|
||||
}
|
||||
|
||||
/* WARNING: Defining parameters here with the ?: trick causes them to remember last value. */
|
||||
parameters {
|
||||
choice(
|
||||
name: 'BUILD_TYPE',
|
||||
description: 'Makefile target to build. Optional Parameter.',
|
||||
choices: genChoices(params.BUILD_TYPE, ['manual', 'nightly', 'release', 'pr', 'e2e']),
|
||||
)
|
||||
booleanParam(
|
||||
name: 'PUBLISH',
|
||||
description: 'Trigger publishing of build results for nightly or release.',
|
||||
defaultValue: getPublishDefault(params.PUBLISH),
|
||||
)
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Prep') {
|
||||
steps { script {
|
||||
println("Current JOB: ${env.JOB_NAME}")
|
||||
println "Current JOB: ${env.JOB_NAME}"
|
||||
/* just for a shorter access */
|
||||
btype = utils.getBuildType()
|
||||
} }
|
||||
@@ -43,16 +27,13 @@ pipeline {
|
||||
stage('Build') {
|
||||
parallel {
|
||||
stage('iOS') { steps { script {
|
||||
ios = jenkins.Build('status-mobile/platforms/ios')
|
||||
ios = jenkins.Build('status-react/combined/mobile-ios')
|
||||
} } }
|
||||
stage('Android') { steps { script {
|
||||
apk = jenkins.Build('status-mobile/platforms/android')
|
||||
apk = jenkins.Build('status-react/combined/mobile-android')
|
||||
} } }
|
||||
stage('Android e2e') { steps { script {
|
||||
apke2e = jenkins.Build('status-mobile/platforms/android-e2e')
|
||||
} } }
|
||||
stage('Tests') { steps { script {
|
||||
jenkins.Build('status-mobile/platforms/tests')
|
||||
apke2e = jenkins.Build('status-react/combined/mobile-android-e2e')
|
||||
} } }
|
||||
}
|
||||
}
|
||||
@@ -63,7 +44,7 @@ pipeline {
|
||||
//jenkins.copyArts(iose2e)
|
||||
jenkins.copyArts(apk)
|
||||
jenkins.copyArts(apke2e)
|
||||
sha = "pkg/${utils.pkgFilename(ext: 'sha256')}"
|
||||
sha = "pkg/${utils.pkgFilename('sha256')}"
|
||||
dir('pkg') {
|
||||
/* generate sha256 checksums for upload */
|
||||
sh "sha256sum * | tee ../${sha}"
|
||||
@@ -78,60 +59,37 @@ pipeline {
|
||||
/* mobile */
|
||||
Apk: utils.pkgUrl(apk), Apke2e: utils.pkgUrl(apke2e),
|
||||
iOS: utils.pkgUrl(ios), /*iOSe2e: utils.pkgUrl(iose2e),*/
|
||||
Diawi: utils.getEnv(ios, 'DIAWI_URL'),
|
||||
Diawi: utils.utils.getEnv(ios, 'DIAWI_URL'),
|
||||
/* upload the sha256 checksums file too */
|
||||
SHA: s3.uploadArtifact(sha),
|
||||
]
|
||||
/* add URLs to the build description */
|
||||
jenkins.setBuildDesc(urls)
|
||||
/* Create JSON file with newest build URLs */
|
||||
switch (btype) {
|
||||
/* legacy naming, should have named it nightly.json */
|
||||
case 'nightly': s3.updateBucketJSON(urls, 'latest.json'); break
|
||||
}
|
||||
} }
|
||||
}
|
||||
stage('Publish') {
|
||||
when { expression { params.PUBLISH } }
|
||||
steps { script {
|
||||
switch (btype) {
|
||||
case 'nightly':
|
||||
/* Create JSON file with newest build URLs */
|
||||
s3.updateBucketJSON(urls, 'latest.json');
|
||||
build(job: 'website/status.im', wait: false);
|
||||
break;
|
||||
case 'release':
|
||||
github.publishReleaseFiles(repo: 'status-mobile');
|
||||
break;
|
||||
case 'nightly': build(job: 'misc/status.im', wait: false); break
|
||||
case 'release': github.publishReleaseMobile(); break
|
||||
}
|
||||
} }
|
||||
}
|
||||
stage('Run e2e') {
|
||||
when { expression { btype == 'nightly' && params.PUBLISH } }
|
||||
when { expression { btype == 'nightly' } }
|
||||
steps { script {
|
||||
e2eApk = utils.getEnv(apke2e, 'SAUCE_URL')
|
||||
build(
|
||||
job: 'status-mobile/e2e/status-app-nightly',
|
||||
parameters: [string(name: 'APK_URL', value: e2eApk)],
|
||||
job: 'end-to-end-tests/status-app-nightly',
|
||||
parameters: [string(name: 'APK_NAME', value: e2eApk)],
|
||||
wait: false
|
||||
)
|
||||
} }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper that generates list of available choices for a parameter
|
||||
* but re-orders them based on the currently set value. First is default. */
|
||||
def List genChoices(String previousChoice, List defaultChoices) {
|
||||
if (previousChoice == null) {
|
||||
return defaultChoices
|
||||
}
|
||||
choices = defaultChoices.minus(previousChoice)
|
||||
choices.add(0, previousChoice)
|
||||
return choices
|
||||
}
|
||||
|
||||
/* Helper that makes PUBLISH default to 'false' unless:
|
||||
* - The build is for a release branch
|
||||
* - A user explicitly specified a value
|
||||
* Since release builds create and re-create GitHub drafts every time. */
|
||||
def Boolean getPublishDefault(Boolean previousValue) {
|
||||
if (env.JOB_NAME.startsWith('status-mobile/release')) { return true }
|
||||
if (previousValue != null) { return previousValue }
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
library 'status-react-jenkins@v1.2.8'
|
||||
|
||||
pipeline {
|
||||
agent { label 'macos && arm64 && nix-2.11 && xcode-14.3' }
|
||||
agent { label 'macos-xcode-11.5' }
|
||||
|
||||
parameters {
|
||||
string(
|
||||
@@ -25,11 +22,7 @@ pipeline {
|
||||
artifactNumToKeepStr: '10',
|
||||
))
|
||||
/* Allows combined build to copy */
|
||||
copyArtifactPermission('/status-mobile/*')
|
||||
/* Abort old PR builds. */
|
||||
disableConcurrentBuilds(
|
||||
abortPrevious: isPRBuild
|
||||
)
|
||||
copyArtifactPermission('/status-react/*')
|
||||
}
|
||||
|
||||
environment {
|
||||
@@ -48,24 +41,51 @@ pipeline {
|
||||
stage('Prep') {
|
||||
steps {
|
||||
script {
|
||||
utils.symlinkEnv()
|
||||
println("Build Number: ${utils.genBuildNumber()}")
|
||||
btype = utils.getBuildType()
|
||||
print "Running ${btype} build!"
|
||||
jenkins.abortPreviousRunningBuilds()
|
||||
/* Cleanup and Prep */
|
||||
commonPrep(btype)
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('JSBundle') {
|
||||
steps {
|
||||
script { ios.jsbundle() }
|
||||
}
|
||||
}
|
||||
stage('Bundle') {
|
||||
steps {
|
||||
script { api = ios.bundle() }
|
||||
}
|
||||
post {
|
||||
failure {
|
||||
archiveArtifacts 'ios/logs/*'
|
||||
}
|
||||
stage('Parallel Assemble') {
|
||||
parallel {
|
||||
stage('Checks') { stages {
|
||||
stage('Lint') {
|
||||
steps {
|
||||
script {
|
||||
/* We want the build result to be uploaded */
|
||||
catchError(
|
||||
message: 'Linting check failed!',
|
||||
buildResult: 'FAILURE',
|
||||
stageResult: 'FAILURE'
|
||||
) {
|
||||
sh 'make lint'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Tests') {
|
||||
steps {
|
||||
script {
|
||||
sh 'make test'
|
||||
}
|
||||
}
|
||||
}
|
||||
} }
|
||||
stage('Build') { stages {
|
||||
stage('JSBundle') {
|
||||
steps {
|
||||
script { ios.jsbundle() }
|
||||
}
|
||||
}
|
||||
stage('Bundle') {
|
||||
steps {
|
||||
script { api = ios.bundle() }
|
||||
}
|
||||
}
|
||||
} }
|
||||
}
|
||||
}
|
||||
stage('Parallel Upload') {
|
||||
@@ -76,19 +96,31 @@ pipeline {
|
||||
}
|
||||
}
|
||||
stage('Upload') {
|
||||
when { expression { !utils.isReleaseBuild() } }
|
||||
steps { script {
|
||||
env.DIAWI_URL = ios.uploadToDiawi()
|
||||
env.PKG_URL = env.DIAWI_URL
|
||||
jenkins.setBuildDesc(IPA: env.PKG_URL)
|
||||
} }
|
||||
steps {
|
||||
script {
|
||||
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 {
|
||||
env.DIAWI_URL = ios.uploadToDiawi()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Cleanup') {
|
||||
steps {
|
||||
sh 'make watchman-clean'
|
||||
sh 'make purge'
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
success { script { github.notifyPR(true) } }
|
||||
failure { script { github.notifyPR(false) } }
|
||||
always { sh 'make purge' }
|
||||
always { sh 'make _fix-node-perms' }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,16 @@
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-react-jenkins@v1.2.8'
|
||||
|
||||
pipeline {
|
||||
agent { label params.AGENT_LABEL }
|
||||
|
||||
parameters {
|
||||
string(
|
||||
name: 'NIX_CACHE_HOST',
|
||||
description: 'FQDN of Nix binary cache host.',
|
||||
defaultValue: params.NIX_CACHE_HOST ?: 'cache-01.do-ams3.nix.ci.statusim.net'
|
||||
)
|
||||
string(
|
||||
name: 'NIX_CACHE_USER',
|
||||
description: 'Username for Nix binary cache host.',
|
||||
defaultValue: params.NIX_CACHE_USER ?: 'nix-cache'
|
||||
)
|
||||
}
|
||||
|
||||
environment {
|
||||
/* See nix/README.md */
|
||||
NIX_IGNORE_SYMLINK_STORE = 1
|
||||
/* we source .bash_profile to be able to use nix-store */
|
||||
NIX_SSHOPTS = "-o StrictHostKeyChecking=no source .profile;"
|
||||
NIX_SSHOPTS = "-o StrictHostKeyChecking=no source .bash_profile;"
|
||||
/* where our /nix/store is hosted */
|
||||
NIX_CACHE_USER = 'nix-cache'
|
||||
NIX_CACHE_HOST = 'master-01.do-ams3.ci.misc.statusim.net'
|
||||
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
|
||||
}
|
||||
|
||||
@@ -39,7 +29,7 @@ pipeline {
|
||||
stages {
|
||||
stage('Setup') {
|
||||
steps { script {
|
||||
nix.shell('nix-env -i openssh', sandbox: false, pure: false)
|
||||
nix.shell('nix-env -i openssh', pure: false)
|
||||
/* some build targets don't build on MacOS */
|
||||
uname = sh(script: 'uname', returnStdout: true)
|
||||
} }
|
||||
@@ -61,9 +51,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
|
||||
@@ -72,7 +63,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,
|
||||
@@ -83,7 +74,7 @@ pipeline {
|
||||
}
|
||||
stage('Build nix shell deps') {
|
||||
steps { script {
|
||||
/* Build/fetch deps required to start default Nix shell. */
|
||||
/* build/fetch things required to instantiate shell.nix for TARGET=all */
|
||||
nix.build(
|
||||
attr: 'shells.default.buildInputs',
|
||||
sandbox: false,
|
||||
@@ -96,9 +87,8 @@ pipeline {
|
||||
sshagent(credentials: ['nix-cache-ssh']) {
|
||||
nix.shell("""
|
||||
find /nix/store/ -mindepth 1 -maxdepth 1 -type d \
|
||||
-not -name '*.links' -and -not -name '*-status-mobile-*' \
|
||||
| xargs nix copy \
|
||||
--to ssh-ng://${params.NIX_CACHE_USER}@${params.NIX_CACHE_HOST}
|
||||
-not -name '*.links' -and -not -name '*-status-react-*' \
|
||||
| xargs nix-copy-closure -v --to ${NIX_CACHE_USER}@${NIX_CACHE_HOST}
|
||||
""",
|
||||
pure: false
|
||||
)
|
||||
@@ -1,85 +0,0 @@
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux && x86_64 && nix-2.11' }
|
||||
|
||||
options {
|
||||
timestamps()
|
||||
/* Prevent Jenkins jobs from running forever */
|
||||
timeout(time: 15, unit: 'MINUTES')
|
||||
/* Limit builds retained */
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '10',
|
||||
daysToKeepStr: '20',
|
||||
artifactNumToKeepStr: '10',
|
||||
))
|
||||
/* Abort old PR builds. */
|
||||
disableConcurrentBuilds(
|
||||
abortPrevious: isPRBuild
|
||||
)
|
||||
}
|
||||
|
||||
parameters {
|
||||
string(
|
||||
name: 'BUILD_TYPE',
|
||||
description: 'Specify build type. Values: pr / e2e / nightly / release',
|
||||
defaultValue: 'pr',
|
||||
)
|
||||
}
|
||||
|
||||
environment {
|
||||
LANG = "en_US.UTF-8"
|
||||
LC_ALL = "en_US.UTF-8"
|
||||
LANGUAGE = "en_US.UTF-8"
|
||||
TARGET = 'tests'
|
||||
BUILD_ENV = 'prod'
|
||||
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
|
||||
LOG_FILE = utils.pkgFilename(ext: 'log', arch: 'tests')
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Checks') {
|
||||
parallel {
|
||||
stage('Lint') {
|
||||
steps {
|
||||
sh """#!/bin/bash
|
||||
set -eo pipefail
|
||||
make lint 2>&1 | tee ${LOG_FILE}
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('Tests') {
|
||||
steps {
|
||||
sh """#!/bin/bash
|
||||
set -eo pipefail
|
||||
make test 2>&1 | tee -a ${LOG_FILE}
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Component Tests') {
|
||||
steps {
|
||||
sh """#!/bin/bash
|
||||
set -eo pipefail
|
||||
make component-test 2>&1 | tee -a ${LOG_FILE}
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('Upload') {
|
||||
steps {
|
||||
script {
|
||||
env.PKG_URL = s3.uploadArtifact(LOG_FILE)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
success { script { github.notifyPR(true) } }
|
||||
failure { script { github.notifyPR(false) } }
|
||||
always { sh 'make purge' }
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,11 @@ This folder contains files defininf [Jenkins pipelines](https://jenkins.io/doc/b
|
||||
|
||||
All `Jenkinsfile`s contain the following line:
|
||||
```groovy
|
||||
library 'status-jenkins-lib@master'
|
||||
library 'status-react-jenkins@master'
|
||||
```
|
||||
|
||||
Which loads the used methods - like `nix.shell()` - from a separate private repo:
|
||||
|
||||
https://github.com/status-im/status-jenkins-lib
|
||||
https://github.com/status-im/status-react-jenkins
|
||||
|
||||
This is done to improve security of our CI setup.
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
|
||||
pipeline {
|
||||
|
||||
agent { label 'linux' }
|
||||
|
||||
parameters {
|
||||
string(
|
||||
name: 'APK_URL',
|
||||
description: 'URL of APK uploaded to SauceLabs.',
|
||||
name: 'NETWORK',
|
||||
description: 'Name of test network to use.',
|
||||
defaultValue: 'ropsten',
|
||||
)
|
||||
string(
|
||||
name: 'KEYWORD_EXPRESSION',
|
||||
description: 'This will run tests which contain names that match the given string expression (Optional)',
|
||||
defaultValue: '',
|
||||
name: 'APK_NAME',
|
||||
description: 'Filename of APK uploaded to SauceLabs.',
|
||||
)
|
||||
}
|
||||
|
||||
@@ -20,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') {
|
||||
@@ -41,7 +27,6 @@ pipeline {
|
||||
}
|
||||
} }
|
||||
}
|
||||
|
||||
stage('Test') {
|
||||
steps {
|
||||
withCredentials([
|
||||
@@ -63,23 +48,17 @@ pipeline {
|
||||
credentialsId: 'infura-e2e-token',
|
||||
variable: 'WEB3_INFURA_PROJECT_ID'
|
||||
),
|
||||
file(
|
||||
credentialsId: "mobile-tests-eth-accounts",
|
||||
variable: 'TEST_ETH_ACCOUNTS_FILE'
|
||||
),
|
||||
]) {
|
||||
dir('test/appium/tests') {
|
||||
/* Provide Eth test accounts secrets. */
|
||||
sh 'cp -f $TEST_ETH_ACCOUNTS_FILE users.py'
|
||||
sh """
|
||||
python3 -m pytest \
|
||||
--numprocesses 4 \
|
||||
--numprocesses 15 \
|
||||
--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}
|
||||
-m "not upgrade" \
|
||||
--network=${params.NETWORK} \
|
||||
--apk=${params.APK_NAME}
|
||||
"""
|
||||
}
|
||||
}
|
||||
@@ -103,8 +82,5 @@ pipeline {
|
||||
)
|
||||
}
|
||||
}
|
||||
cleanup {
|
||||
sh 'make purge'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
|
||||
pipeline {
|
||||
|
||||
agent { label 'linux' }
|
||||
@@ -10,66 +8,42 @@ pipeline {
|
||||
description: 'Name of the branch to checkout and build.',
|
||||
defaultValue: 'develop',
|
||||
)
|
||||
string(
|
||||
name: 'NETWORK',
|
||||
description: 'Name of test network to use.',
|
||||
defaultValue: 'ropsten',
|
||||
)
|
||||
string(
|
||||
name: 'TEST_MARKERS',
|
||||
description: 'Marker expression for matching tests to run.',
|
||||
defaultValue: 'critical or high',
|
||||
)
|
||||
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)',
|
||||
defaultValue: '',
|
||||
)
|
||||
string(
|
||||
name: 'TR_CASE_IDS',
|
||||
description: 'IDs of the TestRail case, separated by a comma (Optional)',
|
||||
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') {
|
||||
@@ -77,20 +51,18 @@ pipeline {
|
||||
}
|
||||
} }
|
||||
}
|
||||
|
||||
stage('Test') {
|
||||
steps { script {
|
||||
currentBuild.displayName = "PR-${params.PR_ID}"
|
||||
/* for managing optional arguments */
|
||||
def extraPytestOpts = ''
|
||||
if (params.TR_CASE_IDS != '') {
|
||||
extraPytestOpts = "--run_testrail_ids='${params.TR_CASE_IDS}'"
|
||||
} else {
|
||||
extraPytestOpts = "-m \"${params.TEST_MARKERS}\""
|
||||
}
|
||||
|
||||
withCredentials([
|
||||
usernamePassword(
|
||||
credentialsId: 'status-im-auto',
|
||||
credentialsId: 'status-im-auto-token',
|
||||
usernameVariable: 'GIT_HUB_USER', /* ignored */
|
||||
passwordVariable: 'GIT_HUB_TOKEN'
|
||||
),
|
||||
@@ -112,22 +84,17 @@ pipeline {
|
||||
credentialsId: 'infura-e2e-token',
|
||||
variable: 'WEB3_INFURA_PROJECT_ID'
|
||||
),
|
||||
file(
|
||||
credentialsId: "mobile-tests-eth-accounts",
|
||||
variable: 'TEST_ETH_ACCOUNTS_FILE'
|
||||
),
|
||||
]) {
|
||||
dir('test/appium/tests') {
|
||||
/* Provide Eth test account secrets. */
|
||||
sh 'cp -f $TEST_ETH_ACCOUNTS_FILE users.py'
|
||||
sh """
|
||||
python3 -m pytest \
|
||||
--numprocesses 4 \
|
||||
--numprocesses 15 \
|
||||
--rerun_count=2 \
|
||||
--testrail_report=True \
|
||||
-k \"${params.KEYWORD_EXPRESSION}\" \
|
||||
--apk=${params.APK_URL ?: apk_path} \
|
||||
--build=PR-${params.PR_ID}-${utils.timestamp()} \
|
||||
-m "${params.TEST_MARKERS}" \
|
||||
--network=${params.NETWORK} \
|
||||
--apk=${params.APK_NAME} \
|
||||
--build=PR-${params.PR_ID} \
|
||||
--pr_number=${params.PR_ID} \
|
||||
${extraPytestOpts}
|
||||
"""
|
||||
@@ -136,9 +103,4 @@ pipeline {
|
||||
} }
|
||||
}
|
||||
}
|
||||
post {
|
||||
cleanup {
|
||||
sh 'make purge'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,20 @@
|
||||
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: 'NETWORK',
|
||||
description: 'Name of test network to use',
|
||||
defaultValue: 'ropsten',
|
||||
)
|
||||
string(
|
||||
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)',
|
||||
)
|
||||
string(
|
||||
name: 'KEYWORD_EXPRESSION',
|
||||
description: 'This will run tests which contain names that match the given string expression (Optional)',
|
||||
defaultValue: '',
|
||||
)
|
||||
string(
|
||||
name: 'TR_CASE_IDS',
|
||||
description: 'IDs of the TestRail case, separated by a comma (Optional)',
|
||||
defaultValue: '',
|
||||
name: 'APK_NAME_UPGRADE',
|
||||
description: 'Filename of APK of upgraded application (installed on top of base)',
|
||||
)
|
||||
}
|
||||
|
||||
@@ -31,17 +24,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') {
|
||||
@@ -49,14 +31,8 @@ pipeline {
|
||||
}
|
||||
} }
|
||||
}
|
||||
|
||||
stage('Test') {
|
||||
steps { script {
|
||||
/* for managing optional arguments */
|
||||
def extraPytestOpts = ''
|
||||
if (params.TR_CASE_IDS != '') {
|
||||
extraPytestOpts = "--run_testrail_ids='${params.TR_CASE_IDS}'"
|
||||
}
|
||||
steps {
|
||||
withCredentials([
|
||||
usernamePassword(
|
||||
credentialsId: 'test-rail-api',
|
||||
@@ -76,29 +52,22 @@ pipeline {
|
||||
credentialsId: 'infura-e2e-token',
|
||||
variable: 'WEB3_INFURA_PROJECT_ID'
|
||||
),
|
||||
file(
|
||||
credentialsId: "mobile-tests-eth-accounts",
|
||||
variable: 'TEST_ETH_ACCOUNTS_FILE'
|
||||
),
|
||||
]) {
|
||||
dir('test/appium/tests') {
|
||||
/* Provide Eth test accounts secrets. */
|
||||
sh 'cp -f $TEST_ETH_ACCOUNTS_FILE users.py'
|
||||
sh """
|
||||
python3 -m pytest \
|
||||
-m "upgrade" \
|
||||
-k \"${params.KEYWORD_EXPRESSION}\" \
|
||||
--numprocesses 4 \
|
||||
-m upgrade \
|
||||
--numprocesses 15 \
|
||||
--rerun_count=2 \
|
||||
--testrail_report=True \
|
||||
--apk=${params.APK_URL} \
|
||||
--apk_upgrade=${params.APK_URL_UPGRADE} \
|
||||
${extraPytestOpts}
|
||||
--network=${params.NETWORK} \
|
||||
--apk=${params.APK_NAME} \
|
||||
--apk_upgrade=${params.APK_NAME_UPGRADE}
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
} }
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
@@ -117,8 +86,5 @@ pipeline {
|
||||
)
|
||||
}
|
||||
}
|
||||
cleanup {
|
||||
sh 'make purge'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-react-jenkins@v1.2.8'
|
||||
|
||||
pipeline {
|
||||
agent { label 'macos' }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-react-jenkins@v1.2.8'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
@@ -38,7 +38,7 @@ pipeline {
|
||||
steps { script {
|
||||
withCredentials([
|
||||
string(
|
||||
credentialsId: 'google-play-api-key-json',
|
||||
credentialsId: 'SUPPLY_JSON_KEY_DATA',
|
||||
variable: 'GOOGLE_PLAY_JSON_KEY'
|
||||
),
|
||||
]) {
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/**
|
||||
* 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:
|
||||
*
|
||||
* Failed with exit code 1 (in target 'StatusImPR' from project 'StatusIm')
|
||||
**/
|
||||
|
||||
pipeline {
|
||||
agent {
|
||||
label params.HOST_LABEL
|
||||
}
|
||||
|
||||
triggers {
|
||||
/* Run daily at 2am */
|
||||
cron('H 2 * * *')
|
||||
}
|
||||
options {
|
||||
timestamps()
|
||||
/* Prevent Jenkins jobs from running forever */
|
||||
timeout(time: 5, unit: 'MINUTES')
|
||||
/* Limit builds retained */
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '20',
|
||||
))
|
||||
}
|
||||
|
||||
parameters {
|
||||
string(
|
||||
name: 'HOST_LABEL',
|
||||
description: 'Label of host to run on',
|
||||
/* Using startTimeInMillis to randomize which host gets the update. */
|
||||
defaultValue: "maci7-0${(currentBuild.startTimeInMillis % 3) + 1}",
|
||||
)
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Update') {
|
||||
steps {
|
||||
sh 'pod repo update'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
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'
|
||||
}
|
||||
}
|
||||
} }
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
# Description
|
||||
|
||||
This document describes how to update Status APK builds for the [F-Droid](https://f-droid.org/) Android application catalogue.
|
||||
|
||||
# Intro
|
||||
|
||||
In simplest terms F-Droid requires a YAML file that defines the steps necessary to create a universal unsigned APK build. This is achieved by submitting a new app versions into the `metadata/im.status.ethereum.yml` file in the [fdroiddata](https://gitlab.com/fdroid/fdroiddata) repository.
|
||||
|
||||
The app builds defined this way run on servers that generate the unsigned APKs using the [fdroidserver](https://gitlab.com/fdroid/fdroidserver) software. The [server setup](https://f-droid.org/en/docs/Build_Server_Setup/) is quite involved but is not necessary unless you want to run your own instance. Normally the applications defines in `fdroiddata` are built by servers maintained by [the F-Droid volunteers](https://f-droid.org/en/contribute/).
|
||||
|
||||
First release of Status app was merged in [fdroid/fdroiddata#7179](https://gitlab.com/fdroid/fdroiddata/-/merge_requests/7179).
|
||||
|
||||
# Adding New Versions
|
||||
|
||||
You can find our configuration file at [`metadata/im.status.ethereum.yml`](https://gitlab.com/fdroid/fdroiddata/-/blob/master/metadata/im.status.ethereum.yml)
|
||||
|
||||
The file defines all the necessary metadata like `SourceCode`, `Website`, or `License`, but the most important key is `Builds`, which looks like this:
|
||||
```yml
|
||||
Builds:
|
||||
- versionName: 1.4.1
|
||||
versionCode: 2020070112
|
||||
commit: cfb825a11b61d312af8cb5d36686af540c31f481
|
||||
sudo:
|
||||
- mkdir -m 0755 /nix
|
||||
- chown vagrant /nix
|
||||
init: ./nix/scripts/setup.sh
|
||||
output: ./result/app-release-unsigned.apk
|
||||
scanignore:
|
||||
- android/build.gradle
|
||||
scandelete:
|
||||
- ios
|
||||
build: make release-android BUILD_TYPE=release BUILD_NUMBER=2020070112 ANDROID_APK_SIGNED=false
|
||||
```
|
||||
It contains a list of objects defining each release of the application. In order to add a new release simply copy a previous release object and adjust the following values:
|
||||
|
||||
* `versionName` - String version like `1.4.1`
|
||||
* `versionCode` - Android `versionCode`. We use a timestamp generated by [a script](../scripts/version/gen_build_no.sh)
|
||||
* `commit` - Specific commit SHA1 from which the given release was built
|
||||
* `BUILD_NUMBER` in `build` step - Same value as `versionCode`
|
||||
|
||||
The `versionCode` should be the same as the one in build that was uplodade to Play Store. It can be found in the build logs or by using:
|
||||
```
|
||||
> apkanalyzer manifest version-code StatusIm-v1.4.1.apk
|
||||
2020070112
|
||||
```
|
||||
|
||||
At the bottom of the file you should also update the following keys:
|
||||
|
||||
* `CurrentVersion` - Same as the new `versionName` added
|
||||
* `CurrentVersionCode` - Same as the `versionCode` added
|
||||
|
||||
Then submit a merge request to the [fdroid/fdroiddata](https://gitlab.com/fdroid/fdroiddata) repository.
|
||||
|
||||
# Checking Builds
|
||||
|
||||
The simplest way to test if the app builds via F-Droid is to use the Docker image:
|
||||
https://gitlab.com/fdroid/docker-executable-fdroidserver
|
||||
|
||||
Which is available under `registry.gitlab.com/fdroid/docker-executable-fdroidserver:latest`.
|
||||
|
||||
Because we use Nix to build the mobile app we need to slightly modify the image with this `Dockerfile`:
|
||||
```Dockerfile
|
||||
FROM registry.gitlab.com/fdroid/docker-executable-fdroidserver:latest
|
||||
ARG BUILDER_UID=1000
|
||||
ENV BUILDER_USER=vagrant
|
||||
RUN useradd -u $BUILDER_UID $BUILDER_USER
|
||||
RUN mkdir -m 0755 /nix /home/$BUILDER_USER \
|
||||
&& chown -R $BUILDER_USER /nix /home/$BUILDER_USER
|
||||
```
|
||||
Build it using:
|
||||
```
|
||||
docker build --build-arg=BUILDER_UID=$UID -t statusteam/docker-executable-fdroidserver:latest .
|
||||
```
|
||||
Then clone the [fdroiddata](https://gitlab.com/fdroid/fdroiddata) and [fdroidserver](https://gitlab.com/fdroid/fdroidserver) repos and use it to test the build of a specific Status Android app version: `1.4.1`
|
||||
```
|
||||
docker run --rm \
|
||||
-u $UID:$GID \
|
||||
-v $(pwd)/nix:/nix \
|
||||
-v $(pwd)/fdroiddata:/repo \
|
||||
-v $(pwd)/fdroidserver:/fdroidserver \
|
||||
statusteam/docker-executable-fdroidserver:latest \
|
||||
build im.status.ethereum:1.4.1
|
||||
```
|
||||
We have to create a user and specify the UID because Nix cannot run as `root` and that is the default user for the F-Droid Docker image. By adding our own user and setting the UID we also make it possible to mount folders like `fdroiddata` and `fdroidserver`.
|
||||
|
||||
You can specify a `--vebose` flag for `build` command for additional information.
|
||||
|
||||
You should also run `lint im.status.ethereum` to verify the YAML format is correct.
|
||||
|
||||
# Details
|
||||
|
||||
The original research was done in [#8512](https://github.com/status-im/status-react/issues/8512).
|
||||
|
||||
Normally F-Droid server wants to run Gradle itself, but we do not specify the `gradle` key in order to run `make release-android` ourselves in `build` step.
|
||||
@@ -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"`.
|
||||
@@ -1,53 +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)
|
||||
|
||||
|
||||
## 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)
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
# Codebase Structure and Guidelines
|
||||
# Codebase Strucuture and Guidelines
|
||||
|
||||
As of Nov/2022, we're starting to document and migrate the codebase to [new
|
||||
guidelines](new-guidelines.md), which will supersede some of the guidelines in
|
||||
this document.
|
||||
|
||||
## Starting the app
|
||||
|
||||
@@ -57,6 +54,7 @@ Core namespace must only contain functions that can be called outside of the mod
|
||||
|
||||
### db.cljs
|
||||
|
||||
- must contain specs for the app-db subpart the module modifies
|
||||
- must contain getter and setter functions used by fx producing functions and subscriptions
|
||||
- db logic called by other modules
|
||||
|
||||
@@ -74,11 +72,24 @@ These guidelines make db.cljs namespaces the place to go when making changes to
|
||||
|
||||
### Events
|
||||
|
||||
- all events must be defined in the `core.cljs` namespaces
|
||||
- events must always be declared with `fx/defn` macro
|
||||
- all events must be defined in the single `status-im.events` namespace which can be considered as an index of everything going on in the app
|
||||
- events must always be declared with `register-handler-fx`, no `register-handler-db`
|
||||
- events must never use the `trim-v` interceptor
|
||||
- events must only contain a function call defined in a module
|
||||
```clojure
|
||||
(handlers/register-handler-fx
|
||||
:notifications/handle-push-notification-open
|
||||
(fn [cofx [_ event]]
|
||||
(notifications/handle-push-notification-open event cofx)))
|
||||
```
|
||||
- events must use synthetic namespaces:
|
||||
|
||||
- `:module.ui/` for user triggered events
|
||||
- `:module.callback/` for callback events, which are events bringing back the result of an fx to the event loop, the name of the event should end with `-success` or `-error` most of the time. Other possibilities can be `-granted`, `-denied` for instance.
|
||||
- `:module/` for internal events, examples are time based events marked `-timed-out`, external changes marked `-changed` or reception of external events marked `-received`.
|
||||
|
||||
## Testing flow
|
||||
- All PRs automatically go to "REVIEW" column on [Pipeline for QA](https://github.com/status-im/status-mobile/projects/7) project on Github. This is our main board for QA / devs interaction
|
||||
- All PRs automatically go to "REVIEW" column on [Pipeline for QA](https://github.com/status-im/status-react/projects/7) project on Github. This is our main board for QA / devs interaction
|
||||
- After the PR gets at least 1 approval, it should be moved to "E2E Tests" column. Some PRs may need approvals from more than one person.
|
||||
- Critical path tests are automatically run for all PRs in "E2E Tests" column.
|
||||
- If E2E tests pass:
|
||||
@@ -89,18 +100,36 @@ These guidelines make db.cljs namespaces the place to go when making changes to
|
||||
- If issues - label 'TESTED-ISSUES' and comment from QA with bugs.
|
||||
- After fix and/or discussion the process is repeated.
|
||||
|
||||
- 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.
|
||||
- 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.
|
||||
The app relies on system locale to select a language from the [list of supported languages](https://github.com/status-im/status-react/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-react/blob/develop/STARTING_GUIDE.md#configure-gpg-keys-for-signing-commits).
|
||||
|
||||
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).
|
||||
|
||||
Once your commits are verified and PR approved, you can run the script like so:
|
||||
Once your commits are verfied and PR approved, you can run the script like so:
|
||||
|
||||
```bash
|
||||
$ git checkout develop
|
||||
|
||||
@@ -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'
|
||||
```
|
||||
@@ -49,7 +49,7 @@ decentralization and security.
|
||||
Q2 we will provide two ways of accessing the Ethereum network:
|
||||
|
||||
- Upstream RPC with Infura (default)
|
||||
- Custom upstream node (https://github.com/status-im/status-mobile/issues/3994)
|
||||
- Custom upstream node (https://github.com/status-im/status-react/issues/3994)
|
||||
|
||||
From a decentralization point of view we need the latter before we can release
|
||||
the beta.
|
||||
|
||||
@@ -20,11 +20,11 @@ chance to talk to strangers and it is open by default.
|
||||
Whether group chats are in scope or not has been a recurring discussing and a
|
||||
lot of effort has been wasted related to this.
|
||||
|
||||
There are currently a lot of outstanding regressions related to group chat: https://github.com/status-im/status-mobile/labels/group-chat Additionally, since group chats are private the encryption and security of those are generally harder than 1-1 and public chat.
|
||||
There are currently a lot of outstanding regressions related to group chat: https://github.com/status-im/status-react/labels/group-chat Additionally, since group chats are private the encryption and security of those are generally harder than 1-1 and public chat.
|
||||
|
||||
## Decision
|
||||
|
||||
Disable group chat for beta and don't work on bugs related to it until after. See https://github.com/status-im/status-mobile/issues/3995
|
||||
Disable group chat for beta and don't work on bugs related to it until after. See https://github.com/status-im/status-react/issues/3995
|
||||
|
||||
This ensures we can release beta without blockers, and then we can take some
|
||||
time to fix group chats properly.
|
||||
|
||||
@@ -13,15 +13,13 @@ Proposed
|
||||
|
||||
We have some data that we don't want to appear in the logs (user passwords are
|
||||
a good example). Currently, they are passed around as strings, that could be
|
||||
printed out by mistake in a log entry (see https://github.com/status-im/status-mobile/issues/4053)
|
||||
printed out by mistake in a log entry (see https://github.com/status-im/status-react/issues/4053)
|
||||
|
||||
## Decision
|
||||
|
||||
To minimize the risk of leaking passwords through logs, we should not pass
|
||||
passwords as strings in our codebase. We introduced a new type `MaskedData` in
|
||||
`status-im.utils.security`.
|
||||
update (16-Dec-2022) `status-im.utils.security` is now moved over to `utils.security.core`
|
||||
|
||||
We use `(security/mask-data <data to hide>` to wrap sensitive data into this
|
||||
type and then use `(security/unmask <masked-data>)` to get the plaintext back.
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ We also have an ongoing document with them.
|
||||
|
||||
#### iOS Test Flight Release
|
||||
**Upload to AppStore Connect**
|
||||
Use [this Jenkins job](https://jenkins.status.im/job/status-mobile/job/upload_release_ios/)
|
||||
Use [this Jenkins job](https://jenkins.status.im/job/status-react/job/upload_release_ios/)
|
||||
|
||||
**“What to test” field**
|
||||
When AppStore Connect asks you to fill in the field called “what to test”, just copy the release notes there.
|
||||
@@ -114,7 +114,7 @@ If reviewed successfully, we can share it to our users by adding “testflight-b
|
||||
The uploaded release is **immediately available**!
|
||||
Do it only if the iOS build is approved by Apple!
|
||||
|
||||
Use [this Jenkins job](https://jenkins.status.im/job/status-mobile/job/upload_release_android/)
|
||||
Use [this Jenkins job](https://jenkins.status.im/job/status-react/job/upload_release_android/)
|
||||
|
||||
Don’t forget to update the screenshots if necessary!
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ As a rule of thumb, coverage should increase.
|
||||
**3. Reject PRs that don't write what tests the author have done and what platforms you used to test, including screenshots, videos or logs**
|
||||
This means QA and dev have to spend less time catching obvious problems.
|
||||
|
||||
**4. Run tests when a PR is at "Review" stage on https://github.com/status-im/status-mobile/projects/7 (or add new 'e2e stage' between review and `TO TEST`)**
|
||||
**4. Run tests when a PR is at "Review" stage on https://github.com/status-im/status-react/projects/7 (or add new 'e2e stage' between review and `TO TEST`)**
|
||||
|
||||
**5. Dev asks for 2-3 reviewers, including a designer if the change affects UI, and these reviewers review within a day.**
|
||||
This ensures we don't have *diffusion of responsibility* and that PRs are reviewed quickly.
|
||||
|
||||