Skip to content

ahmdmhasn/xcode-cloud-dispatch-action

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 

Repository files navigation

Xcode Cloud Dispatcher Action 🚀

A lightweight, professional GitHub Action to manually trigger Xcode Cloud builds for Flutter and Native iOS projects. It automatically detects your marketing version and returns a direct deep-link to the build summary in App Store Connect.

Features

  • 📱 Universal Support: Works out-of-the-box for Flutter (pubspec.yaml) and Native iOS (MARKETING_VERSION or CFBundleShortVersionString).
  • 🔗 Deep Linking: Generates a direct URL to the specific build run (requires Team/App ID).
  • 🔑 Automated Auth: Handles ES256 JWT generation for the App Store Connect API.
  • 🛠 Flexible: Optionally provide a custom project_path or info_plist_path for version detection.
  • 💬 PR Optimized: Designed to update PR comments for a seamless developer experience.

Usage

Create a workflow file (e.g., .github/workflows/xcode_cloud.yml) in your repository. This example triggers the build when a user comments /build on a Pull Request.

name: Xcode Cloud Dispatch
on:
  issue_comment:
    types: [created]

jobs:
  dispatch:
    # Only run if it's a PR comment and the command is exactly /build
    if: github.event.issue.pull_request && github.event.comment.body == '/build'
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4
        with:
          # Targets the PR branch head
          ref: ${{ format('refs/pull/{0}/head', github.event.issue.number) }}

      - name: Trigger Xcode Cloud
        id: xcode
        uses: ahmdmhasn/xcode-cloud-dispatch-action@v0.2
        with:
          apple_key_id: ${{ secrets.APPSTORE_KEY_ID }}
          apple_issuer_id: ${{ secrets.APPSTORE_ISSUER_ID }}
          apple_private_key: ${{ secrets.APPSTORE_PRIVATE_KEY }}
          workflow_id: ${{ vars.XCODE_CLOUD_WORKFLOW_ID }}
          # Providing these enables the deep-link output
          team_id: "your-team-uuid"
          app_id: "your-app-id"

      - name: Feedback to PR
        if: always()
        run: |
          VERSION="${{ steps.xcode.outputs.marketing_version }}"
          BUILD="${{ steps.xcode.outputs.build_number }}"
          URL="${{ steps.xcode.outputs.build_url }}"
          
          MSG="🚀 **Xcode Cloud Build Started**"
          if [[ -n "$VERSION" ]]; then MSG="$MSG\n**Version:** \`$VERSION\`"; fi
          MSG="$MSG\n**Build:** \`$BUILD\`\n\n[View Build Summary]($URL)"

          # Updates the original /build comment with the results
          gh comment edit "${{ github.event.comment.id }}" --body "${{ github.event.comment.body }}\n\n> $MSG"
        env:
          GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}"

Inputs

Input Description Required Default
apple_key_id App Store Connect API Key ID (e.g., 2X9....) Yes -
apple_issuer_id App Store Connect Issuer ID (UUID) Yes -
apple_private_key The content of your .p8 private key file Yes -
workflow_id The Xcode Cloud Workflow ID from App Store Connect Yes -
project_path Path to your .xcodeproj (e.g., ios/Runner.xcodeproj). Used to read MARKETING_VERSION from project.pbxproj. No Auto-detected
info_plist_path Path to your Info.plist. Use this for projects where CFBundleShortVersionString is a hardcoded string rather than $(MARKETING_VERSION). No -
branch Branch name to build (e.g., main, tech/my-feature). If omitted, Xcode Cloud uses the default branch configured in the workflow. No -
team_id Your App Store Connect Team ID (UUID) No -
app_id Your Apple App ID (10-digit number) No -

Outputs

Output Description
build_number The integer build number assigned by Apple (e.g., 42)
marketing_version The version detected (e.g., 1.2.0)
build_url A direct link to the build summary or general dashboard

Setup Tips

  1. Private Key: When adding your APPLE_PRIVATE_KEY to GitHub Secrets, paste the entire content including -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY-----.
  2. Workflow ID: You can find this in App Store Connect under the "Xcode Cloud" tab in your App settings.
  3. Permissions: Ensure your App Store Connect API Key has at least Developer or App Manager access.
  4. Version Detection: The action detects your version in this order:
    • Flutter: reads version from pubspec.yaml
    • Native (modern): reads MARKETING_VERSION from project.pbxproj — either auto-detected or via project_path
    • Native (legacy): if your project hardcodes the version directly in Info.plist, provide info_plist_path and the action will read CFBundleShortVersionString via plutil

Known Limitations

  • Apple Rate Limit: Apple enforces a limit of 22 builds per app per 24 hours for TestFlight and App Store uploads. Triggering too many builds in a short window will result in rejected uploads. Plan your CI usage accordingly.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages