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-lock.json
|
||||||
/package.json
|
/package.json
|
||||||
/.re-natal
|
/.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') {
|
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') {
|
stage('Upload apk for e2e tests') {
|
||||||
|
|
|
@ -134,7 +134,8 @@ timeout(90) {
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('Upload apk for e2e tests') {
|
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([
|
withCredentials([
|
||||||
string(credentialsId: 'SAUCE_ACCESS_KEY', variable: 'SAUCE_ACCESS_KEY'),
|
string(credentialsId: 'SAUCE_ACCESS_KEY', variable: 'SAUCE_ACCESS_KEY'),
|
||||||
string(credentialsId: 'SAUCE_USERNAME', variable: 'SAUCE_USERNAME'),
|
string(credentialsId: 'SAUCE_USERNAME', variable: 'SAUCE_USERNAME'),
|
||||||
|
@ -146,6 +147,7 @@ timeout(90) {
|
||||||
sh 'fastlane android upload_diawi'
|
sh 'fastlane android upload_diawi'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
stage('Run extended e2e tests') {
|
stage('Run extended e2e tests') {
|
||||||
build job: 'end-to-end-tests/status-app-nightly', parameters: [string(name: 'apk', value: '--apk=' + env.SAUCE_LABS_APK)], wait: false
|
build job: 'end-to-end-tests/status-app-nightly', parameters: [string(name: 'apk', value: '--apk=' + env.SAUCE_LABS_APK)], wait: false
|
||||||
|
|
|
@ -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",
|
export_method: "app-store",
|
||||||
output_directory: "status_appstore"
|
output_directory: "status_appstore"
|
||||||
)
|
)
|
||||||
upload_to_testflight(
|
|
||||||
ipa: "status_appstore/StatusIm.ipa"
|
|
||||||
)
|
|
||||||
|
|
||||||
slack(
|
slack(
|
||||||
message: "New nightly build uploaded to TestFlight",
|
message: "New nightly build uploaded to TestFlight",
|
||||||
|
@ -227,7 +224,6 @@ platform :ios do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
desc "This fastlane step is a workaround!"
|
desc "This fastlane step is a workaround!"
|
||||||
desc "every now and then Realm fails on iOS on the 'Download Core` step"
|
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"
|
desc "the issue is because multiple downloads use the same temp dir"
|
||||||
|
@ -241,6 +237,10 @@ platform :ios do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
desc "This fastlane step cleans up XCode DerivedData folder"
|
||||||
|
lane :cleanup do
|
||||||
|
clear_derived_data
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# This script manages app build numbers.
|
# This script manages app build numbers.
|
||||||
# It returns the next build number to be used.
|
# It returns the next build number to be used.
|
||||||
|
@ -21,7 +18,7 @@ set -e
|
||||||
#
|
#
|
||||||
|
|
||||||
getNumber () {
|
getNumber () {
|
||||||
echo "$BUILD" | sed 's/[^0-9]*//g'
|
echo "$1" | sed 's/[^0-9]*//g'
|
||||||
}
|
}
|
||||||
|
|
||||||
REGEX='^build-[0-9]\+$'
|
REGEX='^build-[0-9]\+$'
|
||||||
|
@ -29,28 +26,45 @@ REGEX='^build-[0-9]\+$'
|
||||||
# make sure we have all the tags
|
# make sure we have all the tags
|
||||||
git fetch --tags --quiet >/dev/null || >&2 echo "Could not fetch tags from remote"
|
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
|
# check if current commit has a build tag
|
||||||
# is built multiple times (with different build configurations, for instance),
|
# since we are building in separate jobs we have to check for a tag
|
||||||
# so we increment the build number every time.
|
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
|
# find the last used build number
|
||||||
BUILD=$(git tag -l --sort=-v:refname | grep -e "$REGEX" | head -n 1)
|
BUILD=$(git tag -l --sort=-v:refname | grep -e "$REGEX" | head -n 1)
|
||||||
# extract the number
|
# extract the number
|
||||||
BUILD_NO=$(getNumber "$BUILD")
|
BUILD_NO=$(getNumber "$BUILD")
|
||||||
|
|
||||||
if [ "$1" = "--increment" ]; then
|
# These need to be provided by Jenkins
|
||||||
# These need to be provided by Jenkins
|
if [ -z "${GIT_USER}" ] || [ -z "${GIT_PASS}" ]; then
|
||||||
if [ -z "${GIT_USER}" ] || [ -z "${GIT_PASS}" ]; then
|
|
||||||
echo "Git credentials not specified! (GIT_USER, GIT_PASS)" >&2
|
echo "Git credentials not specified! (GIT_USER, GIT_PASS)" >&2
|
||||||
exit 1
|
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
|
|
||||||
fi
|
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
|
# finally print build number
|
||||||
echo "$BUILD_NO"
|
echo "$BUILD_NO"
|
||||||
|
|
Loading…
Reference in New Issue