#!groovy
/*
* This work is protected under copyright law in the Kingdom of
* The Netherlands. The rules of the Berne Convention for the
* Protection of Literary and Artistic Works apply.
* Digital Me B.V. is the copyright owner.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Define the remote and the branch used to release
def release = [ remote: 'origin', branch: 'devel_bear' ]
// 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,
credentialsId: null,
]
library(
identifier: "libCmn@${libCmn.branch}",
retriever: modernSCM([
$class: 'GitSCMSource',
remote: libCmn.remote,
credentialsId: libCmn.credentialsId
])
)
// Load Jenkins shared libraries to customize this project
def libCst = [
remote: 'ssh://git@code.in.digital-me.nl:2222/DEVops/JenkinsLibCustom.git',
branch: env.BRANCH_NAME,
credentialsId: 'bot-ci-dgm-rsa',
]
library(
identifier: "libCst@${libCst.branch}",
retriever: modernSCM([
$class: 'GitSCMSource',
remote: libCst.remote,
credentialsId: libCst.credentialsId
])
)
// Initialize lazyConfig for this pipeline
lazyConfig(
name: 'DummyAnd',
nopoll: release['branch'],
)
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])/
if (m) returnGroup ? m[0] : m[0][2]
else return null
}
def withGitPassword(id, body = { sh 'git version' }) {
withCredentials([usernamePassword([credentialsId: id, passwordVariable: 'GIT_PASSWORD', usernameVariable: 'GIT_USER'])]) {
// TODO: Move git_askpass.sh as a library resource
withEnv(["GIT_ASKPASS=/opt/jenkins-scripts/git_askpass.sh"]) {
sh("git fetch --all --quiet")
body()
}
}
}
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)
}
def prepareChangelogs(versionCode) {
lDir = 'fastlane/metadata/android'
// TODO: Test if latest changelogs have changed since last tag and use gitLog if not
sh("""
for LOCALE in \$(ls -1d ${lDir}/??-??); do
cp -vf \${LOCALE}/changelogs/latest.txt \${LOCALE}/changelogs/${versionCode}.txt
done
""")
}
def gitUpdateChangelogs(versionCode, remote = 'origin', branch = 'master') {
def dryRun = ( env.DRYRUN == 'true' ) ? '--dry-run' : ''
def lDir = 'fastlane/metadata/android'
sh("""
git status --porcelain ${lDir} | grep -q 'changelogs/${versionCode}\\.txt\$' \
|| { echo 'Nothing to update'; exit 0; }
git stash save --quiet --include-untracked changelogs
git checkout --quiet ${branch}
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}
""")
}
def gitUpdateVersion(versionName, versionCode, remote = 'origin', branch = 'master') {
def dryRun = ( env.DRYRUN == 'true' ) ? '--dry-run' : ''
def gradleFilePath = 'app/build.gradle'
def gradleFile = readFile(encoding: 'UTF-8', file: gradleFilePath)
gName = getVersion('versionName', true)
gCode = getVersion('versionCode', true)
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)
sh("""
git status --porcelain ${gradleFilePath} | grep -q '${gradleFilePath}\$' \
|| { echo 'Nothing to update'; exit 0; }
git stash save --quiet versions
git checkout --quiet ${branch}
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}
""")
}
// Define lazyStages
lazyStage {
name = 'prepare'
input = (owner.env.BRANCH_NAME == release['branch']) ? [
message: 'Version name ?',
parameters: [string(defaultValue: '', description: 'Version name?', name: 'VERSION')]
] : null
tasks = [
run: {
echo("Lazy input = ${env.LAZY_INPUT}")
if (!env.LAZY_INPUT) error 'Not lazy input!'
def currentVersion = [ name: getVersion('versionName') as String, code: getVersion('versionCode') as Integer ]
echo("currentVersion = ${currentVersion.toString()}")
withGitPassword('bot-ci-dgm', {
if (env.BRANCH_NAME == release['branch']) {
echo("Git logs since last tag:\n" + gitLog())
prepareChangelogs(currentVersion.code)
gitUpdateChangelogs(currentVersion.code, release['remote'], release['branch'])
if (env.LAZY_INPUT != '') {
gitUpdateVersion(env.LAZY_INPUT, currentVersion.code, release['remote'], release['branch'])
echo("newVersion = [name: ${env.LAZY_INPUT}, code: ${currentVersion.code}]" )
}
} else {
sh("""
git pull --quiet --rebase ${release['remote']} ${release['branch']}
git push --quiet ${release['remote']} ${env.BRANCH_NAME}
""")
}
})
},
on: 'android',
]
}
lazyStage {
name = 'validate'
tasks = [
run: {
fastlane('android', 'test')
},
on: 'android',
]
}
lazyStage {
name = 'package'
tasks = [
run: {
fastlane('android', 'build')
},
post: {
archiveArtifacts(artifacts: 'app/build/outputs/apk/**', allowEmptyArchive: false)
},
on: 'android',
]
}
if (env.BRANCH_NAME == release['branch']) {
lazyStage {
name = 'release'
tasks = [
pre: {
unarchive(mapping:['app/build/outputs/apk/' : '.'])
sh("ls -lA app/build/outputs/apk")
},
run: {
withGitPassword('bot-ci-dgm', {
sh("git pull ${release['remote']} ${release['branch']}")
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()}")
if ( env.DRYRUN != 'true' ) fastlane('android', 'alpha')
gitTag("${currentVersion.name}-${currentVersion.code}")
gitUpdateVersion(nextVersion.name, nextVersion.code, release['remote'], release['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')
}
]
}
}