In my previous article, I wrote about deploying a Flutter Web application on Github. Every time you submit your code, Github Actions will be triggered to complete the build and deployment of the Flutter Web. Is it also possible to build iOS packages automatically? The answer is yes, and this article explains how to build it.
Steps outlined
To achieve the goal of building a Flutter iOS package, you must perform the following steps:
- Install the Apple certificate and configuration file
- Specify the correct Flutter version
- Pull the flutter packages
- Building the application
- Sign it with the correct Apple certificate
- generate
.xarchive
- from
.xarchive
Generated in the.ipa
- Share it with your users
For a smooth build, we must provide:
- You can pack applescertificate(
.p12
), and the password for exporting the certificate - Certificate correspondingDescription file(
.mobileprovision
)
If you don’t know how to get a certificate and description file, please refer to this article: iOS Packaging Certificate Making.
All set, let’s get started!
What are GitHub Actions
GitHub Actions is GitHub’s continuous integration service, launched in October 2018.
As you know, continuous integration consists of many operations, such as grabbing code, running tests, logging into remote servers, publishing to third-party services, and so on. GitHub calls these actions actions.
Many operations are similar across projects and can be fully shared. GitHub noticed this and came up with the neat idea of allowing developers to write each action as a separate script file and store it in the repository so that other developers can reference it.
If you need an action, you don’t have to write a complex script, you can just refer to someone else’s action, and the whole continuous integration process becomes a combination of actions.
The basic concept
(1) Workflow: Continuous integration of a running process, that is, a workflow.
(2) Job: A Workflow consists of one or more jobs. It is a continuous integrated operation that can complete multiple tasks.
(3) Steps: Each job consists of multiple steps to be completed step by step.
(4) Action: Each step can execute one or more actions in turn.
For a quick look at GiHub Actions, see the GitHub Actions Tutorial
We’ll create a GitHub Action that lets you generate your IPA with one click.
Configuration making Actions
Let’s create our first workflow! In your project, you will need to create a workflows folder in the.github folder, and then create a new file called ios-release.yml.
The ios-release.yml file will contain our first job (job)build_ios:
name: Flutter_iOS
on:
push:
branches: [master]
jobs:
build_ios:
runs-on: macos-latest
steps:
- name: Checkout the code
uses: actions/checkout@v2
Copy the code
This job is triggered when you push new changes on the Master branch. Our first step is to check out the code for our branch.
Installing an Apple Certificate
Because the project is open source, packaging requires certificates, passwords, and description files that we don’t want to make public. At this time, we can make use of the secrets function provided by GitHub, which can safely store private content.
Since certificates and description files are file types and secrets store strings, we need to base64 the files as strings at this point. Concrete steps, can read the article “How to use environment variables and secrets using making Actions” (damienaicheh. Making. IO/lot/acti…
For example: base64 build_certificate. P12 | pbcopy
We will define the following keys:
.p12
The key of the certificate isP12_BASE64
- The key of the associated password is
P12_PASSWORD
- Description The file key is
PROVISIONING_PROFILE_BASE64
The next step is to install your Apple certificate, for which we will use an action from the community called Apple-Actions /import-codesign-certs@v1 and use the secrets we defined earlier
- name: Install Apple Certificate
uses: apple-actions/import-codesign-certs@v1
with:
p12-file-base64: The ${{ secrets.P12_BASE64 }}
p12-password: The ${{ secrets.P12_PASSWORD }}
Copy the code
To sign the application, we also need to install our description file:
- name: Install the provisioning profile
env:
PROVISIONING_CERTIFICATE_BASE64: The ${{ secrets.PROVISIONING_PROFILE_BASE64 }}
run: | PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
echo -n "$PROVISIONING_CERTIFICATE_BASE64" | base64 --decode --output $PP_PATH
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
Copy the code
As you can see above, this script has three operations:
- create
secrets
variable - from
secrets
Import description file - Configuration Description File
Build Flutter code
To be able to use Flutter in our workflow, we need to install it. To achieve this, we will use another action from the community:
- name: Install and set Flutter version
uses: Subosito/[email protected]
with:
flutter-version: '2.10.0'
Copy the code
We need to add this action and specify which version of Flutter we want to use. It is recommended to specify the exact version of flutter rather than using stable as the value to avoid potentially significant changes when a new stable version is released.
Now we can pull packages for our application:
- name: Restore packages
run: flutter pub get
Copy the code
Once they are retrieved, we can build the application in Release mode without signing it:
- name: Build Flutter
run: flutter build ios --release --no-codesign
Copy the code
We will install the certificate before applying the next step!
Generate xArchive
First, open your iOS project using XCode and select the target, and make sure that Automatically Manage Signing is not selected in Signing & Capabilities so that we can sign it using the required certificate, Without editing the XCode project.
Next, when you sign an iOS application, you don’t sign the pod associated with it, so you need to specify it in your Podfile, as follows:
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
config.build_settings['CODE_SIGNING_REQUIRED'] = "NO"
config.build_settings['CODE_SIGNING_ALLOWED'] = "NO"
end
end
end
Copy the code
Before we can build xArchive, we need to resolve the project’s Swift dependencies. This is especially useful if you have some Flutter iOS plugin written in Swift.
- name: Build resolve Swift dependencies
run: xcodebuild -resolvePackageDependencies -workspace ios/Runner.xcworkspace -scheme Runner -configuration Release
Copy the code
Now to create an XArchive, you need to find some information that can be found in your description file or Apple certificate:
- Development team identifier
- UUID, which is the identifier for your Provisioning Profile
- Code signature identification
After all this, we can use it like this:
- name: Build xArchive
run: | xcodebuild -workspace ios/Runner.xcworkspace -scheme Runner -configuration Release DEVELOPMENT_TEAM=YOUR_TEAM_ID -sdk 'iphoneos' -destination 'generic/platform=iOS' -archivePath build-output/app.xcarchive PROVISIONING_PROFILE=YOUR_UUID clean archive CODE_SIGN_IDENTITY="Apple Distribution: Damien Aicheh"Copy the code
Generation of ipa
Using the generated XArchive, we can export it as ipA. To do this, we need to add a new file in the project called exportoptions.plist to specify the ExportOptions.
<! DOCTYPEplist PUBLIC "- / / / / DTD PLIST Apple 1.0 / / EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>app-store</string> <! -- app-store, ad-hoc, enterprise, development -->
<key>teamID</key>
<string>YOUR_TEAM_ID</string>
<key>signingStyle</key>
<string>manual</string>
<key>provisioningProfiles</key>
<dict>
<key>YOUR_BUNDLE_ID</key>
<string>YOUR_UUID</string>
</dict>
</dict>
</plist>
Copy the code
Depending on your project configuration, you may need to add more options to this file. If desired, you can create an exportOptions.plist file for each environment of the project.
Then simply run this command line and your IPA will generate:
- name: Export ipa
run: xcodebuild -exportArchive -archivePath build-output/app.xcarchive -exportPath build-output/ios -exportOptionsPlist ios/ExportOptions.plist
Copy the code
Release the product
To access the generated IPA from the GitHub interface, let’s add one final action:
- name: Publish iOS Artefacts
uses: actions/upload-artifact@v1
with:
name: release-ios
path: build-output/ios
Copy the code
This will release the ios folder containing our IPA. You can then install it on your device.
The last
Now you can share your application with users based on the context of your project! You’ll find sample code in this Github: flutter_BEST_practice.
Refer to the
- How to build and sign your Flutter iOS application using GitHub Actions
- How to use environment variables and secrets using GitHub Actions
- Install the Apple certificate on the macOS runner for Xcode development