.package.zsh 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. #!/usr/bin/env zsh
  2. builtin emulate -L zsh
  3. setopt EXTENDED_GLOB
  4. setopt PUSHD_SILENT
  5. setopt ERR_EXIT
  6. setopt ERR_RETURN
  7. setopt NO_UNSET
  8. setopt PIPE_FAIL
  9. setopt NO_AUTO_PUSHD
  10. setopt NO_PUSHD_IGNORE_DUPS
  11. setopt FUNCTION_ARGZERO
  12. ## Enable for script debugging
  13. #setopt WARN_CREATE_GLOBAL
  14. #setopt WARN_NESTED_VAR
  15. #setopt XTRACE
  16. if (( ! ${+CI} )) {
  17. print -u2 -PR "%F{1} ✖︎ ${ZSH_ARGZERO:t:r} requires CI environment%f"
  18. exit 1
  19. }
  20. autoload -Uz is-at-least && if ! is-at-least 5.9; then
  21. print -u2 -PR "%F{1}${funcstack[1]##*/}:%f Running on Zsh version %B${ZSH_VERSION}%b, but Zsh %B5.9%b is the minimum supported version. Upgrade Zsh to fix this issue."
  22. exit 1
  23. fi
  24. TRAPZERR() {
  25. print -u2 -PR "::error::%F{1} ✖︎ script execution error%f"
  26. print -PR -e "
  27. Callstack:
  28. ${(j:\n :)funcfiletrace}
  29. "
  30. exit 2
  31. }
  32. package() {
  33. if (( ! ${+SCRIPT_HOME} )) typeset -g SCRIPT_HOME=${ZSH_ARGZERO:A:h}
  34. local host_os=${${(s:-:)ZSH_ARGZERO:t:r}[2]}
  35. local project_root=${SCRIPT_HOME:A:h:h}
  36. local buildspec_file=${project_root}/buildspec.json
  37. fpath=(${SCRIPT_HOME}/utils.zsh ${fpath})
  38. autoload -Uz log_error log_output log_group check_${host_os}
  39. local -i debug=0
  40. local target
  41. local -r -a _valid_targets=(
  42. macos-x86_64
  43. macos-arm64
  44. ubuntu-x86_64
  45. )
  46. local config='RelWithDebInfo'
  47. local -r -a _valid_configs=(Debug RelWithDebInfo Release MinSizeRel)
  48. local -i codesign=0
  49. local -i notarize=0
  50. local -i package=0
  51. local -i skip_deps=0
  52. local -a args
  53. while (( # )) {
  54. case ${1} {
  55. -t|--target|-c|--config)
  56. if (( # == 1 )) || [[ ${2:0:1} == '-' ]] {
  57. log_error "Missing value for option %B${1}%b"
  58. exit 2
  59. }
  60. ;;
  61. }
  62. case ${1} {
  63. --) shift; args+=($@); break ;;
  64. -t|--target)
  65. if (( ! ${_valid_targets[(Ie)${2}]} )) {
  66. log_error "Invalid value %B${2}%b for option %B${1}%b"
  67. exit 2
  68. }
  69. target=${2}
  70. shift 2
  71. ;;
  72. -c|--config)
  73. if (( ! ${_valid_configs[(Ie)${2}]} )) {
  74. log_error "Invalid value %B${2}%b for option %B${1}%b"
  75. exit 2
  76. }
  77. config=${2}
  78. shift 2
  79. ;;
  80. -s|--codesign) codesign=1; shift ;;
  81. -n|--notarize) notarize=1; shift ;;
  82. -p|--package) typeset -g package=1; shift ;;
  83. --debug) debug=0; shift ;;
  84. *) log_error "Unknown option: %B${1}%b"; log_output ${_usage}; exit 2 ;;
  85. }
  86. }
  87. : "${target:="${host_os}-${CPUTYPE}"}"
  88. set -- ${(@)args}
  89. check_${host_os}
  90. local product_name
  91. read -r product_name <<< \
  92. "$(jq -r '.name' ${buildspec_file})"
  93. local commit_version='0.0.0'
  94. local commit_distance='0'
  95. local commit_hash
  96. if [[ -d ${project_root}/.git ]] {
  97. local git_description="$(git describe --tags --long)"
  98. commit_version="${${git_description%-*}%-*}"
  99. commit_hash="${git_description##*-g}"
  100. commit_distance="${${git_description%-*}##*-}"
  101. }
  102. local output_name
  103. if (( commit_distance > 0 )) {
  104. output_name="obs-studio-${commit_version}-${commit_hash}"
  105. } else {
  106. output_name="obs-studio-${commit_version}"
  107. }
  108. if [[ ${host_os} == macos ]] {
  109. if [[ ! -d build_macos/OBS.app ]] {
  110. log_error 'No application bundle found. Run the build script to create a valid application bundle.'
  111. return 0
  112. }
  113. local -A arch_names=(x86_64 Intel arm64 Apple)
  114. output_name="${output_name}-macos-${(L)arch_names[${target##*-}]}"
  115. local volume_name
  116. if (( commit_distance > 0 )) {
  117. volume_name="OBS Studio ${commit_version}-${commit_hash} (${arch_names[${target##*-}]})"
  118. } else {
  119. volume_name="OBS Studio ${commit_version} (${arch_names[${target##*-}]})"
  120. }
  121. if (( package )) {
  122. pushd build_macos
  123. mkdir -p obs-studio/.background
  124. cp ${project_root}/cmake/macos/resources/background.tiff obs-studio/.background/
  125. cp ${project_root}/cmake/macos/resources/AppIcon.icns obs-studio/.VolumeIcon.icns
  126. ln -s /Applications obs-studio/Applications
  127. mkdir -p obs-studio/OBS.app
  128. ditto OBS.app obs-studio/OBS.app
  129. local -i _status=0
  130. autoload -Uz create_diskimage
  131. create_diskimage obs-studio ${volume_name} ${output_name} || _status=1
  132. rm -r obs-studio
  133. if (( _status )) {
  134. log_error "Disk image creation failed."
  135. return 2
  136. }
  137. typeset -gx CODESIGN_IDENT="${CODESIGN_IDENT:--}"
  138. typeset -gx CODESIGN_TEAM="$(print "${CODESIGN_IDENT}" | /usr/bin/sed -En 's/.+\((.+)\)/\1/p')"
  139. codesign --sign "${CODESIGN_IDENT}" ${output_name}.dmg
  140. if (( codesign && notarize )) {
  141. if ! [[ ${CODESIGN_IDENT} != '-' && ${CODESIGN_TEAM} && ${CODESIGN_IDENT_USER} && ${CODESIGN_IDENT_PASS} ]] {
  142. log_error "Notarization requires Apple ID and application password."
  143. return 2
  144. }
  145. xcrun notarytool store-credentials 'OBS-Codesign-Password' --apple-id "${CODESIGN_IDENT_USER}" --team-id "${CODESIGN_TEAM}" --password "${CODESIGN_IDENT_PASS}"
  146. xcrun notarytool submit "${output_name}".dmg --keychain-profile "OBS-Codesign-Password" --wait
  147. local -i _status=0
  148. xcrun stapler staple ${output_name}.dmg || _status=1
  149. if (( _status )) {
  150. log_error "Notarization failed. Use 'xcrun notarytool log <submission ID>' to check errors."
  151. return 2
  152. }
  153. }
  154. popd
  155. } else {
  156. log_group "Archiving obs-studio..."
  157. pushd build_macos
  158. XZ_OPT=-T0 tar -cvJf ${output_name}.tar.xz OBS.app
  159. popd
  160. }
  161. if [[ ${config} == Release ]] {
  162. log_group "Archiving debug symbols..."
  163. mkdir -p build_macos/dSYMs
  164. pushd build_macos/dSYMs
  165. rm -rf -- *.dSYM(N)
  166. cp -pR ${PWD:h}/**/*.dSYM .
  167. XZ_OPT=-T0 tar -cvJf ${output_name}-dSYMs.tar.xz -- *
  168. mv ${output_name}-dSYMs.tar.xz ${PWD:h}
  169. popd
  170. }
  171. log_group
  172. } elif [[ ${host_os} == ubuntu ]] {
  173. local cmake_bin='/usr/bin/cmake'
  174. local -a cmake_args=()
  175. if (( debug )) cmake_args+=(--verbose)
  176. if (( package )) {
  177. log_group "Packaging obs-studio..."
  178. pushd ${project_root}
  179. ${cmake_bin} --build build_${target%%-*} --config ${config} --target package ${cmake_args}
  180. output_name="${output_name}-${target##*-}-ubuntu-gnu"
  181. pushd ${project_root}/build_${target%%-*}
  182. local -a files=(obs-studio-*-Linux*.(ddeb|deb|ddeb.sha256|deb.sha256))
  183. for file (${files}) {
  184. mv ${file} ${file//obs-studio-*-Linux/${output_name}}
  185. }
  186. popd
  187. popd
  188. } else {
  189. log_group "Archiving obs-studio..."
  190. output_name="${output_name}-${target##*-}-ubuntu-gnu"
  191. pushd ${project_root}/build_${target%%-*}/install/${config}
  192. XZ_OPT=-T0 tar -cvJf ${project_root}/build_${target%%-*}/${output_name}.tar.xz (bin|lib|share)
  193. popd
  194. }
  195. pushd ${project_root}
  196. ${cmake_bin} --build build_${target%%-*} --config ${config} --target package_source ${cmake_args}
  197. output_name="${output_name}-sources"
  198. pushd ${project_root}/build_${target%%-*}
  199. local -a files=(obs-studio-*-sources.tar.*)
  200. for file (${files}) {
  201. mv ${file} ${file//obs-studio-*-sources/${output_name}}
  202. }
  203. popd
  204. popd
  205. log_group
  206. }
  207. }
  208. package ${@}