2024-03-29 21:27:38 +03:00
# SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: AGPL-3.0-or-later
2024-02-20 10:29:04 +03:00
# run fastlane
# bundle exec fastlane
# update fastlane
# bundle update fastlane
# update plugins
# bundle exec fastlane update_plugins
2017-09-28 14:53:37 +03:00
# This is the minimum version number required.
fastlane_version "2.58.0"
2019-12-04 12:45:26 +03:00
## config
# add following to your shell rc:
# export FASTLANE_NEXTCLOUD_STORE_FILE=""
# export FASTLANE_NEXTCLOUD_STORE_PASSWORD=""
# export FASTLANE_NEXTCLOUD_KEY_ALIAS=""
# export FASTLANE_NEXTCLOUD_KEY_PASSWORD=""
# export FASTLANE_NEXTCLOUD_GITHUB_API_TOKEN=""
2020-07-22 15:41:29 +03:00
# export FASTLANE_NEXTCLOUD_HUAWEI_CLIENT_ID=""
# export FASTLANE_NEXTCLOUD_HUAWEI_CLIENT_SECRET=""
# export FASTLANE_NEXTCLOUD_HUAWEI_APP_ID=""
2019-12-04 12:45:26 +03:00
skip_docs
## public lanes
2019-06-26 15:38:00 +03:00
lane :screenshotsPhone do
2019-12-18 10:24:25 +03:00
beautifyPhone()
2019-06-26 15:38:00 +03:00
build_for_screengrab()
screengrab(
device_type: "phone",
app_apk_path: APK_LOCATION,
tests_apk_path: TEST_APK_LOCATION
)
end
lane :screenshotsTablet do
2019-12-18 10:24:25 +03:00
beautifyPhone()
2019-06-26 15:38:00 +03:00
build_for_screengrab()
screengrab(
2019-12-04 12:45:26 +03:00
device_type: "sevenInch",
app_apk_path: APK_LOCATION,
tests_apk_path: TEST_APK_LOCATION
2019-06-26 15:38:00 +03:00
)
end
2019-12-04 12:45:26 +03:00
desc "Release phase 1: make gplay/generic for RC, then test it"
2020-07-31 13:47:00 +03:00
lane :RC_releasePhase1 do
2019-12-04 12:45:26 +03:00
disableLogger()
makeReleases()
enableLogger()
end
desc "Release phase 2 for RC: checks, tag, upload gplay to playstore with values from build.gradle"
2020-07-31 13:47:00 +03:00
lane :RC_releasePhase2 do |options|
2021-12-15 17:40:14 +03:00
checkReleaseRequirements_RC()
2019-12-04 12:45:26 +03:00
info = androidVersion
2021-10-26 09:37:01 +03:00
promptVersion(info)
2019-12-04 12:45:26 +03:00
checkChangelog(info)
checkLibrary_RC()
checkIfScreenshotsExist()
checkIfAPKexists()
tag(info)
uploadToPlaystore_RC(info)
2020-01-08 11:38:23 +03:00
createGithubRelease_RC(info)
fdroidMergeRequest_RC(info)
createChangelogPullRequest_RC(info)
2019-12-04 12:45:26 +03:00
end
2020-07-31 13:47:00 +03:00
desc "Release phase 1: make gplay/generic for FINAL, then test it"
lane :Final_releasePhase1 do
2021-10-21 12:33:28 +03:00
makeReleases()
2020-07-31 13:47:00 +03:00
end
2019-12-04 12:45:26 +03:00
desc "Release phase 2 for FINAL: checks, tag, upload gplay to playstore with values from build.gradle"
2020-07-31 13:47:00 +03:00
lane :Final_releasePhase2 do |options|
2021-12-15 17:40:14 +03:00
checkReleaseRequirements_Final()
2019-12-04 12:45:26 +03:00
info = androidVersion
2021-10-20 15:03:03 +03:00
promptVersion(info)
2019-12-04 12:45:26 +03:00
checkChangelog(info)
checkLibrary_Final()
checkIfScreenshotsExist()
checkIfAPKexists()
tag(info)
uploadToPlaystore_Final(info)
createGithubRelease_Final(info)
fdroidMergeRequest_Final(info)
createChangelogPullRequest_Final(info)
2024-02-20 10:29:04 +03:00
uploadToHuawei_Final(info)
2019-12-04 12:45:26 +03:00
end
desc "Makes gplay and generic releases in ../releases/"
2021-10-21 12:33:28 +03:00
lane :makeReleases do
info = androidVersion
2022-03-21 17:25:36 +03:00
sh("rm -rf ../release/ && mkdir -p ../release")
gradle(task: 'clean')
2019-12-04 12:45:26 +03:00
2022-03-21 17:25:36 +03:00
createGenericRelease(versionCode:info["versionCode"])
2019-12-04 12:45:26 +03:00
2022-03-21 17:25:36 +03:00
createGplayRelease(versionCode:info["versionCode"])
2021-12-10 13:24:34 +03:00
2022-03-21 17:25:36 +03:00
createHuaweiRelease()
2019-12-04 12:45:26 +03:00
end
desc "Create GPlay release"
lane :createGplayRelease do |options|
2022-03-21 17:25:36 +03:00
buildBundle(flavor:"Gplay")
sh("mv ../app/build/outputs/bundle/gplayRelease/app-gplay-release.aab ../release/")
buildApkFromBundle(outputDir: "../release", bundlePath: "../release/app-gplay-release.aab")
sh("rm ../release/toc.pb")
sh("mv ../release/universal.apk ../release/gplay-release-#{options[:versionCode]}.apk")
2019-12-04 12:45:26 +03:00
end
desc "Create Generic release"
lane :createGenericRelease do |options|
SignedRelease(flavor:"Generic")
2022-02-04 18:28:12 +03:00
sh("mv ../app/build/outputs/apk/generic/release/*.apk ../release/")
2022-03-21 17:25:36 +03:00
sh("mv ../release/generic-release-#{options[:versionCode]}.apk ../release/nextcloud-#{options[:versionCode]}.apk")
2019-12-04 12:45:26 +03:00
end
2021-12-10 13:24:34 +03:00
desc "Create Huawei release"
2022-03-21 17:25:36 +03:00
lane :createHuaweiRelease do
2021-12-10 13:24:34 +03:00
SignedRelease(flavor:"Huawei")
2022-02-04 18:28:12 +03:00
sh("mv ../app/build/outputs/apk/huawei/release/*.apk ../release/")
2021-12-10 13:24:34 +03:00
end
2019-12-04 12:45:26 +03:00
desc "Create Dev release"
2022-03-21 17:25:36 +03:00
lane :createDevRelease do
2019-12-04 12:45:26 +03:00
SignedRelease(flavor:"VersionDev")
2022-02-04 18:28:12 +03:00
sh("mv ../app/build/outputs/apk/versionDev/release/*.apk ../release/")
2019-12-04 12:45:26 +03:00
end
2019-12-18 10:24:25 +03:00
desc "Beautify phone for screenshots: set time, remove other icons, no charging"
lane :beautifyPhone do
sh("adb shell settings put global sysui_demo_allowed 1")
sh("adb shell am broadcast -a com.android.systemui.demo -e command clock -e hhmm 1200")
sh("adb shell am broadcast -a com.android.systemui.demo -e command network -e mobile show -e level 4 -e datatype false")
sh("adb shell am broadcast -a com.android.systemui.demo -e command notifications -e visible false")
sh("adb shell am broadcast -a com.android.systemui.demo -e command battery -e plugged false -e level 100")
end
2020-07-22 15:41:29 +03:00
# to install
# bundle exec fastlane add_plugin huawei_appgallery_connect
# bundle install --path build/vendor/bundle
private_lane :uploadToHuawei_Final do |options|
huawei_appgallery_connect(
client_id: ENV["FASTLANE_NEXTCLOUD_HUAWEI_CLIENT_ID"],
client_secret: ENV["FASTLANE_NEXTCLOUD_HUAWEI_CLIENT_SECRET"],
app_id: ENV["FASTLANE_NEXTCLOUD_HUAWEI_APP_ID"],
2021-12-10 13:24:34 +03:00
apk_path: "release/huawei-release-" + options["versionCode"] + ".apk",
2020-07-22 15:41:29 +03:00
submit_for_review: true,
2022-05-03 13:48:11 +03:00
delay_before_submit_for_review: 30,
2020-07-22 15:41:29 +03:00
)
end
2019-12-04 12:45:26 +03:00
## private lanes
2019-06-26 15:38:00 +03:00
desc "Build debug and test APK for screenshots"
private_lane :build_for_screengrab do
build_android_app(
task: 'assemble',
flavor: 'Generic',
build_type: 'Debug'
)
APK_LOCATION = lane_context[SharedValues::GRADLE_ALL_APK_OUTPUT_PATHS].select{ |i| i[/00/] }[0]
build_android_app(
task: 'assemble',
flavor: 'Generic',
build_type: 'DebugAndroidTest'
)
TEST_APK_LOCATION = lane_context[SharedValues::GRADLE_ALL_APK_OUTPUT_PATHS].select{ |i| i[/androidTest/] }[0]
2017-09-28 14:53:37 +03:00
end
2019-12-04 12:45:26 +03:00
2021-12-15 17:40:14 +03:00
private_lane :checkReleaseRequirements_common do
2021-12-22 14:44:45 +03:00
sh("if ! command -v fdroid &>/dev/null; then echo 'fdroid command not found' && exit 1; fi")
2022-03-21 17:25:36 +03:00
sh("if ! command -v bundletool &>/dev/null; then echo 'bundletool command not found' && exit 1; fi")
2021-12-15 17:40:14 +03:00
end
private_lane :checkReleaseRequirements_RC do
checkReleaseRequirements_common()
2021-12-22 14:44:45 +03:00
sh("if ! command -v fdroidMergeRequestRC &>/dev/null; then echo 'fdroidMergeRequestRC command not found'; exit 1; fi")
sh("if ! command -v createChangelogPullRequestRC &>/dev/null; then echo 'createChangelogPullRequestRC command not found'; exit 1; fi")
2021-12-15 17:40:14 +03:00
end
private_lane :checkReleaseRequirements_Final do
checkReleaseRequirements_common()
2021-12-22 14:44:45 +03:00
sh("if ! command -v fdroidMergeRequestFinal &>/dev/null; then echo 'fdroidMergeRequestFinal command not found'; exit 1; fi")
sh("if ! command -v createChangelogPullRequestFinal &>/dev/null; then echo 'createChangelogPullRequestFinal command not found'; exit 1; fi")
2021-12-15 17:40:14 +03:00
end
2019-12-04 12:45:26 +03:00
private_lane :createChangelogPullRequest_RC do |options|
sh("createChangelogPullRequestRC " + options["tag"] + " \"" + options["versionName"] + "\" " + options["versionCode"] + " \"" + options["branch"] + "\" ")
end
private_lane :createChangelogPullRequest_Final do |options|
sh("createChangelogPullRequestFinal " + options["tag"] + " \"" + options["versionName"] + "\" " + options["versionCode"] + " \"" + options["branch"] + "\" ")
end
private_lane :checkIfAPKexists do |options|
2022-03-28 18:19:35 +03:00
sh("if [ $(/bin/ls -1 ../release | wc -l) -ne 4 ]; then echo 'Release artifacts not present or wrong number present; aborting!' ; exit 1 ;
2019-12-04 12:45:26 +03:00
fi")
end
desc "compute version"
2021-10-20 15:03:03 +03:00
private_lane :androidVersion do
2022-02-04 18:28:12 +03:00
File.open("../app/build.gradle","r") do |f|
2019-12-04 12:45:26 +03:00
text = f.read
# everything between Document and Authors
major = text.match(/def versionMajor = ([0-9]*)$/)
minor = text.match(/def versionMinor = ([0-9]*)$/)
patch = text.match(/def versionPatch = ([0-9]*)$/)
build = text.match(/def versionBuild = ([0-9]*).*$/)
majorInt = major[1].to_i
minorInt = minor[1].to_i
patchInt = patch[1].to_i
buildInt = build[1].to_i
versionCode = majorInt * 10000000 + minorInt * 10000 + patchInt * 100 + buildInt
if buildInt > 89
name = major[1] + "." + minor[1] + "." + patch[1]
tag = "stable-" + major[1] + "." + minor[1] + "." + patch[1]
branch = "stable-" + major[1] + "." + minor[1]
elsif buildInt > 50
name = major[1] + "." + minor[1] + "." + patch[1] + " RC" + (buildInt - 50).to_s
tag = "rc-" + major[1] + "." + minor[1] + "." + patch[1] + "-" + format('%02d', (buildInt - 50))
branch = "stable-" + major[1] + "." + minor[1]
else
name = major[1] + "." + minor[1] + "." + patch[1] + " Alpha " + format('%02d', (buildInt + 1))
tag = "/"
branch = "stable-" + major[1] + "." + minor[1]
end
2021-10-20 15:03:03 +03:00
{ "versionCode" => versionCode.to_s, "versionName" => name, "tag" => tag, "branch" => branch }
end
end
2019-12-04 12:45:26 +03:00
2021-10-20 15:03:03 +03:00
desc "Show versions and prompt for confirmation"
private_lane :promptVersion do |options|
print "VersionCode: " + options["versionCode"].to_s + "\n"
print "Name: " + options["versionName"] + "\n"
print "Tag: " + options["tag"] + "\n"
print "Branch: " + options["branch"] + "\n"
print "\ndisable IPv6 to upload to Gplay!!!\n"
2019-12-04 12:45:26 +03:00
2021-10-20 15:03:03 +03:00
answer = prompt(text: "is this okay?", boolean: true)
2019-12-04 12:45:26 +03:00
2021-10-20 15:03:03 +03:00
if !answer
exit
2019-12-04 12:45:26 +03:00
end
end
desc "check if library is set correctly"
private_lane :checkLibrary_RC do
sh(" if [ $(egrep 'androidLibraryVersion.*master.*' ../build.gradle -c) -eq 1 ] ; then echo 'Library is set to master tag; aborting!' ; exit 1 ; fi")
end
desc "check if library is set correctly: must NOT contain master nor rc"
private_lane :checkLibrary_Final do
sh(" if [ $(grep 'androidLibraryVersion' ../build.gradle | egrep 'master|rc' -c) -eq 1 ] ; then echo 'Library is still set to rc tag; aborting!' ; exit 1 ; fi")
end
desc "check if screenshots exists and exit"
private_lane :checkIfScreenshotsExist do
2023-01-25 19:59:38 +03:00
sh(" if [ $(find metadata/android/*/images -type f -not -name icon.png | grep -c . ) -gt 0 ] ; then echo 'Screenshots in fastlane folder exist; aborting!' ; exit 1 ; fi")
2019-12-04 12:45:26 +03:00
end
private_lane :tag do |options|
add_git_tag(
tag: options["tag"],
sign: true
)
push_git_tags(
tag: options["tag"])
end
private_lane :disableLogger do
2022-02-04 18:28:12 +03:00
sh("sed -i s'#<bool name=\"logger_enabled\">false</bool>#<bool name=\"logger_enabled\">true</bool>#' ../app/src/main/res/values/setup.xml")
2019-12-04 12:45:26 +03:00
end
private_lane :enableLogger do
2022-02-04 18:28:12 +03:00
sh("sed -i s'#<bool name=\"logger_enabled\">true</bool>#<bool name=\"logger_enabled\">false</bool>#' ../app/src/main/res/values/setup.xml")
2019-12-04 12:45:26 +03:00
end
2022-03-21 18:10:28 +03:00
desc "Upload to play store (beta)"
2019-12-04 12:45:26 +03:00
private_lane :uploadToPlaystore_RC do |options|
upload_to_play_store(
skip_upload_images: true,
track: 'beta',
2022-03-21 18:10:28 +03:00
aab: "release/app-gplay-release.aab"
2019-12-04 12:45:26 +03:00
)
end
desc "Upload to play store"
private_lane :uploadToPlaystore_Final do |options|
upload_to_play_store(
skip_upload_images: true,
2022-11-03 22:59:07 +03:00
skip_upload_apk: true,
2022-03-21 18:10:28 +03:00
aab: "release/app-gplay-release.aab"
2019-12-04 12:45:26 +03:00
)
end
2022-03-21 17:25:36 +03:00
2022-03-21 18:10:28 +03:00
desc "Build app bundle"
2022-03-21 17:25:36 +03:00
private_lane :buildBundle do |options|
gradle(
task: 'bundle',
flavor: options[:flavor],
2022-03-21 18:10:28 +03:00
build_type: 'Release',
print_command: false,
properties: {
"android.injected.signing.store.file" => ENV["FASTLANE_NEXTCLOUD_UPLOAD_STORE_FILE"],
"android.injected.signing.store.password" => ENV["FASTLANE_NEXTCLOUD_UPLOAD_STORE_PASSWORD"],
"android.injected.signing.key.alias" => ENV["FASTLANE_NEXTCLOUD_UPLOAD_KEY_ALIAS"],
"android.injected.signing.key.password" => ENV["FASTLANE_NEXTCLOUD_UPLOAD_KEY_PASSWORD"],
}
)
2022-03-21 17:25:36 +03:00
end
2022-03-21 18:10:28 +03:00
desc "Generate signed universal APK from app bundle"
2022-03-21 17:25:36 +03:00
private_lane :buildApkFromBundle do |options|
sh(command:"bundletool build-apks --mode universal --output '#{options[:outputDir]}' --output-format DIRECTORY" +
" --ks '#{ENV["FASTLANE_NEXTCLOUD_STORE_FILE"]}'"+
" --ks-pass 'pass:#{ENV["FASTLANE_NEXTCLOUD_STORE_PASSWORD"]}'"+
" --ks-key-alias '#{ENV["FASTLANE_NEXTCLOUD_KEY_ALIAS"]}'"+
" --key-pass 'pass:#{ENV["FASTLANE_NEXTCLOUD_KEY_PASSWORD"]}'"+
" --bundle '#{options[:bundlePath]}'",
log:false)
end
2022-03-21 18:10:28 +03:00
desc "Build signed APK"
2019-12-04 12:45:26 +03:00
private_lane :SignedRelease do |options|
gradle(
task: 'assemble',
flavor: options[:flavor],
build_type: 'Release',
print_command: false,
properties: {
"android.injected.signing.store.file" => ENV["FASTLANE_NEXTCLOUD_STORE_FILE"],
"android.injected.signing.store.password" => ENV["FASTLANE_NEXTCLOUD_STORE_PASSWORD"],
"android.injected.signing.key.alias" => ENV["FASTLANE_NEXTCLOUD_KEY_ALIAS"],
"android.injected.signing.key.password" => ENV["FASTLANE_NEXTCLOUD_KEY_PASSWORD"],
}
)
end
private_lane :createGithubRelease_RC do |options|
set_github_release(
repository_name: "nextcloud/android",
api_token: ENV["FASTLANE_NEXTCLOUD_GITHUB_API_TOKEN"],
name: options["versionName"],
tag_name: options["tag"],
is_prerelease: true,
description: (File.read("metadata/android/en-US/changelogs/" + options["versionCode"] + ".txt") rescue "No changelog provided"),
upload_assets: [ "release/gplay-release-" + options["versionCode"] + ".apk", "release/nextcloud-" +
options["versionCode"] + ".apk" ]
)
end
private_lane :createGithubRelease_Final do |options|
set_github_release(
repository_name: "nextcloud/android",
api_token: ENV["FASTLANE_NEXTCLOUD_GITHUB_API_TOKEN"],
name: options["versionName"],
tag_name: options["tag"],
description: (File.read("metadata/android/en-US/changelogs/" + options["versionCode"] + ".txt") rescue "No changelog provided"),
upload_assets: [ "release/gplay-release-" + options["versionCode"] + ".apk", "release/nextcloud-" +
options["versionCode"] + ".apk" ]
)
end
private_lane :fdroidMergeRequest_RC do |options|
sh("fdroidMergeRequestRC " + options["tag"] + " \"" + options["versionName"] + "\" " + options["versionCode"])
end
private_lane :fdroidMergeRequest_Final do |options|
sh("fdroidMergeRequestFinal " + options["tag"] + " \"" + options["versionName"] + "\" " + options["versionCode"])
end
private_lane :checkChangelog do |options|
sh(" if [ ! -e metadata/android/en-US/changelogs/" + options["versionCode"] + ".txt ] ; then echo 'Changelog fastlane/metadata/android/en-US/changelogs/" + options["versionCode"] + ".txt does not exist' ; exit 1 ; fi")
sh(" if [ $(wc -m metadata/android/en-US/changelogs/" + options["versionCode"] + ".txt | cut -d' ' -f1) -ge 500 ] ; then echo 'Changlog more than 500 chars' ; exit 1 ; fi")
end