Skip to content

Instantly share code, notes, and snippets.

@ldiqual

ldiqual/Fastfile Secret

Created February 1, 2018 20:58
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save ldiqual/b060cff88f8ad2147fefa7f5af210e02 to your computer and use it in GitHub Desktop.
Save ldiqual/b060cff88f8ad2147fefa7f5af210e02 to your computer and use it in GitHub Desktop.
opt_out_usage
fastlane_version "1.49.0"
default_platform :ios
skip_docs
platform :ios do
desc "Lints the project"
lane :lint do
sh "cd ../ && ./Pods/SwiftLint/swiftlint --strict"
sh "../tools/detect-unused-strings.py"
sh "../tools/detect-unused-images.py"
sh "../tools/detect-unused-screennames.py"
end
lane :certs do
certs_scoop()
certs_scoopinternal()
certs_scoopqa()
end
lane :certs_scoop do
# Scoop
# Note that we're not generating dev certs because we don't want
# the prod app to run in dev mode
["appstore"].each { |type|
match(
type: type,
team_id: "H7TK3C9688",
team_name: "Scoop Technologies, Inc",
app_identifier: "com.takescoop.Scoop",
git_branch: "master"
)
}
# Scoop.NotificationService
["appstore"].each { |type|
match(
type: type,
team_id: "H7TK3C9688",
team_name: "Scoop Technologies, Inc",
app_identifier: "com.takescoop.Scoop.NotificationService",
git_branch: "master"
)
}
end
lane :certs_scoopinternal do
# ScoopInternal
["development", "appstore"].each { |type|
match(
type: type,
team_id: "H7TK3C9688",
team_name: "Scoop Technologies, Inc",
app_identifier: "com.takescoop.ScoopInternal",
git_branch: "master"
)
}
# ScoopInternal.NotificationService
["development", "appstore"].each { |type|
match(
type: type,
team_id: "H7TK3C9688",
team_name: "Scoop Technologies, Inc",
app_identifier: "com.takescoop.ScoopInternal.NotificationService",
git_branch: "master"
)
}
end
lane :certs_scoopqa do
# ScoopQA
# No development cert because of https://github.com/fastlane/fastlane/issues/11038
["enterprise"].each { |type|
match(
type: type,
team_id: "FSZJ3MZBGC",
team_name: "Scoop Technologies, Inc",
app_identifier: "com.takescoop.ScoopQA",
git_branch: "enterprise"
)
}
# ScoopQA.NotificationService
["enterprise"].each { |type|
match(
type: type,
team_id: "FSZJ3MZBGC",
team_name: "Scoop Technologies, Inc",
app_identifier: "com.takescoop.ScoopQA.NotificationService",
git_branch: "enterprise"
)
}
end
# Changes the password for all certificates, appstore + enterprise
lane :certs_change_password do
require 'io/console'
fastlane_require 'match'
old_password = STDIN.getpass('Old password: ')
new_password = STDIN.getpass('New password: ')
["master", "enterprise"].each { |git_branch|
match_params = FastlaneCore::Configuration.create(Match::Options.available_options, {
:git_branch => git_branch
})
match_params.load_configuration_file("Matchfile")
Match::ChangePassword::update(
params: match_params,
from: old_password,
to: new_password
)
}
end
desc "Patches the Scoop project to allow Pods caching"
lane :patch_scoop_project_for_pods_cache do
fastlane_require 'xcodeproj'
project = Xcodeproj::Project.open("../Scoop.xcodeproj")
def target_named(project, name)
project.targets.select { |target| target.name == name }.first
end
def update_phase_for_target(target)
phase = target.shell_script_build_phases.select { |phase| phase.name.include?('Embed Pods Frameworks') }.first
prefix = [
'if [ -z "${FAKE_BUILT_PRODUCTS_DIR}" ]; then',
' built_products_dir=$BUILT_PRODUCTS_DIR',
'else',
' built_products_dir=$FAKE_BUILT_PRODUCTS_DIR',
'fi'
].join("\n")
phase.shell_script = "#{prefix}\nBUILT_PRODUCTS_DIR=$built_products_dir #{phase.shell_script}"
end
all_targets = [
'ScoopInternal',
'ScoopQA',
'ScoopTests'
]
for target_name in all_targets do
target = target_named(project, target_name)
update_phase_for_target(target)
end
project.save()
end
desc "Runs all the tests"
lane :test do
cache_folder = File.expand_path('../build/Debug-iphonesimulator')
pods_framework_path = File.join(cache_folder, 'Pods_Common_ScoopTests.framework')
does_local_cache_exist = File.exist?(pods_framework_path)
if does_local_cache_exist
UI.message "Found local Pods cache, building ScoopTests alone"
scan(
project: File.expand_path('../Scoop.xcodeproj'),
scheme: 'ScoopInternal',
xcargs: "PODS_CONFIGURATION_BUILD_DIR=#{cache_folder} FAKE_BUILT_PRODUCTS_DIR=#{cache_folder}",
include_simulator_logs: false,
)
else
UI.message "Couldn't find local Pods cache, building the whole workspace"
scan(include_simulator_logs: false)
end
end
desc "Clears the remote cache for Pods-Common-ScoopQA"
lane :clear_pods_cache_for_qa do
clear_pods_cache(:configuration => 'release')
end
desc "Clears the remote cache for Pods-Common-ScoopTests"
lane :clear_pods_cache_for_tests do
clear_pods_cache(:configuration => 'debug')
end
desc "Clears the remote cache for a specific configuration"
lane :clear_pods_cache do |options|
configuration = options[:configuration]
sha1 = podfile_sha1()
s3_key = pods_cache_s3_key(
:podfile_sha1 => sha1,
:configuration => configuration
)
sh("aws s3 rm '#{s3_key}'")
end
desc "Restores the Pods-Common-ScoopQA cache or builds it"
lane :restore_or_build_pods_cache_for_qa do
sha1 = podfile_sha1()
s3_key = pods_cache_s3_key(
:podfile_sha1 => sha1,
:configuration => 'release'
)
does_cache_exist = s3_key_exists(:s3_key => s3_key)
if does_cache_exist
restore_pods_cache_for_qa()
else
build_pods_for_qa()
save_pods_cache_for_qa()
end
end
desc "Restores the Pods-Common-ScoopTests cache or builds it"
lane :restore_or_build_pods_cache_for_tests do
sha1 = podfile_sha1()
s3_key = pods_cache_s3_key(
:podfile_sha1 => sha1,
:configuration => 'debug'
)
does_cache_exist = s3_key_exists(:s3_key => s3_key)
if does_cache_exist
restore_pods_cache_for_tests()
else
build_pods_for_tests()
save_pods_cache_for_tests()
end
end
desc "Builds the Pods-Common-ScoopQA cache"
lane :build_pods_for_qa do
project_path = File.expand_path('../Pods/Pods.xcodeproj')
pod_schemes = [
'Pods-Common-ScoopQA',
'Pods-NotificationService-ScoopQANotificationService'
]
for pod_scheme in pod_schemes do
xcodebuild(
:project => project_path,
:scheme => pod_scheme,
:configuration => 'Release',
:destination => 'generic/platform=iOS'
)
end
end
desc "Builds the Pods-Common-ScoopTests cache"
lane :build_pods_for_tests do
project_path = File.expand_path('../Pods/Pods.xcodeproj')
pod_schemes = [
'Pods-Common-ScoopInternal',
'Pods-NotificationService-ScoopInternalNotificationService',
'Pods-Common-ScoopTests'
]
for pod_scheme in pod_schemes do
xcodebuild(
:project => project_path,
:scheme => pod_scheme,
:configuration => 'Debug',
:destination => 'platform=iOS Simulator,name=iPhone 5s,OS=11.2'
)
end
end
desc "Restores the Pods-Common-ScoopQA cache from S3"
lane :restore_pods_cache_for_qa do
restore_pods_cache(:configuration => 'release')
end
desc "Restores the Pods-Common-ScoopTests cache from S3"
lane :restore_pods_cache_for_tests do
restore_pods_cache(:configuration => 'debug')
end
desc "Restores the Pods cache from S3"
lane :restore_pods_cache do |options|
configuration = options[:configuration]
sha1 = podfile_sha1()
s3_key = pods_cache_s3_key(
:podfile_sha1 => sha1,
:configuration => configuration
)
zip_output_file = "/tmp/#{SecureRandom.hex}.zip"
cache_output_dir = File.expand_path('../build')
FileUtils.mkdir_p(cache_output_dir)
sh("aws s3 cp '#{s3_key}' '#{zip_output_file}'")
sh("cd '#{cache_output_dir}' && unzip '#{zip_output_file}'")
FileUtils.rm(zip_output_file)
UI.message "Restored cache for '#{sha1}'"
true
end
desc "Saves the Pods-Common-ScoopQA cache to S3"
lane :save_pods_cache_for_qa do
save_pods_cache(
:configuration => 'release',
:output_build_folder => 'Release-iphoneos'
)
end
desc "Saves the Pods-Common-ScoopTests cache to S3"
lane :save_pods_cache_for_tests do
save_pods_cache(
:configuration => 'debug',
:output_build_folder => 'Debug-iphonesimulator'
)
end
desc "Saves the Pods cache to S3"
lane :save_pods_cache do |options|
configuration = options[:configuration]
output_build_folder = options[:output_build_folder]
sha1 = podfile_sha1()
s3_key = pods_cache_s3_key(
:podfile_sha1 => sha1,
:configuration => configuration
)
build_directory = File.expand_path('../build')
zip_output_file = "/tmp/#{SecureRandom.hex}.zip"
sh("cd '#{build_directory}' && zip -r '#{zip_output_file}' ./#{output_build_folder}")
sh("aws s3 cp '#{zip_output_file}' '#{s3_key}'")
FileUtils.rm(zip_output_file)
end
desc "Deploys a QA build to s3 and the #mobile-builds channel"
lane :qa do
fastlane_require 'scoop-mobile-scripts'
version = get_version_number()
build_number = bump_build_number()
certs_scoopqa()
cache_folder = File.expand_path('../build/Release-iphoneos')
pods_framework_path = File.join(cache_folder, 'Pods_Common_ScoopQA.framework')
does_local_cache_exist = File.exist?(pods_framework_path)
if does_local_cache_exist
UI.message "Found local Pods cache, archiving ScoopQA alone"
gym(
project: File.expand_path('../Scoop.xcodeproj'),
scheme: 'ScoopQA',
configuration: 'Release',
destination: 'generic/platform=iOS',
xcargs: "PODS_CONFIGURATION_BUILD_DIR=#{cache_folder} FAKE_BUILT_PRODUCTS_DIR=#{cache_folder}",
export_options: { compileBitcode: false },
# Workaround https://github.com/fastlane/fastlane/issues/11201
export_method: 'enterprise'
)
else
UI.message "Couldn't find local Pods cache, archiving the whole workspace"
gym(
export_options: { compileBitcode: false },
# Workaround https://github.com/fastlane/fastlane/issues/11201
export_method: 'enterprise'
)
end
ipa_path = lane_context[SharedValues::IPA_OUTPUT_PATH]
download_url = upload_to_s3(
app_path: ipa_path,
version: version,
build_number: build_number,
app_name: 'Scoop QA',
bundle_identifier: 'com.takescoop.ScoopQA'
)
notify_slack(url: download_url, build_number: build_number)
tag(version: version, build_number: build_number)
if ENV['CIRCLE_ARTIFACTS']
backup_xcarchive(
destination: ENV['CIRCLE_ARTIFACTS'],
versioned: false
)
end
end
desc "Deploys ScoopInternal on TestFlight"
lane :internal do
version = get_version_number()
build_number = bump_build_number()
certs_scoopinternal()
gym(
# Workaround https://github.com/fastlane/fastlane/issues/11201
export_method: 'app-store'
)
ipa_path = lane_context[SharedValues::IPA_OUTPUT_PATH]
deliver()
tag(version: version, build_number: build_number)
if ENV['CIRCLE_ARTIFACTS']
backup_xcarchive(
destination: ENV['CIRCLE_ARTIFACTS'],
versioned: false
)
end
end
desc "Deploys Scoop (Production) on TestFlight"
lane :production do
version = get_version_number()
build_number = bump_build_number()
certs_scoop()
gym(
# Workaround https://github.com/fastlane/fastlane/issues/11201
export_method: 'app-store'
)
ipa_path = lane_context[SharedValues::IPA_OUTPUT_PATH]
deliver()
tag(version: version, build_number: build_number)
if ENV['CIRCLE_ARTIFACTS']
backup_xcarchive(
destination: ENV['CIRCLE_ARTIFACTS'],
versioned: false
)
end
end
desc "Generates an Appetize preview in the current Pull Request"
lane :add_appetize_to_pull_request do
fastlane_require 'octokit'
require './device_grid.rb'
# Make sure we do have a PR open
repo = 'TakeScoop/scoop-ios'
branch = git_branch
client = Octokit::Client.new(:access_token => ENV['SCOOP_OPS_CIRCLECI_GITHUB_TOKEN'])
pull_request = client.pull_requests(repo, :head => 'TakeScoop:' + branch).first
if pull_request.nil?
puts "Could not find a pull request associated with the branch #{branch}"
next
end
# Build the app for Appetize and upload it
public_key = build_and_upload_to_appetize(
api_token: ENV['APPETIZE_API_TOKEN'],
xcodebuild: {
workspace: "Scoop.xcworkspace",
scheme: "ScoopInternal"
}
)
# Generate a nice device grid to add to the bot comment
devices = ['iphone5s', 'iphone6s', 'iphone6splus']
grid = device_grid(public_key, devices)
# Comment body
comment_body = ""
comment_body << "**😍 What a wonderful PR! 😍**\n"
comment_body << "\n"
comment_body << "### Try it out\n"
comment_body << "*Based on commit #{last_git_commit[:commit_hash]}*\n"
comment_body << "\n"
comment_body << grid
# Comment in the PR
client.add_comment(repo, pull_request['number'], comment_body)
puts "Added comment to pull request #{pull_request['number']}"
end
end
private_lane :podfile_sha1 do |options|
podfile_path = File.expand_path('../Podfile')
sh("shasum '#{podfile_path}'").split(" ")[0].strip
end
private_lane :pods_cache_s3_key do |options|
podfile_sha1 = options[:podfile_sha1]
configuration = options[:configuration]
xcode_version = sh("xcodebuild -version | grep 'Build version' | awk '{ print $3 }'").strip
"s3://scoop-mobile-builds/cache/pods_#{configuration}_#{podfile_sha1}_xcode-#{xcode_version}.zip"
end
private_lane :s3_key_exists do |options|
s3_key = options[:s3_key]
sh("aws s3 ls '#{s3_key}' &> /dev/null; echo $?").strip.to_i == 0
end
private_lane :bump_build_number do |options|
build_number = (sh "cd .. && bundle exec scoop bump-build-number").rstrip().to_i
increment_build_number(build_number: build_number)
build_number
end
# Tag this version. Example: 1.1.4.256
private_lane :tag do |options|
version = options[:version]
build_number = options[:build_number]
tag = "#{version}.#{build_number}"
add_git_tag(tag: tag)
push_git_tags
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment