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
15 # The final disk image (dmg) is placed in |output_dir|.
19 ME="$(basename "${0}")"
22 declare -a g_cleanup_dirs
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 HOST_UNINSTALLER_NAME=$(read_property "HOST_UNINSTALLER_NAME")
34 HOST_PKG=$(read_property "HOST_PKG")
35 DMG_VOLUME_NAME=$(read_property "DMG_VOLUME_NAME")
36 DMG_FILE_NAME=$(read_property "DMG_FILE_NAME")
39 ME2ME_HOST='PrivilegedHelperTools/org.chromium.chromoting.me2me_host.app'
40 ME2ME_NM_HOST="${ME2ME_HOST}/Contents/MacOS/native_messaging_host"
41 IT2ME_NM_HOST="${ME2ME_HOST}/Contents/MacOS/remote_assistance_host"
42 UNINSTALLER="Applications/${HOST_UNINSTALLER_NAME}.app"
43 PREFPANE='PreferencePanes/org.chromium.chromoting.prefPane'
45 # The Chromoting Host installer is a meta-package that consists of 3
47 # * Chromoting Host Service package
48 # * Chromoting Host Uninstaller package
49 # * Keystone package (GoogleSoftwareUpdate - for Official builds only)
50 PKGPROJ_HOST='ChromotingHost.pkgproj'
51 PKGPROJ_HOST_SERVICE='ChromotingHostService.pkgproj'
52 PKGPROJ_HOST_UNINSTALLER='ChromotingHostUninstaller.pkgproj'
54 # Final (user-visible) pkg name.
55 PKG_FINAL="${HOST_PKG}.pkg"
57 DMG_FILE_NAME="${DMG_FILE_NAME}.dmg"
59 # Temp directory for Packages output.
61 g_cleanup_dirs+=("${PKG_DIR}")
63 # Temp directories for building the dmg.
64 DMG_TEMP_DIR="$(mktemp -d -t "${ME}"-dmg)"
65 g_cleanup_dirs+=("${DMG_TEMP_DIR}")
67 DMG_EMPTY_DIR="$(mktemp -d -t "${ME}"-empty)"
68 g_cleanup_dirs+=("${DMG_EMPTY_DIR}")
72 echo "[$(date +'%Y-%m-%d %H:%M:%S%z')]: ${@}" >&2
80 # shell_safe_path ensures that |path| is safe to pass to tools as a
81 # command-line argument. If the first character in |path| is "-", "./" is
82 # prepended to it. The possibly-modified |path| is output.
85 if [[ "${path:0:1}" = "-" ]]; then
92 # Read a single property from the properties file.
95 local filename="${PROPS_FILENAME}"
96 echo `grep "${property}" "${filename}" | tail -n 1 | cut -d "=" -f2-`
101 if [[ ! -d "${dir}" ]]; then
105 if [[ -e "${output_dir}/${DMG_FILE_NAME}" ]]; then
106 err "Output directory is dirty from previous build."
113 local keychain="${2}"
116 if [[ ! -e "${name}" ]]; then
117 err_exit "Input file doesn't exist: ${name}"
120 echo Signing "${name}"
121 codesign -vv -s "${id}" --keychain "${keychain}" "${name}"
122 codesign -v "${name}"
126 local input_dir="${1}"
127 local keychain="${2}"
130 sign "${input_dir}/${ME2ME_NM_HOST}" "${keychain}" "${id}"
131 sign "${input_dir}/${IT2ME_NM_HOST}" "${keychain}" "${id}"
132 sign "${input_dir}/${ME2ME_HOST}" "${keychain}" "${id}"
133 sign "${input_dir}/${UNINSTALLER}" "${keychain}" "${id}"
134 sign "${input_dir}/${PREFPANE}" "${keychain}" "${id}"
138 local input_dir="${1}"
139 local keychain="${2}"
142 local package="${input_dir}/${PKG_DIR}/${PKG_FINAL}"
143 productsign --sign "${id}" --keychain "${keychain}" \
144 "${package}" "${package}.signed"
145 mv -f "${package}.signed" "${package}"
150 echo "Building .pkg from ${pkg}"
151 packagesbuild -v "${pkg}"
155 local input_dir="${1}"
156 build_package "${input_dir}/${PKGPROJ_HOST_SERVICE}"
157 build_package "${input_dir}/${PKGPROJ_HOST_UNINSTALLER}"
158 build_package "${input_dir}/${PKGPROJ_HOST}"
162 local input_dir="${1}"
163 local output_dir="${2}"
166 echo "Building .dmg..."
167 "${input_dir}/pkg-dmg" \
169 --tempdir "${DMG_TEMP_DIR}" \
170 --source "${DMG_EMPTY_DIR}" \
171 --target "${output_dir}/${DMG_FILE_NAME}" \
172 --volname "${DMG_VOLUME_NAME}" \
173 --copy "${input_dir}/${PKG_DIR}/${PKG_FINAL}" \
174 --copy "${input_dir}/Scripts/keystone_install.sh:/.keystone_install"
176 if [[ ! -f "${output_dir}/${DMG_FILE_NAME}" ]]; then
177 err_exit "Unable to create disk image: ${DMG_FILE_NAME}"
182 if [[ "${#g_cleanup_dirs[@]}" > 0 ]]; then
183 rm -rf "${g_cleanup_dirs[@]}"
188 echo "Usage: ${ME} output_dir input_dir [keychain codesign_id"\
189 "[productsign_id]]" >&2
190 echo " Sign the binaries using the specified <codesign_id>, build" >&2
191 echo " the installer and then sign the installer using the given" >&2
192 echo " <productsign_id>." >&2
193 echo " If the <keychain> and signing ids are not specified then the" >&2
194 echo " installer is built without signing any binaries." >&2
198 local output_dir="$(shell_safe_path "${1}")"
199 local input_dir="$(shell_safe_path "${2}")"
200 local do_sign_binaries=0
202 if [[ ${#} -ge 3 ]]; then
203 keychain="$(shell_safe_path "${3}")"
205 echo "Signing binaries using ${keychain}"
207 echo "Not signing binaries (no keychain or identify specified)"
210 if [[ ${#} -ge 4 ]]; then
213 local productsign_id=""
214 if [[ ${#} -ge 5 ]]; then
215 productsign_id="${5}"
218 if [[ "${do_sign_binaries}" == 1 && -z "${codesign_id}" ]]; then
219 err_exit "Can't sign binaries - please specify a codesign_id"
223 verify_clean_dir "${output_dir}"
225 if [[ "${do_sign_binaries}" == 1 ]]; then
226 sign_binaries "${input_dir}" "${keychain}" "${codesign_id}"
228 build_packages "${input_dir}"
229 if [[ "${do_sign_binaries}" == 1 && -n "${productsign_id}" ]]; then
230 echo "Signing installer..."
231 sign_installer "${input_dir}" "${keychain}" "${productsign_id}"
233 build_dmg "${input_dir}" "${output_dir}"
238 if [[ ${#} < 2 ]]; then