forked from gravitational/teleport
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild-pkg-app.sh
executable file
·222 lines (196 loc) · 6.19 KB
/
build-pkg-app.sh
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
#!/bin/bash
set -eu
# Flag variables
TELEPORT_TYPE='' # -t, oss or ent
TELEPORT_VERSION='' # -v, version, without leading 'v'
TARBALL_DIRECTORY='' # -s
BUNDLEID="${TSH_BUNDLEID}"
PACKAGE_ARCH=amd64 # -a, default to amd64 for backward-compatibilty.
PACKAGE_NAME=tsh # -p, name of app, defaulted to tsh
usage() {
log "Usage: $0 -t oss|eng -v version [-s tarball_directory] [-b bundle_id] [-n] [-p tsh|tctl]"
}
# make_non_relocatable_plist changes the default component plist of the $root
# package to non-relocatable.
# This makes install paths consistent, which also facilitates pathing in
# pre/postscripts.
# Creates component_plist.
# See `man pkgbuild` for reference.
make_non_relocatable_plist() {
local root="$1"
local component_plist="$2"
pkgbuild --analyze --root "$root" "$component_plist"
plutil -replace BundleIsRelocatable -bool NO "$component_plist"
}
main() {
local buildassets=''
buildassets="$(dirname "$0")"
# Don't follow sourced script.
#shellcheck disable=SC1090
#shellcheck disable=SC1091
. "$buildassets/build-common.sh"
local opt=''
while getopts "t:v:s:b:a:p:n" opt; do
case "$opt" in
t)
if [[ "$OPTARG" != "oss" && "$OPTARG" != "ent" ]]; then
log "$0: invalid value for -$opt, want 'oss' or 'ent'"
usage
exit 1
fi
TELEPORT_TYPE="$OPTARG"
;;
v)
TELEPORT_VERSION="$OPTARG"
;;
s)
# Find out the absolute path to -s.
if [[ "$OPTARG" != /* ]]; then
OPTARG="$PWD/$OPTARG"
fi
TARBALL_DIRECTORY="$OPTARG"
;;
b)
BUNDLEID="$OPTARG"
;;
a)
PACKAGE_ARCH="$OPTARG"
;;
p)
if [[ "$OPTARG" != "tsh" && "$OPTARG" != "tctl" ]]; then
log "$0: invalid value for -$opt, want 'tsh' or 'tctl'"
usage
exit 1
fi
PACKAGE_NAME="$OPTARG"
;;
n)
DRY_RUN_PREFIX='echo + ' # declared by build-common.sh
;;
*)
usage
exit 1
;;
esac
done
shift $((OPTIND-1))
# Cut leading 'v' from version, in case it's there.
if [[ "$TELEPORT_VERSION" == v* ]]; then
TELEPORT_VERSION="${TELEPORT_VERSION:1}"
fi
if [[ -z "$TELEPORT_TYPE" || -z "${TELEPORT_VERSION}" ]]; then
usage
exit 1
fi
if [[ -z "${BUNDLEID}" ]]; then
echo "No bundle ID specified. Either set TSH_BUNDLEID or use -b bundle_id"
usage
exit 1
fi
# Verify environment varibles.
if [[ "${APPLE_USERNAME:-}" == "" ]]; then
echo "\
The APPLE_USERNAME environment variable needs to be set to the Apple ID used\
for notarization requests"
exit 1
fi
if [[ "${APPLE_PASSWORD:-}" == "" ]]; then
echo "\
The APPLE_PASSWORD environment variable needs to be set to an app-specific\
password created by APPLE_USERNAME"
exit 1
fi
if [[ -z "${DEVELOPER_ID_APPLICATION}" ]]; then
echo "\
The DEVELOPER_ID_APPLICATION environment variable needs to be set to the hash\
or name of the key to sign applications"
exit 1
fi
if [[ -z "${DEVELOPER_ID_INSTALLER}" ]]; then
echo "\
The DEVELOPER_ID_INSTALLER environment variable needs to be set to the hash\
or name of the key to sign packages"
exit 1
fi
# Use similar find-or-download logic as build-package.sh for compatibility
# purposes.
local ent=''
[[ "$TELEPORT_TYPE" == 'ent' ]] && ent='-ent'
local tarname=''
tarname="$(printf \
"teleport%s-v%s-darwin-%s-bin.tar.gz" \
"$ent" "$TELEPORT_VERSION" "$PACKAGE_ARCH")"
[[ -n "$TARBALL_DIRECTORY" ]] && tarname="$TARBALL_DIRECTORY/$tarname"
tarout='' # find_or_fetch_tarball writes to this
find_or_fetch_tarball "$tarname" tarout
log "Using tarball at $tarout"
tarname="$tarout"
# Unpack tar, get ready to sign/notarize/package.
local tmp=''
tmp="$(mktemp -d)"
[[ -n "$DRY_RUN_PREFIX" ]] && log "tmp = $tmp"
$DRY_RUN_PREFIX trap "rm -fr '$tmp'" EXIT
# $tmp/ (eventually) looks like this:
# teleport/tsh # oss
# teleport-ent/tsh # ent
# scripts # cloned from build.assets
# root/tsh-vXXX.app # package root
# tsh-vXXX.pkg.unsigned # created by the script
# tsh-vXXX.pkg # created by the script
mkdir "$tmp/root"
# This creates either 'teleport/' or 'teleport-ent/' under tmp.
# We only care about the 'tsh' file for the script.
tar xzf "$tarname" -C "$tmp"
# Prepare app shell.
local target="$tmp/root/$PACKAGE_NAME.app"
cp -r "$tmp/teleport$ent/$PACKAGE_NAME.app" "$target"
local entitlements="$buildassets/macos/$TSH_SKELETON/$TSH_SKELETON.entitlements"
if [[ "$PACKAGE_NAME" == "tctl" ]]; then
entitlements="$buildassets/macos/$TCTL_SKELETON/$TCTL_SKELETON.entitlements"
fi
# Sign app.
$DRY_RUN_PREFIX codesign -f \
-o kill,hard,runtime \
-s "$DEVELOPER_ID_APPLICATION" \
-i "$BUNDLEID" \
--entitlements "$entitlements" \
--timestamp \
"$target"
# Prepare and sign the installer package.
# Note that the installer does __NOT__ have a `v` in the version number.
# The package for the universal binary does not have an architecture in the name.
local arch_tag=""
if [[ "$PACKAGE_ARCH" != "universal" ]]; then
arch_tag="-$PACKAGE_ARCH"
fi
target="$tmp/$PACKAGE_NAME-$TELEPORT_VERSION$arch_tag.pkg" # switches from app to pkg
local pkg_root="$tmp/root"
local pkg_component_plist="$tmp/$PACKAGE_NAME-component.plist"
local pkg_scripts="$buildassets/macos/scripts/$PACKAGE_NAME"
make_non_relocatable_plist "$pkg_root" "$pkg_component_plist"
pkgbuild \
--root "$pkg_root" \
--component-plist "$pkg_component_plist" \
--identifier "$BUNDLEID" \
--version "v$TELEPORT_VERSION" \
--install-location /Applications \
--scripts "$pkg_scripts" \
"$target.unsigned"
$DRY_RUN_PREFIX productsign \
--sign "$DEVELOPER_ID_INSTALLER" \
--timestamp \
"$target.unsigned" \
"$target"
# Make sure $target exists in case of dry runs.
if [[ -n "$DRY_RUN_PREFIX" ]]; then
cp "$target.unsigned" "$target"
fi
# Notarize.
notarize "$target" "$TEAMID" "$BUNDLEID"
# Copy resulting package to $PWD, generate hashes.
mv "$target" .
local bn=''
bn="$(basename "$target")"
shasum -a 256 "$bn" > "$bn.sha256"
}
main "$@"