[{"data":1,"prerenderedAt":1067},["ShallowReactive",2],{"/blog/how-we-migrated-our-markdown-processing-to-commonmark":3,"navigation-en-us":279,"banner-en-us":707,"footer-en-us":717,"blog-post-authors-en-us-Brett Walker":962,"blog-related-posts-en-us-how-we-migrated-our-markdown-processing-to-commonmark":977,"blog-promotions-en-us":1003,"next-steps-en-us":1057},{"id":4,"title":5,"authors":6,"body":8,"category":259,"date":260,"description":261,"extension":262,"externalUrl":263,"faq":263,"featured":264,"heroImage":265,"meta":266,"navigation":267,"path":268,"seo":269,"slug":273,"stem":274,"tags":275,"template":277,"updatedDate":263,"__hash__":278},"blogPosts/en-us/blog/how-we-migrated-our-markdown-processing-to-commonmark.md","How we migrated to CommonMark",[7],"Brett Walker",{"type":9,"value":10,"toc":251},"minimark",[11,21,26,41,49,58,73,76,79,93,97,106,111,120,128,137,141,149,152,166,170,173,176,180,183,212,225,239,243],[12,13,14,20],"p",{},[15,16,19],"a",{"href":17,"rel":18},"https://daringfireball.net/projects/markdown/",[],"Markdown"," was originally created by John Gruber as a way of writing readable plain text that can be easily converted into HTML or XHTML. Over the years it has become widely adopted for writing online content, whether it's a blog post, discussion threads, documentation, and even books.",[22,23,25],"h3",{"id":24},"why-we-moved-to-commonmark","Why we moved to CommonMark",[12,27,28,29,34,35,40],{},"Various \"flavors\" of Markdown have been created, each with their own extensions and idiosyncrasies. ",[15,30,33],{"href":31,"rel":32},"https://github.github.com/gfm/",[],"GitHub Flavored Markdown"," is one of the most widely used and adopted set of extensions (such as task lists). With all the flavors behaving a little differently, it has become increasingly difficult to write Markdown content and have it ",[15,36,39],{"href":37,"rel":38},"https://babelmark.github.io",[],"properly rendered everywhere",".",[12,42,43,48],{},[15,44,47],{"href":45,"rel":46},"https://docs.gitlab.com/user/markdown/",[],"GitLab uses Markdown extensively"," – almost all user-generated content is written in it, from issue and merge request descriptions, to comments and discussions, wiki pages, etc.",[12,50,51,52,57],{},"The goal of ",[15,53,56],{"href":54,"rel":55},"https://commonmark.org",[],"CommonMark"," is to create \"a strongly defined, highly compatible specification of Markdown\":",[59,60,61],"blockquote",{},[12,62,63,64,68,69,72],{},"We propose a ",[65,66,67],"strong",{},"standard, unambiguous syntax specification for Markdown",", along with a ",[65,70,71],{},"suite of comprehensive tests"," to validate Markdown implementations against this specification. We believe this is necessary, even essential, for the future of Markdown.",[12,74,75],{},"By adopting CommonMark as standard, we move closer to having Markdown files that are consistently rendered across applications. Ideally, Markdown content should be able to be rendered the same on GitHub, GitLab, or any other Markdown-aware application.",[12,77,78],{},"Users have also opened numerous issues about our Markdown not working as they expected. CommonMark solves most of these problems, and therefore gives our users a more consistent and usable experience.",[12,80,81,82,87,88,40],{},"Many platforms have also migrated to CommonMark, including ",[15,83,86],{"href":84,"rel":85},"https://github.com",[],"GitHub"," and ",[15,89,92],{"href":90,"rel":91},"https://discourse.org",[],"Discourse",[22,94,96],{"id":95},"phases-of-migration","Phases of migration",[12,98,99,100,105],{},"We rolled out the migration in phases, wanting to make it as painless as possible. We achieved this with the gracious help of ",[15,101,104],{"href":102,"rel":103},"https://gitlab.com/blackst0ne",[],"@blackst0ne"," who started the effort.",[107,108,110],"h4",{"id":109},"phase-1-only-new-content","Phase 1: Only new content",[12,112,113,114,119],{},"In the first phase (",[15,115,118],{"href":116,"rel":117},"https://docs.gitlab.com/releases/",[],"GitLab 11.1","), we only allowed CommonMark to be used in newly created content, such as issue and merge request descriptions, comments, etc. Any older content, even if edited, would continue to be rendered using RedCarpet.",[12,121,122,123,127],{},"Since we cache rendered Markdown for performance, we keep a ",[124,125,126],"code",{},"cached_markdown_version"," value in our database. Using this, we were able to determine whether the content should be rendered with CommonMark or not. As the largest version number at the time was 3, we designated version 10 as being the start of any CommonMark cached content. Anything less would be considered RedCarpet markdown.",[12,129,130,131,136],{},"Additionally we did not use CommonMark for repository and wiki files.  We wanted a ",[15,132,135],{"href":133,"rel":134},"https://handbook.gitlab.com/handbook/values/#minimal-viable-change-mvc",[],"minimal viable change"," to not only test the waters but minimize any initial problems.",[107,138,140],{"id":139},"phase-2-repository-and-wiki-files","Phase 2: Repository and wiki files",[12,142,143,144,148],{},"The next step (",[15,145,147],{"href":116,"rel":146},[],"GitLab 11.3",") was to allow repository and wiki files to be rendered with CommonMark. This was a bigger change in the sense that existing content could potentially look different.",[12,150,151],{},"In practice, RedCarpet and CommonMark are very similar, as would be expected, and are in general compatible. There are a few instances where the syntax is different, such as the indentation needed for bulleted lists inside a numbered list, or the use of superscripts, which CommonMark does not support. For most documents, no change is needed.",[12,153,154,155,160,161,40],{},"However we also knew that we couldn't touch user files or do any sort of migration. Instead, we created a ",[15,156,159],{"href":157,"rel":158},"https://gitlab.com/digitalmoksha/diff_redcarpet_cmark",[],"small tool"," that can generate the changes necessary for files to be converted. This is done by rendering into HTML using RedCarpet, and then generating CommonMark from it using ",[15,162,165],{"href":163,"rel":164},"https://pandoc.org",[],"Pandoc",[107,167,169],{"id":168},"phase-3-commonmark-throughout","Phase 3: CommonMark throughout",[12,171,172],{},"The final phase was to remove RedCarpet completely. By this time, CommonMark had been in use for several months – only older content was still being rendered with RedCarpet. However, we were accumulating technical debt by supporting both methods – new functionality or security fixes had to consider both renderers.",[12,174,175],{},"With RedCarpet removed, we now display older content with CommonMark. Differences are small and only affect a small percentage of the overall content, and the possibility of looking at older issues or merge requests decreases with time.",[107,177,179],{"id":178},"improvements-upstream","Improvements upstream",[12,181,182],{},"There were a couple of issues we ran into during the implementation where we were able to drive some changes to the upstream libraries.",[12,184,185,186,189,190,195,196,201,202,205,206,211],{},"The first is that RedCarpet supports using ",[124,187,188],{},"~~"," to indicate using strikethrough. We use ",[15,191,194],{"href":192,"rel":193},"https://github.com/github/cmark-gfm",[],"cmark-gfm"," for rendering, giving us both CommonMark and common GitHub Flavored Markdown extensions. And although it supports using any number of tildes for strikethrough, we wanted to make the transition a little easier by ",[15,197,200],{"href":198,"rel":199},"https://github.com/github/cmark-gfm/issues/71",[],"only supporting double tildes",". A new option, ",[124,203,204],{},"CMARK_OPT_STRIKETHROUGH_DOUBLE_TILDE",", was added to ",[15,207,210],{"href":208,"rel":209},"https://github.com/gjtorikian/commonmarker/commit/1a973ba872e50b22ee53652ffa12cdfe2fe90155",[]," gjtorikian/commonmarker",", allowing us to turn on support for double-tilde strikethroughs.",[12,213,214,215,220,221,224],{},"Second, we found a bug in ",[15,216,219],{"href":217,"rel":218},"https://github.com/gjtorikian/commonmarker/issues/56",[],"gjtorikian/commonmarker",", where a ",[124,222,223],{},"\u003Ctbody>"," wasn't getting rendered. This was quickly fixed.",[12,226,227,228,87,233,238],{},"Many thanks to ",[15,229,232],{"href":230,"rel":231},"https://github.com/kivikakk",[],"@kivikakk",[15,234,237],{"href":235,"rel":236},"https://github.com/gjtorikian",[],"@gjtorikian"," for their help with these issues.",[22,240,242],{"id":241},"conclusion","Conclusion",[12,244,245,246,250],{},"The transition took several months, but we're happy to have moved our Markdown processing to the next level. And should you run into the few problematic edge cases, ",[15,247,249],{"href":157,"rel":248},[],"diff_redcarpet_cmark"," should be able to help.",{"title":252,"searchDepth":253,"depth":253,"links":254},"",2,[255,257,258],{"id":24,"depth":256,"text":25},3,{"id":95,"depth":256,"text":96},{"id":241,"depth":256,"text":242},"engineering","2019-06-13","A senior backend engineer shares how (and why) we migrated our Markdown processing from RedCarpet to CommonMark.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749671172/Blog/Hero%20Images/markdown-tutorial-cover.png",{},true,"/en-us/blog/how-we-migrated-our-markdown-processing-to-commonmark",{"title":5,"description":261,"ogTitle":5,"ogDescription":261,"noIndex":264,"ogImage":265,"ogUrl":270,"ogSiteName":271,"ogType":272,"canonicalUrls":270},"https://about.gitlab.com/blog/how-we-migrated-our-markdown-processing-to-commonmark","https://about.gitlab.com","article","how-we-migrated-our-markdown-processing-to-commonmark","en-us/blog/how-we-migrated-our-markdown-processing-to-commonmark",[276],"collaboration","BlogPost","xcOAyu2_NFJrHZCO0e6YfkvgQQE8ymW0tIx5_8LAvhY",{"logo":280,"freeTrial":285,"sales":290,"login":295,"items":300,"search":627,"minimal":658,"duo":677,"switchNav":686,"pricingDeployment":697},{"config":281},{"href":282,"dataGaName":283,"dataGaLocation":284},"/","gitlab logo","header",{"text":286,"config":287},"Get free trial",{"href":288,"dataGaName":289,"dataGaLocation":284},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":291,"config":292},"Request a demo",{"href":293,"dataGaName":294,"dataGaLocation":284},"/sales/?contact-topic=request-demo","sales",{"text":296,"config":297},"Sign in",{"href":298,"dataGaName":299,"dataGaLocation":284},"https://gitlab.com/users/sign_in/","sign in",[301,330,430,435,549,605],{"text":302,"config":303,"menu":305},"Platform",{"dataNavLevelOne":304},"platform",{"type":306,"columns":307},"cards",[308,314,322],{"title":302,"description":309,"link":310},"The intelligent orchestration platform for DevSecOps",{"text":311,"config":312},"Explore our Platform",{"href":313,"dataGaName":304,"dataGaLocation":284},"/platform/",{"title":315,"description":316,"link":317},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":318,"config":319},"Meet GitLab Duo",{"href":320,"dataGaName":321,"dataGaLocation":284},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":323,"description":324,"link":325},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":326,"config":327},"Learn more",{"href":328,"dataGaName":329,"dataGaLocation":284},"/why-gitlab/","why gitlab",{"text":331,"left":267,"config":332,"menu":334},"Product",{"dataNavLevelOne":333},"solutions",{"type":335,"link":336,"columns":340,"feature":409},"lists",{"text":337,"config":338},"View all Solutions",{"href":339,"dataGaName":333,"dataGaLocation":284},"/solutions/",[341,365,388],{"title":342,"description":343,"link":344,"items":349},"Automation","CI/CD and automation to accelerate deployment",{"config":345},{"icon":346,"href":347,"dataGaName":348,"dataGaLocation":284},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[350,354,357,361],{"text":351,"config":352},"CI/CD",{"href":353,"dataGaLocation":284,"dataGaName":351},"/solutions/continuous-integration/",{"text":315,"config":355},{"href":320,"dataGaLocation":284,"dataGaName":356},"gitlab duo agent platform - product menu",{"text":358,"config":359},"Source Code Management",{"href":360,"dataGaLocation":284,"dataGaName":358},"/solutions/source-code-management/",{"text":362,"config":363},"Automated Software Delivery",{"href":347,"dataGaLocation":284,"dataGaName":364},"Automated software delivery",{"title":366,"description":367,"link":368,"items":373},"Security","Deliver code faster without compromising security",{"config":369},{"href":370,"dataGaName":371,"dataGaLocation":284,"icon":372},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[374,378,383],{"text":375,"config":376},"Application Security Testing",{"href":370,"dataGaName":377,"dataGaLocation":284},"Application security testing",{"text":379,"config":380},"Software Supply Chain Security",{"href":381,"dataGaLocation":284,"dataGaName":382},"/solutions/supply-chain/","Software supply chain security",{"text":384,"config":385},"Software Compliance",{"href":386,"dataGaName":387,"dataGaLocation":284},"/solutions/software-compliance/","software compliance",{"title":389,"link":390,"items":395},"Measurement",{"config":391},{"icon":392,"href":393,"dataGaName":394,"dataGaLocation":284},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[396,400,404],{"text":397,"config":398},"Visibility & Measurement",{"href":393,"dataGaLocation":284,"dataGaName":399},"Visibility and Measurement",{"text":401,"config":402},"Value Stream Management",{"href":403,"dataGaLocation":284,"dataGaName":401},"/solutions/value-stream-management/",{"text":405,"config":406},"Analytics & Insights",{"href":407,"dataGaLocation":284,"dataGaName":408},"/solutions/analytics-and-insights/","Analytics and insights",{"title":410,"type":335,"items":411},"GitLab for",[412,418,424],{"text":413,"config":414},"Enterprise",{"icon":415,"href":416,"dataGaLocation":284,"dataGaName":417},"Building","/enterprise/","enterprise",{"text":419,"config":420},"Small Business",{"icon":421,"href":422,"dataGaLocation":284,"dataGaName":423},"Work","/small-business/","small business",{"text":425,"config":426},"Public Sector",{"icon":427,"href":428,"dataGaLocation":284,"dataGaName":429},"Organization","/solutions/public-sector/","public sector",{"text":431,"config":432},"Pricing",{"href":433,"dataGaName":434,"dataGaLocation":284,"dataNavLevelOne":434},"/pricing/","pricing",{"text":436,"config":437,"menu":439},"Resources",{"dataNavLevelOne":438},"resources",{"type":335,"link":440,"columns":444,"feature":538},{"text":441,"config":442},"View all resources",{"href":443,"dataGaName":438,"dataGaLocation":284},"/resources/",[445,478,505],{"title":446,"items":447},"Getting started",[448,453,458,463,468,473],{"text":449,"config":450},"Install",{"href":451,"dataGaName":452,"dataGaLocation":284},"/install/","install",{"text":454,"config":455},"Quick start guides",{"href":456,"dataGaName":457,"dataGaLocation":284},"/get-started/","quick setup checklists",{"text":459,"config":460},"Learn",{"href":461,"dataGaLocation":284,"dataGaName":462},"https://university.gitlab.com/","learn",{"text":464,"config":465},"Product documentation",{"href":466,"dataGaName":467,"dataGaLocation":284},"https://docs.gitlab.com/","product documentation",{"text":469,"config":470},"Best practice videos",{"href":471,"dataGaName":472,"dataGaLocation":284},"/getting-started-videos/","best practice videos",{"text":474,"config":475},"Integrations",{"href":476,"dataGaName":477,"dataGaLocation":284},"/integrations/","integrations",{"title":479,"items":480},"Discover",[481,486,491,496,500],{"text":482,"config":483},"Customer success stories",{"href":484,"dataGaName":485,"dataGaLocation":284},"/customers/","customer success stories",{"text":487,"config":488},"Blog",{"href":489,"dataGaName":490,"dataGaLocation":284},"/blog/","blog",{"text":492,"config":493},"Demo Hub",{"href":494,"dataGaName":495,"dataGaLocation":284},"/demo-hub/","demo hub",{"text":497,"config":498},"The Source",{"href":499,"dataGaName":490,"dataGaLocation":284},"/the-source/",{"text":501,"config":502},"Remote",{"href":503,"dataGaName":504,"dataGaLocation":284},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":506,"items":507},"Connect",[508,513,518,523,528,533],{"text":509,"config":510},"GitLab Services",{"href":511,"dataGaName":512,"dataGaLocation":284},"/services/","services",{"text":514,"config":515},"Contribute",{"href":516,"dataGaName":517,"dataGaLocation":284},"https://contributors.gitlab.com","contribute",{"text":519,"config":520},"Community",{"href":521,"dataGaName":522,"dataGaLocation":284},"/community/","community",{"text":524,"config":525},"Forum",{"href":526,"dataGaName":527,"dataGaLocation":284},"https://forum.gitlab.com/","forum",{"text":529,"config":530},"Events",{"href":531,"dataGaName":532,"dataGaLocation":284},"/events/","events",{"text":534,"config":535},"Partners",{"href":536,"dataGaName":537,"dataGaLocation":284},"/partners/","partners",{"config":539,"title":542,"text":543,"link":544},{"background":540,"textColor":541},"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":545,"config":546},"Read the latest",{"href":547,"dataGaName":548,"dataGaLocation":284},"/whats-new/","whats new",{"text":550,"config":551,"menu":553},"Company",{"dataNavLevelOne":552},"company",{"type":335,"columns":554},[555],{"items":556},[557,562,568,570,575,580,585,590,595,600],{"text":558,"config":559},"About",{"href":560,"dataGaName":561,"dataGaLocation":284},"/company/","about",{"text":563,"config":564,"footerGa":567},"Jobs",{"href":565,"dataGaName":566,"dataGaLocation":284},"/jobs/","jobs",{"dataGaName":566},{"text":529,"config":569},{"href":531,"dataGaName":532,"dataGaLocation":284},{"text":571,"config":572},"Leadership",{"href":573,"dataGaName":574,"dataGaLocation":284},"/company/team/e-group/","leadership",{"text":576,"config":577},"Handbook",{"href":578,"dataGaName":579,"dataGaLocation":284},"https://handbook.gitlab.com/","handbook",{"text":581,"config":582},"Investor relations",{"href":583,"dataGaName":584,"dataGaLocation":284},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":586,"config":587},"Trust Center",{"href":588,"dataGaName":589,"dataGaLocation":284},"/security/","trust center",{"text":591,"config":592},"AI Transparency Center",{"href":593,"dataGaName":594,"dataGaLocation":284},"/ai-transparency-center/","ai transparency center",{"text":596,"config":597},"Newsletter",{"href":598,"dataGaName":599,"dataGaLocation":284},"/company/contact/#contact-forms","newsletter",{"text":601,"config":602},"Press",{"href":603,"dataGaName":604,"dataGaLocation":284},"/press/","press",{"text":606,"config":607,"menu":608},"Contact us",{"dataNavLevelOne":552},{"type":335,"columns":609},[610],{"items":611},[612,617,622],{"text":613,"config":614},"Talk to sales",{"href":615,"dataGaName":616,"dataGaLocation":284},"/sales/","talk to sales",{"text":618,"config":619},"Support portal",{"href":620,"dataGaName":621,"dataGaLocation":284},"https://support.gitlab.com/hc/en-us","support portal",{"text":623,"config":624},"Customer portal",{"href":625,"dataGaName":626,"dataGaLocation":284},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":628,"login":629,"suggestions":636},"Close",{"text":630,"link":631},"To search repositories and projects, login to",{"text":632,"config":633},"gitlab.com",{"href":298,"dataGaName":634,"dataGaLocation":635},"search login","search",{"text":637,"default":638},"Suggestions",[639,641,645,647,651,655],{"text":315,"config":640},{"href":320,"dataGaName":315,"dataGaLocation":635},{"text":642,"config":643},"Code Suggestions (AI)",{"href":644,"dataGaName":642,"dataGaLocation":635},"/solutions/code-suggestions/",{"text":351,"config":646},{"href":353,"dataGaName":351,"dataGaLocation":635},{"text":648,"config":649},"GitLab on AWS",{"href":650,"dataGaName":648,"dataGaLocation":635},"/partners/technology-partners/aws/",{"text":652,"config":653},"GitLab on Google Cloud",{"href":654,"dataGaName":652,"dataGaLocation":635},"/partners/technology-partners/google-cloud-platform/",{"text":656,"config":657},"Why GitLab?",{"href":328,"dataGaName":656,"dataGaLocation":635},{"freeTrial":659,"mobileIcon":664,"desktopIcon":669,"secondaryButton":672},{"text":660,"config":661},"Start free trial",{"href":662,"dataGaName":289,"dataGaLocation":663},"https://gitlab.com/-/trials/new/","nav",{"altText":665,"config":666},"Gitlab Icon",{"src":667,"dataGaName":668,"dataGaLocation":663},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":665,"config":670},{"src":671,"dataGaName":668,"dataGaLocation":663},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":673,"config":674},"Get Started",{"href":675,"dataGaName":676,"dataGaLocation":663},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":678,"mobileIcon":682,"desktopIcon":684},{"text":679,"config":680},"Learn more about GitLab Duo",{"href":320,"dataGaName":681,"dataGaLocation":663},"gitlab duo",{"altText":665,"config":683},{"src":667,"dataGaName":668,"dataGaLocation":663},{"altText":665,"config":685},{"src":671,"dataGaName":668,"dataGaLocation":663},{"button":687,"mobileIcon":692,"desktopIcon":694},{"text":688,"config":689},"/switch",{"href":690,"dataGaName":691,"dataGaLocation":663},"#contact","switch",{"altText":665,"config":693},{"src":667,"dataGaName":668,"dataGaLocation":663},{"altText":665,"config":695},{"src":696,"dataGaName":668,"dataGaLocation":663},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":698,"mobileIcon":703,"desktopIcon":705},{"text":699,"config":700},"Back to pricing",{"href":433,"dataGaName":701,"dataGaLocation":663,"icon":702},"back to pricing","GoBack",{"altText":665,"config":704},{"src":667,"dataGaName":668,"dataGaLocation":663},{"altText":665,"config":706},{"src":671,"dataGaName":668,"dataGaLocation":663},{"title":708,"titleMobile":709,"button":710,"config":715},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":326,"config":711},{"href":712,"dataGaName":713,"dataGaLocation":714},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":716,"disabled":264},"release",{"data":718},{"text":719,"source":720,"edit":726,"contribute":731,"config":736,"items":741,"minimal":951},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":721,"config":722},"View page source",{"href":723,"dataGaName":724,"dataGaLocation":725},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":727,"config":728},"Edit this page",{"href":729,"dataGaName":730,"dataGaLocation":725},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":732,"config":733},"Please contribute",{"href":734,"dataGaName":735,"dataGaLocation":725},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":737,"facebook":738,"youtube":739,"linkedin":740},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[742,789,843,887,919],{"title":431,"links":743,"subMenu":758},[744,748,753],{"text":745,"config":746},"View plans",{"href":433,"dataGaName":747,"dataGaLocation":725},"view plans",{"text":749,"config":750},"Why Premium?",{"href":751,"dataGaName":752,"dataGaLocation":725},"/pricing/premium/","why premium",{"text":754,"config":755},"Why Ultimate?",{"href":756,"dataGaName":757,"dataGaLocation":725},"/pricing/ultimate/","why ultimate",[759],{"title":760,"links":761},"Contact Us",[762,765,767,769,774,779,784],{"text":763,"config":764},"Contact sales",{"href":615,"dataGaName":294,"dataGaLocation":725},{"text":618,"config":766},{"href":620,"dataGaName":621,"dataGaLocation":725},{"text":623,"config":768},{"href":625,"dataGaName":626,"dataGaLocation":725},{"text":770,"config":771},"Status",{"href":772,"dataGaName":773,"dataGaLocation":725},"https://status.gitlab.com/","status",{"text":775,"config":776},"Terms of use",{"href":777,"dataGaName":778,"dataGaLocation":725},"/terms/","terms of use",{"text":780,"config":781},"Privacy statement",{"href":782,"dataGaName":783,"dataGaLocation":725},"/privacy/","privacy statement",{"text":785,"config":786},"Cookie preferences",{"dataGaName":787,"dataGaLocation":725,"id":788,"isOneTrustButton":267},"cookie preferences","ot-sdk-btn",{"title":331,"links":790,"subMenu":799},[791,795],{"text":792,"config":793},"DevSecOps platform",{"href":313,"dataGaName":794,"dataGaLocation":725},"devsecops platform",{"text":796,"config":797},"AI-Assisted Development",{"href":320,"dataGaName":798,"dataGaLocation":725},"ai-assisted development",[800],{"title":801,"links":802},"Topics",[803,808,813,818,823,828,833,838],{"text":804,"config":805},"CICD",{"href":806,"dataGaName":807,"dataGaLocation":725},"/topics/ci-cd/","cicd",{"text":809,"config":810},"GitOps",{"href":811,"dataGaName":812,"dataGaLocation":725},"/topics/gitops/","gitops",{"text":814,"config":815},"DevOps",{"href":816,"dataGaName":817,"dataGaLocation":725},"/topics/devops/","devops",{"text":819,"config":820},"Version Control",{"href":821,"dataGaName":822,"dataGaLocation":725},"/topics/version-control/","version control",{"text":824,"config":825},"DevSecOps",{"href":826,"dataGaName":827,"dataGaLocation":725},"/topics/devsecops/","devsecops",{"text":829,"config":830},"Cloud Native",{"href":831,"dataGaName":832,"dataGaLocation":725},"/topics/cloud-native/","cloud native",{"text":834,"config":835},"AI for Coding",{"href":836,"dataGaName":837,"dataGaLocation":725},"/topics/devops/ai-for-coding/","ai for coding",{"text":839,"config":840},"Agentic AI",{"href":841,"dataGaName":842,"dataGaLocation":725},"/topics/agentic-ai/","agentic ai",{"title":844,"links":845},"Solutions",[846,848,850,855,859,862,866,869,871,874,877,882],{"text":375,"config":847},{"href":370,"dataGaName":375,"dataGaLocation":725},{"text":364,"config":849},{"href":347,"dataGaName":348,"dataGaLocation":725},{"text":851,"config":852},"Agile development",{"href":853,"dataGaName":854,"dataGaLocation":725},"/solutions/agile-delivery/","agile delivery",{"text":856,"config":857},"SCM",{"href":360,"dataGaName":858,"dataGaLocation":725},"source code management",{"text":804,"config":860},{"href":353,"dataGaName":861,"dataGaLocation":725},"continuous integration & delivery",{"text":863,"config":864},"Value stream management",{"href":403,"dataGaName":865,"dataGaLocation":725},"value stream management",{"text":809,"config":867},{"href":868,"dataGaName":812,"dataGaLocation":725},"/solutions/gitops/",{"text":413,"config":870},{"href":416,"dataGaName":417,"dataGaLocation":725},{"text":872,"config":873},"Small business",{"href":422,"dataGaName":423,"dataGaLocation":725},{"text":875,"config":876},"Public sector",{"href":428,"dataGaName":429,"dataGaLocation":725},{"text":878,"config":879},"Education",{"href":880,"dataGaName":881,"dataGaLocation":725},"/solutions/education/","education",{"text":883,"config":884},"Financial services",{"href":885,"dataGaName":886,"dataGaLocation":725},"/solutions/finance/","financial services",{"title":436,"links":888},[889,891,893,895,898,900,903,905,907,909,911,913,915,917],{"text":449,"config":890},{"href":451,"dataGaName":452,"dataGaLocation":725},{"text":454,"config":892},{"href":456,"dataGaName":457,"dataGaLocation":725},{"text":459,"config":894},{"href":461,"dataGaName":462,"dataGaLocation":725},{"text":464,"config":896},{"href":466,"dataGaName":897,"dataGaLocation":725},"docs",{"text":487,"config":899},{"href":489,"dataGaName":490,"dataGaLocation":725},{"text":901,"config":902},"What's new",{"href":547,"dataGaName":548,"dataGaLocation":725},{"text":482,"config":904},{"href":484,"dataGaName":485,"dataGaLocation":725},{"text":501,"config":906},{"href":503,"dataGaName":504,"dataGaLocation":725},{"text":509,"config":908},{"href":511,"dataGaName":512,"dataGaLocation":725},{"text":514,"config":910},{"href":516,"dataGaName":517,"dataGaLocation":725},{"text":519,"config":912},{"href":521,"dataGaName":522,"dataGaLocation":725},{"text":524,"config":914},{"href":526,"dataGaName":527,"dataGaLocation":725},{"text":529,"config":916},{"href":531,"dataGaName":532,"dataGaLocation":725},{"text":534,"config":918},{"href":536,"dataGaName":537,"dataGaLocation":725},{"title":550,"links":920},[921,923,925,927,929,931,935,940,942,944,946],{"text":558,"config":922},{"href":560,"dataGaName":552,"dataGaLocation":725},{"text":563,"config":924},{"href":565,"dataGaName":566,"dataGaLocation":725},{"text":571,"config":926},{"href":573,"dataGaName":574,"dataGaLocation":725},{"text":576,"config":928},{"href":578,"dataGaName":579,"dataGaLocation":725},{"text":581,"config":930},{"href":583,"dataGaName":584,"dataGaLocation":725},{"text":932,"config":933},"Sustainability",{"href":934,"dataGaName":932,"dataGaLocation":725},"/sustainability/",{"text":936,"config":937},"Diversity, inclusion and belonging (DIB)",{"href":938,"dataGaName":939,"dataGaLocation":725},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":586,"config":941},{"href":588,"dataGaName":589,"dataGaLocation":725},{"text":596,"config":943},{"href":598,"dataGaName":599,"dataGaLocation":725},{"text":601,"config":945},{"href":603,"dataGaName":604,"dataGaLocation":725},{"text":947,"config":948},"Modern Slavery Transparency Statement",{"href":949,"dataGaName":950,"dataGaLocation":725},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":952},[953,956,959],{"text":954,"config":955},"Terms",{"href":777,"dataGaName":778,"dataGaLocation":725},{"text":957,"config":958},"Cookies",{"dataGaName":787,"dataGaLocation":725,"id":788,"isOneTrustButton":267},{"text":960,"config":961},"Privacy",{"href":782,"dataGaName":783,"dataGaLocation":725},[963],{"id":964,"title":7,"body":263,"config":965,"content":967,"description":263,"extension":971,"meta":972,"navigation":267,"path":973,"seo":974,"stem":975,"__hash__":976},"blogAuthors/en-us/blog/authors/brett-walker.yml",{"template":966},"BlogAuthor",{"name":7,"config":968},{"headshot":969,"ctfId":970},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749670155/Blog/Author%20Headshots/digitalmoksha-headshot.jpg","digitalmoksha","yml",{},"/en-us/blog/authors/brett-walker",{},"en-us/blog/authors/brett-walker","ktLx8H0sWL7REEk1p_RJaxT-uuNjGcn89CyctrJ-ELE",[978,987,995],{"title":979,"description":980,"heroImage":981,"category":259,"date":982,"authors":983,"slug":986,"externalUrl":263},"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",[984,985],"Mathias Ewald","Martin Paloncy, Edgeless Systems","confidential-ai-for-gitlab-self-hosted",{"title":988,"description":989,"heroImage":990,"category":259,"date":991,"authors":992,"slug":994,"externalUrl":263},"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",[993],"Lysanne Pinto","green-devops-carbon-measurement-cicd-pipeline",{"title":996,"description":997,"heroImage":998,"category":259,"date":999,"authors":1000,"slug":1002,"externalUrl":263},"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",[1001],"Paul Meresanu","how-to-build-ci-cd-observability-at-scale",{"promotions":1004},[1005,1019,1031,1043],{"id":1006,"categories":1007,"header":1009,"text":1010,"button":1011,"image":1016},"ai-modernization",[1008],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":1012,"config":1013},"Get your AI maturity score",{"href":1014,"dataGaName":1015,"dataGaLocation":490},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":1017},{"src":1018},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":1020,"categories":1021,"header":1023,"text":1010,"button":1024,"image":1028},"devops-modernization",[1022,827],"product","Are you just managing tools or shipping innovation?",{"text":1025,"config":1026},"Get your DevOps maturity score",{"href":1027,"dataGaName":1015,"dataGaLocation":490},"/assessments/devops-modernization-assessment/",{"config":1029},{"src":1030},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":1032,"categories":1033,"header":1035,"text":1010,"button":1036,"image":1040},"security-modernization",[1034],"security","Are you trading speed for security?",{"text":1037,"config":1038},"Get your security maturity score",{"href":1039,"dataGaName":1015,"dataGaLocation":490},"/assessments/security-modernization-assessment/",{"config":1041},{"src":1042},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":1044,"paths":1045,"header":1048,"text":1049,"button":1050,"image":1055},"github-azure-migration",[1046,1047],"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":1051,"config":1052},"See how GitLab compares to GitHub",{"href":1053,"dataGaName":1054,"dataGaLocation":490},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":1056},{"src":1030},{"header":1058,"blurb":1059,"button":1060,"secondaryButton":1065},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":1061,"config":1062},"Get your free trial",{"href":1063,"dataGaName":289,"dataGaLocation":1064},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":763,"config":1066},{"href":615,"dataGaName":294,"dataGaLocation":1064},1786803735240]