[{"data":1,"prerenderedAt":1408},["ShallowReactive",2],{"/blog/tuto-mac-m1-gitlab-ci":3,"navigation-en-us":622,"banner-en-us":1048,"footer-en-us":1058,"blog-post-authors-en-us-Benedikt Rollik":1303,"blog-related-posts-en-us-tuto-mac-m1-gitlab-ci":1318,"blog-promotions-en-us":1344,"next-steps-en-us":1398},{"id":4,"title":5,"authors":6,"body":8,"category":602,"date":603,"description":604,"extension":605,"externalUrl":606,"faq":606,"featured":607,"heroImage":608,"meta":609,"navigation":456,"path":610,"seo":611,"slug":615,"stem":616,"tags":617,"template":620,"updatedDate":606,"__hash__":621},"blogPosts/en-us/blog/tuto-mac-m1-gitlab-ci.md","How to use Scaleway to self-host your GitLab Runners",[7],"Benedikt Rollik",{"type":9,"value":10,"toc":595},"minimark",[11,22,25,40,49,83,88,171,175,187,237,240,245,248,280,284,297,366,370,386,389,409,561,564,568,582,585,591],[12,13,14,15,21],"p",{},"GitLab's complete DevOps platform comes with built-in continuous integration (CI) and continuous delivery (CD) via ",[16,17,20],"a",{"href":18,"rel":19},"https://docs.gitlab.com/ci/",[],"GitLab CI/CD",". GitLab CI/CD is a great solution to increase developer productivity and motivation to write higher-quality code without sacrificing speed. It runs a series of tests every time a commit is pushed, providing immediate visibility into the results of changes in the codebase. While it is not a hassle to set up a CI using Linux-based machines, iOS and macOS developers may find it is more complicated to have access to a Mac that is connected and available 24 hours a day.",[12,23,24],{},"GitLab Runners, provided on GitLab.com, are the engine that executes CI workflows. Due to various requirements, some users may opt to self-host runners on public cloud VMs. This is super easy if the build VM OS requirement is Linux-based since there are several low-cost public cloud Linux-based VM solutions. However, iOS and macOS developers may find fewer options for public cloud-delivered macOS based systems.",[12,26,27,28,33,34,39],{},"In this blog post tutorial, you will learn how to set up CI for iOS and macOS application development using a Scaleway Virtual Instance running the ",[16,29,32],{"href":30,"rel":31},"https://www.scaleway.com/en/docs/install-gitlab-with-dbaas/",[],"GitLab application"," and a GitLab Runner that runs on a Scaleway-hosted ",[16,35,38],{"href":36,"rel":37},"https://www.scaleway.com/en/hello-m1/",[],"Mac mini M1",". To complete this tutorial most successfully, we assume that you have some experience creating Xcode and GitLab projects, as well as some experiences using a Terminal and git.",[41,42,43],"blockquote",{},[12,44,45],{},[46,47,48],"strong",{},"Requirements",[50,51,52,61,69,72],"ul",{},[53,54,55,56],"li",{},"You have an account and are logged into ",[16,57,60],{"href":58,"rel":59},"https://console.scaleway.com",[],"console.scaleway.com",[53,62,63,64],{},"You have ",[16,65,68],{"href":66,"rel":67},"https://www.scaleway.com/en/docs/configure-new-ssh-key/",[],"configured your SSH Key",[53,70,71],{},"You have a Virtual Instance running the GitLab InstantApp",[53,73,74,77,78,82],{},[46,75,76],{},"Note:"," We assume you have already deployed a Virtual Instance running the GitLab InstantApp. If not, ",[16,79,81],{"href":30,"rel":80},[],"deploy GitLab"," before continuing with this tutorial.",[84,85,87],"h3",{"id":86},"deploying-the-mac-mini-m1","Deploying the Mac mini M1",[89,90,91,116,123,140,153,160],"ol",{},[53,92,93,94,98,99,102,103,106,107,110,115],{},"Log into your ",[16,95,97],{"href":58,"rel":96},[],"Scaleway console"," and click on ",[46,100,101],{},"Apple silicon"," in the ",[46,104,105],{},"Compute"," section of the sidebar.",[108,109],"br",{},[111,112],"img",{"alt":113,"src":114},"Orga_dashboard","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398975/blog/Content%20Images/scaleway-blog/Orga_dashboard.png","\nClick on the \"Apple silicon\" in the Scaleway console.",[53,117,118,119,122],{},"The Apple silicon M1 as-a-Service splash screen displays. Click ",[46,120,121],{},"Create a Mac mini M1",".",[53,124,125,126],{},"Enter the details for your Mac mini M1:",[50,127,128,131,134,137],{},[53,129,130],{},"Select the geographic region in which your Mac mini M1 will be deployed.",[53,132,133],{},"Choose the macOS version you want to run on the Mac mini M1.",[53,135,136],{},"Select the hardware configuration for your Mac mini M1.",[53,138,139],{},"Enter a name for your Mac mini M1.",[53,141,142,143,145,146,148,152],{},"Click ",[46,144,121],{}," to launch the installation of your Apple silicon M1 as-a-Service.",[108,147],{},[111,149],{"alt":150,"src":151},"M1_creation","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398975/blog/Content%20Images/scaleway-blog/M1_creation.png","\nClick \"Create a Mac mini M1\" to launch.",[53,154,155,156,159],{},"Once deployed click ",[46,157,158],{},"VNC"," from the Mac mini M1 Overview page to launch the remote desktop client.",[53,161,162,163,166,167,170],{},"Launch the ",[46,164,165],{},"App Store"," and install the ",[46,168,169],{},"Xcode development environment"," on your Mac mini M1.",[84,172,174],{"id":173},"setting-up-the-homebrew-package-manager","Setting-up the Homebrew package manager",[12,176,177,182,183,170],{},[16,178,181],{"href":179,"rel":180},"https://brew.sh/",[],"Homebrew"," is a package manager for macOS. It can be used to manage the software installed on your Mac. We use it to install ",[184,185,186],"code",{},"gitlab-runner",[89,188,189,195],{},[53,190,191,192,122],{},"Click on the Terminal icon to open a new ",[46,193,194],{},"Terminal",[53,196,197,198,201,202],{},"Copy-paste the following code in the terminal application and press ",[46,199,200],{},"Enter"," to install Homebrew and the Xcode command line tools:",[203,204,209],"pre",{"className":205,"code":206,"language":207,"meta":208,"style":208},"language-sh shiki shiki-themes github-light","/bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"\n","sh","",[184,210,211],{"__ignoreMap":208},[212,213,216,220,224,228,231,234],"span",{"class":214,"line":215},"line",1,[212,217,219],{"class":218},"s7eDp","/bin/bash",[212,221,223],{"class":222},"sYu0t"," -c",[212,225,227],{"class":226},"sYBdl"," \"$(",[212,229,230],{"class":218},"curl",[212,232,233],{"class":222}," -fsSL",[212,235,236],{"class":226}," https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"\n",[12,238,239],{},"Leave the terminal window open since it is required for the next step.",[241,242,244],"h4",{"id":243},"installing-the-gitlab-runner","Installing the GitLab Runner",[12,246,247],{},"The GitLab Runner is an application installed on a different computer than your GitLab host and runs jobs in a pipeline. It executes the build task on your Mac mini M1 for the code you push to your GitLab instance.",[89,249,250,256],{},[53,251,252,253,255],{},"Make sure you are still in the ",[46,254,194],{}," application. If you closed it after installing Homebrew, open a new one.",[53,257,258,259,261,262],{},"Run the following command to install ",[184,260,186],{},":",[203,263,267],{"className":264,"code":265,"language":266,"meta":208,"style":208},"language-shell shiki shiki-themes github-light","brew install gitlab-runner\n","shell",[184,268,269],{"__ignoreMap":208},[212,270,271,274,277],{"class":214,"line":215},[212,272,273],{"class":218},"brew",[212,275,276],{"class":226}," install",[212,278,279],{"class":226}," gitlab-runner\n",[84,281,283],{"id":282},"configuring-the-runner-in-gitlab","Configuring the Runner in GitLab",[41,285,286],{},[12,287,288,290,291,296],{},[46,289,76],{}," You require a Virtual Instance running the ",[16,292,295],{"href":293,"rel":294},"https://www.scaleway.com/en/docs/how-to-use-the-gitlab-instant-apps/",[],"GitLab InstantApp"," for the following steps.",[89,298,299,302,313,323,333,336,356],{},[53,300,301],{},"GitLab Runner requires a registration token for the link between your GitLab Instance and the Runner. Open the GitLab web interface of your Virtual Instance and log into it.",[53,303,304,305,308,309,312],{},"Select the project you want to use in GitLab with the Runner. If you don't have a project yet, click ",[46,306,307],{},"+"," > ",[46,310,311],{},"Create Project"," and fill in the required information about the project.",[53,314,315,316,308,319,322],{},"On the projects overview page, click ",[46,317,318],{},"Settings",[46,320,321],{},"CI/CD"," to view the Continuous Integration settings.",[53,324,325,326,102,329,332],{},"On the Continuous Integration settings page, click ",[46,327,328],{},"Expand",[46,330,331],{},"Runner"," section to view the required information to link GitLab with your Runner.",[53,334,335],{},"Scroll down to retrieve the GitLab Instance URL and the registration token.",[53,337,338,339,347,349,350],{},"Run the following command in the Terminal application on your Mac to launch the configuration wizard for your GitLab Runner:",[203,340,345],{"className":341,"code":343,"language":344,"meta":208},[342],"language-text","gitlab-runner register\n","text",[184,346,343],{"__ignoreMap":208},[108,348],{},"Enter the required information as follows:",[203,351,354],{"className":352,"code":353,"language":344,"meta":208},[342],"Runtime platform                                    arch=arm64 os=darwin pid=810 revision=2ebc4dc4 version=13.9.0\nWARNING: Running in user-mode.\nWARNING: Use sudo for system-mode:\nWARNING: $ sudo gitlab-runner...\n\nEnter the GitLab instance URL (for example, https://gitlab.com/):\nhttp://163.172.141.212/   \u003C- Enter the URL of your GitLab instance\nEnter the registration token:\n1mWBwzWAZSL7-pR18K3Y  \u003C- Enter the registration token for your Runner\nEnter a description for the runner:\n[306a20a2-2e01-4f2e-bc76-a004d35d9962]: Mac mini M1  \u003C- Enter a description for your Runner\nEnter tags for the runner (comma-separated):\nMac, mini, M1, dev, xcode  \u003C- Optionally, enter tags for the runner\nRegistering runner... succeeded                     runner=1mWBwzWA\nEnter an executor: shell, virtualbox, docker+machine, custom, docker, docker-ssh, kubernetes, parallels, ssh, docker-ssh+machine:\nshell  \u003C- Enter the \"shell\" executor for the runner\nRunner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!\n",[184,355,353],{"__ignoreMap":208},[53,357,358,359],{},"Reload the CI/CD configuration page of your GitLab instance. The runner is now linked to your project and displays as available.",[41,360,361],{},[12,362,363,365],{},[46,364,76],{}," If you have several projects in a GitLab group, you can configure the Runner at the group-level. Runners available at the group-level are available for all projects within said group.",[84,367,369],{"id":368},"configuring-ci-for-your-project","Configuring CI for your project",[12,371,372,373,376,377,380,381,122],{},"GitLab stores the configuration of the CI in a file called ",[184,374,375],{},".gitlab-ci.yml",". This file should be in the folder you created for your project. Typically this is the same directory where your Xcode project file (",[184,378,379],{},"ProjectName.xcodeproj",") is located. The GitLab CI configuration file is written in ",[16,382,385],{"href":383,"rel":384},"https://yaml.org/",[],"YAML",[12,387,388],{},"Inside the configuration file you can specify information like:",[50,390,391,394,397,400,403,406],{},[53,392,393],{},"The scripts you want to run.",[53,395,396],{},"Other configuration files and templates you want to include.",[53,398,399],{},"Dependencies and caches.",[53,401,402],{},"The commands you want to run in sequence and those you want to run in parallel.",[53,404,405],{},"The location to deploy your application to.",[53,407,408],{},"Whether you want to run the scripts automatically or trigger any of them manually.",[89,410,411,555,558],{},[53,412,413,414,416,417],{},"Open a text editor on your local computer and create the ",[184,415,375],{}," file as in the following example.",[203,418,422],{"className":419,"code":420,"language":421,"meta":208,"style":208},"language-yaml shiki shiki-themes github-light","stages:\n  - build\n  - test\n\nbuild-code-job:\n  stage: build\n  script:\n    - echo \"Check the ruby version, then build some Ruby project files:\"\n    - ruby -v\n    - rake\n\ntest-code-job1:\n  stage: test\n  script:\n    - echo \"If the files are built successfully, test some files with one command:\"\n    - rake test1\n","yaml",[184,423,424,434,443,451,458,466,477,485,494,502,510,515,523,532,539,547],{"__ignoreMap":208},[212,425,426,430],{"class":214,"line":215},[212,427,429],{"class":428},"shJU0","stages",[212,431,433],{"class":432},"sgsFI",":\n",[212,435,437,440],{"class":214,"line":436},2,[212,438,439],{"class":432},"  - ",[212,441,442],{"class":226},"build\n",[212,444,446,448],{"class":214,"line":445},3,[212,447,439],{"class":432},[212,449,450],{"class":226},"test\n",[212,452,454],{"class":214,"line":453},4,[212,455,457],{"emptyLinePlaceholder":456},true,"\n",[212,459,461,464],{"class":214,"line":460},5,[212,462,463],{"class":428},"build-code-job",[212,465,433],{"class":432},[212,467,469,472,475],{"class":214,"line":468},6,[212,470,471],{"class":428},"  stage",[212,473,474],{"class":432},": ",[212,476,442],{"class":226},[212,478,480,483],{"class":214,"line":479},7,[212,481,482],{"class":428},"  script",[212,484,433],{"class":432},[212,486,488,491],{"class":214,"line":487},8,[212,489,490],{"class":432},"    - ",[212,492,493],{"class":226},"echo \"Check the ruby version, then build some Ruby project files:\"\n",[212,495,497,499],{"class":214,"line":496},9,[212,498,490],{"class":432},[212,500,501],{"class":226},"ruby -v\n",[212,503,505,507],{"class":214,"line":504},10,[212,506,490],{"class":432},[212,508,509],{"class":226},"rake\n",[212,511,513],{"class":214,"line":512},11,[212,514,457],{"emptyLinePlaceholder":456},[212,516,518,521],{"class":214,"line":517},12,[212,519,520],{"class":428},"test-code-job1",[212,522,433],{"class":432},[212,524,526,528,530],{"class":214,"line":525},13,[212,527,471],{"class":428},[212,529,474],{"class":432},[212,531,450],{"class":226},[212,533,535,537],{"class":214,"line":534},14,[212,536,482],{"class":428},[212,538,433],{"class":432},[212,540,542,544],{"class":214,"line":541},15,[212,543,490],{"class":432},[212,545,546],{"class":226},"echo \"If the files are built successfully, test some files with one command:\"\n",[212,548,550,552],{"class":214,"line":549},16,[212,551,490],{"class":432},[212,553,554],{"class":226},"rake test1\n",[53,556,557],{},"Save the file and make a new commit to add it to your repository.",[53,559,560],{},"Push the commit to GitLab. The CI will automatically launch the tasks on your Runner.",[12,562,563],{},"For more information on the GitLab CI configuration file, refer to the official documentation.",[84,565,567],{"id":566},"speed-up-development-with-scaleway-and-gitlab","Speed up development with Scaleway and GitLab",[12,569,570,571,576,577],{},"Having a dedicated Mac available for executing your CI jobs can reduce your development team's cycle time. In this tutorial, we covered configuring a dedicated Mac mini M1 to host a GitLab Runner. If you want to learn more about the Mac mini M1 as-a-Service, refer to our ",[16,572,575],{"href":573,"rel":574},"https://www.scaleway.com/en/docs/apple-silicon-as-a-service-quickstart/",[],"product documentation",".\nWe invite the GitLab community to start building on Scaleway today with a €10 voucher to use on dozens of products & services. Find out more ",[16,578,581],{"href":579,"rel":580},"https://www.scaleway.com/en/gitlab-m1/",[],"here.",[583,584],"hr",{},[12,586,587],{},[588,589,590],"em",{},"Mac mini, macOS are trademarks of Apple Inc., registered in the U.S. and other countries and regions. IOS is a trademark or registered trademark of Cisco in the U.S. and other countries and is used by Apple under license. Scaleway is not affiliated with Apple Inc.",[592,593,594],"style",{},"html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .shJU0, html code.shiki .shJU0{--shiki-default:#22863A}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}",{"title":208,"searchDepth":436,"depth":436,"links":596},[597,598,599,600,601],{"id":86,"depth":445,"text":87},{"id":173,"depth":445,"text":174},{"id":282,"depth":445,"text":283},{"id":368,"depth":445,"text":369},{"id":566,"depth":445,"text":567},"engineering","2021-06-07","Learn how to set up GitLab CI for your iOS and macOS projects using a hosted Mac mini M1.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663397/Blog/Hero%20Images/logoforblogpost.jpg",{},"/en-us/blog/tuto-mac-m1-gitlab-ci",{"title":5,"description":604,"ogTitle":5,"ogDescription":604,"noIndex":607,"ogImage":608,"ogUrl":612,"ogSiteName":613,"ogType":614,"canonicalUrls":612},"https://about.gitlab.com/blog/tuto-mac-m1-gitlab-ci","https://about.gitlab.com","article","tuto-mac-m1-gitlab-ci","en-us/blog/tuto-mac-m1-gitlab-ci",[618,619,619],"git","AWS","BlogPost","CbKBP21FD5yQ5YqUOoK3_sun92_SM9umnd819n5KDok",{"logo":623,"freeTrial":628,"sales":633,"login":638,"items":643,"search":968,"minimal":999,"duo":1018,"switchNav":1027,"pricingDeployment":1038},{"config":624},{"href":625,"dataGaName":626,"dataGaLocation":627},"/","gitlab logo","header",{"text":629,"config":630},"Get free trial",{"href":631,"dataGaName":632,"dataGaLocation":627},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":634,"config":635},"Request a demo",{"href":636,"dataGaName":637,"dataGaLocation":627},"/sales/?contact-topic=request-demo","sales",{"text":639,"config":640},"Sign in",{"href":641,"dataGaName":642,"dataGaLocation":627},"https://gitlab.com/users/sign_in/","sign in",[644,673,772,777,890,946],{"text":645,"config":646,"menu":648},"Platform",{"dataNavLevelOne":647},"platform",{"type":649,"columns":650},"cards",[651,657,665],{"title":645,"description":652,"link":653},"The intelligent orchestration platform for DevSecOps",{"text":654,"config":655},"Explore our Platform",{"href":656,"dataGaName":647,"dataGaLocation":627},"/platform/",{"title":658,"description":659,"link":660},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":661,"config":662},"Meet GitLab Duo",{"href":663,"dataGaName":664,"dataGaLocation":627},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":666,"description":667,"link":668},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":669,"config":670},"Learn more",{"href":671,"dataGaName":672,"dataGaLocation":627},"/why-gitlab/","why gitlab",{"text":674,"left":456,"config":675,"menu":677},"Product",{"dataNavLevelOne":676},"solutions",{"type":678,"link":679,"columns":683,"feature":751},"lists",{"text":680,"config":681},"View all Solutions",{"href":682,"dataGaName":676,"dataGaLocation":627},"/solutions/",[684,707,730],{"title":685,"description":686,"link":687,"items":692},"Automation","CI/CD and automation to accelerate deployment",{"config":688},{"icon":689,"href":690,"dataGaName":691,"dataGaLocation":627},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[693,696,699,703],{"text":321,"config":694},{"href":695,"dataGaLocation":627,"dataGaName":321},"/solutions/continuous-integration/",{"text":658,"config":697},{"href":663,"dataGaLocation":627,"dataGaName":698},"gitlab duo agent platform - product menu",{"text":700,"config":701},"Source Code Management",{"href":702,"dataGaLocation":627,"dataGaName":700},"/solutions/source-code-management/",{"text":704,"config":705},"Automated Software Delivery",{"href":690,"dataGaLocation":627,"dataGaName":706},"Automated software delivery",{"title":708,"description":709,"link":710,"items":715},"Security","Deliver code faster without compromising security",{"config":711},{"href":712,"dataGaName":713,"dataGaLocation":627,"icon":714},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[716,720,725],{"text":717,"config":718},"Application Security Testing",{"href":712,"dataGaName":719,"dataGaLocation":627},"Application security testing",{"text":721,"config":722},"Software Supply Chain Security",{"href":723,"dataGaLocation":627,"dataGaName":724},"/solutions/supply-chain/","Software supply chain security",{"text":726,"config":727},"Software Compliance",{"href":728,"dataGaName":729,"dataGaLocation":627},"/solutions/software-compliance/","software compliance",{"title":731,"link":732,"items":737},"Measurement",{"config":733},{"icon":734,"href":735,"dataGaName":736,"dataGaLocation":627},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[738,742,746],{"text":739,"config":740},"Visibility & Measurement",{"href":735,"dataGaLocation":627,"dataGaName":741},"Visibility and Measurement",{"text":743,"config":744},"Value Stream Management",{"href":745,"dataGaLocation":627,"dataGaName":743},"/solutions/value-stream-management/",{"text":747,"config":748},"Analytics & Insights",{"href":749,"dataGaLocation":627,"dataGaName":750},"/solutions/analytics-and-insights/","Analytics and insights",{"title":752,"type":678,"items":753},"GitLab for",[754,760,766],{"text":755,"config":756},"Enterprise",{"icon":757,"href":758,"dataGaLocation":627,"dataGaName":759},"Building","/enterprise/","enterprise",{"text":761,"config":762},"Small Business",{"icon":763,"href":764,"dataGaLocation":627,"dataGaName":765},"Work","/small-business/","small business",{"text":767,"config":768},"Public Sector",{"icon":769,"href":770,"dataGaLocation":627,"dataGaName":771},"Organization","/solutions/public-sector/","public sector",{"text":773,"config":774},"Pricing",{"href":775,"dataGaName":776,"dataGaLocation":627,"dataNavLevelOne":776},"/pricing/","pricing",{"text":778,"config":779,"menu":781},"Resources",{"dataNavLevelOne":780},"resources",{"type":678,"link":782,"columns":786,"feature":879},{"text":783,"config":784},"View all resources",{"href":785,"dataGaName":780,"dataGaLocation":627},"/resources/",[787,819,846],{"title":788,"items":789},"Getting started",[790,795,800,805,809,814],{"text":791,"config":792},"Install",{"href":793,"dataGaName":794,"dataGaLocation":627},"/install/","install",{"text":796,"config":797},"Quick start guides",{"href":798,"dataGaName":799,"dataGaLocation":627},"/get-started/","quick setup checklists",{"text":801,"config":802},"Learn",{"href":803,"dataGaLocation":627,"dataGaName":804},"https://university.gitlab.com/","learn",{"text":806,"config":807},"Product documentation",{"href":808,"dataGaName":575,"dataGaLocation":627},"https://docs.gitlab.com/",{"text":810,"config":811},"Best practice videos",{"href":812,"dataGaName":813,"dataGaLocation":627},"/getting-started-videos/","best practice videos",{"text":815,"config":816},"Integrations",{"href":817,"dataGaName":818,"dataGaLocation":627},"/integrations/","integrations",{"title":820,"items":821},"Discover",[822,827,832,837,841],{"text":823,"config":824},"Customer success stories",{"href":825,"dataGaName":826,"dataGaLocation":627},"/customers/","customer success stories",{"text":828,"config":829},"Blog",{"href":830,"dataGaName":831,"dataGaLocation":627},"/blog/","blog",{"text":833,"config":834},"Demo Hub",{"href":835,"dataGaName":836,"dataGaLocation":627},"/demo-hub/","demo hub",{"text":838,"config":839},"The Source",{"href":840,"dataGaName":831,"dataGaLocation":627},"/the-source/",{"text":842,"config":843},"Remote",{"href":844,"dataGaName":845,"dataGaLocation":627},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":847,"items":848},"Connect",[849,854,859,864,869,874],{"text":850,"config":851},"GitLab Services",{"href":852,"dataGaName":853,"dataGaLocation":627},"/services/","services",{"text":855,"config":856},"Contribute",{"href":857,"dataGaName":858,"dataGaLocation":627},"https://contributors.gitlab.com","contribute",{"text":860,"config":861},"Community",{"href":862,"dataGaName":863,"dataGaLocation":627},"/community/","community",{"text":865,"config":866},"Forum",{"href":867,"dataGaName":868,"dataGaLocation":627},"https://forum.gitlab.com/","forum",{"text":870,"config":871},"Events",{"href":872,"dataGaName":873,"dataGaLocation":627},"/events/","events",{"text":875,"config":876},"Partners",{"href":877,"dataGaName":878,"dataGaLocation":627},"/partners/","partners",{"config":880,"title":883,"text":884,"link":885},{"background":881,"textColor":882},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","What’s new in GitLab","Stay updated with our latest features and improvements.",{"text":886,"config":887},"Read the latest",{"href":888,"dataGaName":889,"dataGaLocation":627},"/whats-new/","whats new",{"text":891,"config":892,"menu":894},"Company",{"dataNavLevelOne":893},"company",{"type":678,"columns":895},[896],{"items":897},[898,903,909,911,916,921,926,931,936,941],{"text":899,"config":900},"About",{"href":901,"dataGaName":902,"dataGaLocation":627},"/company/","about",{"text":904,"config":905,"footerGa":908},"Jobs",{"href":906,"dataGaName":907,"dataGaLocation":627},"/jobs/","jobs",{"dataGaName":907},{"text":870,"config":910},{"href":872,"dataGaName":873,"dataGaLocation":627},{"text":912,"config":913},"Leadership",{"href":914,"dataGaName":915,"dataGaLocation":627},"/company/team/e-group/","leadership",{"text":917,"config":918},"Handbook",{"href":919,"dataGaName":920,"dataGaLocation":627},"https://handbook.gitlab.com/","handbook",{"text":922,"config":923},"Investor relations",{"href":924,"dataGaName":925,"dataGaLocation":627},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":927,"config":928},"Trust Center",{"href":929,"dataGaName":930,"dataGaLocation":627},"/security/","trust center",{"text":932,"config":933},"AI Transparency Center",{"href":934,"dataGaName":935,"dataGaLocation":627},"/ai-transparency-center/","ai transparency center",{"text":937,"config":938},"Newsletter",{"href":939,"dataGaName":940,"dataGaLocation":627},"/company/contact/#contact-forms","newsletter",{"text":942,"config":943},"Press",{"href":944,"dataGaName":945,"dataGaLocation":627},"/press/","press",{"text":947,"config":948,"menu":949},"Contact us",{"dataNavLevelOne":893},{"type":678,"columns":950},[951],{"items":952},[953,958,963],{"text":954,"config":955},"Talk to sales",{"href":956,"dataGaName":957,"dataGaLocation":627},"/sales/","talk to sales",{"text":959,"config":960},"Support portal",{"href":961,"dataGaName":962,"dataGaLocation":627},"https://support.gitlab.com/hc/en-us","support portal",{"text":964,"config":965},"Customer portal",{"href":966,"dataGaName":967,"dataGaLocation":627},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":969,"login":970,"suggestions":977},"Close",{"text":971,"link":972},"To search repositories and projects, login to",{"text":973,"config":974},"gitlab.com",{"href":641,"dataGaName":975,"dataGaLocation":976},"search login","search",{"text":978,"default":979},"Suggestions",[980,982,986,988,992,996],{"text":658,"config":981},{"href":663,"dataGaName":658,"dataGaLocation":976},{"text":983,"config":984},"Code Suggestions (AI)",{"href":985,"dataGaName":983,"dataGaLocation":976},"/solutions/code-suggestions/",{"text":321,"config":987},{"href":695,"dataGaName":321,"dataGaLocation":976},{"text":989,"config":990},"GitLab on AWS",{"href":991,"dataGaName":989,"dataGaLocation":976},"/partners/technology-partners/aws/",{"text":993,"config":994},"GitLab on Google Cloud",{"href":995,"dataGaName":993,"dataGaLocation":976},"/partners/technology-partners/google-cloud-platform/",{"text":997,"config":998},"Why GitLab?",{"href":671,"dataGaName":997,"dataGaLocation":976},{"freeTrial":1000,"mobileIcon":1005,"desktopIcon":1010,"secondaryButton":1013},{"text":1001,"config":1002},"Start free trial",{"href":1003,"dataGaName":632,"dataGaLocation":1004},"https://gitlab.com/-/trials/new/","nav",{"altText":1006,"config":1007},"Gitlab Icon",{"src":1008,"dataGaName":1009,"dataGaLocation":1004},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":1006,"config":1011},{"src":1012,"dataGaName":1009,"dataGaLocation":1004},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":1014,"config":1015},"Get Started",{"href":1016,"dataGaName":1017,"dataGaLocation":1004},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":1019,"mobileIcon":1023,"desktopIcon":1025},{"text":1020,"config":1021},"Learn more about GitLab Duo",{"href":663,"dataGaName":1022,"dataGaLocation":1004},"gitlab duo",{"altText":1006,"config":1024},{"src":1008,"dataGaName":1009,"dataGaLocation":1004},{"altText":1006,"config":1026},{"src":1012,"dataGaName":1009,"dataGaLocation":1004},{"button":1028,"mobileIcon":1033,"desktopIcon":1035},{"text":1029,"config":1030},"/switch",{"href":1031,"dataGaName":1032,"dataGaLocation":1004},"#contact","switch",{"altText":1006,"config":1034},{"src":1008,"dataGaName":1009,"dataGaLocation":1004},{"altText":1006,"config":1036},{"src":1037,"dataGaName":1009,"dataGaLocation":1004},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":1039,"mobileIcon":1044,"desktopIcon":1046},{"text":1040,"config":1041},"Back to pricing",{"href":775,"dataGaName":1042,"dataGaLocation":1004,"icon":1043},"back to pricing","GoBack",{"altText":1006,"config":1045},{"src":1008,"dataGaName":1009,"dataGaLocation":1004},{"altText":1006,"config":1047},{"src":1012,"dataGaName":1009,"dataGaLocation":1004},{"title":1049,"titleMobile":1050,"button":1051,"config":1056},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":669,"config":1052},{"href":1053,"dataGaName":1054,"dataGaLocation":1055},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":1057,"disabled":607},"release",{"data":1059},{"text":1060,"source":1061,"edit":1067,"contribute":1072,"config":1077,"items":1082,"minimal":1292},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":1062,"config":1063},"View page source",{"href":1064,"dataGaName":1065,"dataGaLocation":1066},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":1068,"config":1069},"Edit this page",{"href":1070,"dataGaName":1071,"dataGaLocation":1066},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":1073,"config":1074},"Please contribute",{"href":1075,"dataGaName":1076,"dataGaLocation":1066},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":1078,"facebook":1079,"youtube":1080,"linkedin":1081},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[1083,1130,1184,1228,1260],{"title":773,"links":1084,"subMenu":1099},[1085,1089,1094],{"text":1086,"config":1087},"View plans",{"href":775,"dataGaName":1088,"dataGaLocation":1066},"view plans",{"text":1090,"config":1091},"Why Premium?",{"href":1092,"dataGaName":1093,"dataGaLocation":1066},"/pricing/premium/","why premium",{"text":1095,"config":1096},"Why Ultimate?",{"href":1097,"dataGaName":1098,"dataGaLocation":1066},"/pricing/ultimate/","why ultimate",[1100],{"title":1101,"links":1102},"Contact Us",[1103,1106,1108,1110,1115,1120,1125],{"text":1104,"config":1105},"Contact sales",{"href":956,"dataGaName":637,"dataGaLocation":1066},{"text":959,"config":1107},{"href":961,"dataGaName":962,"dataGaLocation":1066},{"text":964,"config":1109},{"href":966,"dataGaName":967,"dataGaLocation":1066},{"text":1111,"config":1112},"Status",{"href":1113,"dataGaName":1114,"dataGaLocation":1066},"https://status.gitlab.com/","status",{"text":1116,"config":1117},"Terms of use",{"href":1118,"dataGaName":1119,"dataGaLocation":1066},"/terms/","terms of use",{"text":1121,"config":1122},"Privacy statement",{"href":1123,"dataGaName":1124,"dataGaLocation":1066},"/privacy/","privacy statement",{"text":1126,"config":1127},"Cookie preferences",{"dataGaName":1128,"dataGaLocation":1066,"id":1129,"isOneTrustButton":456},"cookie preferences","ot-sdk-btn",{"title":674,"links":1131,"subMenu":1140},[1132,1136],{"text":1133,"config":1134},"DevSecOps platform",{"href":656,"dataGaName":1135,"dataGaLocation":1066},"devsecops platform",{"text":1137,"config":1138},"AI-Assisted Development",{"href":663,"dataGaName":1139,"dataGaLocation":1066},"ai-assisted development",[1141],{"title":1142,"links":1143},"Topics",[1144,1149,1154,1159,1164,1169,1174,1179],{"text":1145,"config":1146},"CICD",{"href":1147,"dataGaName":1148,"dataGaLocation":1066},"/topics/ci-cd/","cicd",{"text":1150,"config":1151},"GitOps",{"href":1152,"dataGaName":1153,"dataGaLocation":1066},"/topics/gitops/","gitops",{"text":1155,"config":1156},"DevOps",{"href":1157,"dataGaName":1158,"dataGaLocation":1066},"/topics/devops/","devops",{"text":1160,"config":1161},"Version Control",{"href":1162,"dataGaName":1163,"dataGaLocation":1066},"/topics/version-control/","version control",{"text":1165,"config":1166},"DevSecOps",{"href":1167,"dataGaName":1168,"dataGaLocation":1066},"/topics/devsecops/","devsecops",{"text":1170,"config":1171},"Cloud Native",{"href":1172,"dataGaName":1173,"dataGaLocation":1066},"/topics/cloud-native/","cloud native",{"text":1175,"config":1176},"AI for Coding",{"href":1177,"dataGaName":1178,"dataGaLocation":1066},"/topics/devops/ai-for-coding/","ai for coding",{"text":1180,"config":1181},"Agentic AI",{"href":1182,"dataGaName":1183,"dataGaLocation":1066},"/topics/agentic-ai/","agentic ai",{"title":1185,"links":1186},"Solutions",[1187,1189,1191,1196,1200,1203,1207,1210,1212,1215,1218,1223],{"text":717,"config":1188},{"href":712,"dataGaName":717,"dataGaLocation":1066},{"text":706,"config":1190},{"href":690,"dataGaName":691,"dataGaLocation":1066},{"text":1192,"config":1193},"Agile development",{"href":1194,"dataGaName":1195,"dataGaLocation":1066},"/solutions/agile-delivery/","agile delivery",{"text":1197,"config":1198},"SCM",{"href":702,"dataGaName":1199,"dataGaLocation":1066},"source code management",{"text":1145,"config":1201},{"href":695,"dataGaName":1202,"dataGaLocation":1066},"continuous integration & delivery",{"text":1204,"config":1205},"Value stream management",{"href":745,"dataGaName":1206,"dataGaLocation":1066},"value stream management",{"text":1150,"config":1208},{"href":1209,"dataGaName":1153,"dataGaLocation":1066},"/solutions/gitops/",{"text":755,"config":1211},{"href":758,"dataGaName":759,"dataGaLocation":1066},{"text":1213,"config":1214},"Small business",{"href":764,"dataGaName":765,"dataGaLocation":1066},{"text":1216,"config":1217},"Public sector",{"href":770,"dataGaName":771,"dataGaLocation":1066},{"text":1219,"config":1220},"Education",{"href":1221,"dataGaName":1222,"dataGaLocation":1066},"/solutions/education/","education",{"text":1224,"config":1225},"Financial services",{"href":1226,"dataGaName":1227,"dataGaLocation":1066},"/solutions/finance/","financial services",{"title":778,"links":1229},[1230,1232,1234,1236,1239,1241,1244,1246,1248,1250,1252,1254,1256,1258],{"text":791,"config":1231},{"href":793,"dataGaName":794,"dataGaLocation":1066},{"text":796,"config":1233},{"href":798,"dataGaName":799,"dataGaLocation":1066},{"text":801,"config":1235},{"href":803,"dataGaName":804,"dataGaLocation":1066},{"text":806,"config":1237},{"href":808,"dataGaName":1238,"dataGaLocation":1066},"docs",{"text":828,"config":1240},{"href":830,"dataGaName":831,"dataGaLocation":1066},{"text":1242,"config":1243},"What's new",{"href":888,"dataGaName":889,"dataGaLocation":1066},{"text":823,"config":1245},{"href":825,"dataGaName":826,"dataGaLocation":1066},{"text":842,"config":1247},{"href":844,"dataGaName":845,"dataGaLocation":1066},{"text":850,"config":1249},{"href":852,"dataGaName":853,"dataGaLocation":1066},{"text":855,"config":1251},{"href":857,"dataGaName":858,"dataGaLocation":1066},{"text":860,"config":1253},{"href":862,"dataGaName":863,"dataGaLocation":1066},{"text":865,"config":1255},{"href":867,"dataGaName":868,"dataGaLocation":1066},{"text":870,"config":1257},{"href":872,"dataGaName":873,"dataGaLocation":1066},{"text":875,"config":1259},{"href":877,"dataGaName":878,"dataGaLocation":1066},{"title":891,"links":1261},[1262,1264,1266,1268,1270,1272,1276,1281,1283,1285,1287],{"text":899,"config":1263},{"href":901,"dataGaName":893,"dataGaLocation":1066},{"text":904,"config":1265},{"href":906,"dataGaName":907,"dataGaLocation":1066},{"text":912,"config":1267},{"href":914,"dataGaName":915,"dataGaLocation":1066},{"text":917,"config":1269},{"href":919,"dataGaName":920,"dataGaLocation":1066},{"text":922,"config":1271},{"href":924,"dataGaName":925,"dataGaLocation":1066},{"text":1273,"config":1274},"Sustainability",{"href":1275,"dataGaName":1273,"dataGaLocation":1066},"/sustainability/",{"text":1277,"config":1278},"Diversity, inclusion and belonging (DIB)",{"href":1279,"dataGaName":1280,"dataGaLocation":1066},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":927,"config":1282},{"href":929,"dataGaName":930,"dataGaLocation":1066},{"text":937,"config":1284},{"href":939,"dataGaName":940,"dataGaLocation":1066},{"text":942,"config":1286},{"href":944,"dataGaName":945,"dataGaLocation":1066},{"text":1288,"config":1289},"Modern Slavery Transparency Statement",{"href":1290,"dataGaName":1291,"dataGaLocation":1066},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":1293},[1294,1297,1300],{"text":1295,"config":1296},"Terms",{"href":1118,"dataGaName":1119,"dataGaLocation":1066},{"text":1298,"config":1299},"Cookies",{"dataGaName":1128,"dataGaLocation":1066,"id":1129,"isOneTrustButton":456},{"text":1301,"config":1302},"Privacy",{"href":1123,"dataGaName":1124,"dataGaLocation":1066},[1304],{"id":1305,"title":7,"body":606,"config":1306,"content":1308,"description":606,"extension":1312,"meta":1313,"navigation":456,"path":1314,"seo":1315,"stem":1316,"__hash__":1317},"blogAuthors/en-us/blog/authors/benedikt-rollik.yml",{"template":1307},"BlogAuthor",{"name":7,"config":1309},{"headshot":1310,"ctfId":1311},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659488/Blog/Author%20Headshots/gitlab-logo-extra-whitespace.png","Benedikt-Rollik","yml",{},"/en-us/blog/authors/benedikt-rollik",{},"en-us/blog/authors/benedikt-rollik","JkRLJwitTBmCQmlPFQPRZY0nZVos90zvA9Nca8xKv0w",[1319,1328,1336],{"title":1320,"description":1321,"heroImage":1322,"category":602,"date":1323,"authors":1324,"slug":1327,"externalUrl":606},"Confidential AI for GitLab Self-Hosted","Give developers AI coding agents in GitLab Duo without source code leaving a hardware-encrypted boundary — no GPUs needed.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1773866173/vte9qh8rriznvyclhkes.png","2026-08-06",[1325,1326],"Mathias Ewald","Martin Paloncy, Edgeless Systems","confidential-ai-for-gitlab-self-hosted",{"title":1329,"description":1330,"heroImage":1331,"category":602,"date":1332,"authors":1333,"slug":1335,"externalUrl":606},"Green DevOps: Why carbon measurement belongs in your CI/CD pipeline","CI/CD pipelines have a hidden carbon cost. Here's why measuring it matters, and how you can get started with Eco CI and Carmen in GitLab.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1765809212/noh0mdfn9o94ry9ykura.png","2026-07-09",[1334],"Lysanne Pinto","green-devops-carbon-measurement-cicd-pipeline",{"title":1337,"description":1338,"heroImage":1339,"category":602,"date":1340,"authors":1341,"slug":1343,"externalUrl":606},"How to build CI/CD observability at scale","This practical guide to GitLab pipeline analytics helps self-managed users gain operational insights using Prometheus and Grafana.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1774465167/n5hlvrsrheadeccyr1oz.png","2026-04-28",[1342],"Paul Meresanu","how-to-build-ci-cd-observability-at-scale",{"promotions":1345},[1346,1360,1372,1384],{"id":1347,"categories":1348,"header":1350,"text":1351,"button":1352,"image":1357},"ai-modernization",[1349],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":1353,"config":1354},"Get your AI maturity score",{"href":1355,"dataGaName":1356,"dataGaLocation":831},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":1358},{"src":1359},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":1361,"categories":1362,"header":1364,"text":1351,"button":1365,"image":1369},"devops-modernization",[1363,1168],"product","Are you just managing tools or shipping innovation?",{"text":1366,"config":1367},"Get your DevOps maturity score",{"href":1368,"dataGaName":1356,"dataGaLocation":831},"/assessments/devops-modernization-assessment/",{"config":1370},{"src":1371},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":1373,"categories":1374,"header":1376,"text":1351,"button":1377,"image":1381},"security-modernization",[1375],"security","Are you trading speed for security?",{"text":1378,"config":1379},"Get your security maturity score",{"href":1380,"dataGaName":1356,"dataGaLocation":831},"/assessments/security-modernization-assessment/",{"config":1382},{"src":1383},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":1385,"paths":1386,"header":1389,"text":1390,"button":1391,"image":1396},"github-azure-migration",[1387,1388],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","Is your team ready for GitHub's Azure move?","GitHub is already rebuilding around Azure. Find out what it means for you.",{"text":1392,"config":1393},"See how GitLab compares to GitHub",{"href":1394,"dataGaName":1395,"dataGaLocation":831},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":1397},{"src":1371},{"header":1399,"blurb":1400,"button":1401,"secondaryButton":1406},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":1402,"config":1403},"Get your free trial",{"href":1404,"dataGaName":632,"dataGaLocation":1405},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":1104,"config":1407},{"href":956,"dataGaName":637,"dataGaLocation":1405},1786803753831]