action.yaml 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. name: Set up macOS Code Signing
  2. description: Sets up code signing certificates, provisioning profiles, and notarization information
  3. inputs:
  4. codesignIdentity:
  5. description: Code signing identity
  6. required: true
  7. codesignCertificate:
  8. description: PKCS12 certificate in base64 format
  9. required: true
  10. certificatePassword:
  11. description: Password required to install PKCS12 certificate
  12. required: true
  13. keychainPassword:
  14. description: Password to use for temporary keychain
  15. required: false
  16. notarizationUser:
  17. description: Apple ID to use for notarization
  18. required: false
  19. notarizationPassword:
  20. description: Application password for notarization
  21. provisioningProfile:
  22. description: Provisioning profile in base64 format
  23. required: false
  24. outputs:
  25. haveCodesignIdent:
  26. description: True if necessary code signing credentials were found
  27. value: ${{ steps.codesign.outputs.haveCodesignIdent }}
  28. haveProvisioningProfile:
  29. description: True if necessary provisioning profile credentials were found
  30. value: ${{ steps.provisioning.outputs.haveProvisioningProfile || steps.codesign.outputs.haveProvisioningProfile }}
  31. provisioningProfileUUID:
  32. description: UUID of imported provisioning profile
  33. value: ${{ steps.provisioning.outputs.provisioningProfileUUID }}
  34. haveNotarizationUser:
  35. description: True if necessary notarization credentials were found
  36. value: ${{ steps.notarization.outputs.haveNotarizationUser || steps.codesign.outputs.haveNotarizationUser }}
  37. codesignIdent:
  38. description: Code signing identity
  39. value: ${{ steps.codesign.outputs.codesignIdent }}
  40. codesignTeam:
  41. description: Code signing team
  42. value: ${{ steps.codesign.outputs.codesignTeam }}
  43. runs:
  44. using: composite
  45. steps:
  46. - name: Check Runner Operating System 🏃‍♂️
  47. if: runner.os != 'macOS'
  48. shell: bash
  49. run: |
  50. : Check Runner Operating System 🏃‍♂️
  51. echo "setup-macos-codesigning action requires a macOS-based runner."
  52. exit 2
  53. - name: macOS Code Signing ✍️
  54. id: codesign
  55. shell: zsh --no-rcs --errexit --pipefail {0}
  56. env:
  57. MACOS_SIGNING_IDENTITY: ${{ inputs.codesignIdentity }}
  58. MACOS_SIGNING_CERT: ${{ inputs.codesignCertificate }}
  59. MACOS_SIGNING_CERT_PASSWORD: ${{ inputs.certificatePassword }}
  60. MACOS_KEYCHAIN_PASSWORD: ${{ inputs.keychainPassword }}
  61. run: |
  62. : macOS Code Signing ✍️
  63. if (( ${+RUNNER_DEBUG} )) setopt XTRACE
  64. if [[ ${MACOS_SIGNING_IDENTITY} && ${MACOS_SIGNING_CERT} ]] {
  65. print 'haveCodesignIdent=true' >> $GITHUB_OUTPUT
  66. local -r certificate_path="${RUNNER_TEMP}/build_certificate.p12"
  67. local -r keychain_path="${RUNNER_TEMP}/app-signing.keychain-db"
  68. print -n "${MACOS_SIGNING_CERT}" | base64 --decode --output=${certificate_path}
  69. : "${MACOS_KEYCHAIN_PASSWORD:="$(print ${RANDOM} | shasum | head -c 32)"}"
  70. print '::group::Keychain setup'
  71. security create-keychain -p "${MACOS_KEYCHAIN_PASSWORD}" ${keychain_path}
  72. security set-keychain-settings -lut 21600 ${keychain_path}
  73. security unlock-keychain -p "${MACOS_KEYCHAIN_PASSWORD}" ${keychain_path}
  74. security import "${certificate_path}" -P "${MACOS_SIGNING_CERT_PASSWORD}" -A \
  75. -t cert -f pkcs12 -k ${keychain_path} \
  76. -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/xcrun
  77. security set-key-partition-list -S 'apple-tool:,apple:' -k "${MACOS_KEYCHAIN_PASSWORD}" \
  78. ${keychain_path} &> /dev/null
  79. security list-keychain -d user -s ${keychain_path} 'login-keychain'
  80. print '::endgroup::'
  81. local -r team_id="${${MACOS_SIGNING_IDENTITY##* }//(\(|\))/}"
  82. print "codesignIdent=${MACOS_SIGNING_IDENTITY}" >> $GITHUB_OUTPUT
  83. print "MACOS_KEYCHAIN_PASSWORD=${MACOS_KEYCHAIN_PASSWORD}" >> $GITHUB_ENV
  84. print "codesignTeam=${team_id}" >> $GITHUB_OUTPUT
  85. } else {
  86. print 'haveCodesignIdent=false' >> $GITHUB_OUTPUT
  87. print 'haveProvisioningProfile=false' >> $GITHUB_OUTPUT
  88. print 'haveNotarizationUser=false' >> $GITHUB_OUTPUT
  89. }
  90. - name: Provisioning Profile 👤
  91. id: provisioning
  92. if: fromJSON(steps.codesign.outputs.haveCodesignIdent)
  93. shell: zsh --no-rcs --errexit --pipefail {0}
  94. env:
  95. MACOS_SIGNING_PROVISIONING_PROFILE: ${{ inputs.provisioningProfile }}
  96. run: |
  97. : Provisioning Profile 👤
  98. if (( ${+RUNNER_DEBUG} )) setopt XTRACE
  99. if [[ "${MACOS_SIGNING_PROVISIONING_PROFILE}" ]] {
  100. print 'haveProvisioningProfile=true' >> $GITHUB_OUTPUT
  101. local -r profile_path="${RUNNER_TEMP}/build_profile.provisionprofile"
  102. print -n "${MACOS_SIGNING_PROVISIONING_PROFILE}" \
  103. | base64 --decode --output="${profile_path}"
  104. print '::group::Provisioning Profile Setup'
  105. mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
  106. security cms -D -i ${profile_path} -o ${RUNNER_TEMP}/build_profile.plist
  107. local -r uuid="$(plutil -extract UUID raw ${RUNNER_TEMP}/build_profile.plist)"
  108. local -r team_id="$(plutil -extract TeamIdentifier.0 raw -expect string ${RUNNER_TEMP}/build_profile.plist)"
  109. if [[ ${team_id} != '${{ steps.codesign.outputs.codesignTeam }}' ]] {
  110. print '::notice::Code Signing team in provisioning profile does not match certificate.'
  111. }
  112. cp ${profile_path} ~/Library/MobileDevice/Provisioning\ Profiles/${uuid}.provisionprofile
  113. print "provisioningProfileUUID=${uuid}" >> $GITHUB_OUTPUT
  114. print '::endgroup::'
  115. } else {
  116. print 'haveProvisioningProfile=false' >> $GITHUB_OUTPUT
  117. }
  118. - name: Notarization 🧑‍💼
  119. id: notarization
  120. if: fromJSON(steps.codesign.outputs.haveCodesignIdent)
  121. shell: zsh --no-rcs --errexit --pipefail {0}
  122. env:
  123. MACOS_NOTARIZATION_USERNAME: ${{ inputs.notarizationUser }}
  124. MACOS_NOTARIZATION_PASSWORD: ${{ inputs.notarizationPassword }}
  125. run: |
  126. : Notarization 🧑‍💼
  127. if (( ${+RUNNER_DEBUG} )) setopt XTRACE
  128. if [[ ${MACOS_NOTARIZATION_USERNAME} && ${MACOS_NOTARIZATION_PASSWORD} ]] {
  129. print 'haveNotarizationUser=true' >> $GITHUB_OUTPUT
  130. } else {
  131. print 'haveNotarizationUser=false' >> $GITHUB_OUTPUT
  132. }