mirror of
https://github.com/status-im/react-native.git
synced 2025-01-10 17:45:59 +00:00
8c7b32d5f1
Summary: ericvicenti - Here are necessary updates for the the testing container workflow. normanjoyner Temporarily disabled E2E tests on the Containership Jenkins pipeline because they seemed to be sporadically failing and slow down the run rate of CI tests. * Run all stages and parallel branches in testing suite even if one fails (just mark the overall job as failed) * Added update to docker tag name to convert spaces to hyphens to cover edge case where the project name may have spaces * Updated buck to more recent version in the base image * Remove duplicate module provider from `.flowconfig` * Correctly exit with status code from failed instrumentation tests * Add JSCHeaders to prepare for testing on stage branches * Fix bug in filtering of failed instrumentation tests * Turn down retry count to 1 for E2E tests and temporarily disable * Add retry3 count to the apk install from buck * Updated base image to install android SDKs through grepping since the IDs update frequ Closes https://github.com/facebook/react-native/pull/13032 Differential Revision: D4799015 Pulled By: ericvicenti fbshipit-source-id: bbac9303e8ca4fe8be0e8b230a2f863c71c3366c
207 lines
6.8 KiB
Groovy
207 lines
6.8 KiB
Groovy
import groovy.json.JsonSlurperClassic
|
|
|
|
def runPipeline() {
|
|
try {
|
|
ansiColor('xterm') {
|
|
runStages();
|
|
}
|
|
} catch(err) {
|
|
echo "Error: ${err}"
|
|
currentBuild.result = "FAILED"
|
|
}
|
|
}
|
|
|
|
def pullDockerImage(imageName) {
|
|
def result = sh(script: "docker pull ${imageName}", returnStatus: true)
|
|
|
|
if (result != 0) {
|
|
throw new Exception("Failed to pull image[${imageName}]")
|
|
}
|
|
}
|
|
|
|
def buildDockerfile(dockerfilePath = "Dockerfile", imageName) {
|
|
def buildCmd = "docker build -f ${dockerfilePath} -t ${imageName} ."
|
|
echo "${buildCmd}"
|
|
|
|
def result = sh(script: buildCmd, returnStatus: true)
|
|
|
|
if (result != 0) {
|
|
throw new Exception("Failed to build image[${imageName}] from '${dockerfilePath}'")
|
|
}
|
|
}
|
|
|
|
def runCmdOnDockerImage(imageName, cmd, run_opts = '') {
|
|
def result = sh(script: "docker run ${run_opts} -i ${imageName} sh -c '${cmd}'", returnStatus: true)
|
|
|
|
if(result != 0) {
|
|
throw new Exception("Failed to run cmd[${cmd}] on image[${imageName}]")
|
|
}
|
|
}
|
|
|
|
def calculateGithubInfo() {
|
|
return [
|
|
branch: env.BRANCH_NAME,
|
|
sha: sh(returnStdout: true, script: 'git rev-parse HEAD').trim(),
|
|
tag: null,
|
|
isPR: "${env.CHANGE_URL}".contains('/pull/')
|
|
]
|
|
}
|
|
|
|
def getParallelInstrumentationTests(testDir, parallelCount, imageName) {
|
|
def integrationTests = [:]
|
|
def testCount = sh(script: "ls ${testDir} | wc -l", returnStdout: true).trim().toInteger()
|
|
def testPerParallel = testCount.intdiv(parallelCount) + 1
|
|
|
|
for (def x = 0; (x*testPerParallel) < testCount; x++) {
|
|
def offset = x
|
|
integrationTests["android integration tests: ${offset}"] = {
|
|
run: {
|
|
runCmdOnDockerImage(imageName, "bash /app/ContainerShip/scripts/run-android-docker-instrumentation-tests.sh --offset=${offset} --count=${testPerParallel}", '--privileged --rm')
|
|
}
|
|
}
|
|
}
|
|
|
|
return integrationTests
|
|
}
|
|
|
|
def runStages() {
|
|
def buildInfo = [
|
|
image: [
|
|
name: "facebook/react-native",
|
|
tag: null
|
|
],
|
|
scm: [
|
|
branch: null,
|
|
sha: null,
|
|
tag: null,
|
|
isPR: false
|
|
]
|
|
]
|
|
|
|
node {
|
|
def jsDockerBuild, androidDockerBuild
|
|
def jsTag, androidTag, jsImageName, androidImageName, parallelInstrumentationTests
|
|
|
|
try {
|
|
stage('Setup') {
|
|
parallel(
|
|
'pull images': {
|
|
pullDockerImage('containership/android-base:latest')
|
|
}
|
|
)
|
|
}
|
|
|
|
stage('Build') {
|
|
checkout scm
|
|
|
|
def githubInfo = calculateGithubInfo()
|
|
buildInfo.scm.branch = githubInfo.branch
|
|
buildInfo.scm.sha = githubInfo.sha
|
|
buildInfo.scm.tag = githubInfo.tag
|
|
buildInfo.scm.isPR = githubInfo.isPR
|
|
buildInfo.image.tag = "${buildInfo.scm.sha}-${env.BUILD_TAG.replace(" ", "-").replace("/", "-").replace("%2F", "-")}"
|
|
|
|
jsTag = "${buildInfo.image.tag}"
|
|
androidTag = "${buildInfo.image.tag}"
|
|
jsImageName = "${buildInfo.image.name}-js:${jsTag}"
|
|
androidImageName = "${buildInfo.image.name}-android:${androidTag}"
|
|
|
|
parallelInstrumentationTests = getParallelInstrumentationTests('./ReactAndroid/src/androidTest/java/com/facebook/react/tests', 1, androidImageName)
|
|
|
|
parallel(
|
|
'javascript build': {
|
|
jsDockerBuild = docker.build("${jsImageName}", "-f ContainerShip/Dockerfile.javascript .")
|
|
},
|
|
'android build': {
|
|
androidDockerBuild = docker.build("${androidImageName}", "-f ContainerShip/Dockerfile.android .")
|
|
}
|
|
)
|
|
|
|
}
|
|
|
|
stage('Tests JS') {
|
|
try {
|
|
parallel(
|
|
'javascript flow': {
|
|
runCmdOnDockerImage(jsImageName, 'yarn run flow -- check', '--rm')
|
|
},
|
|
'javascript tests': {
|
|
runCmdOnDockerImage(jsImageName, 'yarn test --maxWorkers=4', '--rm')
|
|
},
|
|
'documentation tests': {
|
|
runCmdOnDockerImage(jsImageName, 'cd website && yarn test', '--rm')
|
|
},
|
|
'documentation generation': {
|
|
runCmdOnDockerImage(jsImageName, 'cd website && node ./server/generate.js', '--rm')
|
|
}
|
|
)
|
|
} catch(e) {
|
|
currentBuild.result = "FAILED"
|
|
echo "Test JS Stage Error: ${e}"
|
|
}
|
|
}
|
|
|
|
stage('Tests Android') {
|
|
try {
|
|
parallel(
|
|
'android unit tests': {
|
|
runCmdOnDockerImage(androidImageName, 'bash /app/ContainerShip/scripts/run-android-docker-unit-tests.sh', '--privileged --rm')
|
|
},
|
|
'android e2e tests': {
|
|
// temporarily disable e2e tests, they have a high transient failure rate
|
|
// runCmdOnDockerImage(androidImageName, 'bash /app/ContainerShip/scripts/run-ci-e2e-tests.sh --android --js', '--rm')
|
|
echo "Android E2E tests have been temporarily disabled"
|
|
}
|
|
)
|
|
} catch(e) {
|
|
currentBuild.result = "FAILED"
|
|
echo "Tests Android Stage Error: ${e}"
|
|
}
|
|
}
|
|
|
|
stage('Tests Android Instrumentation') {
|
|
// run all tests in parallel
|
|
try {
|
|
parallel(parallelInstrumentationTests)
|
|
} catch(e) {
|
|
currentBuild.result = "FAILED"
|
|
echo "Tests Android Instrumentation Stage Error: ${e}"
|
|
}
|
|
}
|
|
|
|
stage('Cleanup') {
|
|
cleanupImage(jsDockerBuild)
|
|
cleanupImage(androidDockerBuild)
|
|
}
|
|
} catch(err) {
|
|
cleanupImage(jsDockerBuild)
|
|
cleanupImage(androidDockerBuild)
|
|
|
|
throw err
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
def isMasterBranch() {
|
|
return env.GIT_BRANCH == 'master'
|
|
}
|
|
|
|
def gitCommit() {
|
|
return sh(returnStdout: true, script: 'git rev-parse HEAD').trim()
|
|
}
|
|
|
|
def cleanupImage(image) {
|
|
if (image) {
|
|
try {
|
|
sh "docker ps -a | awk '{ print \$1,\$2 }' | grep ${image.id} | awk '{print \$1 }' | xargs -I {} docker rm {}"
|
|
sh "docker rmi -f ${image.id}"
|
|
} catch(e) {
|
|
echo "Error cleaning up ${image.id}"
|
|
echo "${e}"
|
|
}
|
|
}
|
|
}
|
|
|
|
runPipeline()
|