-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Expand file tree
/
Copy pathsetup_quickstart.sh
More file actions
executable file
·273 lines (239 loc) · 9.5 KB
/
setup_quickstart.sh
File metadata and controls
executable file
·273 lines (239 loc) · 9.5 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
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
#!/usr/bin/env bash
# Copyright 2025 Google LLC
#
# 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.
# Script to run in a CI `before_install` phase to setup a SPM-based
# quickstart repo so that it can be used for integration testing.
set -euo pipefail
# Define testing mode constants.
readonly NIGHTLY_RELEASE_TESTING="nightly_release_testing"
readonly PRERELEASE_TESTING="prerelease_testing"
# All script logic is contained in functions. The main function is called at
# the end.
# Global variables:
# - readonly constants are defined at the top.
# - scripts_dir and root_dir are set after constants.
scripts_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
root_dir="$(dirname "$scripts_dir")"
print_usage() {
cat <<EOF
Usage: $(basename "$0") <sample_name> [testing_mode]
This script sets up a quickstart sample for SPM integration testing.
ARGUMENTS:
<sample_name> The name of the quickstart sample directory
(e.g., "authentication").
[testing_mode] Optional. Specifies the testing mode. Can be one of:
- "${NIGHTLY_RELEASE_TESTING}": Points SPM to the latest
CocoaPods tag.
- "${PRERELEASE_TESTING}": Points SPM to the tip of the main
branch.
- (default): Points SPM to the current commit for PR testing.
ENVIRONMENT VARIABLES:
QUICKSTART_REPO: Optional. Path to a local clone of the quickstart-ios repo.
If not set, the script will clone it from GitHub.
Example:
QUICKSTART_REPO=/path/to/quickstart-ios $(basename "$0") authentication
QUICKSTART_BRANCH: Optional. The branch to checkout in the quickstart repo.
Defaults to the repo's default branch.
Example:
QUICKSTART_BRANCH=my-feature-branch $(basename "$0") authentication
BYPASS_SECRET_CHECK: Optional. Set to "true" to bypass the CI secret check
for local runs.
Example:
BYPASS_SECRET_CHECK=true $(basename "$0") authentication
DEBUG: Optional. Set to "true" to enable shell trace mode (`set -x`).
Example: DEBUG=true $(basename "$0") authentication
EOF
}
# Clones or locates the quickstart repo.
#
# Globals:
# - QUICKSTART_REPO (read-only)
# Arguments:
# - $1: The name of the sample.
# Outputs:
# - Echoes the absolute path to the quickstart directory.
setup_quickstart_repo() {
local sample_name="$1"
local quickstart_dir
# If QUICKSTART_REPO is set, use it. Otherwise, clone the repo.
if [[ -n "${QUICKSTART_REPO:-}" ]]; then
# If the user provided a path, it must be a valid directory.
if [[ ! -d "${QUICKSTART_REPO}" ]]; then
echo "Error: QUICKSTART_REPO is set to '${QUICKSTART_REPO}'," \
"but this is not a valid directory." >&2
exit 1
fi
echo "Using local quickstart repository at ${QUICKSTART_REPO}" >&2
quickstart_dir="${QUICKSTART_REPO}"
if ! (cd "${quickstart_dir}" && \
git rev-parse --is-inside-work-tree >/dev/null 2>&1); then
echo "Error: QUICKSTART_REPO ('${quickstart_dir}') is not a git" \
"repository." >&2
exit 1
fi
else
# QUICKSTART_REPO is not set, so clone it.
quickstart_dir="quickstart-ios"
if [[ -d "${quickstart_dir}" ]]; then
echo "Quickstart repository already exists at ${quickstart_dir}" >&2
else
echo "Cloning quickstart repository into '${quickstart_dir}' directory..." >&2
# Do a partial, sparse clone to speed up CI. See
# https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/
git clone --filter=blob:none --sparse \
https://github.com/firebase/quickstart-ios.git "${quickstart_dir}"
fi
(
cd "${quickstart_dir}"
echo "Ensuring sparse checkout is set for ${sample_name}..." >&2
# Checkout the sample and scripts directories.
git sparse-checkout set "${sample_name}" scripts shared
)
fi
# If a branch is specified, check it out.
if [[ -n "${QUICKSTART_BRANCH:-}" ]]; then
echo "Checking out quickstart branch: ${QUICKSTART_BRANCH}" >&2
(
cd "${quickstart_dir}"
git fetch --quiet
git checkout --quiet "${QUICKSTART_BRANCH}"
)
fi
# Return the absolute path to the quickstart directory.
(cd "$quickstart_dir" && pwd)
}
# Updates the SPM dependency in the Xcode project based on the testing mode.
#
# Globals:
# - NIGHTLY_RELEASE_TESTING (read-only)
# - PRERELEASE_TESTING (read-only)
# - scripts_dir (read-only)
# - root_dir (read-only)
# Arguments:
# - $1: The testing mode.
# - $2: The absolute path to the .xcodeproj file.
update_spm_dependency() {
local release_testing_mode="$1"
local absolute_project_file="$2"
case "$release_testing_mode" in
"${NIGHTLY_RELEASE_TESTING}")
# For release testing, find the latest CocoaPods tag.
local latest_tag
latest_tag=$(git -C "$root_dir" tag -l "CocoaPods-*" --sort=-v:refname |
awk '/^CocoaPods-[0-9]+\.[0-9]+\.[0-9]+$/{print; exit}')
if [[ -z "$latest_tag" ]]; then
echo "Error: Could not find the latest CocoaPods tag." >&2
echo "This is often caused by a shallow git clone in a CI environment." >&2
echo "If you are running in GitHub Actions, please ensure your checkout" >&2
echo "step includes 'fetch-depth: 0' to fetch the full git history." >&2
exit 1
fi
local tag_revision
tag_revision=$(git -C "$root_dir" rev-list -n 1 "$latest_tag")
echo "Setting SPM dependency to revision for tag ${latest_tag}:" \
"${tag_revision}"
"$scripts_dir/update_firebase_spm_dependency.sh" \
"$absolute_project_file" --revision "$tag_revision"
;;
"${PRERELEASE_TESTING}")
# For prerelease testing, point to the tip of the main branch.
echo "Setting SPM dependency to the tip of the main branch."
"$scripts_dir/update_firebase_spm_dependency.sh" \
"$absolute_project_file" --prerelease
;;
*)
# For PR testing, point to the current commit.
local current_revision
# Detect if we are in a PR or a regular push
if [ "${GITHUB_EVENT_NAME:-}" == "pull_request" ]; then
if ! command -v jq &> /dev/null; then
echo "Error: jq is required for PR testing." >&2
exit 1
fi
# In a PR, read the real commit SHA from the event payload
# This guarantees a hash that exists on the remote server
current_revision=$(jq -er .pull_request.head.sha "${GITHUB_EVENT_PATH}")
else
# In a Push (or local run), HEAD is safe to use
current_revision=$(git -C "$root_dir" rev-parse HEAD)
fi
echo "Setting SPM dependency to current revision: ${current_revision}"
"$scripts_dir/update_firebase_spm_dependency.sh" \
"$absolute_project_file" --revision "$current_revision"
;;
esac
}
main() {
# --- Argument Parsing ---
if [[ -z "${1:-}" ]]; then
print_usage
exit 1
fi
local sample="$1"
local release_testing="${2-}"
# Validate release_testing argument.
case "$release_testing" in
"" | "${NIGHTLY_RELEASE_TESTING}" | "${PRERELEASE_TESTING}")
# This is a valid value (or empty), so do nothing.
;;
*)
# This is an invalid value.
echo "Error: Invalid testing_mode: '${release_testing}'" >&2
print_usage
exit 1
;;
esac
# --- Environment Setup and Validation ---
# Enable trace mode if DEBUG is set to 'true'
if [[ "${DEBUG:-false}" == "true" ]]; then
set -x
fi
# Source function to check if CI secrets are available.
source "$scripts_dir/check_secrets.sh"
# Some quickstarts may not need a real GoogleService-Info.plist for their
# tests. When QUICKSTART_REPO is set (for local runs) or BYPASS_SECRET_CHECK
# is true, the secrets check is skipped.
if [[ -z "${QUICKSTART_REPO:-}" ]] && \
[[ "${BYPASS_SECRET_CHECK:-}" != "true" ]] && \
! check_secrets && \
[[ "${sample}" != "installations" ]]; then
echo "Skipping quickstart setup: CI secrets are not available."
exit 0
fi
# --- Main Logic ---
local quickstart_dir
quickstart_dir=$(setup_quickstart_repo "$sample")
local quickstart_project_dir="${quickstart_dir}/${sample}"
if [[ ! -d "${quickstart_project_dir}" ]]; then
echo "Error: Sample directory not found at '${quickstart_project_dir}'" >&2
exit 1
fi
# Find the .xcodeproj file within the sample directory.
# Fail if there isn't exactly one.
# Enable nullglob to ensure the glob expands to an empty list if no files
# are found.
shopt -s nullglob
local project_files=("${quickstart_project_dir}"/*.xcodeproj)
# Restore default globbing behavior.
shopt -u nullglob
if [[ "${#project_files[@]}" -ne 1 ]]; then
echo "Error: Expected 1 .xcodeproj file in" \
"'${quickstart_project_dir}', but found ${#project_files[@]}." >&2
exit 1
fi
local project_file="${project_files[0]}"
update_spm_dependency "$release_testing" "$project_file"
}
# Run the main function with all provided arguments.
main "$@"