From 403fc287ab2d9bea6338649af1725beba31f3ab5 Mon Sep 17 00:00:00 2001 From: osy Date: Thu, 27 Jul 2023 15:15:42 -0700 Subject: [PATCH] github: add build actions --- .github/FUNDING.yml | 1 + .github/workflows/build.yml | 149 ++++++++++++++++++++++++++++++++++++ Extras/package.sh | 70 +++++++++++++++++ 3 files changed, 220 insertions(+) create mode 100644 .github/FUNDING.yml create mode 100644 .github/workflows/build.yml create mode 100755 Extras/package.sh diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..072e795 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: utmapp diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..a346057 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,149 @@ +name: Build +on: + push: + branches: + - '**' + tags-ignore: + - '**' + paths-ignore: + - 'LICENSE' + - '**.md' + pull_request: + release: + types: [created] + workflow_dispatch: + inputs: + test_release: + description: 'Test release?' + required: true + default: 'false' + +env: + PRODUCT_NAME: CrystalFetch + BUILD_XCODE_PATH: /Applications/Xcode_14.2.app + +jobs: + build: + name: Build + runs-on: macos-12 + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: recursive + - name: Setup Xcode + shell: bash + run: | + [[ "$(xcode-select -p)" == "${{ env.BUILD_XCODE_PATH }}"* ]] || sudo xcode-select -s "${{ env.BUILD_XCODE_PATH }}" + - name: Build + run: | + xcodebuild archive -archivePath "$PRODUCT_NAME" -scheme "$PRODUCT_NAME" -configuration Release CODE_SIGN_IDENTITY="-" PRODUCT_BUNDLE_PREFIX="$PRODUCT_BUNDLE_PREFIX" + tar -acf $PRODUCT_NAME.xcarchive.tgz $PRODUCT_NAME.xcarchive + env: + PRODUCT_NAME: ${{ env.PRODUCT_NAME }} + PRODUCT_BUNDLE_PREFIX: ${{ vars.PRODUCT_BUNDLE_PREFIX }} + - name: Upload + uses: actions/upload-artifact@v3 + with: + name: ${{ env.PRODUCT_NAME }} + path: ${{ env.PRODUCT_NAME }}.xcarchive.tgz + package: + name: Package + runs-on: macos-12 + needs: [build] + if: github.event_name == 'release' || github.event.inputs.test_release == 'true' + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Import signing certificate into keychain + uses: apple-actions/import-codesign-certs@v1 + with: + p12-file-base64: ${{ secrets.SIGNING_CERTIFICATE_P12_DATA }} + p12-password: ${{ secrets.SIGNING_CERTIFICATE_PASSWORD }} + - name: Install Provisioning Profiles + run: | + mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles + echo $PROFILE_DATA | base64 --decode -o ~/Library/MobileDevice/Provisioning\ Profiles/$PROFILE_UUID.provisionprofile + env: + PROFILE_DATA: ${{ vars.PROFILE_DATA }} + PROFILE_UUID: ${{ vars.PROFILE_UUID }} + - name: Download Artifact + uses: actions/download-artifact@v3 + with: + name: ${{ env.PRODUCT_NAME }} + - name: Package for Release + run: | + tar -xf ${{ env.PRODUCT_NAME }}.xcarchive.tgz + ./Extras/package.sh developer-id $PRODUCT_NAME.xcarchive . "BUNDLE_ID" "$SIGNING_TEAM_ID" "$PROFILE_UUID" + env: + BUNDLE_ID: ${{ vars.PRODUCT_BUNDLE_PREFIX }}.${{ env.PRODUCT_NAME }} + SIGNING_TEAM_ID: ${{ vars.SIGNING_TEAM_ID }} + PROFILE_UUID: ${{ vars.PROFILE_UUID }} + - name: Notarize app + run: npx notarize-cli --file "$PRODUCT_NAME.dmg" --bundle-id "$BUNDLE_ID" + env: + BUNDLE_ID: ${{ vars.PRODUCT_BUNDLE_PREFIX }}.${{ env.PRODUCT_NAME }} + NOTARIZE_USERNAME: ${{ secrets.SIGNING_USERNAME }} + NOTARIZE_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} + - name: Upload Artifact + if: github.event_name != 'release' + uses: actions/upload-artifact@v3 + with: + name: ${{ env.PRODUCT_NAME }}-dmg + path: ${{ env.PRODUCT_NAME }}.dmg + - name: Upload Release Asset + if: github.event_name == 'release' + uses: actions/upload-release-asset@v1.0.2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ${{ env.PRODUCT_NAME }}.dmg + asset_name: ${{ env.PRODUCT_NAME }}.dmg + asset_content_type: application/octet-stream + submit: + name: Submit + runs-on: macos-12 + needs: [build] + if: github.event_name == 'release' || github.event.inputs.test_release == 'true' + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Import signing certificate into keychain + uses: apple-actions/import-codesign-certs@v1 + with: + p12-file-base64: ${{ secrets.SIGNING_CERTIFICATE_P12_DATA }} + p12-password: ${{ secrets.SIGNING_CERTIFICATE_PASSWORD }} + - name: Install Provisioning Profiles + run: | + mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles + echo $PROFILE_DATA | base64 --decode -o ~/Library/MobileDevice/Provisioning\ Profiles/$PROFILE_UUID.provisionprofile + env: + PROFILE_DATA: ${{ vars.APP_STORE_PROFILE_DATA }} + PROFILE_UUID: ${{ vars.APP_STORE_PROFILE_UUID }} + - name: Download Artifact + uses: actions/download-artifact@v3 + with: + name: ${{ env.PRODUCT_NAME }} + - name: Package for App Store + run: | + tar -xf $PRODUCT_NAME.xcarchive.tgz + ./Extras/package.sh app-store $PRODUCT_NAME.xcarchive . "$BUNDLE_ID" "$SIGNING_TEAM_ID" "$PROFILE_UUID" + env: + BUNDLE_ID: ${{ vars.PRODUCT_BUNDLE_PREFIX }}.${{ env.PRODUCT_NAME }} + SIGNING_TEAM_ID: ${{ vars.SIGNING_TEAM_ID }} + PROFILE_UUID: ${{ vars.APP_STORE_PROFILE_UUID }} + - name: Upload Artifact + if: github.event_name != 'release' + uses: actions/upload-artifact@v3 + with: + name: ${{ env.PRODUCT_NAME }}-pkg + path: ${{ env.PRODUCT_NAME }}.pkg + - name: Upload app to App Store Connect + if: github.event_name == 'release' + run: | + xcrun altool --upload-app -t macos -f "$PRODUCT_NAME.pkg" -u "$SUBMIT_USERNAME" -p "$SUBMIT_PASSWORD" + env: + PRODUCT_NAME: ${{ env.PRODUCT_NAME }} + SUBMIT_USERNAME: ${{ secrets.SIGNING_USERNAME }} + SUBMIT_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} diff --git a/Extras/package.sh b/Extras/package.sh new file mode 100755 index 0000000..859e790 --- /dev/null +++ b/Extras/package.sh @@ -0,0 +1,70 @@ +#!/bin/sh + +set -e + +command -v realpath >/dev/null 2>&1 || realpath() { + [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}" +} +BASEDIR="$(dirname "$(realpath $0)")" + +if [ $# -lt 3 ]; then + echo "usage: $0 MODE APP.xcarchive outputPath BUNDLE_ID TEAM_ID PROFILE_NAME" + echo " MODE is one of:" + echo " developer-id (signed DMG)" + echo " app-store (Mac App Store package)" + echo " BUNDLE_ID is the app's bundle id" + echo " TEAM_ID is the Developer ID" + echo " PROFILE_NAME can be the name or UUID" + exit 1 +fi + +MODE=$1 +INPUT=$2 +OUTPUT=$3 +BUNDLE_ID=$4 +TEAM_ID=$5 +PROFILE_NAME=$6 +OPTIONS="/tmp/options.$$.plist" +SIGNED="/tmp/signed.$$" +APP_BUNDLE="$(basename $INPUT/Products/Applications/*.app)" +APP_NAME="${APP_BUNDLE%.*}" + +cat >"$OPTIONS" < + + + + compileBitcode + + installerSigningCertificate + 3rd Party Mac Developer Installer + method + ${MODE} + provisioningProfiles + + ${BUNDLE_ID} + ${PROFILE_NAME} + + signingStyle + manual + stripSwiftSymbols + + teamID + ${TEAM_ID} + thinning + <none> + + +EOL + +xcodebuild -exportArchive -exportOptionsPlist "$OPTIONS" -archivePath "$INPUT" -exportPath "$SIGNED" + +rm "$OPTIONS" + +if [ "$MODE" == "app-store" ]; then + cp "$SIGNED/${APP_NAME}.pkg" "$OUTPUT/${APP_NAME}.pkg" +else + rm -f "$OUTPUT/${APP_NAME}.dmg" + hdiutil create -fs HFS+ -srcfolder "$SIGNED/${APP_NAME}.app" -volname "${APP_NAME}" "$OUTPUT/${APP_NAME}.dmg" +fi +rm -rf "$SIGNED"