{"id":70190,"date":"2025-03-30T13:14:33","date_gmt":"2025-03-30T07:44:33","guid":{"rendered":"https:\/\/www.tothenew.com\/blog\/?p=70190"},"modified":"2025-04-03T10:05:35","modified_gmt":"2025-04-03T04:35:35","slug":"ios-ci-cd-integration-via-fastlane-firebase-using-gitlab-part-3","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/ios-ci-cd-integration-via-fastlane-firebase-using-gitlab-part-3\/","title":{"rendered":"iOS: CI\/CD Integration via FastLane &amp; Firebase using Gitlab : Part \u2013 3"},"content":{"rendered":"<p><span style=\"font-weight: 400;\"><br \/>\nIn the <span style=\"color: #d71b7f;\"><a style=\"color: #d71b7f;\" href=\"https:\/\/www.tothenew.com\/blog\/ios-ci-cd-integration-using-gitlab-fastlane-firebase-part-1-page-2\/\">second part of the blog<\/a><\/span>, we covered the Code Signing approach via the match import command and created a separate repository and uploaded the private keys and certificates in a Gitlab repo for syncing them across the machines. Now we are moving to the next part of this series where we will use CI\/CD workflow via Fastlane &amp; Firebase with Gitlab Actions.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">We will use the next step to create and run your first GitLab CI CD pipeline:-<\/span><\/p>\n<p>1.Create <span style=\"color: #999999;\"><em>.gitlab-ci.yml<\/em><\/span> file.<br \/>\n2. Check the status of your pipeline and jobs.<br \/>\n3. Check the available runner or create a runner.<br \/>\n4. Edit the yml file and delete <span style=\"color: #999999;\"><em>.gitlab-ci.yml<\/em><\/span> file.<\/p>\n<p><strong>Before you begin<\/strong><\/p>\n<p><span style=\"font-weight: 400;\">We are considering that you have access to the details below:<\/span><\/p>\n<ul>\n<li>A GitLab account with access to CI\/CD pipelines.<\/li>\n<li>Your iOS project code is in a GitLab repository.<\/li>\n<li>An Apple Developer account.<\/li>\n<li><span style=\"color: #d71b7f;\"><a style=\"color: #d71b7f;\" href=\"https:\/\/docs.fastlane.tools\/getting-started\/ios\/setup\/\">fastlane<\/a><\/span> is installed locally.<\/li>\n<\/ul>\n<h2><b><br \/>\nGet started with GitLab CI\/CD<br \/>\n<\/b><\/h2>\n<p><span style=\"font-weight: 400;\"><br \/>\nTo use <span style=\"color: #d71b7f;\"><a style=\"color: #d71b7f;\" href=\"https:\/\/docs.gitlab.com\/ci\/\">GitLab CI\/CD<\/a><\/span>, you start with a <span style=\"color: #999999;\"><em>.gitlab-ci.yml<\/em><\/span> file at the root of your project. This file specifies the stages, jobs, and scripts to be executed during your CI\/CD pipeline. It is a YML file with its own custom syntax.<\/span><\/p>\n<p><span style=\"font-weight: 400;\"><br \/>\n<strong>Step 1: Create a <span style=\"color: #999999;\"><em>.gitlab-ci.yml<\/em><\/span> file<\/strong><br \/>\n<\/span><\/p>\n<p>You have to create a YML file in your repository. A YML file where you specify instructions for GitLab CI\/CD. There are two ways to add the YML file in your project as follows-<\/p>\n<p>a) Manually <span style=\"color: #999999;\"><em>(.yml)<\/em><\/span> file creation: <strong>New File<\/strong><\/p>\n<p>Now create a <span style=\"color: #999999;\"><em>.gitlab-ci.yml<\/em><\/span> file: Go to specific project -&gt; in left side bar -&gt; Code &gt; Repository.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/1-1.png\" alt=\"Repository image\" width=\"729\" height=\"445\" \/><\/p>\n<p>Select the branch which you want to commit to. Then select the plus icon and click on New file.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/2-1.png\" alt=\"Add new file\" width=\"732\" height=\"451\" \/><\/p>\n<p>Enter the Filename <span style=\"color: #999999;\"><em>.gitlab-ci.yml<\/em><\/span> and write down code in the file.<\/p>\n<p>Or<\/p>\n<p>b) Choose template: <strong>iOS with Fastlane<\/strong><\/p>\n<p>To Integrate the template type like <strong>iOS with Fastlane<\/strong>: Go to specific project -&gt; in left side bar -&gt; Build &gt; Pipelines.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/3-2.png\" alt=\"Choose template\" width=\"738\" height=\"455\" \/><\/p>\n<p>Select the template which you want to integrate to it. Then select the iOS with Fastlane and click on Use template.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/4.png\" alt=\"Pipeline editor\" width=\"744\" height=\"458\" \/><\/p>\n<p>The template will add some code by default in the file. Click on Commit changes.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/5.png\" alt=\"Commit changes\" width=\"744\" height=\"188\" \/><\/p>\n<p>When you commit the changes then the pipeline will start and runs the jobs.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/6-1.png\" alt=\"Pipeline start\" width=\"749\" height=\"459\" \/><\/p>\n<p><span style=\"font-weight: 400;\"><br \/>\n<strong>Step 2: To check the status of your pipeline and job<\/strong><br \/>\n<\/span><\/p>\n<p>Go to Project -&gt; build -&gt; pipelines.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/7-2.png\" alt=\"Job status check\" width=\"754\" height=\"464\" \/><\/p>\n<p>A pipeline with defined stages should be displayed:<\/p>\n<p>To view a visual representation of your pipeline by selecting the pipeline ID-<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/8-1.png\" alt=\"Pipeline details\" width=\"755\" height=\"465\" \/><\/p>\n<p>To view details of a job by selecting the job name. You can see build.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/9.png\" alt=\"Job detail 1\" width=\"753\" height=\"464\" \/><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/10-1.png\" alt=\"Job details 2\" width=\"753\" height=\"464\" \/><\/p>\n<p>As we can see the job is executed and fails due to some reason. Don\u2019t worry about the failed status (there can be multiple reasons to fail a job like an incorrect executor selected by default, etc). By default, Gitlab will pick the available executor(docker-machine) to execute the job if not specified the executor explicitly.<\/p>\n<p>In this blog, we will use the Gitlab Runner to execute your job.<\/p>\n<p><span style=\"font-weight: 400;\"><br \/>\n<strong>Step 3: To Check available runner or Create runner<\/strong><br \/>\n<\/span><\/p>\n<p>Go to particular <strong>Project -&gt;Settings -&gt; CI\/CD -&gt;Runner<\/strong> and <strong>expand Runners.<\/strong><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/11-1.png\" alt=\"Project runner page\" width=\"755\" height=\"450\" \/><\/p>\n<p>Minimum one runner is active with a green color next to it, to process your jobs.<\/p>\n<p><span style=\"font-weight: 400;\"><br \/>\n<span style=\"color: #d71b7f;\"><a style=\"color: #d71b7f;\" href=\"https:\/\/docs.gitlab.com\/ci\/\">Runners<\/a><\/span> are the agents that run your jobs. These agents can run on physical machines or virtual instances. In your <span style=\"color: #999999;\"><em>.gitlab-ci.yml<\/em><\/span> file, you can specify a container image you want to use when running the job. The runner loads the image, clones your project, and runs the job either locally or in the container.<br \/>\n<\/span><\/p>\n<p>In this blog, We will create a Gitlab runner from scratch.<\/p>\n<h2>The next step is to register the Gitlab runner.<\/h2>\n<p>Click on New project runner under the <strong>Runner section -&gt;project runner:-<\/strong><\/p>\n<p>You can add the some basic details as per required for the configurations tag as \u2018ios-tag, shell\u2019 and runner description as \u2018ios-runner\u2019-<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/11-1-1.png\" alt=\"New project runner page\" width=\"755\" height=\"451\" \/><\/p>\n<p>Click on Create runner post filling the details, Runner is created successfully now. Then, you will be asked for some more details like platform &#8211; <em>Operating systems, Cloud, Containers<\/em>.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/11-2.png\" alt=\"Runner created\" width=\"757\" height=\"460\" \/><\/p>\n<p>In this blog, we will choose the Operating system \u2018macOS\u2019 as a platform.<\/p>\n<p><strong>Important:<\/strong> GitLab Runner must be installed before you can register a runner.<\/p>\n<h3><span style=\"text-decoration: underline;\"><span style=\"color: #d71b7f;\"><a style=\"color: #d71b7f; text-decoration: underline;\" href=\"https:\/\/docs.gitlab.com\/runner\/install\/osx\/\">Installing Gitlab Runner<\/a><\/span><\/span><\/h3>\n<p>The GitLab Runner is a service that\u2019s installed on your Mac, which runs the build and test process that you set up in a configuration file(<span style=\"color: #999999;\"><em>.gitlab-ci.yml<\/em><\/span>).<\/p>\n<ol>\n<li>Download the binary for your system:<\/li>\n<\/ol>\n<ul>\n<li>For Intel-based systems:<\/li>\n<\/ul>\n<pre><span style=\"font-weight: 400;\">$ sudo curl --output \/usr\/local\/bin\/gitlab-runner \"https:\/\/s3.dualstack.us-east-1.amazonaws.com\/gitlab-runner-downloads\/latest\/binaries\/gitlab-runner-darwin-amd64\"<\/span>\r\n<\/pre>\n<ul>\n<li>For Apple Silicon-based systems:<\/li>\n<\/ul>\n<pre><span style=\"font-weight: 400;\">$ sudo curl --output \/usr\/local\/bin\/gitlab-runner \"https:\/\/s3.dualstack.us-east-1.amazonaws.com\/gitlab-runner-downloads\/latest\/binaries\/gitlab-runner-darwin-arm64\"<\/span>\r\n<\/pre>\n<p>2. Give it permissions to execute:<\/p>\n<pre><span style=\"font-weight: 400;\">$ sudo chmod +x \/usr\/local\/bin\/gitlab-runner\r\n<\/span>\r\n<\/pre>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/11-3.png\" alt=\"Installing gitlab runner\" width=\"770\" height=\"102\" \/><\/p>\n<p><strong>Registering Gitlab Runner<\/strong><\/p>\n<p><strong>Step 1:<\/strong><br \/>\nCopy and paste the following command into your command line to register the runner. The same command should be displayed on the above create runner page.<\/p>\n<pre><span style=\"font-weight: 400;\">$ gitlab-runner register  --url https:\/\/gitlab.com  \u2013token [token_value]<\/span>\r\n<\/pre>\n<p><strong>Note:<\/strong> The <strong>[token_value]<\/strong> will be auto generated post create a runner as given in above image for the reference.<\/p>\n<p><strong>Step 2:<\/strong><br \/>\nChoose an executor when prompted by the command line. Executors run builds in different environments. (There are given number of executors, We have used shell since its won\u2019t have any dependency)<br \/>\n(<span style=\"color: #999999;\">ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell<\/span>)<\/p>\n<pre><span style=\"font-weight: 400;\">$ shell<\/span>\r\n<\/pre>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/11-5.png\" alt=\"shell\" width=\"768\" height=\"212\" \/><\/p>\n<p><strong>Step 3 (optional):<\/strong><br \/>\nManually verify that the runner is available to pick up jobs:<\/p>\n<pre><span style=\"font-weight: 400;\">$ gitlab-runner run<\/span>\r\n<\/pre>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/11-6.png\" alt=\"gitlab runner run\" width=\"777\" height=\"208\" \/><\/p>\n<p>To verify that your gitlab runner is running or not, enter the below command:<\/p>\n<pre><span style=\"font-weight: 400;\">$ gitlab-runner verify<\/span>\r\n<\/pre>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/11-7.png\" alt=\"gitlab-runner verify\" width=\"782\" height=\"144\" \/><\/p>\n<p>Check the runner status. If it\u2019s not running, Please use below commands to run the runner:<\/p>\n<pre><span style=\"font-weight: 400;\">$ gitlab-runner stop<\/span>\r\n<\/pre>\n<pre><span style=\"font-weight: 400;\">$ gitlab-runner restart<\/span>\r\n<\/pre>\n<p>Click on View runners-<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/12.png\" alt=\"View runner\" width=\"786\" height=\"473\" \/><\/p>\n<h2>How to verify if Runner properly registered<\/h2>\n<ul>\n<li>Goto below Path &lt;Home&gt;\/Users\/&lt;user&gt;\/gitlab-runner\/config.toml<\/li>\n<li><span style=\"color: #999999;\"><em>.gitlab-runner<\/em><\/span> directory will be created. This is hidden directory<\/li>\n<li>In that directory there is <strong>\u201cconfig.toml\u201d<\/strong><\/li>\n<li>This config file will list down all the runners installed on the Mac machine<\/li>\n<\/ul>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/12-1.png\" alt=\"config.toml\" width=\"614\" height=\"295\" \/><\/p>\n<p><span style=\"font-weight: 400;\"><br \/>\n<strong>Step 4: Edit a <span style=\"color: #999999;\"><em>.gitlab-ci.yml<\/em><\/span> file<\/strong><br \/>\n<\/span><\/p>\n<p>Go to particular <strong>Project -&gt;Code -&gt; Repository -&gt;.gitlab-ci.yml-&gt; Edit-&gt; Edit single file<\/strong><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/12-2.png\" alt=\"Edit songle file\" width=\"782\" height=\"468\" \/><\/p>\n<p>You need to replace the content of file with content given below:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/15.png\" alt=\"Edit file\" width=\"785\" height=\"469\" \/><\/p>\n<p>Content of the file:-<br \/>\n<a href=\"https:\/\/gitlab.com\/ios-tester\/Todo_ios\/-\/blob\/main\/gitlab-ci.yml\" rel=\"nofollow\"><img decoding=\"async\" loading=\"lazy\" class=\"alignright\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2024\/08\/data-copy.png\" alt=\"null\" width=\"56\" height=\"56\" \/><\/a><\/p>\n<pre><span style=\"font-weight: 400;\">\r\nstages:\r\n  <span style=\"color: #ff0000;\">- build<\/span>\r\n  \r\nvariables:\r\n  LC_ALL: <span style=\"color: #ff0000;\">\"en_US.UTF-8\"<\/span>\r\n  LANG: <span style=\"color: #ff0000;\">\"en_US.UTF-8\"<\/span>\r\n  GIT_STRATEGY: <span style=\"color: #ff0000;\">clone<\/span>\r\n\r\n\r\nbuild:\r\n  stage: <span style=\"color: #ff0000;\">build<\/span>\r\n  tags:\r\n    <span style=\"color: #ff0000;\">- ios-tag\r\n    - shell<\/span>\r\n  before_script:\r\n    <span style=\"color: #ff0000;\">- whoami\r\n    - echo $SHELL\r\n    - security default-keychain\r\n    - security list-keychain -d user\r\n    - export KEYCHAIN_PATH=\"$HOME\/Library\/Keychains\/login.keychain-db\"\r\n    - export KEYCHAIN_PASSWORD=\"KEYCHAIN_PASSWORD\"\r\n    - security unlock-keychain -p ${KEYCHAIN_PASSWORD} ${KEYCHAIN_PATH}\r\n    - security find-identity -v -p codesigning -s ${KEYCHAIN_PATH}\r\n    - ruby -v\r\n    - which ruby\r\n    - which bundle\r\n    - bundle install<\/span>\r\n      \r\n  script:\r\n    <span style=\"color: #ff0000;\">- echo \"Start execution\"\r\n    - bundle exec fastlane build --verbose\r\n    - echo \"End execution\"<\/span>\r\n<\/span>\r\n<\/pre>\n<p>And click on Commit changes then job will start the execution:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/16.png\" alt=\"Committed changes\" width=\"790\" height=\"479\" \/><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/17.png\" alt=\"View pipeline\" width=\"790\" height=\"480\" \/><\/p>\n<p>To view a visual representation of your pipeline by selecting the pipeline ID-<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/19.1.png\" alt=\"Selecting pipeline 1\" width=\"788\" height=\"600\" \/><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/20.1.png\" alt=\"Selecting pipeline 2\" width=\"791\" height=\"677\" \/><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/22.1.png\" alt=\"Selecting pipeline 3\" width=\"789\" height=\"685\" \/><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/23.png\" alt=\"Selecting pipeline 4\" width=\"791\" height=\"644\" \/><\/p>\n<p>Pipeline Job status:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/24.png\" alt=\"Job passed\" width=\"787\" height=\"130\" \/><\/p>\n<p>Uploaded build link:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/25.png\" alt=\"Uploaded link\" width=\"787\" height=\"102\" \/><\/p>\n<p>Concluding that we have covered the CI\/CD workflow via Fastlane &amp; Firebase with Gitlab Actions in in this part.<\/p>\n<p>Stay tuned!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the second part of the blog, we covered the Code Signing approach via the match import command and created a separate repository and uploaded the private keys and certificates in a Gitlab repo for syncing them across the machines. Now we are moving to the next part of this series where we will use [&hellip;]<\/p>\n","protected":false},"author":1898,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":106},"categories":[1400],"tags":[4252,6073,4848,4078],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/70190"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/1898"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=70190"}],"version-history":[{"count":27,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/70190\/revisions"}],"predecessor-version":[{"id":71402,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/70190\/revisions\/71402"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=70190"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=70190"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=70190"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}