Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / remoting / host / installer / mac / do_signing.sh
blob2e756f96a85fba6d95f9f4ba4206dbed1a13423b
1 #!/bin/sh
3 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
7 # This script signs the Chromoting binaries, builds the Chrome Remote Desktop
8 # installer and then packages it into a .dmg. It requires that Packages be
9 # installed (for 'packagesbuild').
10 # Packages: http://s.sudre.free.fr/Software/Packages/about.html
12 # usage: do_signing.sh output_dir input_dir [codesign_keychain codesign_id
13 # [productsign_id]]
15 # The final disk image (dmg) is placed in |output_dir|.
17 set -e -u
19 ME="$(basename "${0}")"
20 readonly ME
22 declare -a g_cleanup_dirs
24 setup() {
25 local input_dir="${1}"
27 # The file that contains the properties for this signing build.
28 # The file should contain only key=value pairs, one per line.
29 PROPS_FILENAME="${input_dir}/do_signing.props"
31 # Individually load the properties for this build. Don't 'source' the file
32 # to guard against code accidentally being added to the props file.
33 DMG_VOLUME_NAME=$(read_property "DMG_VOLUME_NAME")
34 DMG_FILE_NAME=$(read_property "DMG_FILE_NAME")
35 HOST_BUNDLE_NAME=$(read_property "HOST_BUNDLE_NAME")
36 HOST_PKG=$(read_property "HOST_PKG")
37 HOST_UNINSTALLER_NAME=$(read_property "HOST_UNINSTALLER_NAME")
38 NATIVE_MESSAGING_HOST_BUNDLE_NAME=$(read_property\
39 "NATIVE_MESSAGING_HOST_BUNDLE_NAME")
40 PREFPANE_BUNDLE_NAME=$(read_property "PREFPANE_BUNDLE_NAME")
41 REMOTE_ASSISTANCE_HOST_BUNDLE_NAME=$(read_property\
42 "REMOTE_ASSISTANCE_HOST_BUNDLE_NAME")
44 # Binaries to sign.
45 ME2ME_HOST="PrivilegedHelperTools/${HOST_BUNDLE_NAME}"
46 ME2ME_NM_HOST="PrivilegedHelperTools/${HOST_BUNDLE_NAME}/Contents/MacOS/"`
47 `"${NATIVE_MESSAGING_HOST_BUNDLE_NAME}/Contents/MacOS/"`
48 `"native_messaging_host"
49 IT2ME_NM_HOST="PrivilegedHelperTools/${HOST_BUNDLE_NAME}/Contents/MacOS/"`
50 `"${REMOTE_ASSISTANCE_HOST_BUNDLE_NAME}/Contents/MacOS/"`
51 `"remote_assistance_host"
52 UNINSTALLER="Applications/${HOST_UNINSTALLER_NAME}.app"
53 PREFPANE="PreferencePanes/${PREFPANE_BUNDLE_NAME}"
55 # The Chromoting Host installer is a meta-package that consists of 3
56 # components:
57 # * Chromoting Host Service package
58 # * Chromoting Host Uninstaller package
59 # * Keystone package (GoogleSoftwareUpdate - for Official builds only)
60 PKGPROJ_HOST="ChromotingHost.pkgproj"
61 PKGPROJ_HOST_SERVICE="ChromotingHostService.pkgproj"
62 PKGPROJ_HOST_UNINSTALLER="ChromotingHostUninstaller.pkgproj"
64 # Final (user-visible) pkg name.
65 PKG_FINAL="${HOST_PKG}.pkg"
67 DMG_FILE_NAME="${DMG_FILE_NAME}.dmg"
69 # Temp directory for Packages output.
70 PKG_DIR=build
71 g_cleanup_dirs+=("${PKG_DIR}")
73 # Temp directories for building the dmg.
74 DMG_TEMP_DIR="$(mktemp -d -t "${ME}"-dmg)"
75 g_cleanup_dirs+=("${DMG_TEMP_DIR}")
77 DMG_EMPTY_DIR="$(mktemp -d -t "${ME}"-empty)"
78 g_cleanup_dirs+=("${DMG_EMPTY_DIR}")
81 err() {
82 echo "[$(date +'%Y-%m-%d %H:%M:%S%z')]: ${@}" >&2
85 err_exit() {
86 err "${@}"
87 exit 1
90 # shell_safe_path ensures that |path| is safe to pass to tools as a
91 # command-line argument. If the first character in |path| is "-", "./" is
92 # prepended to it. The possibly-modified |path| is output.
93 shell_safe_path() {
94 local path="${1}"
95 if [[ "${path:0:1}" = "-" ]]; then
96 echo "./${path}"
97 else
98 echo "${path}"
102 # Read a single property from the properties file.
103 read_property() {
104 local property="${1}"
105 local filename="${PROPS_FILENAME}"
106 echo `grep "\<${property}\>=" "${filename}" | tail -n 1 | cut -d "=" -f2-`
109 verify_clean_dir() {
110 local dir="${1}"
111 if [[ ! -d "${dir}" ]]; then
112 mkdir "${dir}"
115 if [[ -e "${output_dir}/${DMG_FILE_NAME}" ]]; then
116 err "Output directory is dirty from previous build."
117 exit 1
121 sign() {
122 local name="${1}"
123 local keychain="${2}"
124 local id="${3}"
126 if [[ ! -e "${name}" ]]; then
127 err_exit "Input file doesn't exist: ${name}"
130 echo Signing "${name}"
131 codesign -vv -s "${id}" --keychain "${keychain}" "${name}"
132 codesign -v "${name}"
135 sign_binaries() {
136 local input_dir="${1}"
137 local keychain="${2}"
138 local id="${3}"
140 sign "${input_dir}/${ME2ME_NM_HOST}" "${keychain}" "${id}"
141 sign "${input_dir}/${IT2ME_NM_HOST}" "${keychain}" "${id}"
142 sign "${input_dir}/${ME2ME_HOST}" "${keychain}" "${id}"
143 sign "${input_dir}/${UNINSTALLER}" "${keychain}" "${id}"
144 sign "${input_dir}/${PREFPANE}" "${keychain}" "${id}"
147 sign_installer() {
148 local input_dir="${1}"
149 local keychain="${2}"
150 local id="${3}"
152 local package="${input_dir}/${PKG_DIR}/${PKG_FINAL}"
153 productsign --sign "${id}" --keychain "${keychain}" \
154 "${package}" "${package}.signed"
155 mv -f "${package}.signed" "${package}"
158 build_package() {
159 local pkg="${1}"
160 echo "Building .pkg from ${pkg}"
161 packagesbuild -v "${pkg}"
164 build_packages() {
165 local input_dir="${1}"
166 build_package "${input_dir}/${PKGPROJ_HOST_SERVICE}"
167 build_package "${input_dir}/${PKGPROJ_HOST_UNINSTALLER}"
168 build_package "${input_dir}/${PKGPROJ_HOST}"
171 build_dmg() {
172 local input_dir="${1}"
173 local output_dir="${2}"
175 # Create the .dmg.
176 echo "Building .dmg..."
177 "${input_dir}/pkg-dmg" \
178 --format UDBZ \
179 --tempdir "${DMG_TEMP_DIR}" \
180 --source "${DMG_EMPTY_DIR}" \
181 --target "${output_dir}/${DMG_FILE_NAME}" \
182 --volname "${DMG_VOLUME_NAME}" \
183 --copy "${input_dir}/${PKG_DIR}/${PKG_FINAL}" \
184 --copy "${input_dir}/Scripts/keystone_install.sh:/.keystone_install"
186 if [[ ! -f "${output_dir}/${DMG_FILE_NAME}" ]]; then
187 err_exit "Unable to create disk image: ${DMG_FILE_NAME}"
191 cleanup() {
192 if [[ "${#g_cleanup_dirs[@]}" > 0 ]]; then
193 rm -rf "${g_cleanup_dirs[@]}"
197 usage() {
198 echo "Usage: ${ME} output_dir input_dir [keychain codesign_id"\
199 "[productsign_id]]" >&2
200 echo " Sign the binaries using the specified <codesign_id>, build" >&2
201 echo " the installer and then sign the installer using the given" >&2
202 echo " <productsign_id>." >&2
203 echo " If the <keychain> and signing ids are not specified then the" >&2
204 echo " installer is built without signing any binaries." >&2
207 main() {
208 local output_dir="$(shell_safe_path "${1}")"
209 local input_dir="$(shell_safe_path "${2}")"
210 local do_sign_binaries=0
211 local keychain=""
212 if [[ ${#} -ge 3 ]]; then
213 keychain="$(shell_safe_path "${3}")"
214 do_sign_binaries=1
215 echo "Signing binaries using ${keychain}"
216 else
217 echo "Not signing binaries (no keychain or identify specified)"
219 local codesign_id=""
220 if [[ ${#} -ge 4 ]]; then
221 codesign_id="${4}"
223 local productsign_id=""
224 if [[ ${#} -ge 5 ]]; then
225 productsign_id="${5}"
228 if [[ "${do_sign_binaries}" == 1 && -z "${codesign_id}" ]]; then
229 err_exit "Can't sign binaries - please specify a codesign_id"
232 setup "${input_dir}"
233 verify_clean_dir "${output_dir}"
235 if [[ "${do_sign_binaries}" == 1 ]]; then
236 sign_binaries "${input_dir}" "${keychain}" "${codesign_id}"
238 build_packages "${input_dir}"
239 if [[ "${do_sign_binaries}" == 1 && -n "${productsign_id}" ]]; then
240 echo "Signing installer..."
241 sign_installer "${input_dir}" "${keychain}" "${productsign_id}"
243 build_dmg "${input_dir}" "${output_dir}"
245 cleanup
248 if [[ ${#} < 2 ]]; then
249 usage
250 exit 1
253 main "${@}"
254 exit ${?}