File indexing completed on 2024-05-12 16:02:32

0001 #!/usr/bin/env bash
0002 #
0003 #  SPDX-License-Identifier: GPL-3.0-or-later
0004 #
0005 
0006 # print status messages
0007 print_msg() {
0008     printf "\e[32m${1}\e[0m\n" "${@:2}"
0009     # printf "%s\n" "${1}" >> ${OUPUT_LOG}
0010 }
0011 
0012 # print error
0013 print_error() {
0014     printf "\e[31m%s %s\e[0m\n" "Error:" "${1}"
0015 }
0016 
0017 get_script_dir() {
0018     script_source="${BASH_SOURCE[0]}"
0019     # go to target until finding root.
0020     while [ -L "${script_source}" ]; do
0021         script_target="$(readlink ${script_source})"
0022         if [[ "${script_source}" = /* ]]; then
0023             script_source="$script_target"
0024         else
0025             script_dir="$(dirname "${script_source}")"
0026             script_source="${script_dir}/${script_target}"
0027         fi
0028     done
0029     echo "$(dirname ${script_source})"
0030 }
0031 
0032 findEntitlementsFile() {
0033     if [[ -e ${KIS_ENTITLEMENTS} ]]; then
0034         return
0035     fi
0036 
0037     local fileName="macStore-entitlements.plist"
0038     if [[ -f "${DIR_CURRENT}/${fileName}" ]]; then
0039         KIS_ENTITLEMENTS="${DIR_CURRENT}/${fileName}"
0040     elif [[ -f "${SCRIPT_SOURCE_DIR}/${fileName}" ]]; then
0041         KIS_ENTITLEMENTS="${SCRIPT_SOURCE_DIR}/${fileName}"
0042     fi
0043 }
0044 
0045 # Attempt to detach previous mouted DMG
0046 detachKritaDMG() {
0047     if [[ -d "/Volumes/${DMG_title}" ]]; then
0048     echo "WARNING: Another Krita DMG is mounted!"
0049     echo "Attempting eject…"
0050     hdiutil detach "/Volumes/${DMG_title}"
0051     if [ $? -ne 0  ]; then
0052         exit 1
0053     fi
0054     echo "Success!"
0055     fi
0056 }
0057 
0058 print_usage () {
0059     printf "USAGE:
0060   changeSignature.sh -f=<file.dmg>[-s=<identity>] [-notarize-ac=<apple-account>] [-style=<style.txt>] [-bg=<background-image>]
0061 
0062     -f \t\t\t Krita source dmg to covert prepare for Pkg
0063 
0064     -e \t\t\t Optional entitlements file, by default it will resign using macStore-entitlements.plist
0065 \t\t\† from packaging/macos.
0066 
0067     -s \t\t\t Code sign identity for codesign
0068 
0069     -notarize-ac \t Apple account name for notarization purposes
0070 \t\t\t script will attempt to get password from keychain, if fails provide one with
0071 \t\t\t the -notarize-pass option: To add a password run
0072 
0073 \t\t\t   security add-generic-password -a \"AC_USERNAME\" -w <secret_password> -s \"AC_PASSWORD\"
0074 
0075     -notarize-pass \t If given, the Apple account password. Otherwise an attempt will be macdeployqt_exists
0076 \t\t\t to get the password from keychain using the account given in <notarize-ac> option.
0077 
0078     -asc-provider \t some AppleIds might need this option pass the <shortname>
0079 
0080     -name \t\t Set the DMG name output.
0081 
0082 \t\t\t osxdeploy needs an input image to attach to the dmg background
0083 \t\t\t image recommended size is at least 950x500
0084 "
0085 }
0086 
0087 
0088 # Helper functions
0089 countArgs () {
0090     echo "${#}"
0091 }
0092 
0093 stringContains () {
0094     echo "$(grep "${2}" <<< "${1}")"
0095 }
0096 
0097 
0098 # helper to define function only once
0099 batch_codesign() {
0100     xargs -P$(sysctl -n hw.logicalcpu) -I FILE codesign --options runtime --timestamp -f -s "${CODE_SIGNATURE}" --entitlements "${KIS_ENTITLEMENTS}" FILE
0101 }
0102 # Code sign must be done as recommended by apple "sign code inside out in individual stages"
0103 signBundle() {
0104     cd ${KIS_APPLOC}
0105 
0106     # sign Frameworks and libs
0107     cd ${KIS_APPLOC}/krita.app/Contents/Frameworks
0108     # remove debug version as both versions can't be signed.
0109     rm ${KIS_APPLOC}/krita.app/Contents/Frameworks/QtScript.framework/Versions/Current/QtScript_debug
0110     # Do not sign binaries inside frameworks except for Python's
0111     find . -type d -path "*.framework" -prune -false -o -perm +111 -not -type d | batch_codesign
0112     find Python.framework -type f -name "*.o" -or -name "*.so" -or -perm +111 -not -type d -not -type l | batch_codesign
0113     find . -type d -name "*.framework" | xargs printf "%s/Versions/Current\n" | batch_codesign
0114 
0115     # Sign all other files in Framework (needed)
0116     # there are many files in python do we need to sign them all?
0117     find krita-python-libs -type f | batch_codesign
0118     # find python -type f | batch_codesign
0119 
0120     # Sign only libraries and plugins
0121     cd ${KIS_APPLOC}/krita.app/Contents/PlugIns
0122     find . -type f | batch_codesign
0123 
0124     cd ${KIS_APPLOC}/krita.app/Contents/Library/QuickLook
0125     printf "kritaquicklook.qlgenerator" | batch_codesign
0126 
0127     cd ${KIS_APPLOC}/krita.app/Contents/Library/Spotlight
0128     printf "kritaspotlight.mdimporter" | batch_codesign
0129 
0130     # It is necessary to sign every binary Resource file
0131     cd ${KIS_APPLOC}/krita.app/Contents/Resources
0132     find . -perm +111 -type f | batch_codesign
0133 
0134     #Finally sign krita and krita.app
0135     printf "${KIS_APPLOC}/krita.app/Contents/MacOS/krita" | batch_codesign
0136     printf "${KIS_APPLOC}/krita.app" | batch_codesign
0137 }
0138 
0139 sign_hasError() {
0140     local CODESIGN_STATUS=0
0141     for f in $(find "${KIS_APPLOC}" -type f); do
0142         if [[ -z $(file ${f} | grep "Mach-O") ]]; then
0143             continue
0144         fi
0145 
0146         CODESIGN_RESULT=$(codesign -vvv --strict ${f} 2>&1 | grep "not signed")
0147 
0148         if [[ -n "${CODESIGN_RESULT}" ]]; then
0149             CODESIGN_STATUS=1
0150             printf "${f} not signed\n" >&2
0151         fi
0152     done
0153     echo ${CODESIGN_STATUS}
0154 }
0155 
0156 copyApplicationFolder() {
0157     mkdir "${KIS_APPLOC}"
0158 
0159     if [[ ${DMG_INPUT_FILE##*.} = "dmg" ]]; then
0160         detachKritaDMG
0161 
0162         hdiutil attach "${DMG_INPUT_FILE}"
0163         rsync -a "/Volumes/krita/krita.app" "${KIS_APPLOC}/"
0164         hdiutil detach "/Volumes/krita"
0165 
0166     elif [[ ${DMG_INPUT_FILE##*.} = "app" ]]; then
0167         rsync -a "${DMG_INPUT_FILE}" "${KIS_APPLOC}/"
0168     fi
0169 
0170 }
0171 
0172 modifyInfoPlistContents() {
0173     cd "${KIS_APPLOC}/krita.app/Contents"
0174     sed -i '' -e 's/org.krita/org.kde.krita/g' Info.plist
0175     sed -i '' -e "s/org.krita.quicklook/org.kde.krita.quicklook/g" Library/QuickLook/kritaquicklook.qlgenerator/Contents/Info.plist
0176     sed -i '' -e "s/org.krita.spotlight/org.kde.krita.spotlight/g" Library/Spotlight/kritaspotlight.mdimporter/Contents/Info.plist
0177 }
0178 
0179 
0180 
0181 #######################
0182 # Program starts!!
0183 ########################
0184 DMG_title="krita" #if changed krita.temp.dmg must be deleted manually
0185 
0186 DIR_CURRENT="$(pwd)"
0187 cd "$(get_script_dir)"
0188 SCRIPT_SOURCE_DIR="$(pwd)"
0189 cd "${DIR_CURRENT}"
0190 
0191 KIS_APPLOC="${DIR_CURRENT}/pkgWorkdir"
0192 
0193 
0194 # -- Parse input args
0195 for arg in "${@}"; do
0196 
0197     if [[ ${arg} = -f=* ]]; then
0198         DMG_INPUT_FILE="${arg#*=}"
0199         continue
0200     fi
0201 
0202     if [[ ${arg} = -e=* ]]; then
0203         KIS_ENTITLEMENTS="${arg#*=}"
0204         continue
0205     fi
0206     # If string starts with -sign
0207     if [[ ${arg} = -s=* ]]; then
0208         CODE_SIGNATURE="${arg#*=}"
0209         continue
0210     fi
0211 
0212     if [[ ${arg} = -name=* ]]; then
0213         DMG_NAME="${arg#*=}"
0214         continue
0215     fi
0216 
0217     if [[ ${arg} = -notarize-ac=* ]]; then
0218         NOTARIZE_ACC="${arg#*=}"
0219         continue
0220     fi
0221 
0222     if [[ ${arg} = -notarize-pass=* ]]; then
0223         NOTARIZE_PASS="${arg#*=}"
0224         continue
0225     fi
0226 
0227 
0228     if [[ ${arg} = -asc-provider=* ]]; then
0229         ASC_PROVIDER="${arg#*=}"
0230         continue
0231     fi
0232 
0233     if [[ ${arg} = "-h" || ${arg} = "--help" ]]; then
0234         print_usage
0235         exit 1
0236     fi
0237 done
0238 
0239 findEntitlementsFile
0240 
0241 if [[ -z ${KIS_ENTITLEMENTS} ]]; then
0242     echo "Could not find entitlements file use for codesign"
0243     exit
0244 else
0245     echo "using ${KIS_ENTITLEMENTS}"
0246 fi
0247 
0248 # -- Checks and messages
0249 
0250 ### Code Signature & NOTARIZATION
0251 NOTARIZE="false"
0252 if [[ -z "${CODE_SIGNATURE}" ]]; then
0253     echo "WARNING: No code signature provided, Code will not be signed"
0254 else
0255     print_msg "Code will be signed with %s" "${CODE_SIGNATURE}"
0256     ### NOTARIZATION
0257 
0258     if [[ -n "${NOTARIZE_ACC}" ]]; then
0259 
0260         ASC_PROVIDER_OP=""
0261         if [[ -n "${ASC_PROVIDER}" ]]; then
0262             ASC_PROVIDER_OP="--asc-provider ${ASC_PROVIDER}"
0263         fi
0264 
0265         if [[ -z "${NOTARIZE_PASS}" ]]; then
0266             NOTARIZE_PASS="@keychain:AC_PASSWORD"
0267         fi
0268 
0269         # check if we can perform notarization
0270         xcrun altool --notarization-history 0 --username "${NOTARIZE_ACC}" --password "${NOTARIZE_PASS}" ${ASC_PROVIDER_OP} 1> /dev/null
0271 
0272         if [[ ${?} -eq 0 ]]; then
0273             NOTARIZE="true"
0274         else
0275             echo "No password given for notarization or AC_PASSWORD missig in keychain"
0276         fi
0277     fi
0278 fi
0279 
0280 if [[ ${NOTARIZE} = "true" ]]; then
0281     print_msg "Signing checks complete, signatures are valid"
0282 else
0283     echo "WARNING: Account information missing, Signtaure will not be performed"
0284     exit
0285 fi
0286 
0287 
0288 # Application is fetch from a .dmg or from .app
0289 copyApplicationFolder
0290 
0291 modifyInfoPlistContents
0292 
0293 # Code sign krita.app if signature given
0294 if [[ -n "${CODE_SIGNATURE}" ]]; then
0295     signBundle
0296     if [[ $(sign_hasError) -eq 1 ]]; then
0297         print_error "CodeSign errors!"
0298         echo "stopping...."
0299         exit 1
0300     fi
0301     echo "no codesign errors"
0302     printf "
0303 use productbuild to prepare Pkg:
0304 
0305     \t productbuild --component ${KIS_APPLOC}/krita.app  /Applications krita5_submit.pkg --sign \"3rd Party Mac Developer Installer: ...\"
0306 
0307 Then use altool to submit the Pkg:
0308 
0309     \t xcrun altool --upload-package krita5_submit.pkg --bundle-id <bundle-id> -t macos -u <appstore-username> --password <pass> [--asc-provider <teamid>] --bundle-version <version> --bundle-short-version-string <version> --apple-id <app-id_fromStore>
0310 
0311     \n"
0312 fi
0313