fastlane_require 'dotenv' fastlane_require 'jwt' fastlane_require 'base64' fastlane_require 'net/sftp' default_platform(:android) build = number_of_commits + 1958 # adding 1958 for legacy reasons. Must be in sync with getVersionCode() from build.gradle version = get_version_name( gradle_file_path:"build.gradle", ext_constant_name:"androidVersionName") version = version.delete "'" release_note_path_en = "metadata/android/en-US/changelogs/default.txt" platform :android do |options| desc "Run all the tests" lane :test do |options| gradle(task: "test") end desc "Deploy new version to Google Play and APK Store options: beta:false (default)" lane :deploy do |options| # use english-change-log for french language too FileUtils.cp(release_note_path_en, "metadata/android/fr-FR/changelogs/default.txt") deployToPlaystore(beta:options[:beta]) deployToServer(beta:options[:beta]) deployToFDroid(beta:options[:beta]) createGitHubDraftRelease(beta:options[:beta]) slack( default_payloads: [], # reduce the notification to the minimum message: ":rocket: Successfully deployed #{version} with code #{build} to the Play Store :cryptomator:", payload: { "Changes" => File.read(release_note_path_en) } ) end desc "Deploy new version to Play Store" lane :deployToPlaystore do |options| deploy_target = "production" if options[:beta] deploy_target = "beta" end gradle(task: "clean") gradle( task: "assemble", build_type: "Release", flavor: "playstore", print_command: false, properties: { "android.injected.signing.store.file" => ENV["SIGNING_KEYSTORE_PATH"], "android.injected.signing.store.password" => ENV["SIGNING_KEYSTORE_PASSWORD"], "android.injected.signing.key.alias" => ENV["SIGNING_KEY_ALIAS"], "android.injected.signing.key.password" => ENV["SIGNING_KEY_PASSWORD"], } ) upload_to_play_store( track: deploy_target, apk: lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH], mapping: lane_context[SharedValues::GRADLE_MAPPING_TXT_OUTPUT_PATH], version_name: version, version_code: build, release_status: "draft", json_key: ENV["GOOGLE_PLAYSTORE_PRIVATE_KEY_FILE_PATH"], skip_upload_aab: true, skip_upload_metadata: false, skip_upload_images: true, skip_upload_screenshots: true, metadata_path: "fastlane/metadata/android" ) FileUtils.cp(lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH], "release/Cryptomator-#{version}_playstore_signed.apk") end desc "Deploy new version to server" lane :deployToServer do |options| gradle(task: "clean") gradle( task: "assemble", build_type: "Release", flavor: "apkstore", print_command: false, properties: { "android.injected.signing.store.file" => ENV["SIGNING_KEYSTORE_PATH"], "android.injected.signing.store.password" => ENV["SIGNING_KEYSTORE_PASSWORD"], "android.injected.signing.key.alias" => ENV["SIGNING_KEY_ALIAS"], "android.injected.signing.key.password" => ENV["SIGNING_KEY_PASSWORD"], } ) FileUtils.cp(lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH], "release/Cryptomator-#{version}.apk") server_host = ENV["APK_STORE_BASIC_URL"] base_url = "https://#{server_host}/android/" apk_url = "#{base_url}#{version}/Cryptomator-#{version}.apk" release_note_url = "#{base_url}#{version}/release-notes.html" claims = { "version": version, "url": apk_url, "release_notes": release_note_url } private_key = OpenSSL::PKey.read(File.read(ENV["SIGNING_UPDATE_APK_STORE_KEY_PATH"])) token = JWT.encode claims, private_key, "ES256" latest_version_filename = "latest-version-#{version}.json" latest_version_jsn = File.new("latest_versions/#{latest_version_filename}","w") latest_version_jsn.write(token) latest_version_jsn.close if options[:beta] puts "Skipping deployment to server cause there isn't currently a beta channel" else puts "Uploading APK and release note" aws_s3( bucket: ENV['S3_BUCKET'], endpoint: ENV['S3_ENDPOINT'], region: ENV['S3_REGION'], access_key: ENV['S3_ACCESS_KEY'], secret_access_key: ENV['S3_SECRET_ACCESS_KEY'], path: "android/#{version}", files: [ "fastlane/release/Cryptomator-#{version}.apk", "fastlane/release-notes.html" ], skip_html_upload: true, apk: '' ) puts "Uploading #{latest_version_filename} with claims #{claims}" puts "Rename #{latest_version_filename} to latest-version.json for deployment" aws_s3( bucket: ENV['S3_BUCKET'], endpoint: ENV['S3_ENDPOINT'], region: ENV['S3_REGION'], access_key: ENV['S3_ACCESS_KEY'], secret_access_key: ENV['S3_SECRET_ACCESS_KEY'], path: "android", files: [ "fastlane/latest_versions/#{latest_version_filename}" ], skip_html_upload: true, apk: '' ) end FileUtils.mv("release/Cryptomator-#{version}.apk", "release/Cryptomator-#{version}_signed.apk") end desc "Deploy new version to F-Droid" lane :deployToFDroid do |options| gradle(task: "clean") gradle( task: "assemble", build_type: "Release", flavor: "fdroid", print_command: false, properties: { "android.injected.signing.store.file" => ENV["SIGNING_KEYSTORE_PATH"], "android.injected.signing.store.password" => ENV["SIGNING_KEYSTORE_PASSWORD"], "android.injected.signing.key.alias" => ENV["SIGNING_KEY_ALIAS"], "android.injected.signing.key.password" => ENV["SIGNING_KEY_PASSWORD"], } ) FileUtils.cp(lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH], "repo/Cryptomator.apk") sh("cp -r metadata/android/ metadata/org.cryptomator/") sh("fdroid update && fdroid rewritemeta") sh("rm -r metadata/org.cryptomator/") aws_s3( bucket: ENV['S3_BUCKET'], endpoint: ENV['S3_ENDPOINT'], region: ENV['S3_REGION'], access_key: ENV['S3_ACCESS_KEY'], secret_access_key: ENV['S3_SECRET_ACCESS_KEY'], path: "android/fdroid", folder: "fastlane/repo", skip_html_upload: true, apk: '' ) FileUtils.cp(lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH], "release/Cryptomator-#{version}_fdroid_signed.apk") end desc "Create GitHub draft release" lane :createGitHubDraftRelease do |options| target_branch = "main" prerelease = false if options[:beta] target_branch = git_branch prerelease = true end website_apk_sha256 = Digest::SHA256.hexdigest File.read "release/Cryptomator-#{version}_signed.apk" fdroid_apk_sha256 = Digest::SHA256.hexdigest File.read "release/Cryptomator-#{version}_fdroid_signed.apk" release_note = "## What's New\n\n" + File.read(release_note_path_en) + "\n\n---\n\nSHA256 Signature: `#{website_apk_sha256}`\nSHA256 Signature fdroid: `#{fdroid_apk_sha256}`\n" puts release_note github_release = set_github_release( repository_name: "cryptomator/android", api_token: ENV["GITHUB_PERSONAL_ACCESS_TOKEN"], name: "#{version}", tag_name: "#{version}", description: release_note, commitish: target_branch, is_draft: true, is_prerelease: prerelease, upload_assets: ["fastlane/release/Cryptomator-#{version}_fdroid_signed.apk", "fastlane/release/Cryptomator-#{version}_signed.apk"] ) end end