[{"data":1,"prerenderedAt":717},["ShallowReactive",2],{"/en-us/blog/ios-publishing-with-gitlab-and-fastlane/":3,"navigation-en-us":36,"banner-en-us":463,"footer-en-us":480,"Jason Yavorska":690,"next-steps-en-us":702},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"seo":8,"content":16,"config":26,"_id":29,"_type":30,"title":31,"_source":32,"_file":33,"_stem":34,"_extension":35},"/en-us/blog/ios-publishing-with-gitlab-and-fastlane","blog",false,"",{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},"How to publish iOS apps to the App Store with GitLab and fastlane","See how GitLab, together with fastlane, can build, sign, and publish apps for iOS to the App Store.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749680470/Blog/Hero%20Images/ios-publishing-cover.jpg","https://about.gitlab.com/blog/ios-publishing-with-gitlab-and-fastlane","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How to publish iOS apps to the App Store with GitLab and fastlane\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Jason Yavorska\"}],\n        \"datePublished\": \"2019-03-06\",\n      }",{"title":9,"description":10,"authors":17,"heroImage":11,"date":19,"body":20,"category":21,"tags":22},[18],"Jason Yavorska","2019-03-06","_Note: You may also find the blog post [Tutorial: iOS CI/CD with\nGitLab](/blog/ios-cicd-with-gitlab/) from June 2023 helpful._\n\n\nRecently we published a [blog post\n\ndetailing how to get up and running quickly with your Android\napp](/blog/android-publishing-with-gitlab-and-fastlane/), GitLab, and\n\n[_fastlane_](https://fastlane.tools). In this edition, let's look at how to\nget\n\na build of an iOS app up and running, including publishing all the way to\n\nTestFlight. To see how cool this can be, check out this [video\n\nof me making a change on an iPad Pro using the GitLab Web\nIDE](https://www.youtube.com/watch?v=325FyJt7ZG8), getting that\n\nbuilt, and then receiving an update to the test version of my application on\nthe\n\nvery same iPad Pro I was using to develop.\n\n\nFor the purposes of this article, we'll be using a [simple Swift iOS\napp](https://gitlab.com/jyavorska/flappyokr)\n\nthat I recorded the video with.\n\n\n## First, a note on Apple Store configuration\n\n\nWhat we're going to need in order to set all of this up is a mobile\napplication set up\n\nin the App Store, distribution certificates, and a provisioning profile that\nties\n\nit all together.\n\n\nMost of the complexity here actually has to do with setting up your signing\n\nauthority for the App Store. Hopefully in most cases this is already good to\ngo\n\nfor you; if you're a new app developer, I'll try to get you started on the\nright\n\ntrack, but the intricacies of Apple certificate management is out of the\nscope of\n\nthis article, and tends to change somewhat frequently. But, this information\n\nshould get you going.\n\n\n### My apps\n\n\nYour application will need to be set up in App Store Connect so you have an\nID\n\nfor your application, which will be used in your `.xcodebuild`\nconfiguration.\n\nYour app profile and ID are what tie together the code builds with pricing\nand\n\navailability, as well as TestFlight configuration for distributing testing\n\napplications to your users. Note that you don't need to set up public\ntesting –\n\nyou can use personal testing with TestFlight just fine as long as your\ntesting\n\ngroup is small, and the setup is simpler and requires no additional\napprovals\n\nfrom Apple.\n\n\n### Provisioning profile\n\n\nIn addition to the app setup, you need iOS distribution and development keys\n\ncreated in the Certificates, Identifiers, and Profiles section of the Apple\n\nDeveloper console. Once these certificates are created, you can create a\n\nprovisioning profile to unify everything.\n\n\nAlso note that the user you will authenticate with needs to be able to\ncreate\n\ncertificates, so please ensure that they have that ability or you will see\nan\n\nerror during the [_cert_ and\n_sigh_](https://docs.fastlane.tools/codesigning/getting-started/#using-cert-and-sigh)\n\nsteps.\n\n\n### Other options\n\n\nThere are several more ways to set up your certificates and profiles than\nthe\n\nsimple method I've described above, so if you're doing something different\nyou may\n\nneed to adapt. The most important thing is that you need your `.xcodebuild`\n\nconfiguration to point to the appropriate files, and your keychain needs to\nbe\n\navailable on the build machine for the user that the runner is running as.\nWe're\n\nusing _fastlane_ for signing, so if you run into trouble here or want to\nlearn\n\nmore about your options, take a look at their extensive [code signing\ndocumentation](https://docs.fastlane.tools/codesigning/getting-started/).\n\n\nFor this sample project, I'm using the [_cert_ and\n_sigh_](https://docs.fastlane.tools/codesigning/getting-started/#using-cert-and-sigh)\n\napproach, but the [match\n\napproach](https://docs.fastlane.tools/codesigning/getting-started/#using-match)\nmay be better for actual enterprise use.\n\n\n## How to set up GitLab and _fastlane_\n\n\n### How to set up your CI/CD runner\n\n\nWith the above information gathered or set up, we can start with configuring\nthe\n\nGitLab runner on a macOS device. Unfortunately, building on macOS is the\nonly\n\nrealistic way to build iOS apps. This is potentially changing in the future;\n\nkeep an eye on projects like [xcbuild](https://github.com/facebook/xcbuild)\nand\n\n[isign](https://github.com/saucelabs/isign), as well as our own internal\nissue\n\n[gitlab-ce#57576](https://gitlab.com/gitlab-org/gitlab-ce/issues/57576) for\n\ndevelopments in this area.\n\n\nIn the meantime, setting up the runner is fairly straightforward. You can\nfollow\n\nour most current [instructions for setting up GitLab Runner on\nmacOS](https://docs.gitlab.com/runner/install/osx.html)\n\nto get that up and running.\n\n\nNote: Be sure to set your GitLab runner to use the `shell` executor. For\nbuilding iOS on\n\nmacOS, it's a requirement to operate directly as the user on the machine\nrather\n\nthan using containers. Note that when you're using the shell executor, the\n\nbuild and tests run as the identity of the runner logged in user, directly\non\n\nthe build host. This is less secure than using container executors, so\nplease\n\ntake a look at our [security implications\ndocumentation](https://docs.gitlab.com/runner/security/#usage-of-shell-executor)\n\nfor additional detail on what to keep in mind in this scenario.\n\n\n```\n\nsudo curl --output /usr/local/bin/gitlab-runner\nhttps://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-amd64\n\nsudo chmod +x /usr/local/bin/gitlab-runner\n\ncd ~\n\ngitlab-runner install\n\ngitlab-runner start\n\n```\n\n\nWhat you need to be careful about here is ensuring your Apple keychain is\nset up\n\non this host and has access to the keys that Xcode needs in order\n\nto build. The easiest way to test this is to log in as the user that will be\n\nrunning the build and try to build manually. You may receive system prompts\nfor\n\nkeychain access which you need to \"always allow\" for CI/CD to work. You will\nprobably\n\nalso want to log in and watch your first pipeline or two to make sure that\n\nno prompts come up for additional keychain access. Unfortunately Apple does\nnot\n\nmake this super easy to use in unattended mode, but once you have it working\nit\n\ntends to stay that way.\n\n\n### _fastlane_ init\n\n\nIn order to start using _fastane_ with your project, you'll need to run\n\n`fastlane init`. Simply follow the [instructions\n\nto install and run\n_fastlane_](https://docs.fastlane.tools/getting-started/ios/setup/), being\nsure to use the instructions in the\n\n[Use a\nGemfile](https://docs.fastlane.tools/getting-started/ios/setup/#use-a-gemfile)\n\nsection, since we do want this to run quickly and predictably via unattended\nCI.\n\n\nFrom your project directory, you can run the following commands:\n\n\n```\n\nxcode-select --install\n\nsudo gem install fastlane -NV\n\n# Alternatively using Homebrew\n\n# brew cask install fastlane\n\nfastlane init\n\n```\n\n\n_fastlane_ will ask you for some basic configuration and then create a\nproject folder\n\ncalled `fastlane` in your project which will contain three files:\n\n\n#### 1. `fastlane/Appfile`\n\n\nThis file is straightforward, so you just want to check to make sure that\nthe Apple\n\nID and app ID that you set up earlier are correct.\n\n\n```\n\napp_identifier(\"com.vontrance.flappybird\") # The bundle identifier of your\napp\n\napple_id(\"your-email@your-domain.com\") # Your Apple email address\n\n```\n\n\n#### 2. `fastlane/Fastfile`\n\n\nThe `Fastfile` defines the build steps. Since we're using a lot of the\nbuilt-in\n\ncapability of _fastlane_ this is really straightforward. We create a single\n\nlane which gets certificates, builds, and uploads the new build to\nTestFlight.\n\nOf course, you may want to split these out into different jobs depending on\nyour\n\nuse case. Each of these steps, `get_certificates`,\n`get_provisioning_profile`,\n\n`gym`, and `upload_to_testflight` are pre-bundled actions already included\nwith\n\n_fastlane_.\n\n\n`get_certificates` and `get_provisioning_profile` are actions associated\nwith\n\nthe [_cert_ and\n_sigh_](https://docs.fastlane.tools/codesigning/getting-started/#using-cert-and-sigh)\n\napproach to code signing; if you're using _fastlane_\n[match](https://docs.fastlane.tools/codesigning/getting-started/#using-match)\n\nor some other approach you may need to update these.\n\n\n```yaml\n\ndefault_platform(:ios)\n\n\nplatform :ios do\n  desc \"Build the application\"\n  lane :flappybuild do\n    get_certificates\n    get_provisioning_profile\n    gym\n    upload_to_testflight\n  end\nend\n\n```\n\n\n#### 3. `fastlane/Gymfile`\n\n\nThis `gym` file is optional, but I created it manually in order to override\nthe default\n\noutput directory and place the output in the current folder. This makes\nthings a\n\nbit easier for CI. You can read more about `gym` and its options in the\n\n[gym documentation](https://docs.fastlane.tools/actions/gym/).\n\n\n```yaml\n\noutput_directory(\"./\")\n\n```\n\n\n### Our `.gitlab-ci.yml` configuration file\n\n\nNow, we have a CI/CD runner associated with our project so we're ready to\ntry a\n\npipeline. Let's see what's in our `.gitlab-ci.yml` file:\n\n\n```yaml\n\nstages:\n  - build\n\nvariables:\n  LC_ALL: \"en_US.UTF-8\"\n  LANG: \"en_US.UTF-8\"\n  GIT_STRATEGY: clone\n\nbuild:\n  stage: build\n  script:\n    - bundle install\n    - bundle exec fastlane flappybuild\n  artifacts:\n    paths:\n    - ./FlappyBird.ipa\n```\n\n\nYes, that's really it! [We set UTF-8 locale for _fastlane_ per their\n\nrequirements](https://docs.fastlane.tools/getting-started/ios/setup/#set-up-environment-variables),\n\nuse a `clone` strategy with the `shell` executor to ensure we have a clean\n\nworkspace each build, and then simply call our `flappybuild` _fastlane_\ntarget,\n\nwhich we discussed above. This will build, sign, and deploy the latest build\nto\n\nTestFlight.\n\n\nWe also gather the artifact and save it with the build – note that the\n`.ipa`\n\nformat output is a signed ARM executable, so not something you can run in\nthe\n\nsimulator. If you wanted a simulator output to be saved with the build, you\n\nwould simply add a build target that produces it and then add it to the\nartifact\n\npath.\n\n\n### Other environment variables\n\n\nThere are some special environment variables behind the scenes here that are\n\nmaking this work.\n\n\n#### `FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD` and `FASTLANE_SESSION`\n\n\nIn order to authenticate against the App Store for the TestFlight upload,\n\n_fastlane_ must be able to authenticate. In order to do this, you need to\n\ncreate an app-specific password to be used by CI. You can read more about\nthis\n\nprocess in [this\ndocumentation](https://docs.fastlane.tools/best-practices/continuous-integration/#use-of-application-specific-passwords-and-spaceauth).\n\n\nIf you're using two-factor authentication, you'll also need to generate the\n\n`FASTLANE_SESSION` variable – instructions are in the same place.\n\n\n#### `FASTLANE_USER` and `FASTLANE_PASSWORD`\n\n\nIn order for [_cert_ and\n_sigh_](https://docs.fastlane.tools/codesigning/getting-started/#using-cert-and-sigh)\n\nto be able to fetch the provisioning profile and certificates on demand, the\n\n`FASTLANE_USER` and `FASTLANE_PASSWORD` variables must be set. You can read\nmore\n\nabout this\n[here](https://docs.fastlane.tools/best-practices/continuous-integration/#environment-variables-to-set).\n\nYou may not need these if you are using some other approach to signing.\n\n\n## In closing...\n\n\nRemember, you can see a working project with all of this set up by heading\nover\n\nto my [simple demo app](https://gitlab.com/jyavorska/flappyokr).\n\n\nHopefully this has been helpful and has inspired you to get iOS builds and\n\npublishing working within your GitLab project. There is some good additional\n\n[CI/CD\nbest-practice](https://docs.fastlane.tools/best-practices/continuous-integration/)\n\ndocumentation for _fastlane_ if you get stuck anywhere,\n\nand you could also consider using the `CI_BUILD_ID` (which increments each\nbuild)\n\nto [automatically increment a\nversion](https://docs.fastlane.tools/best-practices/continuous-integration/gitlab/#auto-incremented-build-number).\n\n\nAnother great capability of _fastlane_ to try is the ability to\n\n[automatically generate\nscreenshots](https://docs.fastlane.tools/getting-started/ios/screenshots/)\n\nfor the App Store – it's just as easy to set up as the rest of this has\nbeen.\n\n\nWe'd love to hear in the comments how this is working for you, as well as\nyour\n\nideas for how we can make GitLab a better place to do iOS development in\ngeneral.\n\n\nPhoto by eleven_x on [Unsplash](https://unsplash.com/photos/lwaw_DL09S4)\n\n{: .note}\n","engineering",[23,24,25],"CI/CD","integrations","features",{"slug":27,"featured":6,"template":28},"ios-publishing-with-gitlab-and-fastlane","BlogPost","content:en-us:blog:ios-publishing-with-gitlab-and-fastlane.yml","yaml","Ios Publishing With Gitlab And Fastlane","content","en-us/blog/ios-publishing-with-gitlab-and-fastlane.yml","en-us/blog/ios-publishing-with-gitlab-and-fastlane","yml",{"_path":37,"_dir":38,"_draft":6,"_partial":6,"_locale":7,"data":39,"_id":459,"_type":30,"title":460,"_source":32,"_file":461,"_stem":462,"_extension":35},"/shared/en-us/main-navigation","en-us",{"logo":40,"freeTrial":45,"sales":50,"login":55,"items":60,"search":390,"minimal":421,"duo":440,"pricingDeployment":449},{"config":41},{"href":42,"dataGaName":43,"dataGaLocation":44},"/","gitlab logo","header",{"text":46,"config":47},"Get free trial",{"href":48,"dataGaName":49,"dataGaLocation":44},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":51,"config":52},"Talk to sales",{"href":53,"dataGaName":54,"dataGaLocation":44},"/sales/","sales",{"text":56,"config":57},"Sign in",{"href":58,"dataGaName":59,"dataGaLocation":44},"https://gitlab.com/users/sign_in/","sign in",[61,105,202,207,311,371],{"text":62,"config":63,"cards":65,"footer":88},"Platform",{"dataNavLevelOne":64},"platform",[66,72,80],{"title":62,"description":67,"link":68},"The most comprehensive AI-powered DevSecOps Platform",{"text":69,"config":70},"Explore our Platform",{"href":71,"dataGaName":64,"dataGaLocation":44},"/platform/",{"title":73,"description":74,"link":75},"GitLab Duo (AI)","Build software faster with AI at every stage of development",{"text":76,"config":77},"Meet GitLab Duo",{"href":78,"dataGaName":79,"dataGaLocation":44},"/gitlab-duo/","gitlab duo ai",{"title":81,"description":82,"link":83},"Why GitLab","10 reasons why Enterprises choose GitLab",{"text":84,"config":85},"Learn more",{"href":86,"dataGaName":87,"dataGaLocation":44},"/why-gitlab/","why gitlab",{"title":89,"items":90},"Get started with",[91,96,101],{"text":92,"config":93},"Platform Engineering",{"href":94,"dataGaName":95,"dataGaLocation":44},"/solutions/platform-engineering/","platform engineering",{"text":97,"config":98},"Developer Experience",{"href":99,"dataGaName":100,"dataGaLocation":44},"/developer-experience/","Developer experience",{"text":102,"config":103},"MLOps",{"href":104,"dataGaName":102,"dataGaLocation":44},"/topics/devops/the-role-of-ai-in-devops/",{"text":106,"left":107,"config":108,"link":110,"lists":114,"footer":184},"Product",true,{"dataNavLevelOne":109},"solutions",{"text":111,"config":112},"View all Solutions",{"href":113,"dataGaName":109,"dataGaLocation":44},"/solutions/",[115,139,163],{"title":116,"description":117,"link":118,"items":123},"Automation","CI/CD and automation to accelerate deployment",{"config":119},{"icon":120,"href":121,"dataGaName":122,"dataGaLocation":44},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[124,127,131,135],{"text":23,"config":125},{"href":126,"dataGaLocation":44,"dataGaName":23},"/solutions/continuous-integration/",{"text":128,"config":129},"AI-Assisted Development",{"href":78,"dataGaLocation":44,"dataGaName":130},"AI assisted development",{"text":132,"config":133},"Source Code Management",{"href":134,"dataGaLocation":44,"dataGaName":132},"/solutions/source-code-management/",{"text":136,"config":137},"Automated Software Delivery",{"href":121,"dataGaLocation":44,"dataGaName":138},"Automated software delivery",{"title":140,"description":141,"link":142,"items":147},"Security","Deliver code faster without compromising security",{"config":143},{"href":144,"dataGaName":145,"dataGaLocation":44,"icon":146},"/solutions/security-compliance/","security and compliance","ShieldCheckLight",[148,153,158],{"text":149,"config":150},"Application Security Testing",{"href":151,"dataGaName":152,"dataGaLocation":44},"/solutions/application-security-testing/","Application security testing",{"text":154,"config":155},"Software Supply Chain Security",{"href":156,"dataGaLocation":44,"dataGaName":157},"/solutions/supply-chain/","Software supply chain security",{"text":159,"config":160},"Software Compliance",{"href":161,"dataGaName":162,"dataGaLocation":44},"/solutions/software-compliance/","software compliance",{"title":164,"link":165,"items":170},"Measurement",{"config":166},{"icon":167,"href":168,"dataGaName":169,"dataGaLocation":44},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[171,175,179],{"text":172,"config":173},"Visibility & Measurement",{"href":168,"dataGaLocation":44,"dataGaName":174},"Visibility and Measurement",{"text":176,"config":177},"Value Stream Management",{"href":178,"dataGaLocation":44,"dataGaName":176},"/solutions/value-stream-management/",{"text":180,"config":181},"Analytics & Insights",{"href":182,"dataGaLocation":44,"dataGaName":183},"/solutions/analytics-and-insights/","Analytics and insights",{"title":185,"items":186},"GitLab for",[187,192,197],{"text":188,"config":189},"Enterprise",{"href":190,"dataGaLocation":44,"dataGaName":191},"/enterprise/","enterprise",{"text":193,"config":194},"Small Business",{"href":195,"dataGaLocation":44,"dataGaName":196},"/small-business/","small business",{"text":198,"config":199},"Public Sector",{"href":200,"dataGaLocation":44,"dataGaName":201},"/solutions/public-sector/","public sector",{"text":203,"config":204},"Pricing",{"href":205,"dataGaName":206,"dataGaLocation":44,"dataNavLevelOne":206},"/pricing/","pricing",{"text":208,"config":209,"link":211,"lists":215,"feature":298},"Resources",{"dataNavLevelOne":210},"resources",{"text":212,"config":213},"View all resources",{"href":214,"dataGaName":210,"dataGaLocation":44},"/resources/",[216,248,270],{"title":217,"items":218},"Getting started",[219,224,229,234,239,244],{"text":220,"config":221},"Install",{"href":222,"dataGaName":223,"dataGaLocation":44},"/install/","install",{"text":225,"config":226},"Quick start guides",{"href":227,"dataGaName":228,"dataGaLocation":44},"/get-started/","quick setup checklists",{"text":230,"config":231},"Learn",{"href":232,"dataGaLocation":44,"dataGaName":233},"https://university.gitlab.com/","learn",{"text":235,"config":236},"Product documentation",{"href":237,"dataGaName":238,"dataGaLocation":44},"https://docs.gitlab.com/","product documentation",{"text":240,"config":241},"Best practice videos",{"href":242,"dataGaName":243,"dataGaLocation":44},"/getting-started-videos/","best practice videos",{"text":245,"config":246},"Integrations",{"href":247,"dataGaName":24,"dataGaLocation":44},"/integrations/",{"title":249,"items":250},"Discover",[251,256,260,265],{"text":252,"config":253},"Customer success stories",{"href":254,"dataGaName":255,"dataGaLocation":44},"/customers/","customer success stories",{"text":257,"config":258},"Blog",{"href":259,"dataGaName":5,"dataGaLocation":44},"/blog/",{"text":261,"config":262},"Remote",{"href":263,"dataGaName":264,"dataGaLocation":44},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":266,"config":267},"TeamOps",{"href":268,"dataGaName":269,"dataGaLocation":44},"/teamops/","teamops",{"title":271,"items":272},"Connect",[273,278,283,288,293],{"text":274,"config":275},"GitLab Services",{"href":276,"dataGaName":277,"dataGaLocation":44},"/services/","services",{"text":279,"config":280},"Community",{"href":281,"dataGaName":282,"dataGaLocation":44},"/community/","community",{"text":284,"config":285},"Forum",{"href":286,"dataGaName":287,"dataGaLocation":44},"https://forum.gitlab.com/","forum",{"text":289,"config":290},"Events",{"href":291,"dataGaName":292,"dataGaLocation":44},"/events/","events",{"text":294,"config":295},"Partners",{"href":296,"dataGaName":297,"dataGaLocation":44},"/partners/","partners",{"backgroundColor":299,"textColor":300,"text":301,"image":302,"link":306},"#2f2a6b","#fff","Insights for the future of software development",{"altText":303,"config":304},"the source promo card",{"src":305},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758208064/dzl0dbift9xdizyelkk4.svg",{"text":307,"config":308},"Read the latest",{"href":309,"dataGaName":310,"dataGaLocation":44},"/the-source/","the source",{"text":312,"config":313,"lists":315},"Company",{"dataNavLevelOne":314},"company",[316],{"items":317},[318,323,329,331,336,341,346,351,356,361,366],{"text":319,"config":320},"About",{"href":321,"dataGaName":322,"dataGaLocation":44},"/company/","about",{"text":324,"config":325,"footerGa":328},"Jobs",{"href":326,"dataGaName":327,"dataGaLocation":44},"/jobs/","jobs",{"dataGaName":327},{"text":289,"config":330},{"href":291,"dataGaName":292,"dataGaLocation":44},{"text":332,"config":333},"Leadership",{"href":334,"dataGaName":335,"dataGaLocation":44},"/company/team/e-group/","leadership",{"text":337,"config":338},"Team",{"href":339,"dataGaName":340,"dataGaLocation":44},"/company/team/","team",{"text":342,"config":343},"Handbook",{"href":344,"dataGaName":345,"dataGaLocation":44},"https://handbook.gitlab.com/","handbook",{"text":347,"config":348},"Investor relations",{"href":349,"dataGaName":350,"dataGaLocation":44},"https://ir.gitlab.com/","investor relations",{"text":352,"config":353},"Trust Center",{"href":354,"dataGaName":355,"dataGaLocation":44},"/security/","trust center",{"text":357,"config":358},"AI Transparency Center",{"href":359,"dataGaName":360,"dataGaLocation":44},"/ai-transparency-center/","ai transparency center",{"text":362,"config":363},"Newsletter",{"href":364,"dataGaName":365,"dataGaLocation":44},"/company/contact/","newsletter",{"text":367,"config":368},"Press",{"href":369,"dataGaName":370,"dataGaLocation":44},"/press/","press",{"text":372,"config":373,"lists":374},"Contact us",{"dataNavLevelOne":314},[375],{"items":376},[377,380,385],{"text":51,"config":378},{"href":53,"dataGaName":379,"dataGaLocation":44},"talk to sales",{"text":381,"config":382},"Get help",{"href":383,"dataGaName":384,"dataGaLocation":44},"/support/","get help",{"text":386,"config":387},"Customer portal",{"href":388,"dataGaName":389,"dataGaLocation":44},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":391,"login":392,"suggestions":399},"Close",{"text":393,"link":394},"To search repositories and projects, login to",{"text":395,"config":396},"gitlab.com",{"href":58,"dataGaName":397,"dataGaLocation":398},"search login","search",{"text":400,"default":401},"Suggestions",[402,404,408,410,414,418],{"text":73,"config":403},{"href":78,"dataGaName":73,"dataGaLocation":398},{"text":405,"config":406},"Code Suggestions (AI)",{"href":407,"dataGaName":405,"dataGaLocation":398},"/solutions/code-suggestions/",{"text":23,"config":409},{"href":126,"dataGaName":23,"dataGaLocation":398},{"text":411,"config":412},"GitLab on AWS",{"href":413,"dataGaName":411,"dataGaLocation":398},"/partners/technology-partners/aws/",{"text":415,"config":416},"GitLab on Google Cloud",{"href":417,"dataGaName":415,"dataGaLocation":398},"/partners/technology-partners/google-cloud-platform/",{"text":419,"config":420},"Why GitLab?",{"href":86,"dataGaName":419,"dataGaLocation":398},{"freeTrial":422,"mobileIcon":427,"desktopIcon":432,"secondaryButton":435},{"text":423,"config":424},"Start free trial",{"href":425,"dataGaName":49,"dataGaLocation":426},"https://gitlab.com/-/trials/new/","nav",{"altText":428,"config":429},"Gitlab Icon",{"src":430,"dataGaName":431,"dataGaLocation":426},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":428,"config":433},{"src":434,"dataGaName":431,"dataGaLocation":426},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":436,"config":437},"Get Started",{"href":438,"dataGaName":439,"dataGaLocation":426},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":441,"mobileIcon":445,"desktopIcon":447},{"text":442,"config":443},"Learn more about GitLab Duo",{"href":78,"dataGaName":444,"dataGaLocation":426},"gitlab duo",{"altText":428,"config":446},{"src":430,"dataGaName":431,"dataGaLocation":426},{"altText":428,"config":448},{"src":434,"dataGaName":431,"dataGaLocation":426},{"freeTrial":450,"mobileIcon":455,"desktopIcon":457},{"text":451,"config":452},"Back to pricing",{"href":205,"dataGaName":453,"dataGaLocation":426,"icon":454},"back to pricing","GoBack",{"altText":428,"config":456},{"src":430,"dataGaName":431,"dataGaLocation":426},{"altText":428,"config":458},{"src":434,"dataGaName":431,"dataGaLocation":426},"content:shared:en-us:main-navigation.yml","Main Navigation","shared/en-us/main-navigation.yml","shared/en-us/main-navigation",{"_path":464,"_dir":38,"_draft":6,"_partial":6,"_locale":7,"title":465,"button":466,"image":471,"config":475,"_id":477,"_type":30,"_source":32,"_file":478,"_stem":479,"_extension":35},"/shared/en-us/banner","is now in public beta!",{"text":467,"config":468},"Try the Beta",{"href":469,"dataGaName":470,"dataGaLocation":44},"/gitlab-duo/agent-platform/","duo banner",{"altText":472,"config":473},"GitLab Duo Agent Platform",{"src":474},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1753720689/somrf9zaunk0xlt7ne4x.svg",{"layout":476},"release","content:shared:en-us:banner.yml","shared/en-us/banner.yml","shared/en-us/banner",{"_path":481,"_dir":38,"_draft":6,"_partial":6,"_locale":7,"data":482,"_id":686,"_type":30,"title":687,"_source":32,"_file":688,"_stem":689,"_extension":35},"/shared/en-us/main-footer",{"text":483,"source":484,"edit":490,"contribute":495,"config":500,"items":505,"minimal":678},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":485,"config":486},"View page source",{"href":487,"dataGaName":488,"dataGaLocation":489},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":491,"config":492},"Edit this page",{"href":493,"dataGaName":494,"dataGaLocation":489},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":496,"config":497},"Please contribute",{"href":498,"dataGaName":499,"dataGaLocation":489},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":501,"facebook":502,"youtube":503,"linkedin":504},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[506,529,585,614,648],{"title":62,"links":507,"subMenu":512},[508],{"text":509,"config":510},"DevSecOps platform",{"href":71,"dataGaName":511,"dataGaLocation":489},"devsecops platform",[513],{"title":203,"links":514},[515,519,524],{"text":516,"config":517},"View plans",{"href":205,"dataGaName":518,"dataGaLocation":489},"view plans",{"text":520,"config":521},"Why Premium?",{"href":522,"dataGaName":523,"dataGaLocation":489},"/pricing/premium/","why premium",{"text":525,"config":526},"Why Ultimate?",{"href":527,"dataGaName":528,"dataGaLocation":489},"/pricing/ultimate/","why ultimate",{"title":530,"links":531},"Solutions",[532,537,539,541,546,551,555,558,562,567,569,572,575,580],{"text":533,"config":534},"Digital transformation",{"href":535,"dataGaName":536,"dataGaLocation":489},"/topics/digital-transformation/","digital transformation",{"text":149,"config":538},{"href":151,"dataGaName":149,"dataGaLocation":489},{"text":138,"config":540},{"href":121,"dataGaName":122,"dataGaLocation":489},{"text":542,"config":543},"Agile development",{"href":544,"dataGaName":545,"dataGaLocation":489},"/solutions/agile-delivery/","agile delivery",{"text":547,"config":548},"Cloud transformation",{"href":549,"dataGaName":550,"dataGaLocation":489},"/topics/cloud-native/","cloud transformation",{"text":552,"config":553},"SCM",{"href":134,"dataGaName":554,"dataGaLocation":489},"source code management",{"text":23,"config":556},{"href":126,"dataGaName":557,"dataGaLocation":489},"continuous integration & delivery",{"text":559,"config":560},"Value stream management",{"href":178,"dataGaName":561,"dataGaLocation":489},"value stream management",{"text":563,"config":564},"GitOps",{"href":565,"dataGaName":566,"dataGaLocation":489},"/solutions/gitops/","gitops",{"text":188,"config":568},{"href":190,"dataGaName":191,"dataGaLocation":489},{"text":570,"config":571},"Small business",{"href":195,"dataGaName":196,"dataGaLocation":489},{"text":573,"config":574},"Public sector",{"href":200,"dataGaName":201,"dataGaLocation":489},{"text":576,"config":577},"Education",{"href":578,"dataGaName":579,"dataGaLocation":489},"/solutions/education/","education",{"text":581,"config":582},"Financial services",{"href":583,"dataGaName":584,"dataGaLocation":489},"/solutions/finance/","financial services",{"title":208,"links":586},[587,589,591,593,596,598,600,602,604,606,608,610,612],{"text":220,"config":588},{"href":222,"dataGaName":223,"dataGaLocation":489},{"text":225,"config":590},{"href":227,"dataGaName":228,"dataGaLocation":489},{"text":230,"config":592},{"href":232,"dataGaName":233,"dataGaLocation":489},{"text":235,"config":594},{"href":237,"dataGaName":595,"dataGaLocation":489},"docs",{"text":257,"config":597},{"href":259,"dataGaName":5,"dataGaLocation":489},{"text":252,"config":599},{"href":254,"dataGaName":255,"dataGaLocation":489},{"text":261,"config":601},{"href":263,"dataGaName":264,"dataGaLocation":489},{"text":274,"config":603},{"href":276,"dataGaName":277,"dataGaLocation":489},{"text":266,"config":605},{"href":268,"dataGaName":269,"dataGaLocation":489},{"text":279,"config":607},{"href":281,"dataGaName":282,"dataGaLocation":489},{"text":284,"config":609},{"href":286,"dataGaName":287,"dataGaLocation":489},{"text":289,"config":611},{"href":291,"dataGaName":292,"dataGaLocation":489},{"text":294,"config":613},{"href":296,"dataGaName":297,"dataGaLocation":489},{"title":312,"links":615},[616,618,620,622,624,626,628,632,637,639,641,643],{"text":319,"config":617},{"href":321,"dataGaName":314,"dataGaLocation":489},{"text":324,"config":619},{"href":326,"dataGaName":327,"dataGaLocation":489},{"text":332,"config":621},{"href":334,"dataGaName":335,"dataGaLocation":489},{"text":337,"config":623},{"href":339,"dataGaName":340,"dataGaLocation":489},{"text":342,"config":625},{"href":344,"dataGaName":345,"dataGaLocation":489},{"text":347,"config":627},{"href":349,"dataGaName":350,"dataGaLocation":489},{"text":629,"config":630},"Sustainability",{"href":631,"dataGaName":629,"dataGaLocation":489},"/sustainability/",{"text":633,"config":634},"Diversity, inclusion and belonging (DIB)",{"href":635,"dataGaName":636,"dataGaLocation":489},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":352,"config":638},{"href":354,"dataGaName":355,"dataGaLocation":489},{"text":362,"config":640},{"href":364,"dataGaName":365,"dataGaLocation":489},{"text":367,"config":642},{"href":369,"dataGaName":370,"dataGaLocation":489},{"text":644,"config":645},"Modern Slavery Transparency Statement",{"href":646,"dataGaName":647,"dataGaLocation":489},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"title":649,"links":650},"Contact Us",[651,654,656,658,663,668,673],{"text":652,"config":653},"Contact an expert",{"href":53,"dataGaName":54,"dataGaLocation":489},{"text":381,"config":655},{"href":383,"dataGaName":384,"dataGaLocation":489},{"text":386,"config":657},{"href":388,"dataGaName":389,"dataGaLocation":489},{"text":659,"config":660},"Status",{"href":661,"dataGaName":662,"dataGaLocation":489},"https://status.gitlab.com/","status",{"text":664,"config":665},"Terms of use",{"href":666,"dataGaName":667,"dataGaLocation":489},"/terms/","terms of use",{"text":669,"config":670},"Privacy statement",{"href":671,"dataGaName":672,"dataGaLocation":489},"/privacy/","privacy statement",{"text":674,"config":675},"Cookie preferences",{"dataGaName":676,"dataGaLocation":489,"id":677,"isOneTrustButton":107},"cookie preferences","ot-sdk-btn",{"items":679},[680,682,684],{"text":664,"config":681},{"href":666,"dataGaName":667,"dataGaLocation":489},{"text":669,"config":683},{"href":671,"dataGaName":672,"dataGaLocation":489},{"text":674,"config":685},{"dataGaName":676,"dataGaLocation":489,"id":677,"isOneTrustButton":107},"content:shared:en-us:main-footer.yml","Main Footer","shared/en-us/main-footer.yml","shared/en-us/main-footer",[691],{"_path":692,"_dir":693,"_draft":6,"_partial":6,"_locale":7,"content":694,"config":697,"_id":699,"_type":30,"title":18,"_source":32,"_file":700,"_stem":701,"_extension":35},"/en-us/blog/authors/jason-yavorska","authors",{"name":18,"config":695},{"headshot":7,"ctfId":696},"jyavorska",{"template":698},"BlogAuthor","content:en-us:blog:authors:jason-yavorska.yml","en-us/blog/authors/jason-yavorska.yml","en-us/blog/authors/jason-yavorska",{"_path":703,"_dir":38,"_draft":6,"_partial":6,"_locale":7,"header":704,"eyebrow":705,"blurb":706,"button":707,"secondaryButton":711,"_id":713,"_type":30,"title":714,"_source":32,"_file":715,"_stem":716,"_extension":35},"/shared/en-us/next-steps","Start shipping better software faster","50%+ of the Fortune 100 trust GitLab","See what your team can do with the intelligent\n\n\nDevSecOps platform.\n",{"text":46,"config":708},{"href":709,"dataGaName":49,"dataGaLocation":710},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":51,"config":712},{"href":53,"dataGaName":54,"dataGaLocation":710},"content:shared:en-us:next-steps.yml","Next Steps","shared/en-us/next-steps.yml","shared/en-us/next-steps",1758326267061]