From 058fed59a135c2dac95893864c4f29a837adfe98 Mon Sep 17 00:00:00 2001 From: Michael Kazakov Date: Tue, 14 May 2024 20:26:10 +0100 Subject: [PATCH] CI chore --- .github/workflows/release.yml | 65 ++++++++++++++++++++++++++++++ Scripts/README.md | 3 ++ Scripts/build_release.sh | 74 +++++++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+) create mode 100644 .github/workflows/release.yml create mode 100755 Scripts/build_release.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..71b1b6fcc --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,65 @@ +name: Release Build + +on: + workflow_dispatch: + +env: + XC_VERSION: ${{ '15.1' }} + +jobs: + build: + runs-on: macos-14 + if: github.ref == 'refs/heads/main' # run this job only for the main branch + steps: + - name: Select latest Xcode + run: "sudo xcode-select -s /Applications/Xcode_$XC_VERSION.app" + - name: Install deps + run: brew install create-dmg + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Install the Apple certificate and provisioning profile + env: + BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }} + P12_PASSWORD: ${{ secrets.P12_PASSWORD }} + BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }} + KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} + NOTARIZATION_APPLE_ID: ${{ secrets.NOTARIZATION_APPLE_ID }} + NOTARIZATION_PWD: ${{ secrets.NOTARIZATION_PWD }} + NOTARIZATION_TEAM: ${{ secrets.NOTARIZATION_TEAM }} + run: | + # create variables + CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12 + PP_PATH=$RUNNER_TEMP/build_pp.provisionprofile + KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db + # import certificate and provisioning profile from secrets + echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH + echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH + # 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 list-keychain -d user -s $KEYCHAIN_PATH + # apply provisioning profile + mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles + cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles + # store notatization credentials + xcrun notarytool store-credentials AC_PASSWORD --apple-id $NOTARIZATION_APPLE_ID --team-id $NOTARIZATION_TEAM --password $NOTARIZATION_PWD + - name: Build and package + env: + NC_SENSITIVE: ${{ secrets.NC_SENSITIVE }} + run: | + echo -n "$NC_SENSITIVE" | base64 --decode -o /Users/runner/.nc_sensitive.h + cd Scripts && ./build_release.sh + - name: Clean up keychain and provisioning profile + if: ${{ always() }} + run: | + security delete-keychain $RUNNER_TEMP/app-signing.keychain-db + rm ~/Library/MobileDevice/Provisioning\ Profiles/build_pp.provisionprofile + - uses: actions/upload-artifact@v4 + with: + name: nimble-commander + path: Scripts/*.dmg + if-no-files-found: error diff --git a/Scripts/README.md b/Scripts/README.md index 6ba18c885..a379854c1 100644 --- a/Scripts/README.md +++ b/Scripts/README.md @@ -10,6 +10,9 @@ Builds Nimble Commander with the `NimbleCommander-NonMAS` scheme / `Release` con `xcodebuild`, `xcpretty` and `create-dmg` must be available in the environment in order for this script to run. It also requires the codesigning certificate to be properly signed. +## `build_release.sh` +Same a `build_nightly.sh`, but creates a release build. + ## `build_unsigned.sh` Builds Nimble Commander with the `NimbleCommander-Unsigned` scheme / `Release` configuration and packages the runnable build into a `.dmg` image. `xcodebuild`, `xcpretty` and `create-dmg` must be available in the environment in order for this script to run. diff --git a/Scripts/build_release.sh b/Scripts/build_release.sh new file mode 100755 index 000000000..57dbeaf9d --- /dev/null +++ b/Scripts/build_release.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +set -e +set -o pipefail + +if ! [ -x "$(command -v xcpretty)" ] ; then + echo 'xcpretty is not found, aborting. (https://github.com/xcpretty/xcpretty)' + exit -1 +fi + +if ! [ -x "$(command -v create-dmg)" ] ; then + echo 'create-dmg is not found, aborting. (https://github.com/create-dmg/create-dmg)' + exit -1 +fi + +# https://github.com/xcpretty/xcpretty/issues/48 +export LC_CTYPE=en_US.UTF-8 + +PBUDDY=/usr/libexec/PlistBuddy + +# Set up the paths to the sources and artifacts +SCRIPTS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +ROOT_DIR=$(cd "$SCRIPTS_DIR/.." && pwd) +XCODEPROJ="${ROOT_DIR}/Source/NimbleCommander/NimbleCommander.xcodeproj" +BUILD_DIR="${SCRIPTS_DIR}/build_release.tmp" +ARCHIVE_PATH="${BUILD_DIR}/NC_NonMAS.xcarchive" +BUILT_PATH="${BUILD_DIR}/built" +mkdir -p "${BUILD_DIR}" +mkdir -p "${ARCHIVE_PATH}" + +# Gather common flags in the XC variable +XC="xcodebuild \ + -project ${XCODEPROJ} \ + -scheme NimbleCommander-NonMAS \ + -configuration Release \ + OTHER_CFLAGS=\"-fdebug-prefix-map=${ROOT_DIR}=.\"" + +# Build and archive the project +$XC -archivePath ${ARCHIVE_PATH} archive | xcpretty + +# Export a signed version +xcodebuild -exportArchive \ + -archivePath $ARCHIVE_PATH \ + -exportPath $BUILT_PATH \ + -exportOptionsPlist export_options.plist + +# Extract the version number and the build number +APP_NAME=$($XC -showBuildSettings | grep " FULL_PRODUCT_NAME =" | sed -e 's/.*= *//' ) +APP_PATH="${BUILT_PATH}/${APP_NAME}" +VERSION=$( $PBUDDY -c "Print CFBundleShortVersionString" "${APP_PATH}/Contents/Info.plist" ) +BUILD=$( $PBUDDY -c "Print CFBundleVersion" "${APP_PATH}/Contents/Info.plist" ) +DMG_NAME="nimble-commander-${VERSION}(${BUILD}).dmg" + +# Wrap the built application into a .dmg disk image +create-dmg \ + --volname "Nimble Commander" \ + --window-pos 200 200 \ + --window-size 610 386 \ + --background "dmg/background.png" \ + --text-size 12 \ + --icon-size 128 \ + --icon "${APP_NAME}" 176 192 \ + --app-drop-link 432 192 \ + --codesign "Developer ID Application: Mikhail Kazakov (AC5SJT236H)" \ + "${DMG_NAME}" \ + "${APP_PATH}" + +# Upload the built dmg into Apple's notary service and wait for the response +xcrun notarytool submit ${DMG_NAME} --keychain-profile AC_PASSWORD --wait + +# Finally, staple the dmg +xcrun stapler staple "${DMG_NAME}" + +# Done!