ADD: upload Mac Catalyst to TestFlight when both mac-dmg and testflight labels present

This commit is contained in:
Marcos Rodriguez 2026-02-21 20:32:08 -05:00
parent 582d6b8e44
commit 19c0d3ae39
2 changed files with 119 additions and 3 deletions

View File

@ -16,17 +16,45 @@ jobs:
build-mac-catalyst:
if: >
github.event_name == 'workflow_dispatch' ||
(github.event.action == 'labeled' && github.event.label.name == 'mac-dmg')
(github.event.action == 'labeled' && (github.event.label.name == 'mac-dmg' || github.event.label.name == 'testflight'))
runs-on: macos-15
timeout-minutes: 120
steps:
- name: Check PR labels
if: github.event_name == 'pull_request'
id: labels
env:
GH_TOKEN: ${{ github.token }}
run: |
LABELS=$(gh api "repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/labels" --jq '.[].name' | tr '\n' ',')
echo "all=${LABELS}" >> $GITHUB_OUTPUT
if [[ "$LABELS" == *"mac-dmg"* ]]; then
echo "has_mac_dmg=true" >> $GITHUB_OUTPUT
else
echo "has_mac_dmg=false" >> $GITHUB_OUTPUT
fi
if [[ "$LABELS" == *"testflight"* ]] && [[ "$LABELS" == *"mac-dmg"* ]]; then
echo "upload_testflight=true" >> $GITHUB_OUTPUT
else
echo "upload_testflight=false" >> $GITHUB_OUTPUT
fi
echo "Labels on PR: ${LABELS}"
- name: Skip if mac-dmg label not present
if: github.event_name == 'pull_request' && steps.labels.outputs.has_mac_dmg != 'true'
run: |
echo "mac-dmg label not found on PR — skipping build."
exit 0
- name: Checkout project
if: github.event_name == 'workflow_dispatch' || steps.labels.outputs.has_mac_dmg == 'true'
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Node.js
if: github.event_name == 'workflow_dispatch' || steps.labels.outputs.has_mac_dmg == 'true'
uses: actions/setup-node@v6
with:
node-version: 24
@ -34,53 +62,81 @@ jobs:
cache-dependency-path: package-lock.json
- name: Setup Xcode
if: github.event_name == 'workflow_dispatch' || steps.labels.outputs.has_mac_dmg == 'true'
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest
- name: Set up Ruby
if: github.event_name == 'workflow_dispatch' || steps.labels.outputs.has_mac_dmg == 'true'
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.1.6
bundler-cache: true
- name: Install Node modules
if: github.event_name == 'workflow_dispatch' || steps.labels.outputs.has_mac_dmg == 'true'
run: npm ci
- name: Install CocoaPods dependencies
if: github.event_name == 'workflow_dispatch' || steps.labels.outputs.has_mac_dmg == 'true'
run: bundle exec fastlane ios install_pods
env:
SKIP_APP_STORE_CONNECT_AUTH: '1'
- name: Build Mac Catalyst app with Fastlane
if: github.event_name == 'workflow_dispatch' || steps.labels.outputs.has_mac_dmg == 'true'
id: build_catalyst
run: bundle exec fastlane ios build_catalyst_app_lane
env:
SKIP_APP_STORE_CONNECT_AUTH: '1'
SKIP_CLEAR_DERIVED_DATA: '1'
CATALYST_SIGNING_IDENTITY: ${{ steps.labels.outputs.upload_testflight == 'true' && secrets.CATALYST_SIGNING_IDENTITY || '' }}
CATALYST_TEAM_ID: ${{ steps.labels.outputs.upload_testflight == 'true' && secrets.CATALYST_TEAM_ID || '' }}
- name: Upload Mac Catalyst DMG
id: upload_dmg
if: success()
if: success() && (github.event_name == 'workflow_dispatch' || steps.labels.outputs.has_mac_dmg == 'true')
uses: actions/upload-artifact@v6
with:
name: BlueWallet-Mac-Catalyst
path: ${{ steps.build_catalyst.outputs.catalyst_dmg_path }}
if-no-files-found: warn
- name: Upload to TestFlight
if: success() && steps.labels.outputs.upload_testflight == 'true'
run: bundle exec fastlane ios upload_catalyst_to_testflight
env:
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
APPLE_API_ISSUER_ID: ${{ secrets.APPLE_API_ISSUER_ID }}
APPLE_API_KEY_PATH: ${{ secrets.APPLE_API_KEY_PATH }}
APPLE_API_KEY_CONTENT: ${{ secrets.APPLE_API_KEY_CONTENT }}
CATALYST_TEAM_ID: ${{ secrets.CATALYST_TEAM_ID }}
TEAM_ID: ${{ secrets.TEAM_ID }}
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
LATEST_COMMIT_MESSAGE: ${{ github.event.pull_request.title || 'Manual build' }}
- name: Comment on PR with DMG link
if: success() && github.event_name == 'pull_request'
if: success() && github.event_name == 'pull_request' && steps.labels.outputs.has_mac_dmg == 'true'
env:
GH_TOKEN: ${{ github.token }}
UPLOADED_TO_TF: ${{ steps.labels.outputs.upload_testflight }}
run: |
ARTIFACT_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts/${{ steps.upload_dmg.outputs.artifact-id }}"
COMMENT_TAG="<!-- catalyst-dmg-link -->"
TF_LINE=""
if [[ "$UPLOADED_TO_TF" == "true" ]]; then
TF_LINE=$'\n\n**Also uploaded to TestFlight.** Check [App Store Connect](https://appstoreconnect.apple.com) for the build.'
fi
COMMENT_BODY="${COMMENT_TAG}
### Mac Catalyst Build
The Mac Catalyst DMG is ready for download:
[Download BlueWallet-Mac-Catalyst.dmg](${ARTIFACT_URL})
${TF_LINE}
> **First launch:** Right-click the app → Open → click Open in the dialog. You only need to do this once.

View File

@ -676,6 +676,66 @@ platform :ios do
end
end
desc "Upload Mac Catalyst app to TestFlight"
lane :upload_catalyst_to_testflight do
Dir.chdir(project_root) do
# Locate the xcarchive
archive_path = lane_context[SharedValues::XCODEBUILD_ARCHIVE]
if archive_path.nil? || archive_path.empty?
archive_path = Dir.glob(File.join(Dir.home, "Library/Developer/Xcode/Archives/**/*.xcarchive")).max_by { |path| File.mtime(path) }
end
UI.user_error!("No xcarchive found for TestFlight upload") if archive_path.nil? || !File.exist?(archive_path)
UI.message("Using archive: #{archive_path}")
output_dir = File.join(project_root, "ios", "build", "catalyst-output")
FileUtils.mkdir_p(output_dir)
# Export the archive as a .pkg for Mac Catalyst
export_plist_path = File.join(output_dir, "ExportOptions.plist")
File.write(export_plist_path, <<~PLIST)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>app-store</string>
<key>destination</key>
<string>upload</string>
<key>teamID</key>
<string>#{ENV['CATALYST_TEAM_ID'] || ENV['TEAM_ID']}</string>
<key>signingStyle</key>
<string>automatic</string>
</dict>
</plist>
PLIST
pkg_path = File.join(output_dir, "BlueWallet.pkg")
sh("xcodebuild -exportArchive -archivePath '#{archive_path}' -exportOptionsPlist '#{export_plist_path}' -exportPath '#{output_dir}'")
# Find the exported pkg
exported_pkg = Dir.glob(File.join(output_dir, "*.pkg")).first
UI.user_error!("No .pkg found after export") if exported_pkg.nil? || !File.exist?(exported_pkg)
UI.success("Exported pkg: #{exported_pkg}")
# Build changelog
branch_name = ENV['BRANCH_NAME'] || "unknown-branch"
last_commit_message = ENV['LATEST_COMMIT_MESSAGE'] || "No commit message found"
changelog = "Build Information:\n"
changelog += "- Branch: #{branch_name}\n" if branch_name != 'master'
changelog += "- Commit: #{last_commit_message}\n"
# Upload to TestFlight
upload_to_testflight(
api_key_path: "./appstore_api_key.json",
pkg: exported_pkg,
skip_waiting_for_build_processing: true,
changelog: changelog
)
UI.success("Successfully uploaded Mac Catalyst app to TestFlight!")
end
end
desc "Upload IPA to TestFlight"
lane :upload_to_testflight_lane do