Files
moeka-project/.github/workflows/release-pocket-ios.yml
T

159 lines
5.6 KiB
YAML

name: Release Pocket (iOS)
permissions:
contents: write
actions: read
on:
release:
types:
- prereleased
workflow_dispatch:
inputs:
testflight:
description: Upload to TestFlight
type: boolean
default: false
tag:
description: GitHub Release tag (empty to skip)
type: string
required: false
default: ''
jobs:
build:
name: Build iOS
runs-on: macos-26
env:
PRODUCT_NAME: 'AIRI'
VITE_ENABLE_POSTHOG: 'true'
UPLOAD_TESTFLIGHT: ${{ github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.testflight) }}
RELEASE_TAG: ${{ github.event.release.tag_name || inputs.tag }}
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v4
with:
run_install: false
- uses: actions/setup-node@v6
with:
node-version: lts/*
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm run build:packages
- name: Build assets
run: pnpm -F @proj-airi/stage-pocket run build
- name: Sync assets to iOS
run: pnpm -F @proj-airi/stage-pocket exec cap sync ios
- name: Install Apple certificate
env:
CERT_BASE64: ${{ secrets.APPLE_DISTRIBUTION_CERT_BASE64 }}
CERT_PASSWORD: ${{ secrets.APPLE_DISTRIBUTION_CERT_PASSWORD }}
run: |
CERT_PATH="$RUNNER_TEMP/certificate.p12"
KEYCHAIN_PATH="$RUNNER_TEMP/app-signing.keychain-db"
KEYCHAIN_PASSWORD="$(openssl rand -hex 16)"
echo "$CERT_BASE64" | base64 --decode -o "$CERT_PATH"
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security set-keychain-settings -lut 3600 "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security import "$CERT_PATH" -k "$KEYCHAIN_PATH" -P "$CERT_PASSWORD" \
-T /usr/bin/codesign -T /usr/bin/security
security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security list-keychains -d user -s "$KEYCHAIN_PATH" login.keychain-db
echo "KEYCHAIN_PATH=$KEYCHAIN_PATH" >> "$GITHUB_ENV"
- name: Install provisioning profile
env:
PROFILE_BASE64: ${{ secrets.APPLE_PROVISIONING_PROFILE_BASE64 }}
run: |
PROFILE_PATH="$RUNNER_TEMP/profile.mobileprovision"
echo "$PROFILE_BASE64" | base64 --decode -o "$PROFILE_PATH"
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp "$PROFILE_PATH" ~/Library/MobileDevice/Provisioning\ Profiles/
- name: Read version from Xcode project
run: |
PBXPROJ="apps/stage-pocket/ios/App/App.xcodeproj/project.pbxproj"
VERSION="$(sed -n 's/.*MARKETING_VERSION = \(.*\);/\1/p' "$PBXPROJ" | head -1 | tr -d ' ')"
BUILD_NUMBER="$(sed -n 's/.*CURRENT_PROJECT_VERSION = \(.*\);/\1/p' "$PBXPROJ" | head -1 | tr -d ' ')"
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
echo "BUILD_NUMBER=$BUILD_NUMBER" >> "$GITHUB_ENV"
- name: Archive iOS
run: |
xcodebuild archive \
-project apps/stage-pocket/ios/App/App.xcodeproj \
-scheme App \
-configuration Release \
-destination "generic/platform=iOS" \
-archivePath "$RUNNER_TEMP/App.xcarchive" \
CURRENT_PROJECT_VERSION=${{ env.BUILD_NUMBER }}
- name: Export IPA
run: |
xcodebuild -exportArchive \
-archivePath "$RUNNER_TEMP/App.xcarchive" \
-exportPath "$RUNNER_TEMP/output" \
-exportOptionsPlist apps/stage-pocket/ios/ExportOptions.plist
- name: Rename IPA for distribution
run: |
IPA_SOURCE="$(find "$RUNNER_TEMP/output" -name '*.ipa' -print -quit)"
IPA_NAME="${PRODUCT_NAME}-${VERSION}_(${BUILD_NUMBER})-ios.ipa"
mv "$IPA_SOURCE" "$RUNNER_TEMP/output/$IPA_NAME"
echo "IPA_NAME=$IPA_NAME" >> "$GITHUB_ENV"
- name: Upload IPA artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.IPA_NAME }}
path: ${{ runner.temp }}/output/${{ env.IPA_NAME }}
if-no-files-found: error
- name: Install Transporter
if: ${{ env.UPLOAD_TESTFLIGHT == 'true' }}
run: |
curl -fsSL "https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/ra/resources/download/public/Transporter__OSX/bin/" -o "$RUNNER_TEMP/itmstransporter.pkg"
sudo installer -pkg "$RUNNER_TEMP/itmstransporter.pkg" -target /
rm -f "$RUNNER_TEMP/itmstransporter.pkg"
- name: Upload to TestFlight
if: ${{ env.UPLOAD_TESTFLIGHT == 'true' }}
uses: apple-actions/upload-testflight-build@v4
with:
app-path: ${{ runner.temp }}/output/${{ env.IPA_NAME }}
issuer-id: ${{ secrets.APPSTORE_CONNECT_API_ISSUER_ID }}
api-key-id: ${{ secrets.APPSTORE_CONNECT_API_KEY_ID }}
api-private-key: ${{ secrets.APPSTORE_CONNECT_API_KEY }}
- name: Upload to GitHub Releases
if: ${{ env.RELEASE_TAG != '' }}
uses: softprops/action-gh-release@v2
with:
files: ${{ runner.temp }}/output/${{ env.IPA_NAME }}
append_body: true
fail_on_unmatched_files: true
tag_name: ${{ env.RELEASE_TAG }}
- name: Clean up signing
if: always()
run: |
if [ -n "$KEYCHAIN_PATH" ]; then
security delete-keychain "$KEYCHAIN_PATH" 2>/dev/null || true
fi
rm -f ~/Library/MobileDevice/Provisioning\ Profiles/*.mobileprovision