In the last part we created a build using the pipeline feature of Azure DevOps. In this tutorial we are going to use the Azure’s Release pipeline to push the build to the App Store. This is the continuous deployment part of CI/CD.
Open your project on DevOps and select “Releases” under the “Pipelines” section in the left panel. Select the “New Pipeline” which will open up a dialog for selecting a template.
Template Selection & Setup

We are going to select an empty job, since there is no pre-defined template for uploading a build to the App Store.
Enter the stage name as “Deployment”. It can be whatever you want but for clarification purposes I set it as Deployment.
We will now select an Artifact which we want to upload. An artifact is something that is created whan an Azure Build Pipeline runs. So in our case the artifact is the one that is generated from our previous tutorial.
Click the Add button besides the Artifacts label or click on Add an artifact. This will open a new dialog on the right.
In the drop down you will see our CI setup from the last tutorial. Select that and click the Add button.
After adding the artifact our release pipeline will look something like below.
Now select the lightning icon for the artifact we just added. This will open a dialog on the right which will have a setting to enable/disable the Continuous Deployment trigger. When the build trigger is enabled our release pipeline will automatically start when a new build is completed by our build (CI) pipeline. We are not going to enable the Pull Request trigger.
So far we have setup the pipeline to start automatically when a new build is available in our build pipeline. We have also setup a Deployment stage to which we will add tasks for the actual deployment in the next section.
Deployment task
Select 1 job 0 task hyperlink which will switch to the Tasks tab. Select the + plus besides the Agent Job to open a list of new tasks. Search for Apple App Store. If you don’t see any tasks you will have to install the application from the Marketplace. Once installed when you search for Apple App Store again you will see a couple of new tasks as below.
Add the Apple App Store Release task. It will add the task which requires a Service Connection. A service connection is basically a connection to the Apple’s itunesconnect website.
We will now add a new service connection. Click on the New button besides Service Connection which will open a new dialog. In the new dialog enter the email & password. Even though the app-specific password and Fastlane Session are marked as optional they are mandatory to automate the process of uploading the build to App Store.
App-Specific Password
To create app-specific password visit appleid.apple.com/account/manage in a new tab and scroll down to the security section. Click on the Generate password… link below the label APP-SPECIFIC PASSWORDS which will open a dialog. Enter any name for the label and click Create. Copy the generated text and switch back to our Azure DevOps tab and paste it under App-specific password field.
Fastlane Session token
As a prerequisite you should already have the fastlane installed on your machine. Fastlane is required to generate the session token so that our cloud machine can login automatically without our intervention. Time to open the terminal and fire some commands.
fastlane spaceauth -u [email protected]
You will will be asked for your password and then a 6 digit code as a part of two factor authentication. It will generate the session token for you and will ask if you want to copy it. Press ‘y’ and then switch to your Azure DevOps tab and paste the session token in the Fastlane Session field.
Enter the service connection name as per your preference and the description if you need it.

Publish details
You will see the service connection now set. Next enter your app’s bundle id. Select Skip Build Processing Wait and Skip Submission so that our pipeline doesn’t wait for the build to be made available, otherwise it will consume precious build minutes. Lastly enter the App Specific Apple Id which you can get by logging into https://appstoreconnect.apple.com and clicking your App to view it’s details and then finally visiting App Information under General section.

That is it guys. Your hard work will finally pay off when you run your pipeline and see the green ticks going one by one as the tasks are getting completed. This would be one of the best feeling in the world.
Do you have any suggestions, optimisation and/or just want to connect let me know in the comments below.
Hi Sir, I have followed your each step for CI/CD but my Ci part is failed and shown below error.
The following build commands failed:
CompileSwift normal arm64
CompileSwiftSources normal arm64 com.apple.xcode.tools.swift.compiler
I am using Apple M1 chip.
Please help me to sort out this issue. Thanks in advance.
Hello arjavdave, how you doing?!
On line ‘fastlane spaceship -u [email protected]‘ I guess you should say
‘fastlane spaceauth -u [email protected]‘ right?
Tks I lot for you tutorial, It help me!!!
Thank you so much
hi Rubens, Thanks for pointing it out. I have fixed it.
Hi sir,
Can we self-hosted agent.if we can part-2 is suitable for that too if not can i know process to self-hosted apple build…?
Thanks in Advance
Hi Kalyan,
I don’t see any reason why this won’t work on a self hosted agent. Make sure you use a Mac for a self hosted agent.
followed same step but getting error : Directory ‘/Users/runner/work/1/a’ is empty. Nothing will be added to build artifact ‘drop’. please help me out.
Kalyan, Have you selected “Create app package” in the “Xcode Build” task while running a build (CI) pipeline?
yes sir having Provisioning profile “XXXXX.com.tXl” doesn’t include signing certificate “Apple Distribution:XXXXXX(XXXX)”. (in target ‘XXX’ from project ‘XXXX’)
Hi arjavdave,
Thanks for the blog its helped me alot with brief explanation.
Hello. This works, but the fastlane session expires in a couple of hours. I have to regenerate it (spaceauth) and replace the one in the service connection before every release, or else, it will fail. Is there any workaround for this?
Unfortunately there is no work around for this. That is how apple has setup the security.
Hi arjavdave,
Great job on the blog!
Thank you for the detailed explanation. I have everything setup and when I am trying to run the Release task, I keep getting this error – “Error: The Apple app Store Release task can only run on a Mac Computer”. I am running all these tasks on my MacBook Pro. Am I missing anything here?
Thanks
Josh
Hey arjavdave thks so much for both guides part 1 and part 2, I have a angular app using capacitor, i manage to use majority of your steps i have a lot issue in some of them in the part 1 (capacitor specific).
I want to ask you a question do you know how can we control the version number with the CI? At the moment manual what i do is, i open the app in xcode and change the version number before I manually archive and then i sent to Apple Connect.
Let me know if you can give a hand on that.
Hi arjavdave,
Great job on the blog!
Thank you for the detailed explanation. I have everything setup and when I am trying to run the Release task, I keep getting this error – “Error: The Apple app Store Release task can only run on a Mac Computer”. I am running all these tasks on my MacBook Pro. Am I missing anything here? Please can you help me.
Thanks
Shailaja