Revert "revert: to 19.5.4"

This reverts commit 3ea2274537.
This commit is contained in:
Yaroslav Serhieiev
2022-03-14 16:27:23 +02:00
parent de031468bc
commit 02ec8964c0
43 changed files with 1050 additions and 176 deletions
@@ -0,0 +1,12 @@
- label: ":android::mushroom:-RN_67_demo_project"
command:
- "nvm install"
- "JAVA_HOME=/usr/local/opt/openjdk@11/ ./scripts/demo-projects.android.sh"
- "./scripts/upload_artifact.sh"
env:
REACT_NATIVE_VERSION: 0.67.2
DETOX_DISABLE_POD_INSTALL: true
DETOX_DISABLE_POSTINSTALL: true
artifact_paths:
- "/Users/builder/work/coverage/**/*.lcov"
- "/Users/builder/work/artifacts*.tar.gz"
@@ -0,0 +1,12 @@
- label: ":android:-:six::four:-RN_64_android"
command:
- "nvm install"
- "JAVA_HOME=/usr/local/opt/openjdk@11/ ./scripts/ci.android.sh"
- "./scripts/upload_artifact.sh"
env:
REACT_NATIVE_VERSION: 0.64.1
DETOX_DISABLE_POD_INSTALL: true
DETOX_DISABLE_POSTINSTALL: true
artifact_paths:
- "/Users/builder/work/coverage/**/*.lcov"
- "/Users/builder/work/artifacts*.tar.gz"
@@ -0,0 +1,13 @@
- label: ":android:-:six::seven:-RN_67_android"
command:
- "nvm install"
- "JAVA_HOME=/usr/local/opt/openjdk@11/ ./scripts/ci.android.sh"
- "./scripts/upload_artifact.sh"
env:
REACT_NATIVE_VERSION: 0.67.2
DETOX_DISABLE_POD_INSTALL: true
DETOX_DISABLE_POSTINSTALL: true
SKIP_UNIT_TESTS: true
artifact_paths:
- "/Users/builder/work/coverage/**/*.lcov"
- "/Users/builder/work/artifacts*.tar.gz"
@@ -0,0 +1,10 @@
- label: ":ios::mushroom:-RN_67_demo_project"
command:
- "nvm install"
- "JAVA_HOME=/usr/local/opt/openjdk@11/ ./scripts/ci.ios.sh"
- "./scripts/upload_artifact.sh"
env:
REACT_NATIVE_VERSION: 0.67.2
artifact_paths:
- "/Users/builder/work/coverage/**/*.lcov"
- "/Users/builder/work/artifacts*.tar.gz"
+10
View File
@@ -0,0 +1,10 @@
- label: ":ios:-:six::four: RN_64_iOS"
command:
- "nvm install"
- "JAVA_HOME=/usr/local/opt/openjdk@11/ ./scripts/ci.ios.sh"
- "./scripts/upload_artifact.sh"
env:
REACT_NATIVE_VERSION: 0.64.1
artifact_paths:
- "/Users/builder/work/coverage/**/*.lcov"
- "/Users/builder/work/artifacts*.tar.gz"
+10
View File
@@ -0,0 +1,10 @@
- label: ":ios:-:six::seven: RN_67_iOS"
command:
- "nvm install"
- "JAVA_HOME=/usr/local/opt/openjdk@11/ ./scripts/ci.ios.sh"
- "./scripts/upload_artifact.sh"
env:
REACT_NATIVE_VERSION: 0.67.2
artifact_paths:
- "/Users/builder/work/coverage/**/*.lcov"
- "/Users/builder/work/artifacts*.tar.gz"
+25
View File
@@ -0,0 +1,25 @@
steps:
- block: ":partyparrot: Enter the Debug Mode!"
prompt: "Detox your mind"
if: 'build.message =~ /^debug\$/i'
fields:
- select: "Ingridients"
key: "debug-builds"
multiple: true
hint: "hey Chef, what are we cooking today?"
options:
- label: "iOS RN 64"
value: "ios_rn_64"
- label: "iOS RN 67"
value: "ios_rn_67"
- label: "Android RN 64"
value: "android_rn_64"
- label: "Android RN 67"
value: "android_rn_67"
- label: "Android Demo App RN 67"
value: "android_demo_app_rn_67"
- label: "iOS Demo App RN 67"
value: "ios_demo_app_rn_67"
- label: "Get Release Pipeline"
command: '.buildkite/pipeline.sh debug | buildkite-agent pipeline upload'
+30
View File
@@ -0,0 +1,30 @@
- wait
- label: ":ios: Package iOS"
key: 'ios_package'
command:
- "nvm install"
- "npm run package:ios"
artifact_paths: "/Users/builder/work/detox/*.tbz"
- label: ":android: Package android"
key: 'android_package'
command:
- "nvm install"
- "npm install"
- "JAVA_HOME=/usr/local/opt/openjdk@11/ npm run package:android"
env:
DETOX_DISABLE_POSTINSTALL: true
DETOX_DISABLE_POD_INSTALL: true
artifact_paths: "/Users/builder/work/detox/Detox-android/**/*"
- label: ":shipit: Publish"
depends_on:
- 'android_package'
- 'ios_package'
command:
- "nvm install"
- "npm install"
- "npm run release"
env:
DETOX_DISABLE_POD_INSTALL: true
DETOX_DISABLE_POSTINSTALL: true
+63
View File
@@ -0,0 +1,63 @@
steps:
- block: ":rocket: Release!"
prompt: "Fill out the details for release"
if: 'build.message =~ /^release\$/i'
fields:
- select: "IS PRE-RELEASE?"
key: "pre-release"
default: "true"
hint: "A corresponding pre-release prefix will be added to published version name, with the npm tag of this version (for instance, `19.5.0-preminor.0`)."
options:
- label: "Yes, this is a PRE-release version."
value: "true"
- label: "No, this is a REAL release version."
value: "false"
- select: "VERSION TYPE"
key: "release-version-type"
hint: "A successful build will be released with a version update according to the selected type."
options:
- label: "Patch"
value: "patch"
- label: "Minor"
value: "minor"
- label: "Major"
value: "major"
- select: "IS DRY RUN?"
key: "release-dry-run"
hint: "When set to `Yes`, don't actually release anything, just run the scripts."
default: "false"
options:
- label: "Yes"
value: "true"
- label: "No"
value: "false"
- select: "SKIP NPM-PUBLISH?"
key: "release-skip-npm"
hint: "This is a hack to fix previously broken release jobs. You need to really know what you're doing."
default: "false"
options:
- label: "Yes"
value: "true"
- label: "No"
value: "false"
- select: "DO FAST-RELEASE?"
key: "fast-release"
hint: "When set to `Yes`, skip building and testing. USE ONLY IF YOU REALLY REALLY HAVE TO!"
default: "false"
options:
- label: "Yes"
value: "true"
- label: "No"
value: "false"
- text: "NPM TAG"
key: "release-npm-tag"
hint: "Leave `null` for default. For releases from master, the default is `latest`, unless this is a pre-release version, then uses `prerelease` as tag. For releases from other branches, the default is the branch name."
default: 'null'
- label: "Get Release Pipeline"
command: '.buildkite/pipeline.sh release | buildkite-agent pipeline upload'
+29
View File
@@ -0,0 +1,29 @@
#!/bin/bash -e
if [[ "$1" == 'start' ]];then
if [[ $(echo $BUILDKITE_MESSAGE | tr '[:upper:]' '[:lower:]') =~ ^release$ ]];then
cat .buildkite/pipeline.release.yml
elif [[ $(echo $BUILDKITE_MESSAGE | tr '[:upper:]' '[:lower:]') =~ ^debug$ ]];then
cat .buildkite/pipeline.debug.yml
else
.buildkite/pipeline_common.sh
fi
elif [[ "$1" == 'release' ]];then
FAST_RELEASE=$(buildkite-agent meta-data get fast-release)
if [[ "$FAST_RELEASE" == 'true' ]];then
cat .buildkite/pipeline.release.fast.yml
else
.buildkite/pipeline_common.sh
cat .buildkite/pipeline.release.fast.yml
fi
elif [[ "$1" == 'debug' ]];then
stepsList=$(buildkite-agent meta-data get debug-builds)
steps=($(echo $stepsList| tr ";" "\n"))
echo "steps:"
for step in "${steps[@]}"
do
cat .buildkite/jobs/pipeline.$step.yml
done
fi
+10
View File
@@ -0,0 +1,10 @@
#!/bin/bash -e
echo "steps:"
cat .buildkite/jobs/pipeline.ios_rn_64.yml
cat .buildkite/jobs/pipeline.ios_rn_67.yml
cat .buildkite/jobs/pipeline.android_rn_64.yml
cat .buildkite/jobs/pipeline.android_rn_67.yml
cat .buildkite/jobs/pipeline.android_demo_app_rn_67.yml
cat .buildkite/jobs/pipeline.ios_demo_app_rn_67.yml
+1 -1
View File
@@ -1 +1 @@
12.22.1
lts/erbium
+3 -3
View File
@@ -66,9 +66,9 @@ Detox is built from the ground up to support React Native projects as well as pu
The following React Native versions have been tested:
| iOS | Android |
|------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------|
| ≤0.66.x | ≥0.64, ≤0.66 - Visibility edge-case: see this [RN issue](https://github.com/facebook/react-native/issues/23870) \* |
| iOS | Android |
|---------|--------------------------------------------------------------------------------------------------------------------|
| ≤0.67.x | ≥0.64, ≤0.67 - Visibility edge-case: see this [RN issue](https://github.com/facebook/react-native/issues/23870) \* |
Future versions are most likely supported, but have not been tested yet. Please open issues if you find specific issues with newer React Native versions.
+1 -1
View File
@@ -16,7 +16,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (class, nonatomic, readonly) NSUInteger defaultPercentThresholdForVisibility;
@property (class, nonatomic, readonly) NSUInteger consecutiveTouchPointsWithSameContentOffsetThreshold;
+ (NSString*)percentDescriptionForValue:(CGFloat)value;
+ (NSString*)percentDescriptionForPercent:(CGFloat)percent;
@end
+2 -10
View File
@@ -22,16 +22,8 @@
return 12;
}
+ (NSString*)percentDescriptionForValue:(CGFloat)value {
static NSNumberFormatter* formatter;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
formatter = [NSNumberFormatter new];
formatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US"];
formatter.numberStyle = NSNumberFormatterPercentStyle;
});
return [formatter stringFromNumber:@(value)];
+ (NSString*)percentDescriptionForPercent:(CGFloat)percent {
return [NSString stringWithFormat:@"%g%%", percent];
}
@end
@@ -216,7 +216,7 @@ DTX_DIRECT_MEMBERS
if (isRegionObscured) {
*explanation = [NSString stringWithFormat:@"View does not pass visibility percent "
"threshold (%@)", [DetoxPolicy percentDescriptionForValue:percent]];
"threshold (%@)", [DetoxPolicy percentDescriptionForPercent:percent]];
}
return isRegionObscured;
@@ -284,7 +284,7 @@ DTX_DIRECT_MEMBERS
auto errorDescription = [NSString stringWithFormat:@"View is clipped by one or more of its "
"superviews' bounds and does not pass visibility percent "
"threshold (%@)",
[DetoxPolicy percentDescriptionForValue:percent]];
[DetoxPolicy percentDescriptionForPercent:percent]];
auto userInfo = @{ NSLocalizedDescriptionKey: APPLY_PREFIX(errorDescription) };
@@ -298,7 +298,7 @@ DTX_DIRECT_MEMBERS
inWindowBounds:windowToUse.bounds percent:percent]) {
auto errorDescription = [NSString stringWithFormat:@"View is obscured by its window bounds "
"and does not pass visibility percent threshold (%@)",
[DetoxPolicy percentDescriptionForValue:percent]];
[DetoxPolicy percentDescriptionForPercent:percent]];
auto userInfo = @{ NSLocalizedDescriptionKey: APPLY_PREFIX(errorDescription) };
+1 -1
View File
@@ -48,7 +48,7 @@
"mocha": ">=6.0.0",
"mockdate": "^2.0.1",
"prettier": "1.7.0",
"react-native": "0.66.1",
"react-native": "0.67.2",
"react-native-codegen": "^0.0.8",
"typescript": "^4.5.2",
"wtfnode": "^0.9.1"
+9 -4
View File
@@ -46,16 +46,21 @@ buildscript {
allprojects {
repositories {
google()
mavenLocal()
mavenCentral()
maven {
url "$rootDir/../../node_modules/react-native/android"
}
maven {
// Android JSC is installed from npm
url("$rootDir/../node_modules/jsc-android/dist")
}
mavenCentral {
// We don't want to fetch react-native from Maven Central as there are
// older versions over there.
content {
excludeGroup "com.facebook.react"
}
}
google()
mavenLocal()
jcenter()
}
}
@@ -13,7 +13,7 @@ describe(':ios: Visibility Debug Artifacts', () => {
it('should not be able to tap an overlayed button', async () => {
await expectToThrow(
() => element(by.text('Button 1')).tap(),
`View does not pass visibility percent threshold`,
`View does not pass visibility percent threshold (100%)`,
);
});
@@ -796,7 +796,7 @@
ENABLE_BITCODE = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "arm64 ";
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
@@ -853,7 +853,7 @@
ENABLE_BITCODE = NO;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "arm64 ";
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+3 -3
View File
@@ -14,10 +14,10 @@
"packager": "react-native start",
"detox-server": "detox run-server",
"e2e:ios": "detox test -c ios.sim.release",
"e2e:ios-ci": "npm run e2e:ios -- --workers 4 --retries 1 --jest-report-specs -l verbose",
"e2e:ios-ci": "npm run e2e:ios -- --workers 2 --retries 1 --jest-report-specs -l verbose",
"e2e:android": "detox test -c android.emu.release",
"e2e:android-ci-genycloud": "detox test -c android.genycloud.release --workers 5 --retries 1 --jest-report-specs --loglevel verbose",
"e2e:android-ci-google": "detox test -c android.emu.release --workers 3 --retries 1 --jest-report-specs --loglevel verbose --headless",
"e2e:android-ci-google": "detox test -c android.emu.release --workers 3 --retries 1 --jest-report-specs --loglevel verbose --headless --gpu off",
"e2e:android-debug": "detox test -c android.emu.debug",
"integration": "jest --clearCache && jest unit --config integration/config.js -w 1 .",
"integration-update-snapshots": "npm run integration -- -u",
@@ -36,7 +36,7 @@
"@react-native-picker/picker": "^2.1.0",
"moment": "^2.24.0",
"react": "17.0.2",
"react-native": "0.66.1",
"react-native": "0.67.2",
"react-native-webview": "11.4.4"
},
"devDependencies": {
@@ -0,0 +1,600 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
plugins {
id("com.android.library")
// Edited by Detox' post-install script
// id("com.facebook.react")
id("maven-publish")
id("de.undercouch.download")
}
import java.nio.file.Paths
import de.undercouch.gradle.tasks.download.Download
import org.apache.tools.ant.taskdefs.condition.Os
import org.apache.tools.ant.filters.ReplaceTokens
def AAR_OUTPUT_URL = "file://${projectDir}/../android"
// We download various C++ open-source dependencies into downloads.
// We then copy both the downloaded code and our custom makefiles and headers into third-party-ndk.
// After that we build native code from src/main/jni with module path pointing at third-party-ndk.
def customDownloadsDir = System.getenv("REACT_NATIVE_DOWNLOADS_DIR")
def downloadsDir = customDownloadsDir ? new File(customDownloadsDir) : new File("$buildDir/downloads")
def thirdPartyNdkDir = new File("$buildDir/third-party-ndk")
// You need to have following folders in this directory:
// - boost_1_63_0
// - double-conversion-1.1.6
// - folly-deprecate-dynamic-initializer
// - glog-0.3.5
def dependenciesPath = System.getenv("REACT_NATIVE_DEPENDENCIES")
// The Boost library is a very large download (>100MB).
// If Boost is already present on your system, define the REACT_NATIVE_BOOST_PATH env variable
// and the build will use that.
def boostPath = dependenciesPath ?: System.getenv("REACT_NATIVE_BOOST_PATH")
// Setup build type for NDK, supported values: {debug, release}
def nativeBuildType = System.getenv("NATIVE_BUILD_TYPE") ?: "release"
task createNativeDepsDirectories {
downloadsDir.mkdirs()
thirdPartyNdkDir.mkdirs()
}
task downloadBoost(dependsOn: createNativeDepsDirectories, type: Download) {
src("https://github.com/react-native-community/boost-for-react-native/releases/download/v${BOOST_VERSION.replace("_", ".")}-0/boost_${BOOST_VERSION}.tar.gz")
onlyIfNewer(true)
overwrite(false)
dest(new File(downloadsDir, "boost_${BOOST_VERSION}.tar.gz"))
}
task prepareBoost(dependsOn: boostPath ? [] : [downloadBoost], type: Copy) {
from(boostPath ?: tarTree(resources.gzip(downloadBoost.dest)))
from("src/main/jni/third-party/boost")
include("Android.mk", "boost_${BOOST_VERSION}/boost/**/*.hpp", "boost/boost/**/*.hpp", "asm/**/*.S")
includeEmptyDirs = false
into("$thirdPartyNdkDir/boost")
doLast {
file("$thirdPartyNdkDir/boost/boost").renameTo("$thirdPartyNdkDir/boost/boost_${BOOST_VERSION}")
}
}
task downloadDoubleConversion(dependsOn: createNativeDepsDirectories, type: Download) {
src("https://github.com/google/double-conversion/archive/v${DOUBLE_CONVERSION_VERSION}.tar.gz")
onlyIfNewer(true)
overwrite(false)
dest(new File(downloadsDir, "double-conversion-${DOUBLE_CONVERSION_VERSION}.tar.gz"))
}
task prepareDoubleConversion(dependsOn: dependenciesPath ? [] : [downloadDoubleConversion], type: Copy) {
from(dependenciesPath ?: tarTree(downloadDoubleConversion.dest))
from("src/main/jni/third-party/double-conversion/Android.mk")
include("double-conversion-${DOUBLE_CONVERSION_VERSION}/src/**/*", "Android.mk")
filesMatching("*/src/**/*", { fname -> fname.path = "double-conversion/${fname.name}" })
includeEmptyDirs = false
into("$thirdPartyNdkDir/double-conversion")
}
task downloadFolly(dependsOn: createNativeDepsDirectories, type: Download) {
src("https://github.com/facebook/folly/archive/v${FOLLY_VERSION}.tar.gz")
onlyIfNewer(true)
overwrite(false)
dest(new File(downloadsDir, "folly-${FOLLY_VERSION}.tar.gz"))
}
task prepareFolly(dependsOn: dependenciesPath ? [] : [downloadFolly], type: Copy) {
from(dependenciesPath ?: tarTree(downloadFolly.dest))
from("src/main/jni/third-party/folly/Android.mk")
include("folly-${FOLLY_VERSION}/folly/**/*", "Android.mk")
eachFile { fname -> fname.path = (fname.path - "folly-${FOLLY_VERSION}/") }
includeEmptyDirs = false
into("$thirdPartyNdkDir/folly")
}
task downloadFmt(dependsOn: createNativeDepsDirectories, type: Download) {
src("https://github.com/fmtlib/fmt/archive/${FMT_VERSION}.tar.gz")
onlyIfNewer(true)
overwrite(false)
dest(new File(downloadsDir, "fmt-${FMT_VERSION}.tar.gz"))
}
task prepareFmt(dependsOn: dependenciesPath ? [] : [downloadFmt], type: Copy) {
from(dependenciesPath ?: tarTree(downloadFmt.dest))
from("src/main/jni/third-party/fmt/Android.mk")
include("fmt-${FMT_VERSION}/src/**/*", "fmt-${FMT_VERSION}/include/**/*", "Android.mk")
eachFile { fname -> fname.path = (fname.path - "fmt-${FMT_VERSION}/") }
includeEmptyDirs = false
into("$thirdPartyNdkDir/fmt")
}
task downloadLibevent(dependsOn: createNativeDepsDirectories, type: Download) {
src("https://github.com/libevent/libevent/releases/download/release-${LIBEVENT_VERSION}-stable/libevent-${LIBEVENT_VERSION}-stable.tar.gz")
onlyIfNewer(true)
overwrite(false)
dest(new File(downloadsDir, "libevent-${LIBEVENT_VERSION}.tar.gz"))
}
task prepareLibevent(dependsOn: dependenciesPath ? [] : [downloadLibevent], type: Copy) {
from(dependenciesPath ?: tarTree(downloadLibevent.dest))
from("src/main/jni/third-party/libevent/Android.mk")
from("src/main/jni/third-party/libevent/event-config.h")
from("src/main/jni/third-party/libevent/evconfig-private.h")
include(
"libevent-${LIBEVENT_VERSION}-stable/*.c",
"libevent-${LIBEVENT_VERSION}-stable/*.h",
"libevent-${LIBEVENT_VERSION}-stable/include/**/*",
"evconfig-private.h",
"event-config.h",
"Android.mk"
)
eachFile { fname -> fname.path = (fname.path - "libevent-${LIBEVENT_VERSION}-stable/") }
includeEmptyDirs = false
into("$thirdPartyNdkDir/libevent")
doLast {
ant.move(file: "$thirdPartyNdkDir/libevent/event-config.h", tofile: "$thirdPartyNdkDir/libevent/include/event2/event-config.h")
}
}
task prepareHermes(dependsOn: createNativeDepsDirectories, type: Copy) {
def hermesPackagePath = findNodeModulePath(projectDir, "hermes-engine")
if (!hermesPackagePath) {
throw new GradleScriptException("Could not find the hermes-engine npm package", null)
}
def hermesAAR = file("$hermesPackagePath/android/hermes-debug.aar")
if (!hermesAAR.exists()) {
throw new GradleScriptException("The hermes-engine npm package is missing \"android/hermes-debug.aar\"", null)
}
def soFiles = zipTree(hermesAAR).matching({ it.include "**/*.so" })
from soFiles
from "src/main/jni/first-party/hermes/Android.mk"
into "$thirdPartyNdkDir/hermes"
}
task downloadGlog(dependsOn: createNativeDepsDirectories, type: Download) {
src("https://github.com/google/glog/archive/v${GLOG_VERSION}.tar.gz")
onlyIfNewer(true)
overwrite(false)
dest(new File(downloadsDir, "glog-${GLOG_VERSION}.tar.gz"))
}
// Prepare glog sources to be compiled, this task will perform steps that normally should've been
// executed by automake. This way we can avoid dependencies on make/automake
task prepareGlog(dependsOn: dependenciesPath ? [] : [downloadGlog], type: Copy) {
duplicatesStrategy("warn")
from(dependenciesPath ?: tarTree(downloadGlog.dest))
from("src/main/jni/third-party/glog/")
include("glog-${GLOG_VERSION}/src/**/*", "Android.mk", "config.h")
includeEmptyDirs = false
filesMatching("**/*.h.in") {
filter(ReplaceTokens, tokens: [
ac_cv_have_unistd_h : "1",
ac_cv_have_stdint_h : "1",
ac_cv_have_systypes_h : "1",
ac_cv_have_inttypes_h : "1",
ac_cv_have_libgflags : "0",
ac_google_start_namespace : "namespace google {",
ac_cv_have_uint16_t : "1",
ac_cv_have_u_int16_t : "1",
ac_cv_have___uint16 : "0",
ac_google_end_namespace : "}",
ac_cv_have___builtin_expect : "1",
ac_google_namespace : "google",
ac_cv___attribute___noinline : "__attribute__ ((noinline))",
ac_cv___attribute___noreturn : "__attribute__ ((noreturn))",
ac_cv___attribute___printf_4_5: "__attribute__((__format__ (__printf__, 4, 5)))"
])
it.path = (it.name - ".in")
}
into("$thirdPartyNdkDir/glog")
doLast {
copy {
from(fileTree(dir: "$thirdPartyNdkDir/glog", includes: ["stl_logging.h", "logging.h", "raw_logging.h", "vlog_is_on.h", "**/src/glog/log_severity.h"]).files)
includeEmptyDirs = false
into("$thirdPartyNdkDir/glog/exported/glog")
}
}
}
// Create Android.mk library module based on jsc from npm
task prepareJSC {
doLast {
def jscPackagePath = findNodeModulePath(projectDir, "jsc-android")
if (!jscPackagePath) {
throw new GradleScriptException("Could not find the jsc-android npm package", null)
}
def jscDist = file("$jscPackagePath/dist")
if (!jscDist.exists()) {
throw new GradleScriptException("The jsc-android npm package is missing its \"dist\" directory", null)
}
def jscAAR = fileTree(jscDist).matching({ it.include "**/android-jsc/**/*.aar" }).singleFile
def soFiles = zipTree(jscAAR).matching({ it.include "**/*.so" })
def headerFiles = fileTree(jscDist).matching({ it.include "**/include/*.h" })
copy {
from(soFiles)
from(headerFiles)
from("src/main/jni/third-party/jsc/Android.mk")
filesMatching("**/*.h", { it.path = "JavaScriptCore/${it.name}" })
includeEmptyDirs(false)
into("$thirdPartyNdkDir/jsc")
}
}
}
task downloadNdkBuildDependencies {
if (!boostPath) {
dependsOn(downloadBoost)
}
dependsOn(downloadDoubleConversion)
dependsOn(downloadFolly)
dependsOn(downloadGlog)
dependsOn(downloadFmt)
dependsOn(downloadLibevent)
}
/**
* Finds the path of the installed npm package with the given name using Node's
* module resolution algorithm, which searches "node_modules" directories up to
* the file system root. This handles various cases, including:
*
* - Working in the open-source RN repo:
* Gradle: /path/to/react-native/ReactAndroid
* Node module: /path/to/react-native/node_modules/[package]
*
* - Installing RN as a dependency of an app and searching for hoisted
* dependencies:
* Gradle: /path/to/app/node_modules/react-native/ReactAndroid
* Node module: /path/to/app/node_modules/[package]
*
* - Working in a larger repo (e.g., Facebook) that contains RN:
* Gradle: /path/to/repo/path/to/react-native/ReactAndroid
* Node module: /path/to/repo/node_modules/[package]
*
* The search begins at the given base directory (a File object). The returned
* path is a string.
*/
def findNodeModulePath(baseDir, packageName) {
def basePath = baseDir.toPath().normalize()
// Node's module resolution algorithm searches up to the root directory,
// after which the base path will be null
while (basePath) {
def candidatePath = Paths.get(basePath.toString(), "node_modules", packageName)
if (candidatePath.toFile().exists()) {
return candidatePath.toString()
}
basePath = basePath.getParent()
}
return null
}
def getNdkBuildName() {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
return "ndk-build.cmd"
} else {
return "ndk-build"
}
}
def findNdkBuildFullPath() {
// android.ndkDirectory should return project.android.ndkVersion ndkDirectory
def ndkDir = android.ndkDirectory ? android.ndkDirectory.absolutePath : null
if (ndkDir) {
return new File(ndkDir, getNdkBuildName()).getAbsolutePath()
}
// we allow to provide full path to ndk-build tool
if (hasProperty("ndk.command")) {
return property("ndk.command")
}
// or just a path to the containing directory
if (hasProperty("ndk.path")) {
ndkDir = property("ndk.path")
return new File(ndkDir, getNdkBuildName()).getAbsolutePath()
}
// @TODO ANDROID_NDK && ndk.dir is deprecated and will be removed in the future.
if (System.getenv("ANDROID_NDK") != null) {
ndkDir = System.getenv("ANDROID_NDK")
return new File(ndkDir, getNdkBuildName()).getAbsolutePath()
}
return null
}
def reactNativeDevServerPort() {
def value = project.getProperties().get("reactNativeDevServerPort")
return value != null ? value : "8081"
}
def reactNativeInspectorProxyPort() {
def value = project.getProperties().get("reactNativeInspectorProxyPort")
return value != null ? value : reactNativeDevServerPort()
}
def reactNativeArchitectures() {
def isDebug = gradle.startParameter.taskRequests.any {
it.args.any { it.endsWith("Debug") }
}
def value = project.getProperties().get("reactNativeDebugArchitectures")
return value != null && isDebug ? value : "all"
}
def getNdkBuildFullPath() {
def ndkBuildFullPath = findNdkBuildFullPath()
if (ndkBuildFullPath == null) {
throw new GradleScriptException(
"ndk-build binary cannot be found, check if you've set " +
"\$ANDROID_NDK environment variable correctly or if ndk.dir is " +
"setup in local.properties",
null)
}
if (!new File(ndkBuildFullPath).canExecute()) {
throw new GradleScriptException(
"ndk-build binary " + ndkBuildFullPath + " doesn't exist or isn't executable.\n" +
"Check that the \$ANDROID_NDK environment variable, or ndk.dir in local.properties, is set correctly.\n" +
"(On Windows, make sure you escape backslashes in local.properties or use forward slashes, e.g. C:\\\\ndk or C:/ndk rather than C:\\ndk)",
null)
}
return ndkBuildFullPath
}
def buildReactNdkLib = tasks.register("buildReactNdkLib", Exec) {
dependsOn(prepareJSC, prepareHermes, prepareBoost, prepareDoubleConversion, prepareFmt, prepareFolly, prepareGlog, prepareLibevent, extractAARHeaders, extractJNIFiles)
dependsOn("generateCodegenArtifactsFromSchema");
inputs.dir("$projectDir/../ReactCommon")
inputs.dir("src/main/jni")
inputs.dir("src/main/java/com/facebook/react/turbomodule/core/jni")
inputs.dir("src/main/java/com/facebook/react/modules/blob")
outputs.dir("$buildDir/react-ndk/all")
def commandLineArgs = [
getNdkBuildFullPath(),
"APP_ABI=${reactNativeArchitectures()}",
"NDK_DEBUG=" + (nativeBuildType.equalsIgnoreCase("debug") ? "1" : "0"),
"NDK_PROJECT_PATH=null",
"NDK_APPLICATION_MK=$projectDir/src/main/jni/Application.mk",
"NDK_OUT=" + temporaryDir,
"NDK_LIBS_OUT=$buildDir/react-ndk/all",
"THIRD_PARTY_NDK_DIR=$thirdPartyNdkDir",
"REACT_COMMON_DIR=$projectDir/../ReactCommon",
"REACT_GENERATED_SRC_DIR=$buildDir/generated/source",
"REACT_SRC_DIR=$projectDir/src/main/java/com/facebook/react",
"-C", file("src/main/jni/react/jni").absolutePath,
"--jobs", project.findProperty("jobs") ?: Runtime.runtime.availableProcessors()
]
if (Os.isFamily(Os.FAMILY_MAC)) {
// This flag will suppress "fcntl(): Bad file descriptor" warnings on local builds.
commandLineArgs.add("--output-sync=none")
}
commandLine(commandLineArgs)
}
def cleanReactNdkLib = tasks.register("cleanReactNdkLib", Exec) {
ignoreExitValue(true)
errorOutput(new ByteArrayOutputStream())
commandLine(getNdkBuildFullPath(),
"NDK_APPLICATION_MK=$projectDir/src/main/jni/Application.mk",
"THIRD_PARTY_NDK_DIR=$thirdPartyNdkDir",
"REACT_COMMON_DIR=$projectDir/../ReactCommon",
"-C", file("src/main/jni/react/jni").absolutePath,
"clean")
doLast {
file(AAR_OUTPUT_URL).delete()
println("Deleted aar output dir at ${file(AAR_OUTPUT_URL)}")
}
}
def packageReactNdkLibs = tasks.register("packageReactNdkLibs", Copy) {
dependsOn(buildReactNdkLib)
from("$buildDir/react-ndk/all")
into("$buildDir/react-ndk/exported")
exclude("**/libjsc.so")
exclude("**/libhermes.so")
}
def packageReactNdkLibsForBuck = tasks.register("packageReactNdkLibsForBuck", Copy) {
dependsOn(packageReactNdkLibs)
from("$buildDir/react-ndk/exported")
into("src/main/jni/prebuilt/lib")
}
task extractAARHeaders {
doLast {
configurations.extractHeaders.files.each {
def file = it.absoluteFile
def packageName = file.name.tokenize('-')[0]
copy {
from zipTree(file)
into "$projectDir/src/main/jni/first-party/$packageName/headers"
include "**/*.h"
}
}
}
}
task extractJNIFiles {
doLast {
configurations.extractJNI.files.each {
def file = it.absoluteFile
def packageName = file.name.tokenize('-')[0]
copy {
from zipTree(file)
into "$projectDir/src/main/jni/first-party/$packageName/"
include "jni/**/*"
}
}
}
}
task installArchives {
dependsOn("publishReleasePublicationToNpmRepository")
}
android {
compileSdkVersion 30
// Edited by Detox' post-install script
// ndkVersion ANDROID_NDK_VERSION
// if (ANDROID_NDK_PATH != null) {
// ndkPath ANDROID_NDK_PATH
// }
defaultConfig {
minSdkVersion(21)
targetSdkVersion(28)
versionCode(1)
versionName("1.0")
consumerProguardFiles("proguard-rules.pro")
buildConfigField("boolean", "IS_INTERNAL_BUILD", "false")
buildConfigField("int", "EXOPACKAGE_FLAGS", "0")
buildConfigField("int", "HERMES_BYTECODE_VERSION", "0")
resValue "integer", "react_native_dev_server_port", reactNativeDevServerPort()
resValue "integer", "react_native_inspector_proxy_port", reactNativeInspectorProxyPort()
testApplicationId("com.facebook.react.tests.gradle")
testInstrumentationRunner("androidx.test.runner.AndroidJUnitRunner")
}
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDir("$buildDir/react-ndk/exported")
res.srcDirs = ["src/main/res/devsupport", "src/main/res/shell", "src/main/res/views/modal", "src/main/res/views/uimanager"]
java {
srcDirs = ["src/main/java", "src/main/libraries/soloader/java", "src/main/jni/first-party/fb/jni/java"]
exclude("com/facebook/react/processing")
exclude("com/facebook/react/module/processing")
}
}
preBuild.dependsOn(packageReactNdkLibs)
clean.dependsOn(cleanReactNdkLib)
lintOptions {
abortOnError(false)
}
packagingOptions {
exclude("META-INF/NOTICE")
exclude("META-INF/LICENSE")
}
configurations {
extractHeaders
extractJNI
javadocDeps.extendsFrom api
}
}
dependencies {
api("com.facebook.infer.annotation:infer-annotation:0.18.0")
api("com.facebook.yoga:proguard-annotations:1.19.0")
api("javax.inject:javax.inject:1")
api("androidx.appcompat:appcompat:1.0.2")
api("androidx.autofill:autofill:1.1.0")
api("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0")
api("com.facebook.fresco:fresco:${FRESCO_VERSION}")
api("com.facebook.fresco:imagepipeline-okhttp3:${FRESCO_VERSION}")
api("com.facebook.fresco:ui-common:${FRESCO_VERSION}")
api("com.facebook.soloader:soloader:${SO_LOADER_VERSION}")
api("com.google.code.findbugs:jsr305:3.0.2")
api("com.squareup.okhttp3:okhttp:${OKHTTP_VERSION}")
api("com.squareup.okhttp3:okhttp-urlconnection:${OKHTTP_VERSION}")
api("com.squareup.okio:okio:2.9.0")
api("com.facebook.fbjni:fbjni-java-only:0.2.2")
extractHeaders("com.facebook.fbjni:fbjni:0.2.2:headers")
extractJNI("com.facebook.fbjni:fbjni:0.2.2")
javadocDeps("com.squareup:javapoet:1.13.0")
testImplementation("junit:junit:${JUNIT_VERSION}")
testImplementation("org.powermock:powermock-api-mockito2:${POWERMOCK_VERSION}")
testImplementation("org.powermock:powermock-module-junit4-rule:${POWERMOCK_VERSION}")
testImplementation("org.powermock:powermock-classloading-xstream:${POWERMOCK_VERSION}")
testImplementation("org.mockito:mockito-core:${MOCKITO_CORE_VERSION}")
testImplementation("org.easytesting:fest-assert-core:2.0M10")
testImplementation("org.robolectric:robolectric:${ROBOLECTRIC_VERSION}")
androidTestImplementation(fileTree(dir: "src/main/third-party/java/buck-android-support/", include: ["*.jar"]))
androidTestImplementation("androidx.test:runner:${ANDROIDX_TEST_VERSION}")
androidTestImplementation("androidx.test:rules:${ANDROIDX_TEST_VERSION}")
androidTestImplementation("org.mockito:mockito-core:${MOCKITO_CORE_VERSION}")
}
// Edited by Detox' post-install script
// react {
// // TODO: The library name is chosen for parity with Fabric components & iOS
// // This should be changed to a more generic name, e.g. `ReactCoreSpec`.
// libraryName = "rncore"
// jsRootDir = file("../Libraries")
// reactRoot = file("$projectDir/..")
// useJavaGenerator = System.getenv("USE_CODEGEN_JAVAPOET") ?: false
// }
afterEvaluate {
publishing {
publications {
release(MavenPublication) {
// Applies the component for the release build variant.
from components.release
// You can then customize attributes of the publication as shown below.
artifactId = POM_ARTIFACT_ID
groupId = GROUP
version = VERSION_NAME
pom {
name = POM_NAME
description = "A framework for building native apps with React"
url = "https://github.com/facebook/react-native"
developers {
developer {
id = "facebook"
name = "Facebook"
}
}
licenses {
license {
name = "MIT License"
url = "https://github.com/facebook/react-native/blob/HEAD/LICENSE"
distribution = "repo"
}
}
scm {
url = "https://github.com/facebook/react-native.git"
connection = "scm:git:https://github.com/facebook/react-native.git"
developerConnection = "scm:git:[email protected]:facebook/react-native.git"
}
}
}
}
repositories {
maven {
name = "npm"
url = AAR_OUTPUT_URL
}
}
}
}
+21
View File
@@ -62,6 +62,21 @@ function overrideReactAndroidGradleForRn66Android() {
fs.copySync(PATCH_SCRIPT_PATH, REACT_ANDROID_GRADLE_SCRIPT_PATH);
}
function overrideReactAndroidGradleForRn67Android() {
const REACT_ANDROID_PATH = path.join('node_modules', 'react-native', 'ReactAndroid');
const REACT_ANDROID_GRADLE_SCRIPT_PATH = path.join(REACT_ANDROID_PATH, 'build.gradle');
const REACT_ANDROID_GRADLE_BAK_SCRIPT_PATH = path.join(REACT_ANDROID_PATH, 'build.gradle.bak');
const PATCH_SCRIPT_PATH = path.join('scripts', 'ReactAndroid_rn67_build.gradle');
console.log(' Overriding ReactAndroid\'s build.gradle...');
try {
fs.renameSync(REACT_ANDROID_GRADLE_SCRIPT_PATH, REACT_ANDROID_GRADLE_BAK_SCRIPT_PATH);
} catch (e) {
console.warn(' Couldn\'t create a backup to original script (skipping)', e);
}
fs.copySync(PATCH_SCRIPT_PATH, REACT_ANDROID_GRADLE_SCRIPT_PATH);
}
function cleanFindNodeScriptFileForRn64IOS() {
const REACT_SCRIPTS_PATH = path.join('node_modules', 'react-native', 'scripts');
const REACT_FIND_NODE_SCRIPT_PATH = path.join(REACT_SCRIPTS_PATH, 'find-node.sh');
@@ -94,6 +109,12 @@ function run() {
cleanFindNodeScriptFileForRn64IOS();
}
if (semver.minor(rnVersion) === 67) {
console.log(' Detected RN version .67! Applying necessary patches...');
overrideReactAndroidGradleForRn67Android();
cleanFindNodeScriptFileForRn64IOS();
}
console.log('Detox test-app post-install script completed!');
}
@@ -2,92 +2,97 @@
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
"scale" : "3x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
"scale" : "3x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
"scale" : "3x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
"scale" : "2x",
"size" : "60x60"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
"scale" : "3x",
"size" : "60x60"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
"scale" : "1x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
"scale" : "1x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
"scale" : "1x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
"scale" : "1x",
"size" : "76x76"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
"scale" : "2x",
"size" : "76x76"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
"author" : "xcode",
"version" : 1
}
}
}
@@ -1,12 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13168.3" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<development version="8000" identifier="xcode"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13147.4"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
@@ -21,6 +19,7 @@
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<viewLayoutGuide key="safeArea" id="2Ln-re-bR8"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</viewController>
@@ -1,12 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13168.3" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<development version="8000" identifier="xcode"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13147.4"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
@@ -21,11 +19,13 @@
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<viewLayoutGuide key="safeArea" id="vEN-g2-oSq"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="34" y="111"/>
</scene>
</scenes>
</document>
@@ -1,21 +1,18 @@
describe('Example', () => {
beforeAll(async () => {
await device.launchApp();
});
beforeEach(async () => {
await device.launchApp();
await device.reloadReactNative();
});
it('should have welcome screen', async () => {
await expect(element(by.id('welcome'))).toBeVisible();
});
it('should show hello screen after tap', async () => {
await element(by.id('hello_button')).tap();
await expect(element(by.text('Hello!!!'))).toBeVisible();
});
it('should show world screen after tap', async () => {
await element(by.id('world_button')).tap();
await expect(element(by.text('World!!!'))).toBeVisible();
+1 -1
View File
@@ -6,7 +6,7 @@
"test:ios-release": "detox test --configuration ios.sim.release -l verbose",
"test:ios-release-ci": "detox test --configuration ios.sim.release -l verbose --workers 2",
"test:android-release": "detox test --configuration android.emu.release",
"test:android-release-ci": "detox test --configuration android.emu.release -l verbose --workers 2 --headless --record-logs all --take-screenshots all",
"test:android-release-ci": "detox test --configuration android.emu.release -l verbose --workers 2 --headless --gpu off --record-logs all --take-screenshots all",
"test:android-genycloud-release": "detox test --configuration android.genycloud.release",
"test:android-genycloud-release-ci": "detox test --configuration android.genycloud.release -l verbose --workers 2 --record-logs all --take-screenshots all"
},
@@ -18,6 +18,7 @@
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:exported="true"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
+2 -2
View File
@@ -11,12 +11,12 @@ module.exports = {
"ios.release": {
"type": "ios.app",
"binaryPath": "ios/build/Build/Products/Release-iphonesimulator/example.app",
"build": "export RCT_NO_LAUNCH_PACKAGER=true && xcodebuild -project ios/example.xcodeproj -UseNewBuildSystem=NO -scheme example -configuration Release -sdk iphonesimulator -derivedDataPath ios/build -quiet"
"build": "export RCT_NO_LAUNCH_PACKAGER=true && xcodebuild -workspace ios/example.xcworkspace -UseNewBuildSystem=NO -scheme example -configuration Release -sdk iphonesimulator -derivedDataPath ios/build -quiet"
},
"ios.debug": {
"type": "ios.app",
"binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/example.app",
"build": "xcodebuild -project ios/example.xcodeproj -UseNewBuildSystem=NO -scheme example -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build"
"build": "xcodebuild -workspace ios/example.xcworkspace -UseNewBuildSystem=NO -scheme example -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build"
},
"android.debug": {
"type": "android.apk",
+1 -1
View File
@@ -1,7 +1,7 @@
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
platform :ios, '10.0'
platform :ios, '11.0'
target 'example' do
config = use_native_modules!
@@ -304,7 +304,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEAD_CODE_STRIPPING = NO;
INFOPLIST_FILE = example/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
OTHER_LDFLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = com.wix.demo.react.native;
@@ -318,7 +318,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = example/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
OTHER_LDFLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = com.wix.demo.react.native;
@@ -350,7 +350,7 @@
ENABLE_BITCODE = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "arm64 ";
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
@@ -366,7 +366,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -397,7 +397,7 @@
ENABLE_BITCODE = NO;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "arm64 ";
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -406,7 +406,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
@@ -2,47 +2,52 @@
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
"scale" : "3x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
"scale" : "3x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
"scale" : "3x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
"scale" : "2x",
"size" : "60x60"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
"scale" : "3x",
"size" : "60x60"
},
{
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
"author" : "xcode",
"version" : 1
}
}
}
+2 -2
View File
@@ -15,7 +15,7 @@
"test:ios-release": "detox test --configuration ios.sim.release",
"test:android-debug": "detox test --configuration android.emu.debug",
"test:android-release": "detox test --configuration android.emu.release",
"test:android-release-ci": "detox test --configuration android.emu.release -l verbose --headless --record-logs all --take-screenshots all",
"test:android-release-ci": "detox test --configuration android.emu.release -l verbose --headless --gpu off --record-logs all --take-screenshots all",
"e2e:ios": "npm run build:ios && npm run test:ios",
"e2e:android-debug": "npm run build:android-debug && npm run test:android-debug",
"e2e:android-release": "npm run build:android-release && npm run test:android-release",
@@ -25,7 +25,7 @@
"dependencies": {
"@react-native-community/async-storage": "^1.12.0",
"react": "17.0.1",
"react-native": "0.64.1",
"react-native": "0.67.2",
"tslib": "^2.0.3"
},
"devDependencies": {
+5 -3
View File
@@ -1,11 +1,11 @@
const exec = require('shell-utils').exec;
const {log, logSection, getVersionSafe, releaseNpmTag} = require('./ci.common');
const {log, logSection, getVersionSafe, releaseNpmTag, getReleaseVersionType} = require('./ci.common');
function run() {
logSection('Initializing');
exec.execSync('lerna bootstrap --no-ci');
const versionType = process.env.RELEASE_VERSION_TYPE;
const versionType = getReleaseVersionType();
logSection(`Pre-calculating future version... (versionType=${versionType})`);
const npmTag = releaseNpmTag();
@@ -20,7 +20,9 @@ function run() {
exec.execSync(`yes | ${process.env.ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager --licenses`);
process.chdir('detox/android');
exec.execSync(`./gradlew clean detox:publish -Dversion=${futureVersion}`);
process.chdir('../..');
process.chdir('../Detox-android/');
exec.execSync(`tar -zcf ARCHIVE_${futureVersion}.tgz *`);
process.chdir(`../../`);
}
run();
+52 -6
View File
@@ -2,10 +2,43 @@
const semver = require('semver');
const fs = require('fs');
const chalk = require('chalk');
const cp = require('child_process');
const log = (...args) => console.log('[RELEASE]', ...args);
const logSection = (message) => console.log(chalk.blue(`[RELEASE] ${message}`));
// Export buildkite variables for Release build
// We cast toString() because 'buildkite-agent meta-data get' function returns 'object'
const BRANCH = process.env.BUILDKITE_BRANCH;
const RELEASE = process.env.BUILDKITE_MESSAGE.match(/^release$/i);
let RELEASE_VERSION_TYPE, RELEASE_NPM_TAG, RELEASE_DRY_RUN, RELEASE_SKIP_NPM, PRE_RELEASE;
if (RELEASE) {
RELEASE_VERSION_TYPE = cp.execSync(`buildkite-agent meta-data get release-version-type`).toString();
RELEASE_SKIP_NPM = cp.execSync(`buildkite-agent meta-data get release-skip-npm`).toString();
RELEASE_DRY_RUN = cp.execSync(`buildkite-agent meta-data get release-dry-run`).toString();
RELEASE_NPM_TAG = cp.execSync(`buildkite-agent meta-data get release-npm-tag`).toString();
PRE_RELEASE = cp.execSync(`buildkite-agent meta-data get pre-release`).toString();
}
function isRelease() {
return RELEASE;
}
function getReleaseVersionType() {
return (isPreRelease() ? 'pre' : '') + RELEASE_VERSION_TYPE;
}
function isPreRelease() {
return PRE_RELEASE === 'true';
}
function isSkipNpm() {
return RELEASE_SKIP_NPM === 'true';
}
function isDryRun() {
return RELEASE_DRY_RUN === 'true';
}
function getPackageJsonPath() {
return `${process.cwd()}/detox/package.json`;
}
@@ -22,19 +55,32 @@ function getVersionSafe() {
return version;
}
// If theres a npm tag, use it. Otherwise, if releasing from `master` branch, use a `prerelease` prefix for
// pre-releases, and "latest" otherwise, for non-master branches uses the branch name as the npm-tag.
function releaseNpmTag() {
if (process.env.RELEASE_NPM_TAG) {
return process.env.RELEASE_NPM_TAG;
} else if (process.env.BRANCH === 'master') {
return 'latest';
if (RELEASE_NPM_TAG !== 'null') {
return RELEASE_NPM_TAG;
} else if (BRANCH === 'master') {
return isPreRelease() ? 'prerelease' : 'latest';
} else {
return process.env.BRANCH;
return BRANCH.trim().replace(/[^a-zA-Z0-9-]/g, '.');
}
}
function getPackagesFromPreviousBuilds() {
cp.execSync(`buildkite-agent artifact download "**/Detox*.tbz" . --build ${process.env.BUILDKITE_BUILD_ID}`).toString();
cp.execSync(`buildkite-agent artifact download "**/ARCHIVE*.tgz" . --build ${process.env.BUILDKITE_BUILD_ID}`).toString();
cp.execSync(`find . -name "*.t[bg]z" -exec cp {} detox/ \\;`);
}
module.exports = {
log,
logSection,
getVersionSafe,
releaseNpmTag
releaseNpmTag,
getReleaseVersionType,
getPackagesFromPreviousBuilds,
isRelease,
isDryRun,
isSkipNpm
};
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash -ex
source $(dirname "$0")/ci.sh
source $(dirname "$0")/ci.sh 'noGenerate'
mkdir -p coverage
+8 -8
View File
@@ -1,9 +1,9 @@
/* tslint:disable: no-console */
const exec = require('shell-utils').exec;
const {log, logSection} = require('./ci.common');
const {log, logSection, getReleaseVersionType, isDryRun, isSkipNpm} = require('./ci.common');
function publishNewVersion(packageVersion, npmTag) {
function publishNewVersion(npmTag) {
validatePrerequisites();
projectSetup();
publishToNpm(npmTag);
@@ -18,23 +18,23 @@ function validatePrerequisites() {
function projectSetup() {
logSection('Project setup');
exec.execSync(`git checkout ${process.env.BRANCH}`);
exec.execSync(`git checkout ${process.env.BUILDKITE_BRANCH}`);
// exec.execSync(`lerna bootstrap --no-ci --loglevel verebose`);
}
function publishToNpm(npmTag) {
logSection('Lerna publish');
const versionType = process.env.RELEASE_VERSION_TYPE;
const dryRun = process.env.RELEASE_DRY_RUN === "true";
const skipNpm = process.env.RELEASE_SKIP_NPM === "true";
const versionType = getReleaseVersionType();
const dryRun = isDryRun();
const skipNpm = isSkipNpm();
if (dryRun) {
log('DRY RUN: Lerna-publishing without publishing to NPM');
}
else if (skipNpm) {
log('SKIP NPM is set: Lerna-publishing without publishing to NPM');
}
const preid = npmTag === 'latest'? '': `--preid=${npmTag}`;
const preid = versionType.includes("pre") ? `--preid=${npmTag}` : ``;
exec.execSync(`lerna publish ${versionType} --yes --dist-tag ${npmTag} ${preid} ${dryRun ? '--no-push': ''} ${(dryRun || skipNpm) ? '--skip-npm' : ''} -m "Publish %v [ci skip]" --tag-version-prefix='' --force-publish=detox --loglevel trace`);
}
+7 -12
View File
@@ -1,9 +1,9 @@
/* tslint:disable: no-console */
const exec = require('shell-utils').exec;
const fs = require('fs');
const {log, logSection, getVersionSafe, releaseNpmTag} = require('./ci.common');
const {log, logSection, getVersionSafe, releaseNpmTag, isRelease, getPackagesFromPreviousBuilds} = require('./ci.common');
const isRelease = (process.env.RELEASE_VERSION_TYPE && process.env.RELEASE_VERSION_TYPE !== 'none');
// const isRelease = getIsRelease();
function run() {
logSection('Script started');
@@ -14,19 +14,14 @@ function run() {
log('Configuring stuff...');
setupGitConfig();
setupNpmConfig();
getPackagesFromPreviousBuilds();
versionTagAndPublish();
}
function isEnvValid() {
if (!process.env.JENKINS_CI) {
if (!process.env.CI) {
throw new Error(`Release blocked: Not on a CI build machine!`);
}
if (!process.env.JENKINS_MASTER) {
log(`Release blocked: Not on jenkins' master build job!`);
return false;
}
return true;
}
@@ -58,11 +53,11 @@ function versionTagAndPublish() {
log(` package version: ${packageVersion}`);
const currentPublished = findCurrentPublishedVersion();
log(` current published version from ${process.env.BRANCH}: ${currentPublished}`);
log(` current published version from ${process.env.BUILDKITE_BRANCH}: ${currentPublished}`);
if (isRelease) {
if (isRelease()) {
const publishNewVersion = require('./ci.publish');
publishNewVersion(packageVersion, releaseNpmTag());
publishNewVersion(releaseNpmTag());
} else {
// Disabled for the time being
// const tagVersion = require('./ci.tagversion');
+6 -1
View File
@@ -10,4 +10,9 @@ fi
run_f "lerna bootstrap --no-ci"
run_f "lerna run build"
run_f "lerna run test"
if [ "$1" == 'noGenerate' ]; then
run_f "lerna run test --ignore=generation"
else
run_f "lerna run test"
fi
+4 -10
View File
@@ -2,13 +2,11 @@
source $(dirname "$0")/demo-projects.sh
#This solves a bug in brew
HOMEBREW_NO_AUTO_UPDATE=1 brew untap wix/brew
HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew
HOMEBREW_NO_AUTO_UPDATE=1 brew cask reinstall detox-instruments
#This must be built first as all other demo apps use this binary.
# This must be built first as all other demo apps use this binary.
pushd examples/demo-react-native
pushd ios
run_f "pod install"
popd
run_f "detox build -c ios.sim.release"
run_f "detox test -c ios.sim.release"
DETOX_EXPOSE_GLOBALS=0 run_f "detox test -c ios.sim.release"
@@ -18,7 +16,3 @@ pushd examples/demo-react-native-jest
run_f "npm run test:ios-release-ci"
DETOX_EXPOSE_GLOBALS=0 run_f "npm run test:ios-release-ci"
popd
pushd examples/demo-react-native-detox-instruments
run_f "detox test -c ios.sim.release --record-performance all"
popd
-4
View File
@@ -1,9 +1,5 @@
#!/bin/bash -e
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
export PATH=~/.npm-global/bin:$PATH
echo "Node version:"
node --version
+2 -15
View File
@@ -1,16 +1,13 @@
#!/bin/bash
export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY
export AWS_SECRET_ACCESS_KEY=$AWS_ACCESS_SECRET
DATE=`date '+%Y-%m-%d_%H-%M-%S'`
upload_artifacts() {
ARTIFACTS_DIR=$1
CONTEXT=$2
if [ $JENKINS_CI ]; then
ARTIFACTS_NAME="artifacts_${BUILD_ID}_${CONTEXT}_${DATE}.tar.gz"
if [ $CI ]; then
ARTIFACTS_NAME="artifacts_${BUILDKITE_BUILD_NUMBER}_${CONTEXT}_${DATE}.tar.gz"
else
ARTIFACTS_NAME="artifacts_${TRAVIS_BUILD_ID}_${CONTEXT}_${DATE}.tar.gz"
fi
@@ -18,16 +15,6 @@ upload_artifacts() {
if [ -d "$ARTIFACTS_DIR" ]; then
echo "Packing artifacts... (${CONTEXT})"
tar cvzf "${ARTIFACTS_NAME}" ${ARTIFACTS_DIR}
if [ $JENKINS_CI ]; then
echo "Upload: Jenkins will upload using built-in plugin"
else
echo "Uploading artifacts..."
aws s3 cp "${ARTIFACTS_NAME}" s3://detox-artifacts/ --region=us-east-1
fi
echo "The artifacts archive is available for download at:"
echo "https://detox-artifacts.s3.amazonaws.com/${ARTIFACTS_NAME}"
fi
}