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
#!/bin/sh
# Xcode Cloud hook: runs after the repository is cloned, before Xcode Cloud
# looks for the project. Grain.xcodeproj is XcodeGen output and isn't committed,
# so it has to be generated here.
#
# Xcode Cloud finds this script because it sits in ci_scripts/ next to
# Grain.xcodeproj (both at the repo root).
set -ex
# Pinned release binaries, not Homebrew: Xcode Cloud can build on Intel, where
# Homebrew has no bottles, so `brew install git-lfs` compiles Rust, LLVM and
# OpenSSL from source and fails. Bump a version and its checksum together.
GIT_LFS_VERSION=3.8.1
XCODEGEN_VERSION=2.46.0
XCODEGEN_SHA256=ef6d0a23bfb7393387f98e321ffd78a487231172e2e78c48d3c26275c263fd0c
case "$(uname -m)" in
x86_64)
GIT_LFS_ARCH=amd64
GIT_LFS_SHA256=4292b3518e717e53c20a6c2c0696e2069a21e97500ad14b80b06bd52de8f3b72
;;
arm64)
GIT_LFS_ARCH=arm64
GIT_LFS_SHA256=0ba10e897e0496412cd86eacaed4ed554c97ddc29bc5c709d28faa5eaaa2222c
;;
*)
echo "error: no git-lfs pinned for $(uname -m)"
exit 1
;;
esac
TOOLS=$(mktemp -d)
# fetch <url> <sha256> <archive>: download an archive, refusing a wrong checksum.
fetch() {
curl -fsSL --retry 3 -o "$3" "$1"
echo "$2 $3" | shasum -a 256 -c -
}
fetch "https://github.com/git-lfs/git-lfs/releases/download/v$GIT_LFS_VERSION/git-lfs-darwin-$GIT_LFS_ARCH-v$GIT_LFS_VERSION.zip" \
"$GIT_LFS_SHA256" "$TOOLS/git-lfs.zip"
unzip -q "$TOOLS/git-lfs.zip" -d "$TOOLS"
fetch "https://github.com/yonaskolb/XcodeGen/releases/download/$XCODEGEN_VERSION/xcodegen.artifactbundle.zip" \
"$XCODEGEN_SHA256" "$TOOLS/xcodegen.zip"
unzip -q "$TOOLS/xcodegen.zip" -d "$TOOLS"
# xcodegen finds its XcodeGen_XcodeGenKit.bundle beside the binary, so it runs
# from where it was unpacked.
PATH="$TOOLS/git-lfs-$GIT_LFS_VERSION:$TOOLS/xcodegen.artifactbundle/xcodegen-$XCODEGEN_VERSION-macosx/bin:$PATH"
export PATH
cd "$CI_PRIMARY_REPOSITORY_PATH"
# Icons, fonts, and images are git-lfs backed. Without the real bytes the asset
# catalog compile fails with the unhelpful "AppIcon did not have any applicable
# content", so fetch them and then prove they actually landed.
git lfs install
git lfs pull
# `if` rather than an && chain: under `set -e` a failing grep as the loop body's
# last command would kill the subshell, so a clean checkout would abort here.
pointers=$(git lfs ls-files -n | while read -r f; do
if [ -f "$f" ] && head -c 64 "$f" 2>/dev/null | grep -q 'git-lfs.github.com'; then
echo "$f"
fi
done) || true
if [ -n "$pointers" ]; then
echo "error: git-lfs objects are still pointers after 'git lfs pull':"
echo "$pointers"
exit 1
fi
# project.yml interpolates all three; PRODUCT_NAME is ${BUNDLE_NAME}, and
# leaving it unset generates an empty .app name that fails the build with
# "Multiple commands produce '.app'".
export APPLE_TEAM_ID="${APPLE_TEAM_ID:-YN68LN9T7Z}"
export BUNDLE_ID="${BUNDLE_ID:-social.grain.grain}"
export BUNDLE_NAME="${BUNDLE_NAME:-Grain}"
# Build numbers are Xcode Cloud's to assign — it overwrites CFBundleVersion with
# its own run counter when it archives, so writing one into project.yml here has
# no effect (run 45 set CURRENT_PROJECT_VERSION to 104 and still uploaded as
# build 45). Build numbers only have to be unique and increasing *within* a
# marketing version, so restarting at a low number on a new train is fine.
#
# MARKETING_VERSION is left alone: bumping the train is manual and deliberate,
# and it has to happen before the current version is approved (see DEVELOPMENT.md).
xcodegen generate
# Xcode Cloud disables automatic package resolution, so the generated project
# needs the committed pins. Update the root Package.resolved when packages
# change — the live one is written inside the gitignored .xcodeproj:
# just generate && xcodebuild -resolvePackageDependencies -project Grain.xcodeproj -scheme Grain
# cp Grain.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved .
SWIFTPM_DIR="Grain.xcodeproj/project.xcworkspace/xcshareddata/swiftpm"
mkdir -p "$SWIFTPM_DIR"
cp Package.resolved "$SWIFTPM_DIR/Package.resolved"