create Jenkinsfile.combined and extract build teps
Signed-off-by: Jakub Sokołowski <jakub@status.im>
This commit is contained in:
parent
449e5257d5
commit
d38f74fdfd
|
@ -113,3 +113,6 @@ fastlane/README.md
|
|||
/package-lock.json
|
||||
/package.json
|
||||
/.re-natal
|
||||
|
||||
# Jenkins
|
||||
pkg
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
pipeline {
|
||||
agent { label 'macos' }
|
||||
|
||||
options {
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '10',
|
||||
daysToKeepStr: '30',
|
||||
artifactNumToKeepStr: '4',
|
||||
))
|
||||
}
|
||||
|
||||
environment {
|
||||
LANG = 'en_US.UTF-8'
|
||||
LANGUAGE = 'en_US.UTF-8'
|
||||
LC_ALL = 'en_US.UTF-8'
|
||||
FASTLANE_DISABLE_COLORS = 1
|
||||
REALM_DISABLE_ANALYTICS = 1
|
||||
ANDROID_HOME = '/usr/local/share/android-sdk'
|
||||
ANDROID_SDK_ROOT = '/usr/local/share/android-sdk'
|
||||
ANDROID_NDK = '/Users/jenkins/android-ndk-r10e'
|
||||
ANDROID_NDK_HOME = '/Users/jenkins/android-ndk-r10e'
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Prep') {
|
||||
steps {
|
||||
script {
|
||||
/* Necessary to load methods */
|
||||
mobile = load 'ci/mobile.groovy'
|
||||
mobile.prepDeps()
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Tests') {
|
||||
steps {
|
||||
script { mobile.runTests() }
|
||||
}
|
||||
}
|
||||
stage('Build') {
|
||||
steps {
|
||||
script { mobile.leinBuild() }
|
||||
}
|
||||
}
|
||||
stage('Compile') {
|
||||
steps {
|
||||
script { apk = mobile.compileAndroid(e2e: params.RUN_E2E) }
|
||||
}
|
||||
}
|
||||
stage('Bundle') {
|
||||
when { expression { !params.RUN_E2E } }
|
||||
steps {
|
||||
script { mobile.bundleAndroid() }
|
||||
}
|
||||
}
|
||||
stage('Archive') {
|
||||
when { expression { !params.RUN_E2E } }
|
||||
steps {
|
||||
script { archiveArtifacts apk }
|
||||
}
|
||||
}
|
||||
stage('Run e2e') {
|
||||
when { expression { params.RUN_E2E } }
|
||||
steps { script {
|
||||
apk = mobile.uploadSauceLabs()
|
||||
build(
|
||||
job: 'end-to-end-tests/status-app-nightly', wait: false,
|
||||
parameters: [string(name: 'apk', value: "--apk=${apk}")]
|
||||
)
|
||||
} }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
pipeline {
|
||||
agent { label 'master' }
|
||||
|
||||
options {
|
||||
disableConcurrentBuilds()
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '10',
|
||||
daysToKeepStr: '30',
|
||||
artifactNumToKeepStr: '10',
|
||||
))
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Tag') {
|
||||
steps { script {
|
||||
common = load('ci/common.groovy')
|
||||
/* to avoid race conditions in parallel builds */
|
||||
print "Build Number: ${common.tagBuild()}"
|
||||
} }
|
||||
}
|
||||
stage('Build') {
|
||||
parallel {
|
||||
stage('MacOS') {
|
||||
steps { script {
|
||||
osx = build('status-react/combined/desktop-macos')
|
||||
} }
|
||||
}
|
||||
stage('Linux') {
|
||||
steps { script {
|
||||
nix = build('status-react/combined/desktop-linux')
|
||||
} }
|
||||
}
|
||||
stage('iOS') {
|
||||
steps { script {
|
||||
ios = build('status-react/combined/mobile-ios')
|
||||
} }
|
||||
}
|
||||
stage('Android') {
|
||||
steps { script {
|
||||
dro = build('status-react/combined/mobile-android')
|
||||
} }
|
||||
}
|
||||
stage('Android e2e') {
|
||||
steps {
|
||||
build('status-react/combined/mobile-android-e2e')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Archive') {
|
||||
steps {
|
||||
sh('rm -f pkg/*')
|
||||
copyArtifacts(
|
||||
projectName: 'status-react/combined/mobile-ios', target: 'pkg',
|
||||
flatten: true, selector: specific("${ios.number}")
|
||||
)
|
||||
copyArtifacts(
|
||||
projectName: 'status-react/combined/mobile-android', target: 'pkg',
|
||||
flatten: true, selector: specific("${dro.number}")
|
||||
)
|
||||
copyArtifacts(
|
||||
projectName: 'status-react/combined/desktop-macos', target: 'pkg',
|
||||
flatten: true, selector: specific("${osx.number}")
|
||||
)
|
||||
copyArtifacts(
|
||||
projectName: 'status-react/combined/desktop-linux', target: 'pkg',
|
||||
flatten: true, selector: specific("${nix.number}")
|
||||
)
|
||||
archiveArtifacts('pkg/*')
|
||||
}
|
||||
}
|
||||
stage('Upload') {
|
||||
when { expression { params.PUBLISH } }
|
||||
steps { script {
|
||||
def pkg = "pkg/StatusIm-${GIT_COMMIT.take(6)}"
|
||||
apkUrl = common.uploadArtifact("${pkg}.apk")
|
||||
ipaUrl = common.uploadArtifact("${pkg}.ipa")
|
||||
dmgUrl = common.uploadArtifact("${pkg}.dmg")
|
||||
appUrl = common.uploadArtifact("${pkg}.AppImage")
|
||||
} }
|
||||
}
|
||||
stage('Notify') {
|
||||
steps {
|
||||
slackSend(
|
||||
message: (
|
||||
"Build success! "+
|
||||
"<${currentBuild.absoluteUrl}|${currentBuild.displayName}> "+
|
||||
"(${currentBuild.durationString})\n"+
|
||||
(params.PUBLISH ?
|
||||
"APK: ${apkUrl}\n"+
|
||||
"IPA: ${ipaUrl}\n"+
|
||||
"DMG: ${dmgUrl}\n"+
|
||||
"APP: ${appUrl}\n"
|
||||
: '')
|
||||
),
|
||||
color: 'good'
|
||||
)
|
||||
}
|
||||
}
|
||||
stage('Publish') {
|
||||
when { expression { params.PUBLISH } }
|
||||
steps {
|
||||
build(
|
||||
job: 'misc/status-im.github.io-update_env',
|
||||
parameters: [
|
||||
[name: 'APK_URL', value: apkUrl, $class: 'StringParameterValue'],
|
||||
[name: 'IOS_URL', value: ipaUrl, $class: 'StringParameterValue'],
|
||||
[name: 'DMG_URL', value: dmgUrl, $class: 'StringParameterValue'],
|
||||
[name: 'NIX_URL', value: appUrl, $class: 'StringParameterValue']
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
pipeline {
|
||||
agent { label 'fastlane' }
|
||||
|
||||
parameters {
|
||||
booleanParam(
|
||||
name: 'RUN_E2E',
|
||||
defaultValue: false,
|
||||
description: 'If true triggers end-to-end tests.'
|
||||
)
|
||||
}
|
||||
|
||||
options {
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '10',
|
||||
daysToKeepStr: '30',
|
||||
artifactNumToKeepStr: '1',
|
||||
))
|
||||
}
|
||||
|
||||
environment {
|
||||
LANG = 'en_US.UTF-8'
|
||||
LANGUAGE = 'en_US.UTF-8'
|
||||
LC_ALL = 'en_US.UTF-8'
|
||||
FASTLANE_DISABLE_COLORS=1
|
||||
REALM_DISABLE_ANALYTICS=1
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Prep') {
|
||||
steps {
|
||||
script {
|
||||
/* Necessary to load methods */
|
||||
mobile = load 'ci/mobile.groovy'
|
||||
mobile.prepDeps()
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Tests') {
|
||||
steps {
|
||||
script { mobile.runTests() }
|
||||
}
|
||||
}
|
||||
stage('Build') {
|
||||
steps {
|
||||
script { mobile.leinBuild() }
|
||||
}
|
||||
}
|
||||
stage('Compile') {
|
||||
steps {
|
||||
script { api = mobile.compileiOS() }
|
||||
}
|
||||
}
|
||||
stage('Archive') {
|
||||
steps {
|
||||
script { archiveArtifacts api }
|
||||
}
|
||||
}
|
||||
stage('Upload') {
|
||||
when { expression { params.RUN_E2E } }
|
||||
steps {
|
||||
script { env.DIAWI_URL = uploadiOS() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
pipeline {
|
||||
agent { label 'linux-new' }
|
||||
|
||||
options {
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '10',
|
||||
daysToKeepStr: '30',
|
||||
artifactNumToKeepStr: '1',
|
||||
))
|
||||
}
|
||||
|
||||
environment {
|
||||
LANG = 'en_US.UTF-8'
|
||||
LANGUAGE = 'en_US.UTF-8'
|
||||
LC_ALL = 'en_US.UTF-8'
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Prep') {
|
||||
steps {
|
||||
script {
|
||||
/* Necessary to load methods */
|
||||
desktop = load 'ci/desktop.groovy'
|
||||
desktop.prepDeps()
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Build') {
|
||||
steps {
|
||||
script { desktop.buildClojureScript() }
|
||||
}
|
||||
}
|
||||
stage('Compile') {
|
||||
steps {
|
||||
script { desktop.compileLinux() }
|
||||
}
|
||||
}
|
||||
stage('Bundle') {
|
||||
steps {
|
||||
script { app = desktop.bundleLinux() }
|
||||
}
|
||||
}
|
||||
stage('Archive') {
|
||||
steps { archiveArtifacts app }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
pipeline {
|
||||
agent { label 'macos' }
|
||||
|
||||
options {
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '10',
|
||||
daysToKeepStr: '30',
|
||||
artifactNumToKeepStr: '1',
|
||||
))
|
||||
}
|
||||
|
||||
environment {
|
||||
LANG = 'en_US.UTF-8'
|
||||
LANGUAGE = 'en_US.UTF-8'
|
||||
LC_ALL = 'en_US.UTF-8'
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Prep') {
|
||||
steps {
|
||||
script {
|
||||
/* Necessary to load methods */
|
||||
desktop = load 'ci/desktop.groovy'
|
||||
desktop.prepDeps()
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Build') {
|
||||
steps {
|
||||
script { desktop.buildClojureScript() }
|
||||
}
|
||||
}
|
||||
stage('Compile') {
|
||||
steps {
|
||||
script { desktop.compileMacOS() }
|
||||
}
|
||||
}
|
||||
stage('Bundle') {
|
||||
steps {
|
||||
script { dmg = desktop.bundleMacOS() }
|
||||
}
|
||||
}
|
||||
stage('Archive') {
|
||||
steps { archiveArtifacts dmg }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -150,7 +150,10 @@ timeout(90) {
|
|||
}
|
||||
|
||||
stage('Build (Android) for e2e tests') {
|
||||
sh 'cd android && mv app/build/outputs/apk/release/app-release.apk app/build/outputs/apk/release/app-release.original.apk && ENVFILE=.env.e2e ./gradlew assembleRelease'
|
||||
sh 'cd android && \
|
||||
mv app/build/outputs/apk/release/app-release.apk \
|
||||
app/build/outputs/apk/release/app-release.original.apk \
|
||||
&& ENVFILE=.env.e2e ./gradlew assembleRelease'
|
||||
}
|
||||
|
||||
stage('Upload apk for e2e tests') {
|
||||
|
|
|
@ -134,17 +134,19 @@ timeout(90) {
|
|||
}
|
||||
|
||||
stage('Upload apk for e2e tests') {
|
||||
env.SAUCE_LABS_APK = 'im.status.ethereum-e2e-' + shortCommit + '.apk'
|
||||
if (env.CHANGE_ID != null) {
|
||||
env.SAUCE_LABS_APK = 'im.status.ethereum-e2e-' + env.CHANGE_ID + '.apk'
|
||||
withCredentials([
|
||||
string(credentialsId: 'SAUCE_ACCESS_KEY', variable: 'SAUCE_ACCESS_KEY'),
|
||||
string(credentialsId: 'SAUCE_USERNAME', variable: 'SAUCE_USERNAME'),
|
||||
string(credentialsId: 'diawi-token', variable: 'DIAWI_TOKEN'),
|
||||
string(credentialsId: 'GIT_HUB_TOKEN', variable: 'GITHUB_TOKEN'),
|
||||
string(credentialsId: 'SLACK_JENKINS_WEBHOOK', variable: 'SLACK_URL')
|
||||
string(credentialsId: 'SAUCE_ACCESS_KEY', variable: 'SAUCE_ACCESS_KEY'),
|
||||
string(credentialsId: 'SAUCE_USERNAME', variable: 'SAUCE_USERNAME'),
|
||||
string(credentialsId: 'diawi-token', variable: 'DIAWI_TOKEN'),
|
||||
string(credentialsId: 'GIT_HUB_TOKEN', variable: 'GITHUB_TOKEN'),
|
||||
string(credentialsId: 'SLACK_JENKINS_WEBHOOK', variable: 'SLACK_URL')
|
||||
]) {
|
||||
sh 'fastlane android saucelabs'
|
||||
sh 'fastlane android upload_diawi'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Run extended e2e tests') {
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
def installJSDeps(platform) {
|
||||
def attempt = 1
|
||||
def maxAttempts = 10
|
||||
def installed = false
|
||||
/* prepare environment for specific platform build */
|
||||
sh "scripts/prepare-for-platform.sh ${platform}"
|
||||
while (!installed && attempt <= maxAttempts) {
|
||||
println "#${attempt} attempt to install npm deps"
|
||||
sh 'npm install'
|
||||
installed = fileExists('node_modules/web3/index.js')
|
||||
attemp = attempt + 1
|
||||
}
|
||||
}
|
||||
|
||||
def doGitRebase() {
|
||||
try {
|
||||
sh 'git rebase origin/develop'
|
||||
} catch (e) {
|
||||
sh 'git rebase --abort'
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
def tagBuild() {
|
||||
withCredentials([[
|
||||
$class: 'UsernamePasswordMultiBinding',
|
||||
credentialsId: 'status-im-auto',
|
||||
usernameVariable: 'GIT_USER',
|
||||
passwordVariable: 'GIT_PASS'
|
||||
]]) {
|
||||
return sh(
|
||||
returnStdout: true,
|
||||
script: './scripts/build_no.sh --increment'
|
||||
).trim()
|
||||
}
|
||||
}
|
||||
|
||||
def uploadArtifact(filename) {
|
||||
def domain = 'ams3.digitaloceanspaces.com'
|
||||
def bucket = 'status-im-desktop'
|
||||
withCredentials([usernamePassword(
|
||||
credentialsId: 'digital-ocean-access-keys',
|
||||
usernameVariable: 'DO_ACCESS_KEY',
|
||||
passwordVariable: 'DO_SECRET_KEY'
|
||||
)]) {
|
||||
sh """
|
||||
s3cmd \\
|
||||
--acl-public \\
|
||||
--host='${domain}' \\
|
||||
--host-bucket='%(bucket)s.${domain}' \\
|
||||
--access_key=${DO_ACCESS_KEY} \\
|
||||
--secret_key=${DO_SECRET_KEY} \\
|
||||
put ${filename} s3://${bucket}/
|
||||
"""
|
||||
}
|
||||
def url = "https://${bucket}.${domain}/${filename}"
|
||||
return url
|
||||
}
|
||||
|
||||
return this
|
|
@ -0,0 +1,183 @@
|
|||
common = load 'ci/common.groovy'
|
||||
|
||||
qtBin = '/opt/qt59/bin'
|
||||
packageFolder = './StatusImPackage'
|
||||
external_modules_dir = [
|
||||
'node_modules/react-native-i18n/desktop',
|
||||
'node_modules/react-native-config/desktop',
|
||||
'node_modules/react-native-fs/desktop',
|
||||
'node_modules/react-native-http-bridge/desktop',
|
||||
'node_modules/react-native-webview-bridge/desktop',
|
||||
'node_modules/react-native-keychain/desktop',
|
||||
'node_modules/react-native-securerandom/desktop',
|
||||
'modules/react-native-status/desktop',
|
||||
]
|
||||
|
||||
def cleanupBuild() {
|
||||
sh """
|
||||
rm -rf \\
|
||||
node_modules ${packageFolder} \\
|
||||
desktop/modules desktop/node_modules
|
||||
"""
|
||||
}
|
||||
|
||||
def cleanupAndDeps() {
|
||||
cleanupBuild()
|
||||
sh 'cp .env.jenkins .env'
|
||||
sh 'lein deps'
|
||||
common.installJSDeps('desktop')
|
||||
}
|
||||
|
||||
def slackNotify(message, color = 'good') {
|
||||
slackSend(
|
||||
color: color,
|
||||
channel: '#jenkins-desktop',
|
||||
message: "develop (${env.CHANGE_BRANCH}) ${message} ${env.BUILD_URL}"
|
||||
)
|
||||
}
|
||||
|
||||
def buildClojureScript() {
|
||||
sh 'rm -f index.desktop.js'
|
||||
sh 'lein prod-build-desktop'
|
||||
sh "mkdir ${packageFolder}"
|
||||
sh """
|
||||
react-native bundle \\
|
||||
--entry-file index.desktop.js \\
|
||||
--dev false --platform desktop \\
|
||||
--bundle-output ${packageFolder}/StatusIm.jsbundle \\
|
||||
--assets-dest ${packageFolder}/assets
|
||||
"""
|
||||
}
|
||||
|
||||
def uploadArtifact(filename) {
|
||||
def domain = 'ams3.digitaloceanspaces.com'
|
||||
def bucket = 'status-im-desktop'
|
||||
withCredentials([usernamePassword(
|
||||
credentialsId: 'digital-ocean-access-keys',
|
||||
usernameVariable: 'DO_ACCESS_KEY',
|
||||
passwordVariable: 'DO_SECRET_KEY'
|
||||
)]) {
|
||||
sh """
|
||||
s3cmd \\
|
||||
--acl-public \\
|
||||
--host='${domain}' \\
|
||||
--host-bucket='%(bucket)s.${domain}' \\
|
||||
--access_key=${DO_ACCESS_KEY} \\
|
||||
--secret_key=${DO_SECRET_KEY} \\
|
||||
put ${filename} s3://${bucket}/
|
||||
"""
|
||||
|
||||
}
|
||||
def url = "https://${bucket}.${domain}/${filename}"
|
||||
return url
|
||||
}
|
||||
|
||||
/* MAIN --------------------------------------------------*/
|
||||
|
||||
def prepDeps() {
|
||||
common.doGitRebase()
|
||||
cleanupAndDeps()
|
||||
}
|
||||
|
||||
def compileLinux() {
|
||||
/* add path for QT installation binaries */
|
||||
env.PATH = "${qtBin}:${env.PATH}"
|
||||
dir('desktop') {
|
||||
sh 'rm -rf CMakeFiles CMakeCache.txt cmake_install.cmake Makefile'
|
||||
sh """
|
||||
cmake -Wno-dev \\
|
||||
-DCMAKE_BUILD_TYPE=Release \\
|
||||
-DEXTERNAL_MODULES_DIR='${external_modules_dir.join(";")}' \\
|
||||
-DJS_BUNDLE_PATH='${workspace}/${packageFolder}/StatusIm.jsbundle' \\
|
||||
-DCMAKE_CXX_FLAGS:='-DBUILD_FOR_BUNDLE=1'
|
||||
"""
|
||||
sh 'make'
|
||||
}
|
||||
}
|
||||
|
||||
def bundleLinux() {
|
||||
def appFile
|
||||
|
||||
dir(packageFolder) {
|
||||
sh 'rm -rf StatusImAppImage'
|
||||
/* TODO this needs to be fixed: status-react/issues/5378 */
|
||||
sh 'cp /opt/StatusImAppImage.zip ./'
|
||||
sh 'unzip ./StatusImAppImage.zip'
|
||||
sh 'rm -rf AppDir'
|
||||
sh 'mkdir AppDir'
|
||||
}
|
||||
sh "cp -r ./deployment/linux/usr ${packageFolder}/AppDir"
|
||||
sh "cp ./deployment/linux/.env ${packageFolder}/AppDir"
|
||||
sh "cp ./desktop/bin/StatusIm ${packageFolder}/AppDir/usr/bin"
|
||||
sh 'wget https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage'
|
||||
sh 'chmod a+x ./linuxdeployqt-continuous-x86_64.AppImage'
|
||||
|
||||
sh 'rm -f Application-x86_64.AppImage'
|
||||
sh 'rm -f StatusIm-x86_64.AppImage'
|
||||
|
||||
sh "ldd ${packageFolder}/AppDir/usr/bin/StatusIm"
|
||||
sh """
|
||||
./linuxdeployqt-continuous-x86_64.AppImage \\
|
||||
${packageFolder}/AppDir/usr/share/applications/StatusIm.desktop \\
|
||||
-verbose=3 -always-overwrite -no-strip \\
|
||||
-no-translations -bundle-non-qt-libs \\
|
||||
-qmake=${qtBin}/qmake \\
|
||||
-extra-plugins=imageformats/libqsvg.so \\
|
||||
-qmldir='${workspace}/node_modules/react-native'
|
||||
"""
|
||||
dir(packageFolder) {
|
||||
sh 'ldd AppDir/usr/bin/StatusIm'
|
||||
sh 'cp -r assets/share/assets AppDir/usr/bin'
|
||||
sh 'cp -rf StatusImAppImage/* AppDir/usr/bin'
|
||||
sh 'rm -f AppDir/usr/bin/StatusIm.AppImage'
|
||||
}
|
||||
sh """
|
||||
./linuxdeployqt-continuous-x86_64.AppImage \\
|
||||
${packageFolder}/AppDir/usr/share/applications/StatusIm.desktop \\
|
||||
-verbose=3 -appimage -qmake=${qtBin}/qmake
|
||||
"""
|
||||
dir(packageFolder) {
|
||||
sh 'ldd AppDir/usr/bin/StatusIm'
|
||||
sh 'rm -rf StatusIm.AppImage'
|
||||
appFile = "StatusIm-${GIT_COMMIT.take(6)}.AppImage"
|
||||
sh "mv ../StatusIm-x86_64.AppImage ${appFile}"
|
||||
}
|
||||
return "${packageFolder}/${appFile}".drop(2)
|
||||
}
|
||||
|
||||
def compileMacOS() {
|
||||
/* add path for QT installation binaries */
|
||||
env.PATH = "/Users/administrator/qt/5.9.1/clang_64/bin:${env.PATH}"
|
||||
dir('desktop') {
|
||||
sh 'rm -rf CMakeFiles CMakeCache.txt cmake_install.cmake Makefile'
|
||||
sh """
|
||||
cmake -Wno-dev \\
|
||||
-DCMAKE_BUILD_TYPE=Release \\
|
||||
-DEXTERNAL_MODULES_DIR='${external_modules_dir.join(";")}' \\
|
||||
-DJS_BUNDLE_PATH='${workspace}/${packageFolder}/StatusIm.jsbundle' \\
|
||||
-DCMAKE_CXX_FLAGS:='-DBUILD_FOR_BUNDLE=1'
|
||||
"""
|
||||
sh 'make'
|
||||
}
|
||||
}
|
||||
|
||||
def bundleMacOS() {
|
||||
def dmgFile
|
||||
dir(packageFolder) {
|
||||
sh 'git clone https://github.com/vkjr/StatusAppFiles.git'
|
||||
sh 'unzip StatusAppFiles/StatusIm.app.zip'
|
||||
sh 'cp -r assets/share/assets StatusIm.app/Contents/MacOs'
|
||||
sh 'chmod +x StatusIm.app/Contents/MacOs/ubuntu-server'
|
||||
sh 'cp ../desktop/bin/StatusIm StatusIm.app/Contents/MacOs'
|
||||
sh """
|
||||
macdeployqt StatusIm.app -verbose=1 -dmg \\
|
||||
-qmldir='${workspace}/node_modules/react-native/ReactQt/runtime/src/qml/'
|
||||
"""
|
||||
sh 'rm -fr StatusAppFiles'
|
||||
dmgFile = "StatusIm-${GIT_COMMIT.take(6)}.dmg"
|
||||
sh "mv StatusIm.dmg ${dmgFile}"
|
||||
}
|
||||
return "${packageFolder}/${dmgFile}".drop(2)
|
||||
}
|
||||
|
||||
return this
|
|
@ -0,0 +1,102 @@
|
|||
common = load 'ci/common.groovy'
|
||||
|
||||
def uploadArtifact() {
|
||||
def artifact_dir = pwd() + '/android/app/build/outputs/apk/release/'
|
||||
println (artifact_dir + 'app-release.apk')
|
||||
def artifact = (artifact_dir + 'app-release.apk')
|
||||
def server = Artifactory.server('artifacts')
|
||||
def filename = "im.status.ethereum-${GIT_COMMIT.take(6)}-n-fl.apk"
|
||||
def newArtifact = (artifact_dir + filename)
|
||||
sh "cp ${artifact} ${newArtifact}"
|
||||
def uploadSpec = '{ "files": [ { "pattern": "*apk/release/' + filename + '", "target": "nightlies-local" }]}'
|
||||
def buildInfo = server.upload(uploadSpec)
|
||||
return 'http://artifacts.status.im:8081/artifactory/nightlies-local/' + filename
|
||||
}
|
||||
|
||||
def prepDeps() {
|
||||
sh 'rm -rf node_modules'
|
||||
sh 'cp .env.nightly .env'
|
||||
common.installJSDeps('mobile')
|
||||
sh 'mvn -f modules/react-native-status/ios/RCTStatus dependency:unpack'
|
||||
/* generate ios/StatusIm.xcworkspace */
|
||||
dir('ios') {
|
||||
sh 'pod install'
|
||||
}
|
||||
}
|
||||
|
||||
def runTests() {
|
||||
sh 'lein test-cljs'
|
||||
}
|
||||
|
||||
def leinBuild() {
|
||||
sh 'lein prod-build'
|
||||
}
|
||||
|
||||
def compileAndroid(e2e = false) {
|
||||
build_no = common.tagBuild()
|
||||
if (e2e) {
|
||||
env.ENVFILE=".env.e2e"
|
||||
}
|
||||
dir('android') {
|
||||
sh './gradlew react-native-android:installArchives'
|
||||
sh './gradlew assembleRelease'
|
||||
}
|
||||
def pkg = "StatusIm-${GIT_COMMIT.take(6)}.apk"
|
||||
sh "cp android/app/build/outputs/apk/release/app-release.apk ${pkg}"
|
||||
return pkg
|
||||
}
|
||||
|
||||
def bundleAndroid() {
|
||||
withCredentials([
|
||||
string(credentialsId: "SUPPLY_JSON_KEY_DATA", variable: 'GOOGLE_PLAY_JSON_KEY'),
|
||||
string(credentialsId: "SLACK_URL", variable: 'SLACK_URL')
|
||||
]) {
|
||||
sh 'bundle exec fastlane android nightly'
|
||||
}
|
||||
}
|
||||
|
||||
def uploadSauceLabs() {
|
||||
env.SAUCE_LABS_APK = "im.status.ethereum-e2e-${GIT_COMMIT.take(6)}.apk"
|
||||
withCredentials([
|
||||
string(credentialsId: 'SAUCE_ACCESS_KEY', variable: 'SAUCE_ACCESS_KEY'),
|
||||
string(credentialsId: 'SAUCE_USERNAME', variable: 'SAUCE_USERNAME'),
|
||||
string(credentialsId: 'GIT_HUB_TOKEN', variable: 'GITHUB_TOKEN'),
|
||||
string(credentialsId: 'SLACK_JENKINS_WEBHOOK', variable: 'SLACK_URL')
|
||||
]) {
|
||||
sh 'fastlane android saucelabs'
|
||||
}
|
||||
return env.SAUCE_LABS_APK
|
||||
}
|
||||
|
||||
def compileiOS() {
|
||||
version = readFile("${env.WORKSPACE}/VERSION").trim()
|
||||
build_no = common.tagBuild()
|
||||
withCredentials([
|
||||
string(credentialsId: 'SLACK_URL', variable: 'SLACK_URL'),
|
||||
string(credentialsId: "slave-pass-${env.NODE_NAME}", variable: 'KEYCHAIN_PASSWORD'),
|
||||
string(credentialsId: 'FASTLANE_PASSWORD', variable: 'FASTLANE_PASSWORD'),
|
||||
string(credentialsId: 'APPLE_ID', variable: 'APPLE_ID'),
|
||||
string(credentialsId: 'fastlane-match-password', variable:'MATCH_PASSWORD')
|
||||
]) {
|
||||
sh "plutil -replace CFBundleShortVersionString -string ${version} ios/StatusIm/Info.plist"
|
||||
sh "plutil -replace CFBundleVersion -string ${build_no} ios/StatusIm/Info.plist"
|
||||
sh 'fastlane ios nightly'
|
||||
}
|
||||
def pkg = "StatusIm-${GIT_COMMIT.take(6)}.ipa"
|
||||
sh "cp status-adhoc/StatusIm.ipa ${pkg}"
|
||||
return pkg
|
||||
}
|
||||
|
||||
def uploadiOS() {
|
||||
withCredentials([
|
||||
string(credentialsId: 'diawi-token', variable: 'DIAWI_TOKEN'),
|
||||
string(credentialsId: 'GIT_HUB_TOKEN', variable: 'GITHUB_TOKEN'),
|
||||
string(credentialsId: 'SLACK_JENKINS_WEBHOOK', variable: 'SLACK_URL')
|
||||
]) {
|
||||
sh 'fastlane android upload_diawi'
|
||||
}
|
||||
diawiUrl = readFile "${env.WORKSPACE}/fastlane/diawi.out"
|
||||
return diawiUrl
|
||||
}
|
||||
|
||||
return this
|
|
@ -156,9 +156,6 @@ platform :ios do
|
|||
export_method: "app-store",
|
||||
output_directory: "status_appstore"
|
||||
)
|
||||
upload_to_testflight(
|
||||
ipa: "status_appstore/StatusIm.ipa"
|
||||
)
|
||||
|
||||
slack(
|
||||
message: "New nightly build uploaded to TestFlight",
|
||||
|
@ -227,7 +224,6 @@ platform :ios do
|
|||
)
|
||||
end
|
||||
|
||||
|
||||
desc "This fastlane step is a workaround!"
|
||||
desc "every now and then Realm fails on iOS on the 'Download Core` step"
|
||||
desc "the issue is because multiple downloads use the same temp dir"
|
||||
|
@ -241,6 +237,10 @@ platform :ios do
|
|||
)
|
||||
end
|
||||
|
||||
desc "This fastlane step cleans up XCode DerivedData folder"
|
||||
lane :cleanup do
|
||||
clear_derived_data
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
set -e
|
||||
|
||||
#
|
||||
# This script manages app build numbers.
|
||||
# It returns the next build number to be used.
|
||||
|
@ -21,7 +18,7 @@ set -e
|
|||
#
|
||||
|
||||
getNumber () {
|
||||
echo "$BUILD" | sed 's/[^0-9]*//g'
|
||||
echo "$1" | sed 's/[^0-9]*//g'
|
||||
}
|
||||
|
||||
REGEX='^build-[0-9]\+$'
|
||||
|
@ -29,28 +26,45 @@ REGEX='^build-[0-9]\+$'
|
|||
# make sure we have all the tags
|
||||
git fetch --tags --quiet >/dev/null || >&2 echo "Could not fetch tags from remote"
|
||||
|
||||
# even if the current commit has a tag already, it is normal that the same commit
|
||||
# is built multiple times (with different build configurations, for instance),
|
||||
# so we increment the build number every time.
|
||||
# check if current commit has a build tag
|
||||
# since we are building in separate jobs we have to check for a tag
|
||||
BUILD_TAG=$(git tag --points-at HEAD | grep -e "$REGEX")
|
||||
|
||||
# chech for multiple lines
|
||||
if [ 1 -lt $(echo "$BUILD_TAG" | grep -c -) ]; then
|
||||
echo "Commit marked with more than one build tag!" >&2
|
||||
echo "$BUILD_TAG" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# use already existing build number if applicable
|
||||
if [ -n "$BUILD_TAG" ]; then
|
||||
echo "Current commit already tagged: $BUILD_TAG" >&2
|
||||
getNumber $BUILD_TAG
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# if no tag was found and --increment was not given stop
|
||||
if [ "$1" != "--increment" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# find the last used build number
|
||||
BUILD=$(git tag -l --sort=-v:refname | grep -e "$REGEX" | head -n 1)
|
||||
# extract the number
|
||||
BUILD_NO=$(getNumber "$BUILD")
|
||||
|
||||
if [ "$1" = "--increment" ]; then
|
||||
# These need to be provided by Jenkins
|
||||
if [ -z "${GIT_USER}" ] || [ -z "${GIT_PASS}" ]; then
|
||||
echo "Git credentials not specified! (GIT_USER, GIT_PASS)" >&2
|
||||
exit 1
|
||||
fi
|
||||
# increment
|
||||
BUILD_NO="$((BUILD_NO+1))"
|
||||
|
||||
echo "Tagging HEAD: build-$BUILD_NO" >&2
|
||||
git tag "build-$BUILD_NO" HEAD
|
||||
git push --tags https://${GIT_USER}:${GIT_PASS}@github.com/status-im/status-react
|
||||
# These need to be provided by Jenkins
|
||||
if [ -z "${GIT_USER}" ] || [ -z "${GIT_PASS}" ]; then
|
||||
echo "Git credentials not specified! (GIT_USER, GIT_PASS)" >&2
|
||||
exit 1
|
||||
fi
|
||||
# increment
|
||||
BUILD_NO="$((BUILD_NO+1))"
|
||||
|
||||
echo "Tagging HEAD: build-$BUILD_NO" >&2
|
||||
git tag "build-$BUILD_NO" HEAD
|
||||
git push --tags https://${GIT_USER}:${GIT_PASS}@github.com/status-im/status-react
|
||||
|
||||
# finally print build number
|
||||
echo "$BUILD_NO"
|
||||
|
|
Loading…
Reference in New Issue