macOS Direct Release #7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: macOS Direct Release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| channel: | |
| description: "Update channel for appcast" | |
| type: choice | |
| required: true | |
| default: stable | |
| options: | |
| - stable | |
| - beta | |
| sparkle_version: | |
| description: "Sparkle release version" | |
| required: true | |
| default: "2.7.3" | |
| tag: | |
| description: "Git tag to attach the DMG to (optional)" | |
| required: false | |
| default: "" | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: false | |
| jobs: | |
| build: | |
| runs-on: macos-latest | |
| timeout-minutes: 90 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Preflight | |
| id: preflight | |
| env: | |
| SCHEME: ${{ vars.MACOS_DIRECT_SCHEME }} | |
| XCODE_PATH: ${{ vars.MACOS_XCODE_PATH }} | |
| MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }} | |
| MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }} | |
| MACOS_CERTIFICATE_NAME: ${{ secrets.MACOS_CERTIFICATE_NAME }} | |
| MACOS_CI_KEYCHAIN_PWD: ${{ secrets.MACOS_CI_KEYCHAIN_PWD }} | |
| MACOS_SPARKLE_PUBLIC_KEY: ${{ secrets.MACOS_SPARKLE_PUBLIC_KEY }} | |
| MACOS_SPARKLE_PRIVATE_KEY: ${{ secrets.MACOS_SPARKLE_PRIVATE_KEY }} | |
| APPLE_ID: ${{ secrets.APPLE_ID }} | |
| APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} | |
| APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | |
| PUBLIC_RELEASES_R2_ACCESS_KEY_ID: ${{ secrets.PUBLIC_RELEASES_R2_ACCESS_KEY_ID }} | |
| PUBLIC_RELEASES_R2_SECRET_ACCESS_KEY: ${{ secrets.PUBLIC_RELEASES_R2_SECRET_ACCESS_KEY }} | |
| PUBLIC_RELEASES_R2_BUCKET: ${{ secrets.PUBLIC_RELEASES_R2_BUCKET }} | |
| PUBLIC_RELEASES_R2_ENDPOINT: ${{ secrets.PUBLIC_RELEASES_R2_ENDPOINT }} | |
| PUBLIC_RELEASES_R2_PUBLIC_BASE_URL: ${{ secrets.PUBLIC_RELEASES_R2_PUBLIC_BASE_URL }} | |
| PUBLIC_RELEASES_R2_PREFIX: ${{ secrets.PUBLIC_RELEASES_R2_PREFIX }} | |
| run: | | |
| set -euo pipefail | |
| required=( | |
| MACOS_CERTIFICATE | |
| MACOS_CERTIFICATE_PWD | |
| MACOS_CERTIFICATE_NAME | |
| MACOS_CI_KEYCHAIN_PWD | |
| MACOS_SPARKLE_PUBLIC_KEY | |
| MACOS_SPARKLE_PRIVATE_KEY | |
| APPLE_ID | |
| APPLE_PASSWORD | |
| APPLE_TEAM_ID | |
| PUBLIC_RELEASES_R2_ACCESS_KEY_ID | |
| PUBLIC_RELEASES_R2_SECRET_ACCESS_KEY | |
| PUBLIC_RELEASES_R2_BUCKET | |
| PUBLIC_RELEASES_R2_ENDPOINT | |
| PUBLIC_RELEASES_R2_PUBLIC_BASE_URL | |
| ) | |
| missing=0 | |
| for name in "${required[@]}"; do | |
| if [[ -z "${!name:-}" ]]; then | |
| echo "Missing required secret: ${name}" >&2 | |
| missing=1 | |
| fi | |
| done | |
| if [[ "${missing}" -ne 0 ]]; then | |
| exit 1 | |
| fi | |
| if [[ -z "${PUBLIC_RELEASES_R2_PREFIX:-}" ]]; then | |
| echo "PUBLIC_RELEASES_R2_PREFIX not set; defaulting to 'mac' in script." >&2 | |
| fi | |
| if [[ -n "${XCODE_PATH:-}" ]]; then | |
| xcode_path="${XCODE_PATH}" | |
| elif [[ -d "/Applications/Xcode_26.1.app" ]]; then | |
| xcode_path="/Applications/Xcode_26.1.app" | |
| elif [[ -d "/Applications/Xcode_26.0.app" ]]; then | |
| xcode_path="/Applications/Xcode_26.0.app" | |
| elif [[ -d "/Applications/Xcode.app" ]]; then | |
| xcode_path="/Applications/Xcode.app" | |
| else | |
| echo "No suitable Xcode found on runner." >&2 | |
| exit 1 | |
| fi | |
| echo "Using Xcode path: ${xcode_path}" | |
| echo "xcode_path=${xcode_path}" >> "${GITHUB_OUTPUT}" | |
| - name: Set Xcode version | |
| run: sudo xcode-select -s "${{ steps.preflight.outputs.xcode_path }}" | |
| - name: Xcode Version | |
| run: xcodebuild -version | |
| - name: Verify Scheme | |
| env: | |
| SCHEME: ${{ vars.MACOS_DIRECT_SCHEME }} | |
| run: | | |
| set -euo pipefail | |
| scheme="${SCHEME:-Inline (macOS)}" | |
| echo "Using scheme: ${scheme}" | |
| scheme_list=$(xcodebuild -list -project apple/Inline.xcodeproj) | |
| if ! echo "${scheme_list}" | grep -Fq "${scheme}"; then | |
| echo "Xcode scheme '${scheme}' not found in apple/Inline.xcodeproj." >&2 | |
| echo "Set MACOS_DIRECT_SCHEME repository variable to override." >&2 | |
| echo "Available schemes:" >&2 | |
| echo "${scheme_list}" | awk '/Schemes:/{flag=1;next} flag{print}' >&2 | |
| exit 1 | |
| fi | |
| - name: Install create-dmg | |
| run: npm install --global create-dmg | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v1 | |
| with: | |
| bun-version: "latest" | |
| - name: Import macOS signing certificate | |
| env: | |
| MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }} | |
| MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }} | |
| MACOS_CERTIFICATE_NAME: ${{ secrets.MACOS_CERTIFICATE_NAME }} | |
| MACOS_CI_KEYCHAIN_PWD: ${{ secrets.MACOS_CI_KEYCHAIN_PWD }} | |
| run: | | |
| echo "$MACOS_CERTIFICATE" | base64 --decode > certificate.p12 | |
| security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain | |
| security default-keychain -s build.keychain | |
| security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain | |
| security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign | |
| security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain | |
| - name: Build Direct DMG | |
| env: | |
| SPARKLE_VERSION: ${{ inputs.sparkle_version }} | |
| CHANNEL: ${{ inputs.channel }} | |
| SCHEME: ${{ vars.MACOS_DIRECT_SCHEME }} | |
| SPARKLE_PUBLIC_KEY: ${{ secrets.MACOS_SPARKLE_PUBLIC_KEY }} | |
| MACOS_CERTIFICATE_NAME: ${{ secrets.MACOS_CERTIFICATE_NAME }} | |
| APPLE_NOTARIZATION_KEY: ${{ secrets.APPLE_NOTARIZATION_KEY }} | |
| APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }} | |
| APPLE_NOTARIZATION_ISSUER: ${{ secrets.APPLE_NOTARIZATION_ISSUER }} | |
| APPLE_ID: ${{ secrets.APPLE_ID }} | |
| APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} | |
| APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | |
| run: bash scripts/macos/build-direct.sh | |
| - name: Generate Appcast | |
| env: | |
| CHANNEL: ${{ inputs.channel }} | |
| SPARKLE_PRIVATE_KEY: ${{ secrets.MACOS_SPARKLE_PRIVATE_KEY }} | |
| PUBLIC_RELEASES_R2_PUBLIC_BASE_URL: ${{ secrets.PUBLIC_RELEASES_R2_PUBLIC_BASE_URL }} | |
| run: | | |
| BUILD_NUMBER=$(git rev-list --count HEAD) | |
| COMMIT=$(git rev-parse --short HEAD) | |
| COMMIT_LONG=$(git rev-parse HEAD) | |
| APP_PATH="build/InlineMacDirect/Build/Products/Release/Inline.app" | |
| INFO_PLIST="${APP_PATH}/Contents/Info.plist" | |
| VERSION=$(/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" "${INFO_PLIST}") | |
| BASE_URL="${PUBLIC_RELEASES_R2_PUBLIC_BASE_URL%/}" | |
| DMG_URL="${BASE_URL}/mac/${CHANNEL}/${BUILD_NUMBER}/Inline.dmg" | |
| APPCAST_URL="${BASE_URL}/mac/${CHANNEL}/appcast.xml" | |
| SPARKLE_DIR=".action/sparkle" | |
| echo "${SPARKLE_PRIVATE_KEY}" > signing.key | |
| "${SPARKLE_DIR}/bin/sign_update" -f signing.key build/macos-direct/Inline.dmg > sign_update.txt | |
| rm -f signing.key | |
| if ! curl -fsSL "${APPCAST_URL}" -o appcast.xml; then | |
| rm -f appcast.xml | |
| fi | |
| INLINE_BUILD="${BUILD_NUMBER}" \\ | |
| INLINE_VERSION="${VERSION}" \\ | |
| INLINE_CHANNEL="${CHANNEL}" \\ | |
| INLINE_DMG_URL="${DMG_URL}" \\ | |
| INLINE_MIN_MACOS="15.0" \\ | |
| INLINE_COMMIT="${COMMIT}" \\ | |
| INLINE_COMMIT_LONG="${COMMIT_LONG}" \\ | |
| python3 scripts/macos/update_appcast.py | |
| - name: Upload to R2 | |
| env: | |
| CHANNEL: ${{ inputs.channel }} | |
| DMG_PATH: build/macos-direct/Inline.dmg | |
| APPCAST_PATH: appcast_new.xml | |
| PUBLIC_RELEASES_R2_ACCESS_KEY_ID: ${{ secrets.PUBLIC_RELEASES_R2_ACCESS_KEY_ID }} | |
| PUBLIC_RELEASES_R2_SECRET_ACCESS_KEY: ${{ secrets.PUBLIC_RELEASES_R2_SECRET_ACCESS_KEY }} | |
| PUBLIC_RELEASES_R2_BUCKET: ${{ secrets.PUBLIC_RELEASES_R2_BUCKET }} | |
| PUBLIC_RELEASES_R2_ENDPOINT: ${{ secrets.PUBLIC_RELEASES_R2_ENDPOINT }} | |
| PUBLIC_RELEASES_R2_PUBLIC_BASE_URL: ${{ secrets.PUBLIC_RELEASES_R2_PUBLIC_BASE_URL }} | |
| PUBLIC_RELEASES_R2_PREFIX: mac | |
| run: | | |
| BUILD_NUMBER=$(git rev-list --count HEAD) | |
| export BUILD_NUMBER | |
| bun run scripts/macos/release-direct.ts | |
| - name: Upload DMG to GitHub Release | |
| if: inputs.tag != '' | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ inputs.tag }} | |
| files: build/macos-direct/Inline.dmg | |
| - name: Upload DMG | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: inline-macos-dmg | |
| path: build/macos-direct/Inline.dmg |