-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathFastfile
More file actions
227 lines (190 loc) · 10.1 KB
/
Fastfile
File metadata and controls
227 lines (190 loc) · 10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# frozen_string_literal: true
fastlane_require 'xcodeproj'
fastlane_require 'dotenv'
fastlane_require 'open-uri'
fastlane_require 'git'
UI.user_error!('Please run fastlane via `bundle exec`') unless FastlaneCore::Helper.bundler?
########################################################################
# Constants and Environment Variables
########################################################################
# Paths that are re-used across multiple lanes
PROJECT_ROOT_FOLDER = File.dirname(File.expand_path(__dir__))
WORKSPACE_PATH = File.join(PROJECT_ROOT_FOLDER, 'WordPress.xcworkspace')
DERIVED_DATA_PATH = File.join(PROJECT_ROOT_FOLDER, 'DerivedData')
BUILD_PRODUCTS_PATH = File.join(PROJECT_ROOT_FOLDER, 'Artifacts')
WORDPRESS_RELEASE_NOTES_PATH = File.join(PROJECT_ROOT_FOLDER, 'WordPress', 'Resources', 'release_notes.txt')
JETPACK_RELEASE_NOTES_PATH = File.join(PROJECT_ROOT_FOLDER, 'WordPress', 'Jetpack', 'Resources', 'release_notes.txt')
WORDPRESS_BETA_APP_DESCRIPTION_PATH = File.join(PROJECT_ROOT_FOLDER, 'WordPress', 'Resources', 'beta_app_description.txt')
JETPACK_BETA_APP_DESCRIPTION_PATH = File.join(PROJECT_ROOT_FOLDER, 'WordPress', 'Jetpack', 'Resources', 'beta_app_description.txt')
# Env file paths to load
ENV_FILE_NAME = '.wpios-env.default'
USER_ENV_FILE_PATH = File.join(Dir.home, ENV_FILE_NAME)
SECRETS_DIR = File.join(Dir.home, '.configure', 'wordpress-ios', 'secrets')
PROJECT_ENV_FILE_PATH = File.join(SECRETS_DIR, 'project.env')
APP_STORE_CONNECT_KEY_PATH = File.join(SECRETS_DIR, 'app_store_connect_fastlane_api_key.json')
WORDPRESS_BUNDLE_IDENTIFIER = 'org.wordpress'
WORDPRESS_EXTENSIONS_BUNDLE_IDENTIFIERS = %w[
WordPressShare
WordPressDraftAction
WordPressNotificationServiceExtension
WordPressNotificationContentExtension
].map { |suffix| "#{WORDPRESS_BUNDLE_IDENTIFIER}.#{suffix}" }
ALL_WORDPRESS_BUNDLE_IDENTIFIERS = [WORDPRESS_BUNDLE_IDENTIFIER, *WORDPRESS_EXTENSIONS_BUNDLE_IDENTIFIERS].freeze
JETPACK_BUNDLE_IDENTIFIER = 'com.automattic.jetpack'
JETPACK_EXTENSIONS_BUNDLE_IDENTIFIERS = %w[
JetpackShare
JetpackDraftAction
JetpackStatsWidgets
JetpackNotificationServiceExtension
JetpackIntents
].map { |suffix| "#{JETPACK_BUNDLE_IDENTIFIER}.#{suffix}" }
ALL_JETPACK_BUNDLE_IDENTIFIERS = [JETPACK_BUNDLE_IDENTIFIER, *JETPACK_EXTENSIONS_BUNDLE_IDENTIFIERS].freeze
READER_BUNDLE_IDENTIFIER = 'com.automattic.reader'
# Redundant but handy for consistency, especially in codesign.rb
ALL_READER_BUNDLE_IDENTIFIERS = [READER_BUNDLE_IDENTIFIER].freeze
# Environment Variables — used by lanes but also potentially actions
Dotenv.load(USER_ENV_FILE_PATH)
Dotenv.load(PROJECT_ENV_FILE_PATH)
GITHUB_REPO = 'wordpress-mobile/wordpress-iOS'
DEFAULT_BRANCH = 'trunk'
PUBLIC_CONFIG_FILE = File.join(PROJECT_ROOT_FOLDER, 'config', 'Version.public.xcconfig')
ENV['FASTLANE_WWDR_USE_HTTP1_AND_RETRIES'] = 'true'
# Fastlane's `git_branch` action and its relevant helpers use environment variables to modify the output.
# That means if we change the branch as part of an action, it'll return the incorrect branch.
# This environment variable disables that behavior.
# See https://github.com/fastlane/fastlane/pull/21597
ENV['FL_GIT_BRANCH_DONT_USE_ENV_VARS'] = 'true'
# Instanstiate versioning classes
VERSION_CALCULATOR = Fastlane::Wpmreleasetoolkit::Versioning::MarketingVersionCalculator.new
VERSION_FORMATTER = Fastlane::Wpmreleasetoolkit::Versioning::FourPartVersionFormatter.new
BUILD_CODE_FORMATTER = Fastlane::Wpmreleasetoolkit::Versioning::FourPartBuildCodeFormatter.new
PUBLIC_VERSION_FILE = Fastlane::Wpmreleasetoolkit::Versioning::IOSVersionFile.new(xcconfig_path: PUBLIC_CONFIG_FILE)
BUILDKITE_ORGANIZATION = 'automattic'
BUILDKITE_PIPELINE = 'wordpress-ios'
BUILDKITE_RELEASE_PIPELINE = 'release-builds.yml'
# Use this instead of getting values from ENV directly. It will throw an error if the requested value is missing
def get_required_env(key)
UI.user_error!("Environment variable '#{key}' is not set. Have you setup #{USER_ENV_FILE_PATH} correctly?") unless ENV.key?(key)
ENV.fetch(key, nil)
end
########################################################################
# Version Methods
########################################################################
# Returns the release version of the app in the format `1.2` or `1.2.3` if it is a hotfix
#
def release_version_current
# Read the current release version from the .xcconfig file and parse it into an AppVersion object
current_version = VERSION_FORMATTER.parse(PUBLIC_VERSION_FILE.read_release_version)
# Return the formatted release version
VERSION_FORMATTER.release_version(current_version)
end
# Returns the next release version of the app in the format `1.2` or `1.2.3` if it is a hotfix
#
def release_version_next
# Read the current release version from the .xcconfig file and parse it into an AppVersion object
current_version = VERSION_FORMATTER.parse(PUBLIC_VERSION_FILE.read_release_version)
# Calculate the next release version
next_calculated_release_version = VERSION_CALCULATOR.next_release_version(version: current_version)
# Return the formatted release version
VERSION_FORMATTER.release_version(next_calculated_release_version)
end
def current_version_hotfix?
# Read the current release version from the .xcconfig file and parse it into an AppVersion object
current_version = VERSION_FORMATTER.parse(PUBLIC_VERSION_FILE.read_release_version)
# Calculate and return whether the release version is a hotfix
VERSION_CALCULATOR.release_is_hotfix?(version: current_version)
end
# Returns the current build code of the app
#
def build_code_current
# Read the current build code from the .xcconfig file and parse it into an AppVersion object
# The AppVersion is used because WP/JPiOS uses the four part (1.2.3.4) build code format, so the version
# calculator can be used to calculate the next four-part version
version = VERSION_FORMATTER.parse(PUBLIC_VERSION_FILE.read_build_code(attribute_name: 'VERSION_LONG'))
# Return the formatted build code
BUILD_CODE_FORMATTER.build_code(version: version)
end
# Returns the build code of the app for the code freeze. It is the release version name plus sets the build number to 0
#
def build_code_code_freeze
# Read the current build code from the .xcconfig file and parse it into an AppVersion object
# The AppVersion is used because WP/JPiOS uses the four part (1.2.3.4) build code format, so the version
# calculator can be used to calculate the next four-part version
release_version_current = VERSION_FORMATTER.parse(PUBLIC_VERSION_FILE.read_release_version)
# Calculate the next release version, which will be used as the basis of the new build code
build_code_code_freeze = VERSION_CALCULATOR.next_release_version(version: release_version_current)
# Return the formatted build code
BUILD_CODE_FORMATTER.build_code(version: build_code_code_freeze)
end
# Returns the build code of the app for the code freeze. It is the hotfix version name plus sets the build number to 0
#
def build_code_hotfix(release_version:)
version = VERSION_FORMATTER.parse(release_version)
# Return the formatted build code
BUILD_CODE_FORMATTER.build_code(version: version)
end
# Returns the next build code of the app
#
def build_code_next
# Read the current build code from the .xcconfig file and parse it into an AppVersion object
# The AppVersion is used because WP/JPiOS uses the four part (1.2.3.4) build code format, so the version
# calculator can be used to calculate the next four-part version
build_code_current = VERSION_FORMATTER.parse(PUBLIC_VERSION_FILE.read_build_code(attribute_name: 'VERSION_LONG'))
# Calculate the next build code
build_code_next = VERSION_CALCULATOR.next_build_number(version: build_code_current)
# Return the formatted build code
BUILD_CODE_FORMATTER.build_code(version: build_code_next)
end
########################################################################
# Imports domain-specific lanes
########################################################################
import 'lanes/build.rb'
import 'lanes/codesign.rb'
import 'lanes/localization.rb'
import 'lanes/release.rb'
import 'lanes/screenshots.rb'
########################################################################
default_platform(:ios)
before_all do |lane|
# Various actions run 'xcodebuild -showBuildSettings ...' which can at times fail, possibly due to networking and SPM resolution.
# See for example this failure https://buildkite.com/automattic/wordpress-ios/builds/22979#01906bdc-3077-4d17-b742-a55c9a9db4b4
#
# Bumping the interval Fastlane waits for xcodebuild to provide output before retrying seems to be an effective workaround.
#
# See also https://github.com/fastlane/fastlane/issues/20919
ENV['FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT'] = '120'
# Skip these checks/steps for test lane (not needed for testing)
next if lane == :test_without_building
# Ensure we use the latest version of the toolkit
check_for_toolkit_updates unless is_ci || ENV['FASTLANE_SKIP_TOOLKIT_UPDATE_CHECK']
# Fixes weird Keychain bugs
setup_ci
# Check that the env files exist
unless is_ci || File.file?(USER_ENV_FILE_PATH)
example_path = 'fastlane/env/user.env-example '
UI.user_error! "#{ENV_FILE_NAME} not found: Please copy #{example_path} to #{USER_ENV_FILE_PATH} and fill in the values."
end
unless File.file?(PROJECT_ENV_FILE_PATH)
UI.user_error!("project.env not found at #{PROJECT_ENV_FILE_PATH}: Make sure your configuration is up to date with `rake dependencies`")
end
end
def compute_release_branch_name(options:, version: release_version_current)
branch_option = :branch
branch_name = options[branch_option]
if branch_name.nil?
branch_name = release_branch_name(version: version)
UI.message("No branch given via option '#{branch_option}'. Defaulting to #{branch_name}.")
end
branch_name
end
def release_branch_name(version: release_version_current)
"release/#{version}"
end
def editorial_branch_name(version: release_version_current)
"release_notes/#{version}"
end
def pull_request_number
# Buildkite sets this env var to the PR number if on a PR, but to 'false' (and not nil) if not on a PR
pr_num = ENV.fetch('BUILDKITE_PULL_REQUEST', 'false')
pr_num == 'false' ? nil : Integer(pr_num)
end