[{"data":1,"prerenderedAt":1657},["ShallowReactive",2],{"/blog/publish-code-coverage-report-with-gitlab-pages":3,"navigation-en-us":871,"banner-en-us":1297,"footer-en-us":1307,"blog-post-authors-en-us-Grzegorz Bizon":1552,"blog-related-posts-en-us-publish-code-coverage-report-with-gitlab-pages":1567,"blog-promotions-en-us":1593,"next-steps-en-us":1647},{"id":4,"title":5,"authors":6,"body":8,"category":849,"date":850,"description":5,"extension":851,"externalUrl":852,"faq":852,"featured":853,"heroImage":854,"meta":855,"navigation":358,"path":862,"seo":863,"slug":867,"stem":868,"tags":852,"template":869,"updatedDate":852,"__hash__":870},"blogPosts/en-us/blog/publish-code-coverage-report-with-gitlab-pages.md","Publish code coverage report with GitLab Pages",[7],"Grzegorz Bizon",{"type":9,"value":10,"toc":838},"minimark",[11,15,18,23,33,41,44,59,66,70,78,85,88,93,101,136,143,148,210,215,249,252,260,267,293,296,300,312,323,326,332,335,390,395,461,464,470,475,483,655,673,689,700,704,707,710,713,716,730,734,740,746,760,763,767,774,782,788,791,817,824,828,831,834],[12,13,14],"p",{},"At GitLab, we believe that everyone can contribute. We also use automated\ntesting extensively to make contributing to GitLab easier. Using automated\ntesting is a great way to improve confidence when someone needs to change\nthe code, which actually is the case in the majority of contributions to\nsoftware projects.",[12,16,17],{},"But how do we ensure that our test suite covers enough to aid the confidence\nin changing behavior of the software, and what can we do to keep on improving\nit?",[19,20,22],"h2",{"id":21},"what-is-code-coverage","What is code coverage?",[12,24,25,26,32],{},"Using the ",[27,28,31],"a",{"href":29,"rel":30},"https://en.wikipedia.org/wiki/Code_coverage",[],"code coverage"," metric is a\ntechnique that helps to improve the test suite, development process, and the software itself.",[12,34,35,36,40],{},"Tools used to measure the code coverage percentage usually extend the test harness\nenvironment and make it possible to map the application execution process\nback to the ",[27,37,39],{"href":38},"/solutions/source-code-management/","source code"," while automated tests are being executed. With that\napproach, you can not only learn how much of your code is covered by tests,\nbut it is also possible to find out what exact parts of the codebase are not\ncovered well enough.",[12,42,43],{},"Some coverage analysis tools also make it possible to generate code coverage reports in HTML\nformat that you can then view in your browser. It makes it much easier to\ninspect the areas of code that are missing tests and are likely to need some\nimprovements as well.",[12,45,46,47,52,53,58],{},"You can take a look at the Ruby ",[27,48,51],{"href":49,"rel":50},"http://gitlab-org.gitlab.io/gitlab-ce/coverage-ruby/",[],"code coverage report for GitLab","\nthat is hosted on ",[27,54,57],{"href":55,"rel":56},"https://pages.gitlab.io",[],"GitLab Pages",".",[12,60,61],{},[62,63],"img",{"alt":64,"src":65},"Code coverage report summary","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398881/blog/Content%20Images/publish-code-coverage-report-with-gitlab-pages/code-coverage-report-file-summary.png",[19,67,69],{"id":68},"how-to-generate-a-code-coverage-report","How to generate a code coverage report",[12,71,72,73,58],{},"There are a lot of code coverage tools available for many different languages,\nand you will need to find the most appropriate option for your particular needs. At GitLab, with\nprojects using Ruby, we often use ",[27,74,77],{"href":75,"rel":76},"https://github.com/colszowka/simplecov",[],"SimpleCov",[12,79,80,81,84],{},"You will need to check the documentation for your tool of choice to learn how to\ngenerate the code coverage report. Once you are able to do this locally,\ncheck out the rest of this tutorial to learn how to publish the report with\n",[27,82,57],{"href":55,"rel":83},[],"!",[12,86,87],{},"For the sake of this example, we will assume that you are using Ruby with RSpec\nand SimpleCov.",[89,90,92],"h3",{"id":91},"how-to-configure-your-tools","How to configure your tools",[12,94,95,96,100],{},"Configuring SimpleCov can be as simple as extending your ",[97,98,99],"code",{},"spec_helper.rb"," with:",[102,103,108],"pre",{"className":104,"code":105,"language":106,"meta":107,"style":107},"language-ruby shiki shiki-themes github-light","require 'simplecov'\nSimpleCov.start\n","ruby","",[97,109,110,123],{"__ignoreMap":107},[111,112,115,119],"span",{"class":113,"line":114},"line",1,[111,116,118],{"class":117},"sD7c4","require",[111,120,122],{"class":121},"sYBdl"," 'simplecov'\n",[111,124,126,129,132],{"class":113,"line":125},2,[111,127,77],{"class":128},"sYu0t",[111,130,58],{"class":131},"sgsFI",[111,133,135],{"class":134},"s7eDp","start\n",[12,137,138,139,142],{},"When you run the ",[97,140,141],{},"rspec"," command, you will notice the code coverage report being\ngenerated when tests are completed. The RSpec example below comes from a very simple\ncode that contains a single test for the single class that is there:",[12,144,145],{},[97,146,147],{},"spec/dog_spec.rb",[102,149,151],{"className":104,"code":150,"language":106,"meta":107,"style":107},"describe Dog do\n  it 'barks' do\n    expect(subject.bark).to eq 'Woof, woof!'\n  end\nend\n",[97,152,153,164,174,198,204],{"__ignoreMap":107},[111,154,155,158,161],{"class":113,"line":114},[111,156,157],{"class":131},"describe ",[111,159,160],{"class":128},"Dog",[111,162,163],{"class":117}," do\n",[111,165,166,169,172],{"class":113,"line":125},[111,167,168],{"class":131},"  it ",[111,170,171],{"class":121},"'barks'",[111,173,163],{"class":117},[111,175,177,180,183,186,189,192,195],{"class":113,"line":176},3,[111,178,179],{"class":134},"    expect",[111,181,182],{"class":131},"(subject.",[111,184,185],{"class":134},"bark",[111,187,188],{"class":131},").",[111,190,191],{"class":134},"to",[111,193,194],{"class":131}," eq ",[111,196,197],{"class":121},"'Woof, woof!'\n",[111,199,201],{"class":113,"line":200},4,[111,202,203],{"class":117},"  end\n",[111,205,207],{"class":113,"line":206},5,[111,208,209],{"class":117},"end\n",[12,211,212],{},[97,213,214],{},"dog.rb",[102,216,218],{"className":104,"code":217,"language":106,"meta":107,"style":107},"class Dog\n  def bark\n    'Woof, woof!'\n  end\nend\n",[97,219,220,228,236,241,245],{"__ignoreMap":107},[111,221,222,225],{"class":113,"line":114},[111,223,224],{"class":117},"class",[111,226,227],{"class":134}," Dog\n",[111,229,230,233],{"class":113,"line":125},[111,231,232],{"class":117},"  def",[111,234,235],{"class":134}," bark\n",[111,237,238],{"class":113,"line":176},[111,239,240],{"class":121},"    'Woof, woof!'\n",[111,242,243],{"class":113,"line":200},[111,244,203],{"class":117},[111,246,247],{"class":113,"line":206},[111,248,209],{"class":117},[12,250,251],{},"And the RSpec test harness output is:",[102,253,258],{"className":254,"code":256,"language":257,"meta":107},[255],"language-text","Dog\n  barks\n\nFinished in 0.00058 seconds (files took 0.08804 seconds to load)\n1 example, 0 failures\n\nCoverage report generated for RSpec to /tmp/coverage_example/coverage. 6 / 6 LOC (100.0%) covered.\n","text",[97,259,256],{"__ignoreMap":107},[12,261,262,263,266],{},"At the end of the output, you can see that code coverage report was generated\nto the ",[97,264,265],{},"coverage/"," directory whose contents look like:",[102,268,272],{"className":269,"code":270,"language":271,"meta":107,"style":107},"language-bash shiki shiki-themes github-light","$ ls coverage/\nassets/ index.html\n","bash",[97,273,274,285],{"__ignoreMap":107},[111,275,276,279,282],{"class":113,"line":114},[111,277,278],{"class":134},"$",[111,280,281],{"class":121}," ls",[111,283,284],{"class":121}," coverage/\n",[111,286,287,290],{"class":113,"line":125},[111,288,289],{"class":134},"assets/",[111,291,292],{"class":121}," index.html\n",[12,294,295],{},"Yes! This is an HTML code coverage report that we can publish with GitLab Pages!",[89,297,299],{"id":298},"gitlab-ci-configuration","GitLab CI configuration",[12,301,302,303,308,309,58],{},"Take a look at ",[27,304,307],{"href":305,"rel":306},"https://docs.gitlab.com/ci/yaml/",[],"our documentation","\nto learn more about how to use ",[97,310,311],{},".gitlab-ci.yml",[12,313,314,315,319,320,322],{},"The GitLab ",[27,316,318],{"href":317},"/solutions/continuous-integration/","CI configuration"," can be defined in ",[97,321,311],{}," file. Let's go\nthrough the configuration that is necessary to publish coverage report with\nGitLab Pages.",[324,325],"hr",{},[12,327,328],{},[329,330,331],"strong",{},"1. Run the RSpec test suite first",[12,333,334],{},"The most simple approach is to execute all tests within a single job in the\nCI pipeline:",[102,336,340],{"className":337,"code":338,"language":339,"meta":107,"style":107},"language-yaml shiki shiki-themes github-light","image: ruby:2.3\n\nrspec:\n  script:\n    - bundle install\n    - rspec\n\n","yaml",[97,341,342,354,360,367,374,382],{"__ignoreMap":107},[111,343,344,348,351],{"class":113,"line":114},[111,345,347],{"class":346},"shJU0","image",[111,349,350],{"class":131},": ",[111,352,353],{"class":121},"ruby:2.3\n",[111,355,356],{"class":113,"line":125},[111,357,359],{"emptyLinePlaceholder":358},true,"\n",[111,361,362,364],{"class":113,"line":176},[111,363,141],{"class":346},[111,365,366],{"class":131},":\n",[111,368,369,372],{"class":113,"line":200},[111,370,371],{"class":346},"  script",[111,373,366],{"class":131},[111,375,376,379],{"class":113,"line":206},[111,377,378],{"class":131},"    - ",[111,380,381],{"class":121},"bundle install\n",[111,383,385,387],{"class":113,"line":384},6,[111,386,378],{"class":131},[111,388,389],{"class":121},"rspec\n",[12,391,392],{},[329,393,394],{},"2. Store the result as build artifacts",[102,396,398],{"className":337,"code":397,"language":339,"meta":107,"style":107},"image: ruby:2.3\n\nrspec:\n  script:\n    - bundle install\n    - rspec\n  artifacts:\n    paths:\n      - coverage/\n\n",[97,399,400,408,412,418,424,430,436,444,452],{"__ignoreMap":107},[111,401,402,404,406],{"class":113,"line":114},[111,403,347],{"class":346},[111,405,350],{"class":131},[111,407,353],{"class":121},[111,409,410],{"class":113,"line":125},[111,411,359],{"emptyLinePlaceholder":358},[111,413,414,416],{"class":113,"line":176},[111,415,141],{"class":346},[111,417,366],{"class":131},[111,419,420,422],{"class":113,"line":200},[111,421,371],{"class":346},[111,423,366],{"class":131},[111,425,426,428],{"class":113,"line":206},[111,427,378],{"class":131},[111,429,381],{"class":121},[111,431,432,434],{"class":113,"line":384},[111,433,378],{"class":131},[111,435,389],{"class":121},[111,437,439,442],{"class":113,"line":438},7,[111,440,441],{"class":346},"  artifacts",[111,443,366],{"class":131},[111,445,447,450],{"class":113,"line":446},8,[111,448,449],{"class":346},"    paths",[111,451,366],{"class":131},[111,453,455,458],{"class":113,"line":454},9,[111,456,457],{"class":131},"      - ",[111,459,460],{"class":121},"coverage/\n",[12,462,463],{},"Let's see if artifacts were stored correctly using build artifacts browser\nthat is available from the build sidebar. It is there!",[12,465,466],{},[62,467],{"alt":468,"src":469},"code coverage report artifacts","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398880/blog/Content%20Images/publish-code-coverage-report-with-gitlab-pages/coverage-report-artifacts-browser.png",[12,471,472],{},[329,473,474],{},"3. Finally, publish with GitLab Pages",[12,476,477,478,58],{},"Follow the documentation about how to ",[27,479,482],{"href":480,"rel":481},"https://docs.gitlab.com/user/project/pages/",[],"use GitLab Pages",[102,484,486],{"className":337,"code":485,"language":339,"meta":107,"style":107},"image: ruby:2.3\n\nrspec:\n  stage: test\n  script:\n    - bundle install\n    - rspec\n  artifacts:\n    paths:\n      - coverage/\n\npages:\n  stage: deploy\n  dependencies:\n    - rspec\n  script:\n    - mv coverage/ public/\n  artifacts:\n    paths:\n      - public\n    expire_in: 30 days\n  only:\n    - master\n\n",[97,487,488,496,500,506,516,522,528,534,540,546,553,558,566,576,584,591,598,606,613,620,628,639,647],{"__ignoreMap":107},[111,489,490,492,494],{"class":113,"line":114},[111,491,347],{"class":346},[111,493,350],{"class":131},[111,495,353],{"class":121},[111,497,498],{"class":113,"line":125},[111,499,359],{"emptyLinePlaceholder":358},[111,501,502,504],{"class":113,"line":176},[111,503,141],{"class":346},[111,505,366],{"class":131},[111,507,508,511,513],{"class":113,"line":200},[111,509,510],{"class":346},"  stage",[111,512,350],{"class":131},[111,514,515],{"class":121},"test\n",[111,517,518,520],{"class":113,"line":206},[111,519,371],{"class":346},[111,521,366],{"class":131},[111,523,524,526],{"class":113,"line":384},[111,525,378],{"class":131},[111,527,381],{"class":121},[111,529,530,532],{"class":113,"line":438},[111,531,378],{"class":131},[111,533,389],{"class":121},[111,535,536,538],{"class":113,"line":446},[111,537,441],{"class":346},[111,539,366],{"class":131},[111,541,542,544],{"class":113,"line":454},[111,543,449],{"class":346},[111,545,366],{"class":131},[111,547,549,551],{"class":113,"line":548},10,[111,550,457],{"class":131},[111,552,460],{"class":121},[111,554,556],{"class":113,"line":555},11,[111,557,359],{"emptyLinePlaceholder":358},[111,559,561,564],{"class":113,"line":560},12,[111,562,563],{"class":346},"pages",[111,565,366],{"class":131},[111,567,569,571,573],{"class":113,"line":568},13,[111,570,510],{"class":346},[111,572,350],{"class":131},[111,574,575],{"class":121},"deploy\n",[111,577,579,582],{"class":113,"line":578},14,[111,580,581],{"class":346},"  dependencies",[111,583,366],{"class":131},[111,585,587,589],{"class":113,"line":586},15,[111,588,378],{"class":131},[111,590,389],{"class":121},[111,592,594,596],{"class":113,"line":593},16,[111,595,371],{"class":346},[111,597,366],{"class":131},[111,599,601,603],{"class":113,"line":600},17,[111,602,378],{"class":131},[111,604,605],{"class":121},"mv coverage/ public/\n",[111,607,609,611],{"class":113,"line":608},18,[111,610,441],{"class":346},[111,612,366],{"class":131},[111,614,616,618],{"class":113,"line":615},19,[111,617,449],{"class":346},[111,619,366],{"class":131},[111,621,623,625],{"class":113,"line":622},20,[111,624,457],{"class":131},[111,626,627],{"class":121},"public\n",[111,629,631,634,636],{"class":113,"line":630},21,[111,632,633],{"class":346},"    expire_in",[111,635,350],{"class":131},[111,637,638],{"class":121},"30 days\n",[111,640,642,645],{"class":113,"line":641},22,[111,643,644],{"class":346},"  only",[111,646,366],{"class":131},[111,648,650,652],{"class":113,"line":649},23,[111,651,378],{"class":131},[111,653,654],{"class":121},"master\n",[12,656,657,658,661,662,665,666,669,670,672],{},"A job that is meant to publish your code coverage report with GitLab Pages has\nto be placed in the separate stage. Stages ",[97,659,660],{},"test",", ",[97,663,664],{},"build"," and ",[97,667,668],{},"deploy"," are\nspecified by default, but you can change that if needed. Note that you also\nneed to use ",[97,671,563],{}," as a job name.",[12,674,25,675,678,679,681,682,684,685,688],{},[97,676,677],{},"dependencies"," keyword, we tell GitLab to download the artifacts stored\nas part of the ",[97,680,141],{}," job. You also need to rename the directory from ",[97,683,265],{},"\nto ",[97,686,687],{},"public/"," because this is the directory that GitLab Pages expects to find\nstatic website in.",[12,690,691,692,695,696,699],{},"It makes sense to deploy a new coverage report page only when the CI pipeline\nruns on ",[97,693,694],{},"master"," branch, so we added the ",[97,697,698],{},"only"," keyword at the end of the\nconfiguration file. This will also expire artifacts after 30 days, what does\nnot affect coverage report that has already been published.",[89,701,703],{"id":702},"how-to-run-parallel-tests","How to run parallel tests",[12,705,706],{},"Things get a little more complicated when you want to parallelize your test\nsuite.",[12,708,709],{},"GitLab is capable of running tests jobs in parallel and you can use this technique\nto decrease wall-clock elapsed time that is needed to execute all tests /\nbuilds in the CI pipeline significantly.",[12,711,712],{},"Numerous approaches are available, the most simple being to split test manually,\nwhereas the more sophisticated is to use tools or plugins that do distribute\nthe tests jobs evenly in the automated fashion.",[12,714,715],{},"Should you decide to parallelize your test suite, you will need to generate a partial\ncode coverage report in each parallel job and store it as a build artifact.\nThen, you will need another stage in the pipeline with a job that merges the partial\ncode coverage metrics into the previous one and generates a single report that takes all\nresults (generated during parallel jobs) into account.",[12,717,718,719,724,725,58],{},"At GitLab, we parallelize our test suite heavily, and we do use additional\ntools to distribute the test jobs evenly. SimpleCov does not support merging\nresult sets out-of-the-box, so we had to ",[27,720,723],{"href":721,"rel":722},"https://gitlab.com/gitlab-org/gitlab-ce/blob/master/scripts/merge-simplecov",[],"write a patch for it",".\nThere is an issue about ",[27,726,729],{"href":727,"rel":728},"https://gitlab.com/gitlab-org/gitlab-ce/issues/23717",[],"contributing this change back to the SimpleCov",[89,731,733],{"id":732},"how-to-deploy-coverage-report-as-gitlab-pages","How to deploy coverage report as GitLab Pages",[12,735,736,737,739],{},"When you push your changes in ",[97,738,311],{}," to GitLab for the first\ntime, you will see new jobs in the CI pipeline.",[12,741,742],{},[62,743],{"alt":744,"src":745},"coverage-report-deploy-job","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398881/blog/Content%20Images/publish-code-coverage-report-with-gitlab-pages/coverage-report-pages-deploy-job.png",[12,747,748,749,752,753,756,757,58],{},"If the ",[97,750,751],{},"pages:deploy"," job has been successful, the status icon for it is green.\nThis means that you can access you coverage report page using a URL like\n",[97,754,755],{},"http://group-path.gitlab.io/project-path",", for example\n",[97,758,759],{},"https://gitlab-org.gitlab.io/gitlab-ce",[12,761,762],{},"That way, a new coverage report will be published each time you push new code\nto GitLab!",[19,764,766],{"id":765},"how-to-use-the-code-coverage-report-badge","How to use the code coverage report badge",[12,768,769,770,773],{},"Once you have the code coverage report published with GitLab Pages, you may want to\nput a link to it somewhere. We recommend using the code coverage badge that you\ncan add to your ",[97,771,772],{},"README.md"," file for that purpose.",[12,775,776,777,58],{},"This is how it looks in ",[27,778,781],{"href":779,"rel":780},"https://gitlab.com/gitlab-org/gitlab-ce/blob/master/README.md",[],"our README.md",[12,783,784],{},[62,785],{"alt":786,"src":787},"coverage-badge-gitlab","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398881/blog/Content%20Images/publish-code-coverage-report-with-gitlab-pages/code-coverage-badge-gitlab.png",[12,789,790],{},"When someone clicks the coverage badge, the code coverage report page will be opened.\nThe Markdown source is as follows:",[102,792,796],{"className":793,"code":794,"language":795,"meta":107,"style":107},"language-markdown shiki shiki-themes github-light","[![Coverage report](https://gitlab.com/gitlab-org/gitlab-ce/badges/master/coverage.svg?job=coverage)](http://gitlab-org.gitlab.io/gitlab-ce/coverage-ruby)\n","markdown",[97,797,798],{"__ignoreMap":107},[111,799,800,803,807,810,814],{"class":113,"line":114},[111,801,802],{"class":131},"[",[111,804,806],{"class":805},"sEuWB","![Coverage report](https://gitlab.com/gitlab-org/gitlab-ce/badges/master/coverage.svg?job=coverage)",[111,808,809],{"class":131},"](",[111,811,813],{"class":812},"se9n6","http://gitlab-org.gitlab.io/gitlab-ce/coverage-ruby",[111,815,816],{"class":131},")\n",[12,818,819,820,58],{},"You can find more info about report badges and the other types of badges in ",[27,821,307],{"href":822,"rel":823},"https://docs.gitlab.com/ci/pipelines/settings/#pipeline-badges",[],[19,825,827],{"id":826},"summary","Summary",[12,829,830],{},"Although the code coverage technique is great for revealing untested code and\nimproving overall coverage, it is not a great metric to tell how good\nthe tests are, but it helps people to contribute.",[12,832,833],{},"With GitLab, you can create simple software that it is easy to contribute to!",[835,836,837],"style",{},"html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}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 .sEuWB, html code.shiki .sEuWB{--shiki-default:#032F62;--shiki-default-text-decoration:underline}html pre.shiki code .se9n6, html code.shiki .se9n6{--shiki-default:#24292E;--shiki-default-text-decoration:underline}",{"title":107,"searchDepth":125,"depth":125,"links":839},[840,841,847,848],{"id":21,"depth":125,"text":22},{"id":68,"depth":125,"text":69,"children":842},[843,844,845,846],{"id":91,"depth":176,"text":92},{"id":298,"depth":176,"text":299},{"id":702,"depth":176,"text":703},{"id":732,"depth":176,"text":733},{"id":765,"depth":125,"text":766},{"id":826,"depth":125,"text":827},"engineering","2016-11-03","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749672293/Blog/Hero%20Images/code-coverage-report-stats.png",{"excerpt":856},{"type":9,"value":857},[858,860],[12,859,14],{},[12,861,17],{},"/en-us/blog/publish-code-coverage-report-with-gitlab-pages",{"title":5,"description":5,"ogTitle":5,"ogDescription":5,"noIndex":853,"ogImage":854,"ogUrl":864,"ogSiteName":865,"ogType":866,"canonicalUrls":864},"https://about.gitlab.com/blog/publish-code-coverage-report-with-gitlab-pages","https://about.gitlab.com","article","publish-code-coverage-report-with-gitlab-pages","en-us/blog/publish-code-coverage-report-with-gitlab-pages","BlogPost","XsPqxaXGU87fyZlcgJY2lOXLfABebmfnS7v37fEJMwY",{"logo":872,"freeTrial":877,"sales":882,"login":887,"items":892,"search":1217,"minimal":1248,"duo":1267,"switchNav":1276,"pricingDeployment":1287},{"config":873},{"href":874,"dataGaName":875,"dataGaLocation":876},"/","gitlab logo","header",{"text":878,"config":879},"Get free trial",{"href":880,"dataGaName":881,"dataGaLocation":876},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":883,"config":884},"Request a demo",{"href":885,"dataGaName":886,"dataGaLocation":876},"/sales/?contact-topic=request-demo","sales",{"text":888,"config":889},"Sign in",{"href":890,"dataGaName":891,"dataGaLocation":876},"https://gitlab.com/users/sign_in/","sign in",[893,922,1020,1025,1139,1195],{"text":894,"config":895,"menu":897},"Platform",{"dataNavLevelOne":896},"platform",{"type":898,"columns":899},"cards",[900,906,914],{"title":894,"description":901,"link":902},"The intelligent orchestration platform for DevSecOps",{"text":903,"config":904},"Explore our Platform",{"href":905,"dataGaName":896,"dataGaLocation":876},"/platform/",{"title":907,"description":908,"link":909},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":910,"config":911},"Meet GitLab Duo",{"href":912,"dataGaName":913,"dataGaLocation":876},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":915,"description":916,"link":917},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":918,"config":919},"Learn more",{"href":920,"dataGaName":921,"dataGaLocation":876},"/why-gitlab/","why gitlab",{"text":923,"left":358,"config":924,"menu":926},"Product",{"dataNavLevelOne":925},"solutions",{"type":927,"link":928,"columns":932,"feature":999},"lists",{"text":929,"config":930},"View all Solutions",{"href":931,"dataGaName":925,"dataGaLocation":876},"/solutions/",[933,955,978],{"title":934,"description":935,"link":936,"items":941},"Automation","CI/CD and automation to accelerate deployment",{"config":937},{"icon":938,"href":939,"dataGaName":940,"dataGaLocation":876},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[942,945,948,951],{"text":943,"config":944},"CI/CD",{"href":317,"dataGaLocation":876,"dataGaName":943},{"text":907,"config":946},{"href":912,"dataGaLocation":876,"dataGaName":947},"gitlab duo agent platform - product menu",{"text":949,"config":950},"Source Code Management",{"href":38,"dataGaLocation":876,"dataGaName":949},{"text":952,"config":953},"Automated Software Delivery",{"href":939,"dataGaLocation":876,"dataGaName":954},"Automated software delivery",{"title":956,"description":957,"link":958,"items":963},"Security","Deliver code faster without compromising security",{"config":959},{"href":960,"dataGaName":961,"dataGaLocation":876,"icon":962},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[964,968,973],{"text":965,"config":966},"Application Security Testing",{"href":960,"dataGaName":967,"dataGaLocation":876},"Application security testing",{"text":969,"config":970},"Software Supply Chain Security",{"href":971,"dataGaLocation":876,"dataGaName":972},"/solutions/supply-chain/","Software supply chain security",{"text":974,"config":975},"Software Compliance",{"href":976,"dataGaName":977,"dataGaLocation":876},"/solutions/software-compliance/","software compliance",{"title":979,"link":980,"items":985},"Measurement",{"config":981},{"icon":982,"href":983,"dataGaName":984,"dataGaLocation":876},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[986,990,994],{"text":987,"config":988},"Visibility & Measurement",{"href":983,"dataGaLocation":876,"dataGaName":989},"Visibility and Measurement",{"text":991,"config":992},"Value Stream Management",{"href":993,"dataGaLocation":876,"dataGaName":991},"/solutions/value-stream-management/",{"text":995,"config":996},"Analytics & Insights",{"href":997,"dataGaLocation":876,"dataGaName":998},"/solutions/analytics-and-insights/","Analytics and insights",{"title":1000,"type":927,"items":1001},"GitLab for",[1002,1008,1014],{"text":1003,"config":1004},"Enterprise",{"icon":1005,"href":1006,"dataGaLocation":876,"dataGaName":1007},"Building","/enterprise/","enterprise",{"text":1009,"config":1010},"Small Business",{"icon":1011,"href":1012,"dataGaLocation":876,"dataGaName":1013},"Work","/small-business/","small business",{"text":1015,"config":1016},"Public Sector",{"icon":1017,"href":1018,"dataGaLocation":876,"dataGaName":1019},"Organization","/solutions/public-sector/","public sector",{"text":1021,"config":1022},"Pricing",{"href":1023,"dataGaName":1024,"dataGaLocation":876,"dataNavLevelOne":1024},"/pricing/","pricing",{"text":1026,"config":1027,"menu":1029},"Resources",{"dataNavLevelOne":1028},"resources",{"type":927,"link":1030,"columns":1034,"feature":1128},{"text":1031,"config":1032},"View all resources",{"href":1033,"dataGaName":1028,"dataGaLocation":876},"/resources/",[1035,1068,1095],{"title":1036,"items":1037},"Getting started",[1038,1043,1048,1053,1058,1063],{"text":1039,"config":1040},"Install",{"href":1041,"dataGaName":1042,"dataGaLocation":876},"/install/","install",{"text":1044,"config":1045},"Quick start guides",{"href":1046,"dataGaName":1047,"dataGaLocation":876},"/get-started/","quick setup checklists",{"text":1049,"config":1050},"Learn",{"href":1051,"dataGaLocation":876,"dataGaName":1052},"https://university.gitlab.com/","learn",{"text":1054,"config":1055},"Product documentation",{"href":1056,"dataGaName":1057,"dataGaLocation":876},"https://docs.gitlab.com/","product documentation",{"text":1059,"config":1060},"Best practice videos",{"href":1061,"dataGaName":1062,"dataGaLocation":876},"/getting-started-videos/","best practice videos",{"text":1064,"config":1065},"Integrations",{"href":1066,"dataGaName":1067,"dataGaLocation":876},"/integrations/","integrations",{"title":1069,"items":1070},"Discover",[1071,1076,1081,1086,1090],{"text":1072,"config":1073},"Customer success stories",{"href":1074,"dataGaName":1075,"dataGaLocation":876},"/customers/","customer success stories",{"text":1077,"config":1078},"Blog",{"href":1079,"dataGaName":1080,"dataGaLocation":876},"/blog/","blog",{"text":1082,"config":1083},"Demo Hub",{"href":1084,"dataGaName":1085,"dataGaLocation":876},"/demo-hub/","demo hub",{"text":1087,"config":1088},"The Source",{"href":1089,"dataGaName":1080,"dataGaLocation":876},"/the-source/",{"text":1091,"config":1092},"Remote",{"href":1093,"dataGaName":1094,"dataGaLocation":876},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":1096,"items":1097},"Connect",[1098,1103,1108,1113,1118,1123],{"text":1099,"config":1100},"GitLab Services",{"href":1101,"dataGaName":1102,"dataGaLocation":876},"/services/","services",{"text":1104,"config":1105},"Contribute",{"href":1106,"dataGaName":1107,"dataGaLocation":876},"https://contributors.gitlab.com","contribute",{"text":1109,"config":1110},"Community",{"href":1111,"dataGaName":1112,"dataGaLocation":876},"/community/","community",{"text":1114,"config":1115},"Forum",{"href":1116,"dataGaName":1117,"dataGaLocation":876},"https://forum.gitlab.com/","forum",{"text":1119,"config":1120},"Events",{"href":1121,"dataGaName":1122,"dataGaLocation":876},"/events/","events",{"text":1124,"config":1125},"Partners",{"href":1126,"dataGaName":1127,"dataGaLocation":876},"/partners/","partners",{"config":1129,"title":1132,"text":1133,"link":1134},{"background":1130,"textColor":1131},"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":1135,"config":1136},"Read the latest",{"href":1137,"dataGaName":1138,"dataGaLocation":876},"/whats-new/","whats new",{"text":1140,"config":1141,"menu":1143},"Company",{"dataNavLevelOne":1142},"company",{"type":927,"columns":1144},[1145],{"items":1146},[1147,1152,1158,1160,1165,1170,1175,1180,1185,1190],{"text":1148,"config":1149},"About",{"href":1150,"dataGaName":1151,"dataGaLocation":876},"/company/","about",{"text":1153,"config":1154,"footerGa":1157},"Jobs",{"href":1155,"dataGaName":1156,"dataGaLocation":876},"/jobs/","jobs",{"dataGaName":1156},{"text":1119,"config":1159},{"href":1121,"dataGaName":1122,"dataGaLocation":876},{"text":1161,"config":1162},"Leadership",{"href":1163,"dataGaName":1164,"dataGaLocation":876},"/company/team/e-group/","leadership",{"text":1166,"config":1167},"Handbook",{"href":1168,"dataGaName":1169,"dataGaLocation":876},"https://handbook.gitlab.com/","handbook",{"text":1171,"config":1172},"Investor relations",{"href":1173,"dataGaName":1174,"dataGaLocation":876},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":1176,"config":1177},"Trust Center",{"href":1178,"dataGaName":1179,"dataGaLocation":876},"/security/","trust center",{"text":1181,"config":1182},"AI Transparency Center",{"href":1183,"dataGaName":1184,"dataGaLocation":876},"/ai-transparency-center/","ai transparency center",{"text":1186,"config":1187},"Newsletter",{"href":1188,"dataGaName":1189,"dataGaLocation":876},"/company/contact/#contact-forms","newsletter",{"text":1191,"config":1192},"Press",{"href":1193,"dataGaName":1194,"dataGaLocation":876},"/press/","press",{"text":1196,"config":1197,"menu":1198},"Contact us",{"dataNavLevelOne":1142},{"type":927,"columns":1199},[1200],{"items":1201},[1202,1207,1212],{"text":1203,"config":1204},"Talk to sales",{"href":1205,"dataGaName":1206,"dataGaLocation":876},"/sales/","talk to sales",{"text":1208,"config":1209},"Support portal",{"href":1210,"dataGaName":1211,"dataGaLocation":876},"https://support.gitlab.com/hc/en-us","support portal",{"text":1213,"config":1214},"Customer portal",{"href":1215,"dataGaName":1216,"dataGaLocation":876},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":1218,"login":1219,"suggestions":1226},"Close",{"text":1220,"link":1221},"To search repositories and projects, login to",{"text":1222,"config":1223},"gitlab.com",{"href":890,"dataGaName":1224,"dataGaLocation":1225},"search login","search",{"text":1227,"default":1228},"Suggestions",[1229,1231,1235,1237,1241,1245],{"text":907,"config":1230},{"href":912,"dataGaName":907,"dataGaLocation":1225},{"text":1232,"config":1233},"Code Suggestions (AI)",{"href":1234,"dataGaName":1232,"dataGaLocation":1225},"/solutions/code-suggestions/",{"text":943,"config":1236},{"href":317,"dataGaName":943,"dataGaLocation":1225},{"text":1238,"config":1239},"GitLab on AWS",{"href":1240,"dataGaName":1238,"dataGaLocation":1225},"/partners/technology-partners/aws/",{"text":1242,"config":1243},"GitLab on Google Cloud",{"href":1244,"dataGaName":1242,"dataGaLocation":1225},"/partners/technology-partners/google-cloud-platform/",{"text":1246,"config":1247},"Why GitLab?",{"href":920,"dataGaName":1246,"dataGaLocation":1225},{"freeTrial":1249,"mobileIcon":1254,"desktopIcon":1259,"secondaryButton":1262},{"text":1250,"config":1251},"Start free trial",{"href":1252,"dataGaName":881,"dataGaLocation":1253},"https://gitlab.com/-/trials/new/","nav",{"altText":1255,"config":1256},"Gitlab Icon",{"src":1257,"dataGaName":1258,"dataGaLocation":1253},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":1255,"config":1260},{"src":1261,"dataGaName":1258,"dataGaLocation":1253},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":1263,"config":1264},"Get Started",{"href":1265,"dataGaName":1266,"dataGaLocation":1253},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":1268,"mobileIcon":1272,"desktopIcon":1274},{"text":1269,"config":1270},"Learn more about GitLab Duo",{"href":912,"dataGaName":1271,"dataGaLocation":1253},"gitlab duo",{"altText":1255,"config":1273},{"src":1257,"dataGaName":1258,"dataGaLocation":1253},{"altText":1255,"config":1275},{"src":1261,"dataGaName":1258,"dataGaLocation":1253},{"button":1277,"mobileIcon":1282,"desktopIcon":1284},{"text":1278,"config":1279},"/switch",{"href":1280,"dataGaName":1281,"dataGaLocation":1253},"#contact","switch",{"altText":1255,"config":1283},{"src":1257,"dataGaName":1258,"dataGaLocation":1253},{"altText":1255,"config":1285},{"src":1286,"dataGaName":1258,"dataGaLocation":1253},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":1288,"mobileIcon":1293,"desktopIcon":1295},{"text":1289,"config":1290},"Back to pricing",{"href":1023,"dataGaName":1291,"dataGaLocation":1253,"icon":1292},"back to pricing","GoBack",{"altText":1255,"config":1294},{"src":1257,"dataGaName":1258,"dataGaLocation":1253},{"altText":1255,"config":1296},{"src":1261,"dataGaName":1258,"dataGaLocation":1253},{"title":1298,"titleMobile":1299,"button":1300,"config":1305},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":918,"config":1301},{"href":1302,"dataGaName":1303,"dataGaLocation":1304},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":1306,"disabled":853},"release",{"data":1308},{"text":1309,"source":1310,"edit":1316,"contribute":1321,"config":1326,"items":1331,"minimal":1541},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":1311,"config":1312},"View page source",{"href":1313,"dataGaName":1314,"dataGaLocation":1315},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":1317,"config":1318},"Edit this page",{"href":1319,"dataGaName":1320,"dataGaLocation":1315},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":1322,"config":1323},"Please contribute",{"href":1324,"dataGaName":1325,"dataGaLocation":1315},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":1327,"facebook":1328,"youtube":1329,"linkedin":1330},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[1332,1379,1433,1477,1509],{"title":1021,"links":1333,"subMenu":1348},[1334,1338,1343],{"text":1335,"config":1336},"View plans",{"href":1023,"dataGaName":1337,"dataGaLocation":1315},"view plans",{"text":1339,"config":1340},"Why Premium?",{"href":1341,"dataGaName":1342,"dataGaLocation":1315},"/pricing/premium/","why premium",{"text":1344,"config":1345},"Why Ultimate?",{"href":1346,"dataGaName":1347,"dataGaLocation":1315},"/pricing/ultimate/","why ultimate",[1349],{"title":1350,"links":1351},"Contact Us",[1352,1355,1357,1359,1364,1369,1374],{"text":1353,"config":1354},"Contact sales",{"href":1205,"dataGaName":886,"dataGaLocation":1315},{"text":1208,"config":1356},{"href":1210,"dataGaName":1211,"dataGaLocation":1315},{"text":1213,"config":1358},{"href":1215,"dataGaName":1216,"dataGaLocation":1315},{"text":1360,"config":1361},"Status",{"href":1362,"dataGaName":1363,"dataGaLocation":1315},"https://status.gitlab.com/","status",{"text":1365,"config":1366},"Terms of use",{"href":1367,"dataGaName":1368,"dataGaLocation":1315},"/terms/","terms of use",{"text":1370,"config":1371},"Privacy statement",{"href":1372,"dataGaName":1373,"dataGaLocation":1315},"/privacy/","privacy statement",{"text":1375,"config":1376},"Cookie preferences",{"dataGaName":1377,"dataGaLocation":1315,"id":1378,"isOneTrustButton":358},"cookie preferences","ot-sdk-btn",{"title":923,"links":1380,"subMenu":1389},[1381,1385],{"text":1382,"config":1383},"DevSecOps platform",{"href":905,"dataGaName":1384,"dataGaLocation":1315},"devsecops platform",{"text":1386,"config":1387},"AI-Assisted Development",{"href":912,"dataGaName":1388,"dataGaLocation":1315},"ai-assisted development",[1390],{"title":1391,"links":1392},"Topics",[1393,1398,1403,1408,1413,1418,1423,1428],{"text":1394,"config":1395},"CICD",{"href":1396,"dataGaName":1397,"dataGaLocation":1315},"/topics/ci-cd/","cicd",{"text":1399,"config":1400},"GitOps",{"href":1401,"dataGaName":1402,"dataGaLocation":1315},"/topics/gitops/","gitops",{"text":1404,"config":1405},"DevOps",{"href":1406,"dataGaName":1407,"dataGaLocation":1315},"/topics/devops/","devops",{"text":1409,"config":1410},"Version Control",{"href":1411,"dataGaName":1412,"dataGaLocation":1315},"/topics/version-control/","version control",{"text":1414,"config":1415},"DevSecOps",{"href":1416,"dataGaName":1417,"dataGaLocation":1315},"/topics/devsecops/","devsecops",{"text":1419,"config":1420},"Cloud Native",{"href":1421,"dataGaName":1422,"dataGaLocation":1315},"/topics/cloud-native/","cloud native",{"text":1424,"config":1425},"AI for Coding",{"href":1426,"dataGaName":1427,"dataGaLocation":1315},"/topics/devops/ai-for-coding/","ai for coding",{"text":1429,"config":1430},"Agentic AI",{"href":1431,"dataGaName":1432,"dataGaLocation":1315},"/topics/agentic-ai/","agentic ai",{"title":1434,"links":1435},"Solutions",[1436,1438,1440,1445,1449,1452,1456,1459,1461,1464,1467,1472],{"text":965,"config":1437},{"href":960,"dataGaName":965,"dataGaLocation":1315},{"text":954,"config":1439},{"href":939,"dataGaName":940,"dataGaLocation":1315},{"text":1441,"config":1442},"Agile development",{"href":1443,"dataGaName":1444,"dataGaLocation":1315},"/solutions/agile-delivery/","agile delivery",{"text":1446,"config":1447},"SCM",{"href":38,"dataGaName":1448,"dataGaLocation":1315},"source code management",{"text":1394,"config":1450},{"href":317,"dataGaName":1451,"dataGaLocation":1315},"continuous integration & delivery",{"text":1453,"config":1454},"Value stream management",{"href":993,"dataGaName":1455,"dataGaLocation":1315},"value stream management",{"text":1399,"config":1457},{"href":1458,"dataGaName":1402,"dataGaLocation":1315},"/solutions/gitops/",{"text":1003,"config":1460},{"href":1006,"dataGaName":1007,"dataGaLocation":1315},{"text":1462,"config":1463},"Small business",{"href":1012,"dataGaName":1013,"dataGaLocation":1315},{"text":1465,"config":1466},"Public sector",{"href":1018,"dataGaName":1019,"dataGaLocation":1315},{"text":1468,"config":1469},"Education",{"href":1470,"dataGaName":1471,"dataGaLocation":1315},"/solutions/education/","education",{"text":1473,"config":1474},"Financial services",{"href":1475,"dataGaName":1476,"dataGaLocation":1315},"/solutions/finance/","financial services",{"title":1026,"links":1478},[1479,1481,1483,1485,1488,1490,1493,1495,1497,1499,1501,1503,1505,1507],{"text":1039,"config":1480},{"href":1041,"dataGaName":1042,"dataGaLocation":1315},{"text":1044,"config":1482},{"href":1046,"dataGaName":1047,"dataGaLocation":1315},{"text":1049,"config":1484},{"href":1051,"dataGaName":1052,"dataGaLocation":1315},{"text":1054,"config":1486},{"href":1056,"dataGaName":1487,"dataGaLocation":1315},"docs",{"text":1077,"config":1489},{"href":1079,"dataGaName":1080,"dataGaLocation":1315},{"text":1491,"config":1492},"What's new",{"href":1137,"dataGaName":1138,"dataGaLocation":1315},{"text":1072,"config":1494},{"href":1074,"dataGaName":1075,"dataGaLocation":1315},{"text":1091,"config":1496},{"href":1093,"dataGaName":1094,"dataGaLocation":1315},{"text":1099,"config":1498},{"href":1101,"dataGaName":1102,"dataGaLocation":1315},{"text":1104,"config":1500},{"href":1106,"dataGaName":1107,"dataGaLocation":1315},{"text":1109,"config":1502},{"href":1111,"dataGaName":1112,"dataGaLocation":1315},{"text":1114,"config":1504},{"href":1116,"dataGaName":1117,"dataGaLocation":1315},{"text":1119,"config":1506},{"href":1121,"dataGaName":1122,"dataGaLocation":1315},{"text":1124,"config":1508},{"href":1126,"dataGaName":1127,"dataGaLocation":1315},{"title":1140,"links":1510},[1511,1513,1515,1517,1519,1521,1525,1530,1532,1534,1536],{"text":1148,"config":1512},{"href":1150,"dataGaName":1142,"dataGaLocation":1315},{"text":1153,"config":1514},{"href":1155,"dataGaName":1156,"dataGaLocation":1315},{"text":1161,"config":1516},{"href":1163,"dataGaName":1164,"dataGaLocation":1315},{"text":1166,"config":1518},{"href":1168,"dataGaName":1169,"dataGaLocation":1315},{"text":1171,"config":1520},{"href":1173,"dataGaName":1174,"dataGaLocation":1315},{"text":1522,"config":1523},"Sustainability",{"href":1524,"dataGaName":1522,"dataGaLocation":1315},"/sustainability/",{"text":1526,"config":1527},"Diversity, inclusion and belonging (DIB)",{"href":1528,"dataGaName":1529,"dataGaLocation":1315},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":1176,"config":1531},{"href":1178,"dataGaName":1179,"dataGaLocation":1315},{"text":1186,"config":1533},{"href":1188,"dataGaName":1189,"dataGaLocation":1315},{"text":1191,"config":1535},{"href":1193,"dataGaName":1194,"dataGaLocation":1315},{"text":1537,"config":1538},"Modern Slavery Transparency Statement",{"href":1539,"dataGaName":1540,"dataGaLocation":1315},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":1542},[1543,1546,1549],{"text":1544,"config":1545},"Terms",{"href":1367,"dataGaName":1368,"dataGaLocation":1315},{"text":1547,"config":1548},"Cookies",{"dataGaName":1377,"dataGaLocation":1315,"id":1378,"isOneTrustButton":358},{"text":1550,"config":1551},"Privacy",{"href":1372,"dataGaName":1373,"dataGaLocation":1315},[1553],{"id":1554,"title":7,"body":852,"config":1555,"content":1557,"description":852,"extension":1561,"meta":1562,"navigation":358,"path":1563,"seo":1564,"stem":1565,"__hash__":1566},"blogAuthors/en-us/blog/authors/grzegorz-bizon.yml",{"template":1556},"BlogAuthor",{"name":7,"config":1558},{"headshot":1559,"ctfId":1560},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659488/Blog/Author%20Headshots/gitlab-logo-extra-whitespace.png","Grzegorz-Bizon","yml",{},"/en-us/blog/authors/grzegorz-bizon",{},"en-us/blog/authors/grzegorz-bizon","Z1aKSWxubaVpieVMM-H8afTapWLnKt0xl0AyT32DmJE",[1568,1577,1585],{"title":1569,"description":1570,"heroImage":1571,"category":849,"date":1572,"authors":1573,"slug":1576,"externalUrl":852},"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",[1574,1575],"Mathias Ewald","Martin Paloncy, Edgeless Systems","confidential-ai-for-gitlab-self-hosted",{"title":1578,"description":1579,"heroImage":1580,"category":849,"date":1581,"authors":1582,"slug":1584,"externalUrl":852},"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",[1583],"Lysanne Pinto","green-devops-carbon-measurement-cicd-pipeline",{"title":1586,"description":1587,"heroImage":1588,"category":849,"date":1589,"authors":1590,"slug":1592,"externalUrl":852},"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",[1591],"Paul Meresanu","how-to-build-ci-cd-observability-at-scale",{"promotions":1594},[1595,1609,1621,1633],{"id":1596,"categories":1597,"header":1599,"text":1600,"button":1601,"image":1606},"ai-modernization",[1598],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":1602,"config":1603},"Get your AI maturity score",{"href":1604,"dataGaName":1605,"dataGaLocation":1080},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":1607},{"src":1608},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":1610,"categories":1611,"header":1613,"text":1600,"button":1614,"image":1618},"devops-modernization",[1612,1417],"product","Are you just managing tools or shipping innovation?",{"text":1615,"config":1616},"Get your DevOps maturity score",{"href":1617,"dataGaName":1605,"dataGaLocation":1080},"/assessments/devops-modernization-assessment/",{"config":1619},{"src":1620},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":1622,"categories":1623,"header":1625,"text":1600,"button":1626,"image":1630},"security-modernization",[1624],"security","Are you trading speed for security?",{"text":1627,"config":1628},"Get your security maturity score",{"href":1629,"dataGaName":1605,"dataGaLocation":1080},"/assessments/security-modernization-assessment/",{"config":1631},{"src":1632},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":1634,"paths":1635,"header":1638,"text":1639,"button":1640,"image":1645},"github-azure-migration",[1636,1637],"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":1641,"config":1642},"See how GitLab compares to GitHub",{"href":1643,"dataGaName":1644,"dataGaLocation":1080},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":1646},{"src":1620},{"header":1648,"blurb":1649,"button":1650,"secondaryButton":1655},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":1651,"config":1652},"Get your free trial",{"href":1653,"dataGaName":881,"dataGaLocation":1654},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":1353,"config":1656},{"href":1205,"dataGaName":886,"dataGaLocation":1654},1786734933602]