name: Build iOS App on: workflow_dispatch: inputs: target_owner: description: "Gitea org/user that owns the target repo" required: true target_repo: description: "Repository name to build" required: true target_branch: description: "Branch to build" required: true jobs: build: runs-on: macos steps: - name: Clone target repo run: | git clone --depth 1 --branch "${{ inputs.target_branch }}" \ "https://code.all-win.local/${{ inputs.target_owner }}/${{ inputs.target_repo }}.git" \ workspace env: GIT_SSL_NO_VERIFY: "true" - name: Detect build system id: detect run: | cd workspace if [ -f project.yml ]; then echo "build_system=xcodegen" >> "$GITHUB_OUTPUT" elif ls *.xcworkspace 1>/dev/null 2>&1; then echo "build_system=workspace" >> "$GITHUB_OUTPUT" elif ls *.xcodeproj 1>/dev/null 2>&1; then echo "build_system=xcodeproj" >> "$GITHUB_OUTPUT" else echo "::error::No Xcode project found" exit 1 fi - name: Generate Xcode project (if xcodegen) if: steps.detect.outputs.build_system == 'xcodegen' run: | cd workspace xcodegen generate - name: Resolve scheme id: scheme run: | cd workspace if [ -f *.xcworkspace ]; then PROJ=$(ls -d *.xcworkspace | head -1) SCHEME=$(xcodebuild -workspace "$PROJ" -list 2>/dev/null | awk '/Schemes:/{found=1;next} found && /^[[:space:]]+/{print $1; exit}') else PROJ=$(ls -d *.xcodeproj | head -1) SCHEME=$(xcodebuild -project "$PROJ" -list 2>/dev/null | awk '/Schemes:/{found=1;next} found && /^[[:space:]]+/{print $1; exit}') fi echo "scheme=$SCHEME" >> "$GITHUB_OUTPUT" echo "project=$PROJ" >> "$GITHUB_OUTPUT" echo "Detected scheme: $SCHEME in $PROJ" - name: Archive run: | cd workspace PROJ="${{ steps.scheme.outputs.project }}" SCHEME="${{ steps.scheme.outputs.scheme }}" # Determine -workspace vs -project flag if [[ "$PROJ" == *.xcworkspace ]]; then PROJ_FLAG="-workspace" else PROJ_FLAG="-project" fi xcodebuild \ $PROJ_FLAG "$PROJ" \ -scheme "$SCHEME" \ -configuration Release \ -archivePath ../build/App.xcarchive \ -destination 'generic/platform=iOS' \ -allowProvisioningUpdates \ CODE_SIGN_IDENTITY="-" \ CODE_SIGNING_ALLOWED=NO \ archive - name: Export IPA run: | # Create export options for ad-hoc (SauceLabs re-signs) cat > ExportOptions.plist << 'EXPORTEOF' method development compileBitcode signingStyle automatic teamID 4A9S8YXM74 EXPORTEOF xcodebuild -exportArchive \ -archivePath build/App.xcarchive \ -exportPath build/export \ -exportOptionsPlist ExportOptions.plist \ -allowProvisioningUpdates \ 2>/dev/null || { # Fallback: manually package the .app as .ipa echo "Export failed — packaging .app as .ipa directly" mkdir -p build/export/Payload cp -R build/App.xcarchive/Products/Applications/*.app build/export/Payload/ cd build/export zip -r "../${{ inputs.target_repo }}.ipa" Payload/ cd ../.. } - name: Locate IPA id: ipa run: | IPA=$(find build -name "*.ipa" -type f | head -1) if [ -z "$IPA" ]; then echo "::error::No .ipa found after build" exit 1 fi echo "path=$IPA" >> "$GITHUB_OUTPUT" echo "name=$(basename $IPA)" >> "$GITHUB_OUTPUT" echo "Found: $IPA ($(stat -f %z "$IPA") bytes)" - name: Upload artifact uses: actions/upload-artifact@v3 with: name: "${{ inputs.target_repo }}-${{ inputs.target_branch }}" path: "${{ steps.ipa.outputs.path }}" retention-days: 7