Skip to main content

Building for iOS

If you use GitHub to host your code then you can use GitHub Actions to build your app for iOS. This is the first step in automating the deployment of your app to the App Store.

The following tutorial shows you how you can create a workflow file which will be run when you commit code.

  1. Create a .github/workflows directory in your project's root.
  2. Create a file called app-ios.yml with the following content:

_69
name: Build iOS
_69
_69
on:
_69
push:
_69
branches: [ "main" ]
_69
pull_request:
_69
branches: [ "main" ]
_69
_69
jobs:
_69
build:
_69
runs-on: macos-13
_69
name: Build iOS app
_69
steps:
_69
- name: Checkout source
_69
uses: actions/checkout@v4
_69
_69
- name: Install the Apple certificate and provisioning profile
_69
env:
_69
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
_69
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
_69
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }}
_69
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
_69
run: |
_69
# create variables
_69
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
_69
PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
_69
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
_69
_69
# import certificate and provisioning profile from secrets
_69
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
_69
echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH
_69
_69
# create temporary keychain
_69
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
_69
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
_69
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
_69
_69
# import certificate to keychain
_69
security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
_69
security list-keychain -d user -s $KEYCHAIN_PATH
_69
_69
# apply provisioning profile
_69
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
_69
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
_69
_69
- name: Set up XCode
_69
uses: maxim-lobanov/setup-xcode@v1
_69
with:
_69
xcode-version: latest
_69
_69
- name: Setup Node.js
_69
uses: actions/setup-node@v4
_69
with:
_69
node-version: 20.x
_69
_69
- name: Install app dependencies
_69
run: npm install
_69
_69
- name: Build project app
_69
run: npm run build
_69
_69
- name: Capacitor sync
_69
run: npx cap sync
_69
_69
- name: Build project
_69
run: xcodebuild -workspace './ios/App/App.xcworkspace' -scheme App -destination generic/platform=iOS -archivePath App.xcarchive archive
_69
_69
- name: Create binary (.ipa)
_69
run: xcodebuild archive -archivePath App.xcarchive -exportArchive -exportOptionsPlist ./ios/archive.plist -exportPath output -allowProvisioningUpdates

This workflow has several variables that you need to setup in your repository secrets. In your GitHub repo go to Settings > Secrets & Variables > Actions > New repository secret:

Export the Certificate

  1. In Xcode, go the Xcode menu > Settings... > Accounts > Manage Certificates... button.
  2. Right click the Distribution certificate and select Export Certificate.
  3. Save the .p12 file as app.p12 and enter a password.
  4. The P12_PASSWORD secret is the password you used to export the certificate.

To create the BUILD_CERTIFICATE_BASE64 secret run the following command:


_10
base64 -i app.p12 | pbcopy

The contents of the p12 are now in the clipboard and you can paste it into the BUILD_CERTIFICATE_BASE64 secret.

Create the Provisioning Profile

Sign into the Apple Developer Portal

  • Go to Certificates, Identifiers & Profiles > Profiles.
  • Click the + button
  • Choose the App Store Connect distribution option and click Continue.
  • Select your app and click Continue.
  • Select the distribution certificate and click Continue.
  • Give the profile a name and click Generate.
  • Save the profile as profile.mobileprovision..

To create the BUILD_PROVISION_PROFILE_BASE64 secret run the following command:


_10
base64 -i profile.mobileprovision | pbcopy

The contents of the provisioning profile are now in the clipboard and you can paste it into the BUILD_PROVISION_PROFILE_BASE64 secret.

Create a Keychain Password

Create a random password and save it as KEYCHAIN_PASSWORD in your repository secrets.

Create an archive.plist

You will need to create a file called archive.plist in your ios folder with the following content:


_13
<?xml version="1.0" encoding="UTF-8"?>
_13
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
_13
<plist version="1.0">
_13
<dict>
_13
<key>method</key>
_13
<string>app-store</string>
_13
<key>provisioningProfiles</key>
_13
<dict>
_13
<key>[your-bundle-id]</key>
_13
<string>[provisioning-profile-name]</string>
_13
</dict>
_13
</dict>
_13
</plist>

You must replace [your-bundle-id] with your bundle id. Replace [provisioning-profile-name] with the name of the provisioning profile you created.

The xcodebuild archive command uses this file to create the .ipa file.

Summary

The build process with GitHub Actions should now have all the required variables to build your app.

Note: Review the build steps for your app. For example, the step to build the app is running npm run build but you may want to alter this step to create a production build.

The next tutorial shows how you can expand on this workflow to send the build to TestFlight.