Using Appflow CLI with Azure DevOps
Appflow CLI is available to our enterprise customers only. Please contact us for more information.
Introduction
You can utilize Live Updates, Native Builds, and App Store Publishing from the Appflow CLI inside an Azure DevOps Pipeline.
This example will walk you through setting up a pipeline in Azure DevOps that takes you repo, performs an iOS Build for TestFlight, saves it to Azure DevOps as an artifact, and then pushes it directly to TestFlight.
Requirements
For this example, we've already done the following in our Appflow dashboard:
- Set up a Personal Access Token
- Connected our Azure DevOps Repo to an Appflow App
- Created a Signing Credential for iOS App Store (Production), and added to Appflow as "TestFlight"
- Added an App Store Destination as "TestFlight"
Creating a Pipeline
Navigate to the Pipelines section of your Azure DevOps dashboard and click "New Pipeline." For this example we're choosing "Azure Repos Git" as our repository, and "Starter pipeline" as the default configuration.
Writing our Pipeline
Once we've created our pipeline, we'll be dropped into the Pipeline editor, which looks like this:
The first thing we'll want to do is add our Personal Access Token as a Variable. Click on "Variables" in the top right, and set up a new Variable with the name IONIC_TOKEN
and the value of your PAT. Mark this variable as a Secret, then click OK.
Now that we have access to our IONIC_TOKEN
we can write a pipeline. The steps for this example are going to be:
- Install Appflow CLI
- Run an iOS build in Appflow
- Publish our IPA file as an artifact in Azure DevOps
- Deploy to TestFlight in Appflow
Be sure to replace AppIdEx123abc
with your actual App ID from the Appflow Dashboard. You can find this by opening your app in Appflow and looking under its name in the top left.
Full yaml Script
# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms /yaml
trigger:
- main
pool:
vmImage: ubuntu-latest
variables:
- name: iosbuildid
steps:
- script: curl -fsSL https://ionic.io/get-appflow-cli | bash
displayName: 'Install Appflow CLI'
- script: |
set -e -o pipefail
BUILDID=$(appflow build ios app-store --app-id AppIdEx123abc --commit $(Build.SourceVersion) --signing-cert "TestFlight" --ipa-name "app.ipa" --json --token $(IONIC_TOKEN) | jq -r '.buildId')
echo "##vso[task.setvariable variable=iosbuildid]$BUILDID"
displayName: 'Run an iOS build in Appflow'
failOnStderr: false
- publish: $(System.DefaultWorkingDirectory)/app.ipa
artifact: iOSApp
- script: |
appflow deploy ios --app-id AppIdEx123abc --build-id $(iosbuildid) --destination "TestFlight" --token $(IONIC_TOKEN)
displayName: 'Deploy to TestFlight in Appflow'
Add a Pipeline Variable
Let's walk through this pipeline step by step. First we added a variable:
variables:
- name: iosbuildid
We'll use this variable later to store the build ID that came back from our iOS build, so that we can deploy it.
Appflow CLI Installation
Then we installed the Appflow CLI:
steps:
- script: curl -fsSL https://ionic.io/get-appflow-cli | bash
displayName: 'Install Appflow CLI'
Locking the Appflow CLI Version
If you'd like to lock the version of Appflow CLI in place for your pipeline, use the following command to install the Appflow CLI instead, replacing X.X.X
with your desired version number:
export APPFLOW_VERSION=X.X.X; curl -fsSL https://ionic.io/get-appflow-cli | bash
Perform an iOS Build
After that we added a multiline Step that does a few different things. The primary part of this command is appflow build ios app-store --app-id AppIdEx123abc --commit $(Build.SourceVersion) --signing-cert "TestFlight" --ipa-name "app.ipa" --json --token $(IONIC_TOKEN)
which actually performed the build.
We included | jq -r '.buildId'
after that to parse the Build ID from Appflow out of the responses JSON, so that we can store it.
Then we wrapped everything up in a BUILDID=$( )
to save the return value to the system. The next line echo "##vso[task.setvariable variable=iosbuildid]$BUILDID"
saves BUILDID
to the pipeline variable iosbuildid
that we set up earlier, so that we can use it in the deployment step.
We include set -e -o pipefail
and failOnStderr: false
to ensure that errors correctly fail the task and we can still get --json
output.
- script: |
set -e -o pipefail
BUILDID=$(appflow build ios app-store --app-id AppIdEx123abc --commit $(Build.SourceVersion) --signing-cert "TestFlight" --ipa-name "app.ipa" --json --token $(IONIC_TOKEN) | jq -r '.buildId')
echo "##vso[task.setvariable variable=iosbuildid]$BUILDID"
displayName: 'Run an iOS build in Appflow'
failOnStderr: false
Save an Artifact
Since our previous step included --ipa-name "app.ipa"
our IPA file was automatically downloaded and renamed. Let's utilize Azure DevOps publish artifact system to save this file as an artifact.
- publish: $(System.DefaultWorkingDirectory)/app.ipa
artifact: iOSApp
Deploy to TestFlight
Finally, we utilize the iosbuildid
pipeline variable inside of our deployment command to take this build and automatically push it to App Store Connect for use in TestFlight.
- script: |
appflow deploy ios --app-id AppIdEx123abc --build-id $(iosbuildid) --destination "TestFlight" --token $(IONIC_TOKEN)
displayName: 'Deploy to TestFlight in Appflow'
Save and Run
When you save this pipeline, it will automatically run! You should see all build output and errors ported directly back to your Azure DevOps dashboard like so:
Next Steps
This example walked through setting up an iOS build automated through to Testflight, but you can also create Pipelines
for Android builds, or Live Updates. See the other Appflow CLI documentation or run appflow --help
to learn more
about what functions are available in the Appflow CLI.