diff --git a/Jenkinsfile b/Jenkinsfile index 74ccc48..1e544c2 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -22,7 +22,7 @@ // Load Jenkins shared libraries common to all projects def libCmn = [ remote: 'https://code.in.digital-me.nl/git/DEVops/JenkinsLibLazy.git', - branch: env.BRANCH_NAME, + branch: 'master', credentialsId: null, ] @@ -35,48 +35,22 @@ ]) ) -// Initialize lazyConfig for this pipeline -lazyConfig( - name: 'DummyAnd', +// Load Jenkins shared libraries to customize this project +def libCst = [ + remote: 'ssh://git@code.in.digital-me.nl:2222/DEVops/JenkinsLibCustom.git', + branch: 'master', + credentialsId: 'bot-ci-dgm-rsa', +] + +library( + identifier: "libCst@${libCst.branch}", + retriever: modernSCM([ + $class: 'GitSCMSource', + remote: libCst.remote, + credentialsId: libCst.credentialsId + ]) ) -// Define a method to run Fastlane from the later lazyStages -def fastlane(platform, lane) { - // Lookup the relevant credentials first - if (platform == 'android') { - usernamePasswordMap = [ - credentialsId: 'dappre-google', - passwordVariable: 'ANDROID_KEYPASSWORD', - usernameVariable: 'ANDROID_KEYALIAS' - ] - } else { - error "Unknown platform '${plateform}'" - } - - // With the credentials, prepare the relevant environment - withCredentials([usernamePassword(usernamePasswordMap)]){ - if (platform == 'android' ) { - envMap = [ - 'SKIP_SLOW_FASTLANE_WARNING=YES', - 'FASTLANE_SKIP_UPDATE_CHECK=YES', - 'FASTLANE_OPT_OUT_USAGE=YES', - "ANDROID_STOREFILE=/opt/certificates/${ANDROID_KEYALIAS}.jks", - "ANDROID_STOREPASSWORD=${ANDROID_KEYPASSWORD}", - 'JAVA_HOME=/usr/java/latest', - 'SLAVE_AAPT_TIMEOUT=15', - ] - } else { - error "Unknown platform '${plateform}'" - } - - // Now only calling Fastlane - withEnv(envMap) { - sh "bundle install" - sh "bundle exec fastlane ${platform} ${lane}" - } - } -} - def getVersion(part, returnGroup = false) { def gradleFile = readFile(encoding: 'UTF-8', file: 'app/build.gradle') def m = gradleFile =~ /([^\n]*(?:${part})(?:[^:]*:?\s+|\s*=\s*)"?)([.0-9]+)("?\s*(?:(?:\/\/|#)[^\n]*)?[\n])/ @@ -94,6 +68,11 @@ } } +def gitPush(gitRemote = 'origin', gitCommit) { + def dryRun = ( env.DRYRUN == 'true' ) ? '--dry-run' : '' + sh("git push ${dryRun} ${gitRemote} ${gitCommit}") +} + def gitLog(bottom = null, top = 'HEAD') { def from = bottom ?: 'tags/' + sh(script: "git tag -l | tail -1", returnStdout: true).trim() sh(script: "git --no-pager log ${from}...${top} --pretty=format:'- %s' --reverse", returnStdout: true) @@ -110,31 +89,31 @@ """) } -def gitUpdateChangelogs(versionCode, remote = 'origin', branch = 'master') { - def dryRun = ( env.DRYRUN == 'true' ) ? '--dry-run' : '' +def gitUpdateChangelogs(versionCode, gitBranch = null, gitRemote = 'origin') { + prepareChangelogs(versionCode) def lDir = 'fastlane/metadata/android' sh(""" git status --porcelain ${lDir} | grep -q 'changelogs/${versionCode}\\.txt\$' \ || { echo 'Nothing to update'; exit 0; } + """) + if (gitBranch) sh(""" git stash save --quiet --include-untracked changelogs -git checkout --quiet ${branch} +git checkout --quiet ${gitRemote}/${gitBranch} git stash pop -git add ${lDir}/*/changelogs/${versionCode}.txt -git commit --quiet -s -m 'Provide changelogs for this version' ${lDir} -git push ${dryRun} ${remote} ${branch} """) -} - -def gitTag(version, remote = 'origin' ) { - def dryRun = ( env.DRYRUN == 'true' ) ? '--dry-run' : '' sh(""" -git tag -a '${version}' -m 'Create new tag for version ${version}' -git push ${dryRun} ${remote} ${version} +git add ${lDir}/*/changelogs/${versionCode}.txt +git commit --quiet -s -m 'Provide changelogs for version ${versionCode}' ${lDir} """) + if (gitBranch) gitPush(gitRemote, gitBranch) } -def gitUpdateVersion(versionName, versionCode, remote = 'origin', branch = 'master') { - def dryRun = ( env.DRYRUN == 'true' ) ? '--dry-run' : '' +def gitTag(version, gitRemote = 'origin' ) { + sh("git tag -a '${version}' -m 'Create new tag for version ${version}'") + gitPush(gitRemote, version) +} + +def setVersion(versionName, versionCode) { def gradleFilePath = 'app/build.gradle' def gradleFile = readFile(encoding: 'UTF-8', file: gradleFilePath) gName = getVersion('versionName', true) @@ -142,23 +121,41 @@ gradleFile = gradleFile.replace(gName[0], gName[1] + versionName + gName[3]) gradleFile = gradleFile.replace(gCode[0], gCode[1] + versionCode + gCode[3]) writeFile(encoding: 'UTF-8', file: gradleFilePath, text: gradleFile) +} + +def gitUpdateVersion(versionName, versionCode, gitBranch = null, gitRemote = 'origin') { + def gradleFilePath = 'app/build.gradle' + def dryRun = ( env.DRYRUN == 'true' ) ? '--dry-run' : '' + setVersion(versionName, versionCode) sh(""" git status --porcelain ${gradleFilePath} | grep -q '${gradleFilePath}\$' \ || { echo 'Nothing to update'; exit 0; } + """) + if (gitBranch) sh(""" git stash save --quiet versions -git checkout --quiet ${branch} +git checkout --quiet ${gitRemote}/${gitBranch} git stash pop -git commit --quiet -s -m 'Update version from ${gName[2]}-${gCode[2]} to ${versionName}-${versionCode}' app/build.gradle -git push ${dryRun} ${remote} ${branch} -""") + """) + sh("git commit --quiet -s -m 'Update version from ${gName[2]}-${gCode[2]} to ${versionName}-${versionCode}' app/build.gradle") + if (gitBranch) gitPush(gitRemote, gitBranch) } +// Define the remotes and the branches used to release from and to +def releaseFrom = [ remote: 'origin', branch: 'devel_bear' ] +def releaseTo = [ remote: 'origin', branch: 'master' ] + +// Initialize lazyConfig for this pipeline +lazyConfig( + name: 'DummyAnd', + nopoll: '.+_.+', +) + // Define lazyStages lazyStage { name = 'validate' tasks = [ run: { - fastlane('android', 'test') + fastlane('android', 'test') }, on: 'android', ] @@ -177,49 +174,89 @@ ] } -if (env.BRANCH_NAME == 'master') { - lazyStage { - name = 'release' - input = input('Release to alpha ?') - tasks = [ - pre: { - unarchive(mapping:['app/build/outputs/apk/' : '.']) - sh("ls -lA app/build/outputs/apk") - }, - run: { env -> +// Release stage only only if criteria are met +if (env.BRANCH_NAME == releaseFrom['branch'] && env.env ==~ /RELEASE=true/) { + lazyStage { + name = 'release' + // Ask version if release flag and set and we are in the branch to fork release from + input = [ + message: 'Version name ?', + parameters: [string(defaultValue: '', description: 'Version name?', name: 'VERSION')] + ] + tasks = [ + run: { + def currentVersion = [ name: getVersion('versionName') as String, code: getVersion('versionCode') as Integer ] + echo("currentVersion = ${currentVersion.toString()}") + withGitPassword('bot-ci-dgm', { + // Fork a release branch as requested + echo("Git logs since last tag:\n" + gitLog()) + sh("git checkout -b release-${env.LAZY_INPUT}") + gitUpdateChangelogs(currentVersion.code) + gitUpdateVersion(env.LAZY_INPUT, currentVersion.code) + def nextVersion = [ name: getVersion('versionName') as String, code: getVersion('versionCode') as Integer ] + echo("nextVersion = ${nextVersion.toString()}" ) + gitPush(releaseFrom['remote'], "release-${env.LAZY_INPUT}") + }) + }, + on: 'android', + ] + } +} + +// From systemtest to production, only for release branches +if (env.BRANCH_NAME ==~ /^release-.*/) { + lazyStage { + name = 'systemtest' + tasks = [ + pre: { + unarchive(mapping:['app/build/outputs/apk/' : '.']) + sh("ls -lA app/build/outputs/apk") + }, + run: { + withGitPassword('bot-ci-dgm', { + def dryRun = ( env.DRYRUN == 'true' ) ? '--dry-run' : '' def currentVersion = [ name: getVersion('versionName') as String, code: getVersion('versionCode') as Integer ] def nextVersion = [ name: currentVersion.name, code: currentVersion.code + 1] echo("currentVersion = ${currentVersion.toString()} / nextVersion = ${nextVersion.toString()}") - withGitPassword('bot-ci-dgm', { - echo("Git logs since last tag:\n" + gitLog()) - prepareChangelogs(currentVersion.code) - if ( env.DRYRUN != 'true' ) fastlane('android', 'alpha') - gitUpdateChangelogs(currentVersion.code) - gitTag("${currentVersion.name}-${currentVersion.code}") - gitUpdateVersion(nextVersion.name, nextVersion.code) - }) - }, - on: 'android', - ] - } - - lazyStage { - name = 'acceptance' - input = input('Promote alpha to beta ?') - tasks = [ - run: { env -> - if ( env.DRYRUN != 'true' ) fastlane('android', 'beta') - } - ] - } - - lazyStage { - name = 'production' - input = input('Promote beta to production ?') - tasks = [ - run: { env -> - if ( env.DRYRUN != 'true' ) fastlane('android', 'production') - } - ] - } + if ( env.DRYRUN != 'true' ) fastlane('android', 'alpha') + sh(""" +git checkout ${releaseFrom['remote']}/${releaseFrom['branch']} +git merge ${env.BRANCH_NAME} -m 'Merge changes from ${versionName}-${versionCode} back into ${releaseFrom['branch']}' + """) + gitUpdateVersion(nextVersion.name, nextVersion.code) + gitPush(releaseFrom['remote'], releaseFrom['branch']) + }) + }, + on: 'android', + ] + } + + lazyStage { + name = 'acceptance' + input = 'Promote alpha to beta?' + tasks = [ + run: { + if ( env.DRYRUN != 'true' ) fastlane('android', 'beta') + } + ] + } + + lazyStage { + name = 'production' + input = 'Promote beta to production?' + tasks = [ + run: { + if ( env.DRYRUN != 'true' ) fastlane('android', 'production') + withGitPassword('bot-ci-dgm', { + def currentVersion = [ name: getVersion('versionName') as String, code: getVersion('versionCode') as Integer ] + sh(""" +git checkout ${releaseTo['remote']}/${releaseTo['branch']} +git merge ${env.BRANCH_NAME} -m 'Merge changes from ${versionName}-${versionCode} into ${releaseTo['branch']}' + """) + gitPush(releaseTo['remote'], releaseTo['branch']) + gitTag("${currentVersion.name}", releaseTo['remote']) + }) + } + ] + } } diff --git a/app/build.gradle b/app/build.gradle index 033c96a..c92ffbc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -35,8 +35,8 @@ applicationId "nl.digital_me.dummyandroidapp" minSdkVersion 14 targetSdkVersion rootProject.ext.compileSdkVersion - versionCode project.hasProperty('versionCode') ? project.property('versionCode') as int : 29 - versionName project.hasProperty('versionName') ? project.property('versionName') : "0.0.1" + versionCode project.hasProperty('versionCode') ? project.property('versionCode') as int : 32 + versionName project.hasProperty('versionName') ? project.property('versionName') : "0.0.2" multiDexEnabled true } dexOptions { diff --git a/fastlane/metadata/android/en-US/changelogs/30.txt b/fastlane/metadata/android/en-US/changelogs/30.txt new file mode 100644 index 0000000..cfe3c40 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/30.txt @@ -0,0 +1,2 @@ +- using updated build tools + diff --git a/fastlane/metadata/android/nl-NL/changelogs/30.txt b/fastlane/metadata/android/nl-NL/changelogs/30.txt new file mode 100644 index 0000000..29cb24a --- /dev/null +++ b/fastlane/metadata/android/nl-NL/changelogs/30.txt @@ -0,0 +1 @@ +- gebruik bijgewerkt bouwgereedschappen