Press ESC to close

CI/CD With Code Magic

Hello friends, in this article I will talk about the CI/CD tool I use in my native iOS applications developed with Swift. While writing this article, I will proceed by talking about previous experiences, but first let me talk about why I use the CI/CD tool;

  • If you have more than one project and you are actively developing and updating these projects, it will save you from a huge loss of time. Each archive operation takes between 10 and 20 minutes, depending on the speed of your computer.
  • If you like to try new technologies but have to go live at the same time, you have to use stable Xcode versions. For example, I use Sonoma as the operating system and it supports minimum Xcode 15. When you try to archive in the first version of Xcode 15, Xcode crashes. In order to avoid being affected by such situations, the machine you build must be stable. I can easily handle it with this CI/CD tool.
  • When a new commit comes to the branch or a new Tag is added, I can trigger it and start the entire process automatically.
  • If you work in a multi-team, you can do this work with remote machines without having to leave it to someone else.

I use the CI/CD tool for this and many other reasons.

My Previous Experiences

I had experience with different tools before. The one I use most is AppCenter. I had a very good relationship with AppCenter up to a certain point. We used it actively for approximately 4 years. Both in my old company and in my own projects. Adding certificates, creating a project, adding profiles, keystore files, distributing everything could be done very easily. It could easily compile your Xamarin projects or your native projects. When you created an organization for each application, it gave you a build time of 4 hours per month. Even though the machines were a little old, he could build them. So why did I look for a new tool?

I no longer needed to compile Xamarin projects. So I was free from AppCenter addiction. I’ve been in the industry for 6 years and they haven’t even changed color one day 😄 and the SPM packages in my projects I developed with Swift were always in resolve status. In the free plan, there was a 30-minute timeout period. After 30 minutes, it remained in this status and the build failed. For these reasons, I decided to leave AppCenter.

Why CodeMagic

When looking for a new CI/CD tool, the first thing to do was to have a free plan. I didn’t want it to create any extra costs. For this reason, I eliminated Bitrise. I could use Xcode Cloud, but it will be paid in 2024 and I wanted to use it in my Android projects as well. By the way, you can also access the article I wrote about Xcode Cloud here. When I tried Circle CI, I found it difficult to use. That’s why I turned to CodeMagic. Being able to build M1 devices for free with CodeMagic was one of the points that attracted me. If you want to get more information, you can find it here.

How to use?

First, it asks you to create a project for CI/CD. Then, you must provide the source codes of your project to this CodeMagic project. For this, you must create a yaml file after granting access. With this yaml file, you can actually adjust your Xcode version, cocoapods version, maximum build time, profiles and many other things. I created and used the following yaml file in my own project and it has worked for me so far. You can also edit and use it as you wish.

 

workflows:
    ios-native-workflow:
      name: iOS Native
      integrations:
        app_store_connect: CodeMagic
      max_build_duration: 120
      instance_type: mac_mini_m1
      environment:
        xcode: latest
        cocoapods: default
        ios_signing:
          distribution_type: app_store # or: ad_hoc | development | enterprise
          provisioning_profiles:
            - Project_Profile
            - Project_Profile_2
          certificates:
            - Project_Certificate
        vars:
          BUNDLE_ID: "com.sezeromer.id"
          XCODE_WORKSPACE: "Project Name.xcworkspace"  # <-- Name of your Xcode workspace
          XCODE_SCHEME: "Scheme Name" # <-- Name of your Xcode scheme
      scripts:
        - name: Install CocoaPods dependencies
          script: pod install
        - name: Set up provisioning profiles settings on Xcode project
          script: xcode-project use-profiles
        - name: Build ipa for distribution
          script: |
                xcode-project build-ipa \
                --workspace "$CM_BUILD_DIR/$XCODE_WORKSPACE" \
                --scheme "$XCODE_SCHEME"
      artifacts:
        - build/ios/ipa/*.ipa
        - /tmp/xcodebuild_logs/*.log
        - $HOME/Library/Developer/Xcode/DerivedData/**/Build/**/*.app
        - $HOME/Library/Developer/Xcode/DerivedData/**/Build/**/*.dSYM
      publishing:
        email:
          recipients:
            - oomersezer@gmail.com
          notify:
            success: true
            failure: true

        app_store_connect:
          auth: integration

        # Configuration related to TestFlight (optional)
        # Note: This action is performed during post-processing.
          submit_to_testflight: true

            # Optional boolean, defaults to false. Set to true to automatically expire
        # previous build in review or waiting for review in Testflight before
        # submitting a new build to beta review. Expired builds will no longer be available for testers.
        # Note: This action is performed during post-processing.
          expire_build_submitted_for_review: true


        # beta_groups: # Specify the names of beta tester groups that will get access to the build once it has passed beta review.
        #  - group name 1
            # - group name 2

        # Configuration related to App Store (optional)
        # Note: This action is performed during post-processing.
          submit_to_app_store: true

        # Optional boolean, defaults to false. Set to true to cancel the previous
        # submission (if applicable) when submitting a new build to App Store review.
        # This allows automatically submitting a new build for review if a previous submission exists.
        # Note: This action is performed during post-processing.
          cancel_previous_submissions: true

        # Optional, defaults to MANUAL. Supported values: MANUAL, AFTER_APPROVAL or SCHEDULED
          release_type: MANUAL

If you have questions, you can reach us by e-mail or comment. As I experience more, I will come back with new articles. Enjoy your work.

Leave a Reply

Your email address will not be published. Required fields are marked *