From de2a0a7704d289760a5ff465d1e5cf3442d715ad Mon Sep 17 00:00:00 2001 From: Jason Greathouse Date: Thu, 5 Dec 2024 14:33:33 -0600 Subject: [PATCH] add MacOS signing and notary (#1032) --- .devcontainer.json | 3 +- .github/actions/bootstrap-macos/action.yaml | 44 +++++++++++++++++++++ .github/actions/build-rust/action.yaml | 44 +++++++++++++++++++++ .github/workflows/on-pr.yaml | 7 ++++ .github/workflows/on-tag.yaml | 7 ++++ 5 files changed, 104 insertions(+), 1 deletion(-) diff --git a/.devcontainer.json b/.devcontainer.json index 16c2aa49d..549aefb99 100644 --- a/.devcontainer.json +++ b/.devcontainer.json @@ -22,7 +22,8 @@ "timonwong.shellcheck", "be5invis.toml", "redhat.vscode-yaml", - "ms-python.python" + "ms-python.python", + "streetsidesoftware.code-spell-checker" ] } } diff --git a/.github/actions/bootstrap-macos/action.yaml b/.github/actions/bootstrap-macos/action.yaml index bb72ae6ed..792059d47 100644 --- a/.github/actions/bootstrap-macos/action.yaml +++ b/.github/actions/bootstrap-macos/action.yaml @@ -5,6 +5,15 @@ inputs: target: description: "cargo target to build for" required: true + build_certificate_base64: + description: "Base64 encoded Apple certificate - P12 format" + required: true + build_certificate_password: + description: "Password for the Apple certificate" + required: true + auth_key_base64: + description: "Base64 encoded Apple API key - p8 format" + required: true runs: using: composite @@ -27,3 +36,38 @@ runs: echo "RUSTUP_HOME=${HOME}/.rustup" >> "${GITHUB_ENV}" echo "${HOME}/.cargo/bin" >> "${GITHUB_PATH}" echo "$(dirname "${rustup_cargo}")" >> "${GITHUB_PATH}" + + - name: Setup ENV for signing and notarization + env: + BUILD_CERTIFICATE_BASE64: ${{ inputs.build_certificate_base64 }} + P12_PASSWORD: ${{ inputs.build_certificate_password }} + AUTH_KEY_BASE64: ${{ inputs.auth_key_base64 }} + shell: bash + run: | + # create variables + CERTIFICATE_PATH="${RUNNER_TEMP}/build_certificate.p12" + KEYCHAIN_PATH="${RUNNER_TEMP}/app-signing.keychain-db" + AUTH_KEY_PATH="${RUNNER_TEMP}/AuthKey.p8" + + # import certificate + echo -n "${BUILD_CERTIFICATE_BASE64}" | base64 --decode -o "${CERTIFICATE_PATH}" + echo -n "${AUTH_KEY_BASE64}" | base64 --decode -o "${AUTH_KEY_PATH}" + + # create temporary keychain password + KEYCHAIN_PASSWORD=$(openssl rand -base64 32) + echo "::add-mask::${KEYCHAIN_PASSWORD}" + + # create temporary keychain + security create-keychain -p "${KEYCHAIN_PASSWORD}" "${KEYCHAIN_PATH}" + security set-keychain-settings -lut 21600 "${KEYCHAIN_PATH}" + security unlock-keychain -p "${KEYCHAIN_PASSWORD}" "${KEYCHAIN_PATH}" + + # import certificate to keychain + security import "${CERTIFICATE_PATH}" -P "${P12_PASSWORD}" -A -t cert -f pkcs12 -k "${KEYCHAIN_PATH}" + security set-key-partition-list -S apple-tool:,apple: -k "${KEYCHAIN_PASSWORD}" "${KEYCHAIN_PATH}" + security list-keychain -d user -s "${KEYCHAIN_PATH}" + + # setup outputs + echo "AUTH_KEY_PATH=${AUTH_KEY_PATH}" >> "${GITHUB_ENV}" + echo "CERTIFICATE_PATH=${CERTIFICATE_PATH}" >> "${GITHUB_ENV}" + echo "KEYCHAIN_PATH=${KEYCHAIN_PATH}" >> "${GITHUB_ENV}" diff --git a/.github/actions/build-rust/action.yaml b/.github/actions/build-rust/action.yaml index d85dc94fd..5bfb1b8e2 100644 --- a/.github/actions/build-rust/action.yaml +++ b/.github/actions/build-rust/action.yaml @@ -15,6 +15,22 @@ inputs: cache_buster: description: "cache buster" required: true + codesign_identity: + description: "codesign identity" + default: "" + required: false + codesign_prefix: + description: "codesign prefix" + default: "" + required: false + notarytool_key_id: + description: "notarytool key id" + default: "" + required: false + notarytool_issuer: + description: "notarytool issuer" + default: "" + required: false runs: using: composite @@ -99,6 +115,34 @@ runs: cp "${TARGET_DIR}/generate-rsa-keypair" "${ARTIFACT_DIR}/mirror" cp mirror/EXAMPLE.md "${ARTIFACT_DIR}/mirror" + - name: Sign and Notarize MacOS Binaries + if: runner.os == 'macOS' + shell: bash + run: | + binaries=$(find ${ARTIFACT_DIR} -type f -perm +111 -print) + + for f in ${binaries} + do + echo "Signing ${f}" + # we need to sign the binary we include in the tarball. + codesign --sign "${{ inputs.codesign_identity }}" \ + --prefix "${{ inputs.codesign_prefix }}" \ + --options runtime "${f}" + + # we don't actually need to release this zip, its just used as a wrapper for notarization submission + # Can we zip all the binaries together and submit them in one go? + echo "Zipping ${f}" + mkdir -p "$(dirname "${RUNNER_TEMP}/${f}.zip")" + zip -r "${RUNNER_TEMP}/${f}.zip" "${f}" + + echo "Notarizing ${f}" + xcrun notarytool submit "${RUNNER_TEMP}/${f}.zip" \ + --key "${AUTH_KEY_PATH}" \ + --key-id ${{ inputs.notarytool_key_id }} \ + --issuer ${{ inputs.notarytool_issuer }} \ + --wait + done + - name: Tar up artifacts shell: bash run: | diff --git a/.github/workflows/on-pr.yaml b/.github/workflows/on-pr.yaml index c1129ece2..d8b63ccb3 100644 --- a/.github/workflows/on-pr.yaml +++ b/.github/workflows/on-pr.yaml @@ -209,6 +209,9 @@ jobs: uses: ./.github/actions/bootstrap-macos with: target: ${{ matrix.target }} + build_certificate_base64: ${{ secrets.APPLE_BUILD_CERTIFICATE_BASE64 }} + build_certificate_password: ${{ secrets.APPLE_BUILD_CERTIFICATE_PASSWORD }} + auth_key_base64: ${{ secrets.APPLE_AUTH_KEY_BASE64 }} - name: Build Rust uses: ./.github/actions/build-rust @@ -217,6 +220,10 @@ jobs: network: ${{ matrix.network }} version: ${{ needs.meta.outputs.version }} cache_buster: ${{ vars.CACHE_BUSTER }} + codesign_identity: ${{ secrets.APPLE_CODESIGN_IDENTITY }} + codesign_prefix: ${{ secrets.APPLE_CODESIGN_PREFIX }} + notarytool_key_id: ${{ secrets.APPLE_NOTARYTOOL_KEY_ID }} + notarytool_issuer: ${{ secrets.APPLE_NOTARYTOOL_ISSUER }} build-containers: needs: diff --git a/.github/workflows/on-tag.yaml b/.github/workflows/on-tag.yaml index e5e55f2df..04c2788a8 100644 --- a/.github/workflows/on-tag.yaml +++ b/.github/workflows/on-tag.yaml @@ -52,6 +52,9 @@ jobs: uses: ./.github/actions/bootstrap-macos with: target: ${{ matrix.target }} + build_certificate_base64: ${{ secrets.APPLE_BUILD_CERTIFICATE_BASE64 }} + build_certificate_password: ${{ secrets.APPLE_BUILD_CERTIFICATE_PASSWORD }} + auth_key_base64: ${{ secrets.APPLE_AUTH_KEY_BASE64 }} - name: Build Rust uses: ./.github/actions/build-rust @@ -60,6 +63,10 @@ jobs: network: ${{ matrix.network }} version: ${{ github.ref_name }} cache_buster: ${{ vars.CACHE_BUSTER }} + codesign_identity: ${{ secrets.APPLE_CODESIGN_IDENTITY }} + codesign_prefix: ${{ secrets.APPLE_CODESIGN_PREFIX }} + notarytool_key_id: ${{ secrets.APPLE_NOTARYTOOL_KEY_ID }} + notarytool_issuer: ${{ secrets.APPLE_NOTARYTOOL_ISSUER }} build-containers: needs: