mirror of
https://github.com/hanzoai/Detox.git
synced 2026-09-24 16:55:12 +00:00
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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'
|
||||
@@ -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
|
||||
@@ -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'
|
||||
Executable
+29
@@ -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
|
||||
Executable
+10
@@ -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
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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!');
|
||||
}
|
||||
|
||||
|
||||
+42
-37
@@ -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();
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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,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;
|
||||
|
||||
+24
-19
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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
@@ -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
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash -ex
|
||||
|
||||
source $(dirname "$0")/ci.sh
|
||||
source $(dirname "$0")/ci.sh 'noGenerate'
|
||||
|
||||
mkdir -p coverage
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user