diff --git a/.gitignore b/.gitignore index ff4c56a..59abb83 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,13 @@ .gradle /local.properties -/.idea/workspace.xml -/.idea/libraries +/.idea .DS_Store /build /captures fastlane/report.xml last_build.properties +/*.iml +app/app.iml +.ruby-version +.settings +app/.settings diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index 96cc43e..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml deleted file mode 100644 index e7bedf3..0000000 --- a/.idea/copyright/profiles_settings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index 97626ba..0000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index c3bf4f7..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index e980d11..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 054dd51..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml deleted file mode 100644 index 7f68460..0000000 --- a/.idea/runConfigurations.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 45cf85c..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/DummyAndroidApp.iml b/DummyAndroidApp.iml deleted file mode 100644 index 61e9318..0000000 --- a/DummyAndroidApp.iml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..466412a --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,225 @@ +#!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. + */ + +// 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 + ]) +) + +// Initialize lazyConfig for this pipeline +lazyConfig( + name: 'DummyAnd', + env: [ 'DRYRUN=true' ], +) + +// 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])/ + 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 = '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 != 'master') return 0 + +lazyStage { + name = 'release' + tasks = [ + pre: { + unarchive(mapping:['app/build/outputs/apk/' : '.']) + sh("ls -lA app/build/outputs/apk") + }, + run: { env -> + 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 == 'false' ) fastlane('android', 'alpha') + gitUpdateChangelogs(currentVersion.code) + gitTag("${currentVersion.name}-${currentVersion.code}") + gitUpdateVersion(nextVersion.name, nextVersion.code) + }) + }, + on: 'android', + ] +} + +lazyStage { + name = 'acceptance' + tasks = [ + run: { env -> + input('Do we want to promote this release from alpha to beta ?') + if ( env.DRYRUN == 'false' ) fastlane('android', 'beta') + } + ] +} + +lazyStage { env -> + name = 'production' + tasks = [ + run: { + input('Do we want to promote this release from alpha to production ?') + if ( env.DRYRUN == 'false' ) fastlane('android', 'production') + } + ] +} diff --git a/app/app.iml b/app/app.iml deleted file mode 100644 index e7b7b5f..0000000 --- a/app/app.iml +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0db3b02..db7c442 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -35,7 +35,7 @@ applicationId "nl.digital_me.dummyandroidapp" minSdkVersion 14 targetSdkVersion rootProject.ext.compileSdkVersion - versionCode project.hasProperty('versionCode') ? project.property('versionCode') as int : 30 + versionCode project.hasProperty('versionCode') ? project.property('versionCode') as int : 28 versionName project.hasProperty('versionName') ? project.property('versionName') : "0.0.1" multiDexEnabled true } diff --git a/build.gradle b/build.gradle index 01b82c5..e5844dc 100644 --- a/build.gradle +++ b/build.gradle @@ -24,8 +24,8 @@ //modules in the project. ext { compileSdkVersion = 27 - buildToolsVersion = "27.0.0" - supportLibVersion = "27.0.0" + buildToolsVersion = "27.0.3" + supportLibVersion = "27.0.2" } task clean(type: Delete) { diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 7826030..872ebc9 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -102,7 +102,7 @@ end desc "Submit a new Beta Build to Crashlytics Beta" - lane :beta do + lane :crashlytics do gradle(task: "assembleRelease") crashlytics @@ -111,9 +111,32 @@ end desc "Deploy a new version to the Google Play" - lane :deploy do - #gradle(task: "assembleRelease") - #supply + lane :alpha do + supply( + apk: 'app/build/outputs/apk/release/app-release.apk', + mapping: 'app/build/outputs/apk/release/mapping.txt', + track: 'alpha', + skip_upload_apk: false, + skip_upload_metadata: false, + skip_upload_images: true, + skip_upload_screenshots: true, + ) + end + + desc "Deploy a new version to the Google Play" + lane :beta do + supply( + track: 'alpha', + track_promote_to: beta, + ) + end + + desc "Deploy a new version to the Google Play" + lane :production do + supply( + track: 'beta', + track_promote_to: production, + ) end # You can define as many lanes as you want