[{"data":1,"prerenderedAt":1485},["ShallowReactive",2],{"/en-us/blog/tags/code-review/":3,"navigation-en-us":20,"banner-en-us":438,"footer-en-us":453,"code review-tag-page-en-us":664},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"content":8,"config":11,"_id":13,"_type":14,"title":15,"_source":16,"_file":17,"_stem":18,"_extension":19},"/en-us/blog/tags/code-review","tags",false,"",{"tag":9,"tagSlug":10},"code review","code-review",{"template":12},"BlogTag","content:en-us:blog:tags:code-review.yml","yaml","Code Review","content","en-us/blog/tags/code-review.yml","en-us/blog/tags/code-review","yml",{"_path":21,"_dir":22,"_draft":6,"_partial":6,"_locale":7,"data":23,"_id":434,"_type":14,"title":435,"_source":16,"_file":436,"_stem":437,"_extension":19},"/shared/en-us/main-navigation","en-us",{"logo":24,"freeTrial":29,"sales":34,"login":39,"items":44,"search":375,"minimal":406,"duo":425},{"config":25},{"href":26,"dataGaName":27,"dataGaLocation":28},"/","gitlab logo","header",{"text":30,"config":31},"Get free trial",{"href":32,"dataGaName":33,"dataGaLocation":28},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":35,"config":36},"Talk to sales",{"href":37,"dataGaName":38,"dataGaLocation":28},"/sales/","sales",{"text":40,"config":41},"Sign in",{"href":42,"dataGaName":43,"dataGaLocation":28},"https://gitlab.com/users/sign_in/","sign in",[45,89,185,190,296,356],{"text":46,"config":47,"cards":49,"footer":72},"Platform",{"dataNavLevelOne":48},"platform",[50,56,64],{"title":46,"description":51,"link":52},"The most comprehensive AI-powered DevSecOps Platform",{"text":53,"config":54},"Explore our Platform",{"href":55,"dataGaName":48,"dataGaLocation":28},"/platform/",{"title":57,"description":58,"link":59},"GitLab Duo (AI)","Build software faster with AI at every stage of development",{"text":60,"config":61},"Meet GitLab Duo",{"href":62,"dataGaName":63,"dataGaLocation":28},"/gitlab-duo/","gitlab duo ai",{"title":65,"description":66,"link":67},"Why GitLab","10 reasons why Enterprises choose GitLab",{"text":68,"config":69},"Learn more",{"href":70,"dataGaName":71,"dataGaLocation":28},"/why-gitlab/","why gitlab",{"title":73,"items":74},"Get started with",[75,80,85],{"text":76,"config":77},"Platform Engineering",{"href":78,"dataGaName":79,"dataGaLocation":28},"/solutions/platform-engineering/","platform engineering",{"text":81,"config":82},"Developer Experience",{"href":83,"dataGaName":84,"dataGaLocation":28},"/developer-experience/","Developer experience",{"text":86,"config":87},"MLOps",{"href":88,"dataGaName":86,"dataGaLocation":28},"/topics/devops/the-role-of-ai-in-devops/",{"text":90,"left":91,"config":92,"link":94,"lists":98,"footer":167},"Product",true,{"dataNavLevelOne":93},"solutions",{"text":95,"config":96},"View all Solutions",{"href":97,"dataGaName":93,"dataGaLocation":28},"/solutions/",[99,124,146],{"title":100,"description":101,"link":102,"items":107},"Automation","CI/CD and automation to accelerate deployment",{"config":103},{"icon":104,"href":105,"dataGaName":106,"dataGaLocation":28},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[108,112,116,120],{"text":109,"config":110},"CI/CD",{"href":111,"dataGaLocation":28,"dataGaName":109},"/solutions/continuous-integration/",{"text":113,"config":114},"AI-Assisted Development",{"href":62,"dataGaLocation":28,"dataGaName":115},"AI assisted development",{"text":117,"config":118},"Source Code Management",{"href":119,"dataGaLocation":28,"dataGaName":117},"/solutions/source-code-management/",{"text":121,"config":122},"Automated Software Delivery",{"href":105,"dataGaLocation":28,"dataGaName":123},"Automated software delivery",{"title":125,"description":126,"link":127,"items":132},"Security","Deliver code faster without compromising security",{"config":128},{"href":129,"dataGaName":130,"dataGaLocation":28,"icon":131},"/solutions/security-compliance/","security and compliance","ShieldCheckLight",[133,136,141],{"text":134,"config":135},"Security & Compliance",{"href":129,"dataGaLocation":28,"dataGaName":134},{"text":137,"config":138},"Software Supply Chain Security",{"href":139,"dataGaLocation":28,"dataGaName":140},"/solutions/supply-chain/","Software supply chain security",{"text":142,"config":143},"Compliance & Governance",{"href":144,"dataGaLocation":28,"dataGaName":145},"/solutions/continuous-software-compliance/","Compliance and governance",{"title":147,"link":148,"items":153},"Measurement",{"config":149},{"icon":150,"href":151,"dataGaName":152,"dataGaLocation":28},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[154,158,162],{"text":155,"config":156},"Visibility & Measurement",{"href":151,"dataGaLocation":28,"dataGaName":157},"Visibility and Measurement",{"text":159,"config":160},"Value Stream Management",{"href":161,"dataGaLocation":28,"dataGaName":159},"/solutions/value-stream-management/",{"text":163,"config":164},"Analytics & Insights",{"href":165,"dataGaLocation":28,"dataGaName":166},"/solutions/analytics-and-insights/","Analytics and insights",{"title":168,"items":169},"GitLab for",[170,175,180],{"text":171,"config":172},"Enterprise",{"href":173,"dataGaLocation":28,"dataGaName":174},"/enterprise/","enterprise",{"text":176,"config":177},"Small Business",{"href":178,"dataGaLocation":28,"dataGaName":179},"/small-business/","small business",{"text":181,"config":182},"Public Sector",{"href":183,"dataGaLocation":28,"dataGaName":184},"/solutions/public-sector/","public sector",{"text":186,"config":187},"Pricing",{"href":188,"dataGaName":189,"dataGaLocation":28,"dataNavLevelOne":189},"/pricing/","pricing",{"text":191,"config":192,"link":194,"lists":198,"feature":283},"Resources",{"dataNavLevelOne":193},"resources",{"text":195,"config":196},"View all resources",{"href":197,"dataGaName":193,"dataGaLocation":28},"/resources/",[199,232,255],{"title":200,"items":201},"Getting started",[202,207,212,217,222,227],{"text":203,"config":204},"Install",{"href":205,"dataGaName":206,"dataGaLocation":28},"/install/","install",{"text":208,"config":209},"Quick start guides",{"href":210,"dataGaName":211,"dataGaLocation":28},"/get-started/","quick setup checklists",{"text":213,"config":214},"Learn",{"href":215,"dataGaLocation":28,"dataGaName":216},"https://university.gitlab.com/","learn",{"text":218,"config":219},"Product documentation",{"href":220,"dataGaName":221,"dataGaLocation":28},"https://docs.gitlab.com/","product documentation",{"text":223,"config":224},"Best practice videos",{"href":225,"dataGaName":226,"dataGaLocation":28},"/getting-started-videos/","best practice videos",{"text":228,"config":229},"Integrations",{"href":230,"dataGaName":231,"dataGaLocation":28},"/integrations/","integrations",{"title":233,"items":234},"Discover",[235,240,245,250],{"text":236,"config":237},"Customer success stories",{"href":238,"dataGaName":239,"dataGaLocation":28},"/customers/","customer success stories",{"text":241,"config":242},"Blog",{"href":243,"dataGaName":244,"dataGaLocation":28},"/blog/","blog",{"text":246,"config":247},"Remote",{"href":248,"dataGaName":249,"dataGaLocation":28},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":251,"config":252},"TeamOps",{"href":253,"dataGaName":254,"dataGaLocation":28},"/teamops/","teamops",{"title":256,"items":257},"Connect",[258,263,268,273,278],{"text":259,"config":260},"GitLab Services",{"href":261,"dataGaName":262,"dataGaLocation":28},"/services/","services",{"text":264,"config":265},"Community",{"href":266,"dataGaName":267,"dataGaLocation":28},"/community/","community",{"text":269,"config":270},"Forum",{"href":271,"dataGaName":272,"dataGaLocation":28},"https://forum.gitlab.com/","forum",{"text":274,"config":275},"Events",{"href":276,"dataGaName":277,"dataGaLocation":28},"/events/","events",{"text":279,"config":280},"Partners",{"href":281,"dataGaName":282,"dataGaLocation":28},"/partners/","partners",{"backgroundColor":284,"textColor":285,"text":286,"image":287,"link":291},"#2f2a6b","#fff","Insights for the future of software development",{"altText":288,"config":289},"the source promo card",{"src":290},"/images/navigation/the-source-promo-card.svg",{"text":292,"config":293},"Read the latest",{"href":294,"dataGaName":295,"dataGaLocation":28},"/the-source/","the source",{"text":297,"config":298,"lists":300},"Company",{"dataNavLevelOne":299},"company",[301],{"items":302},[303,308,314,316,321,326,331,336,341,346,351],{"text":304,"config":305},"About",{"href":306,"dataGaName":307,"dataGaLocation":28},"/company/","about",{"text":309,"config":310,"footerGa":313},"Jobs",{"href":311,"dataGaName":312,"dataGaLocation":28},"/jobs/","jobs",{"dataGaName":312},{"text":274,"config":315},{"href":276,"dataGaName":277,"dataGaLocation":28},{"text":317,"config":318},"Leadership",{"href":319,"dataGaName":320,"dataGaLocation":28},"/company/team/e-group/","leadership",{"text":322,"config":323},"Team",{"href":324,"dataGaName":325,"dataGaLocation":28},"/company/team/","team",{"text":327,"config":328},"Handbook",{"href":329,"dataGaName":330,"dataGaLocation":28},"https://handbook.gitlab.com/","handbook",{"text":332,"config":333},"Investor relations",{"href":334,"dataGaName":335,"dataGaLocation":28},"https://ir.gitlab.com/","investor relations",{"text":337,"config":338},"Trust Center",{"href":339,"dataGaName":340,"dataGaLocation":28},"/security/","trust center",{"text":342,"config":343},"AI Transparency Center",{"href":344,"dataGaName":345,"dataGaLocation":28},"/ai-transparency-center/","ai transparency center",{"text":347,"config":348},"Newsletter",{"href":349,"dataGaName":350,"dataGaLocation":28},"/company/contact/","newsletter",{"text":352,"config":353},"Press",{"href":354,"dataGaName":355,"dataGaLocation":28},"/press/","press",{"text":357,"config":358,"lists":359},"Contact us",{"dataNavLevelOne":299},[360],{"items":361},[362,365,370],{"text":35,"config":363},{"href":37,"dataGaName":364,"dataGaLocation":28},"talk to sales",{"text":366,"config":367},"Get help",{"href":368,"dataGaName":369,"dataGaLocation":28},"/support/","get help",{"text":371,"config":372},"Customer portal",{"href":373,"dataGaName":374,"dataGaLocation":28},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":376,"login":377,"suggestions":384},"Close",{"text":378,"link":379},"To search repositories and projects, login to",{"text":380,"config":381},"gitlab.com",{"href":42,"dataGaName":382,"dataGaLocation":383},"search login","search",{"text":385,"default":386},"Suggestions",[387,389,393,395,399,403],{"text":57,"config":388},{"href":62,"dataGaName":57,"dataGaLocation":383},{"text":390,"config":391},"Code Suggestions (AI)",{"href":392,"dataGaName":390,"dataGaLocation":383},"/solutions/code-suggestions/",{"text":109,"config":394},{"href":111,"dataGaName":109,"dataGaLocation":383},{"text":396,"config":397},"GitLab on AWS",{"href":398,"dataGaName":396,"dataGaLocation":383},"/partners/technology-partners/aws/",{"text":400,"config":401},"GitLab on Google Cloud",{"href":402,"dataGaName":400,"dataGaLocation":383},"/partners/technology-partners/google-cloud-platform/",{"text":404,"config":405},"Why GitLab?",{"href":70,"dataGaName":404,"dataGaLocation":383},{"freeTrial":407,"mobileIcon":412,"desktopIcon":417,"secondaryButton":420},{"text":408,"config":409},"Start free trial",{"href":410,"dataGaName":33,"dataGaLocation":411},"https://gitlab.com/-/trials/new/","nav",{"altText":413,"config":414},"Gitlab Icon",{"src":415,"dataGaName":416,"dataGaLocation":411},"/images/brand/gitlab-logo-tanuki.svg","gitlab icon",{"altText":413,"config":418},{"src":419,"dataGaName":416,"dataGaLocation":411},"/images/brand/gitlab-logo-type.svg",{"text":421,"config":422},"Get Started",{"href":423,"dataGaName":424,"dataGaLocation":411},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":426,"mobileIcon":430,"desktopIcon":432},{"text":427,"config":428},"Learn more about GitLab Duo",{"href":62,"dataGaName":429,"dataGaLocation":411},"gitlab duo",{"altText":413,"config":431},{"src":415,"dataGaName":416,"dataGaLocation":411},{"altText":413,"config":433},{"src":419,"dataGaName":416,"dataGaLocation":411},"content:shared:en-us:main-navigation.yml","Main Navigation","shared/en-us/main-navigation.yml","shared/en-us/main-navigation",{"_path":439,"_dir":22,"_draft":6,"_partial":6,"_locale":7,"title":440,"button":441,"image":445,"config":448,"_id":450,"_type":14,"_source":16,"_file":451,"_stem":452,"_extension":19},"/shared/en-us/banner","is now in public beta!",{"text":68,"config":442},{"href":443,"dataGaName":444,"dataGaLocation":28},"/gitlab-duo/agent-platform/","duo banner",{"config":446},{"src":447},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1753720689/somrf9zaunk0xlt7ne4x.svg",{"layout":449},"release","content:shared:en-us:banner.yml","shared/en-us/banner.yml","shared/en-us/banner",{"_path":454,"_dir":22,"_draft":6,"_partial":6,"_locale":7,"data":455,"_id":660,"_type":14,"title":661,"_source":16,"_file":662,"_stem":663,"_extension":19},"/shared/en-us/main-footer",{"text":456,"source":457,"edit":463,"contribute":468,"config":473,"items":478,"minimal":652},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":458,"config":459},"View page source",{"href":460,"dataGaName":461,"dataGaLocation":462},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":464,"config":465},"Edit this page",{"href":466,"dataGaName":467,"dataGaLocation":462},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":469,"config":470},"Please contribute",{"href":471,"dataGaName":472,"dataGaLocation":462},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":474,"facebook":475,"youtube":476,"linkedin":477},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[479,502,559,588,622],{"title":46,"links":480,"subMenu":485},[481],{"text":482,"config":483},"DevSecOps platform",{"href":55,"dataGaName":484,"dataGaLocation":462},"devsecops platform",[486],{"title":186,"links":487},[488,492,497],{"text":489,"config":490},"View plans",{"href":188,"dataGaName":491,"dataGaLocation":462},"view plans",{"text":493,"config":494},"Why Premium?",{"href":495,"dataGaName":496,"dataGaLocation":462},"/pricing/premium/","why premium",{"text":498,"config":499},"Why Ultimate?",{"href":500,"dataGaName":501,"dataGaLocation":462},"/pricing/ultimate/","why ultimate",{"title":503,"links":504},"Solutions",[505,510,513,515,520,525,529,532,536,541,543,546,549,554],{"text":506,"config":507},"Digital transformation",{"href":508,"dataGaName":509,"dataGaLocation":462},"/topics/digital-transformation/","digital transformation",{"text":134,"config":511},{"href":129,"dataGaName":512,"dataGaLocation":462},"security & compliance",{"text":123,"config":514},{"href":105,"dataGaName":106,"dataGaLocation":462},{"text":516,"config":517},"Agile development",{"href":518,"dataGaName":519,"dataGaLocation":462},"/solutions/agile-delivery/","agile delivery",{"text":521,"config":522},"Cloud transformation",{"href":523,"dataGaName":524,"dataGaLocation":462},"/topics/cloud-native/","cloud transformation",{"text":526,"config":527},"SCM",{"href":119,"dataGaName":528,"dataGaLocation":462},"source code management",{"text":109,"config":530},{"href":111,"dataGaName":531,"dataGaLocation":462},"continuous integration & delivery",{"text":533,"config":534},"Value stream management",{"href":161,"dataGaName":535,"dataGaLocation":462},"value stream management",{"text":537,"config":538},"GitOps",{"href":539,"dataGaName":540,"dataGaLocation":462},"/solutions/gitops/","gitops",{"text":171,"config":542},{"href":173,"dataGaName":174,"dataGaLocation":462},{"text":544,"config":545},"Small business",{"href":178,"dataGaName":179,"dataGaLocation":462},{"text":547,"config":548},"Public sector",{"href":183,"dataGaName":184,"dataGaLocation":462},{"text":550,"config":551},"Education",{"href":552,"dataGaName":553,"dataGaLocation":462},"/solutions/education/","education",{"text":555,"config":556},"Financial services",{"href":557,"dataGaName":558,"dataGaLocation":462},"/solutions/finance/","financial services",{"title":191,"links":560},[561,563,565,567,570,572,574,576,578,580,582,584,586],{"text":203,"config":562},{"href":205,"dataGaName":206,"dataGaLocation":462},{"text":208,"config":564},{"href":210,"dataGaName":211,"dataGaLocation":462},{"text":213,"config":566},{"href":215,"dataGaName":216,"dataGaLocation":462},{"text":218,"config":568},{"href":220,"dataGaName":569,"dataGaLocation":462},"docs",{"text":241,"config":571},{"href":243,"dataGaName":244,"dataGaLocation":462},{"text":236,"config":573},{"href":238,"dataGaName":239,"dataGaLocation":462},{"text":246,"config":575},{"href":248,"dataGaName":249,"dataGaLocation":462},{"text":259,"config":577},{"href":261,"dataGaName":262,"dataGaLocation":462},{"text":251,"config":579},{"href":253,"dataGaName":254,"dataGaLocation":462},{"text":264,"config":581},{"href":266,"dataGaName":267,"dataGaLocation":462},{"text":269,"config":583},{"href":271,"dataGaName":272,"dataGaLocation":462},{"text":274,"config":585},{"href":276,"dataGaName":277,"dataGaLocation":462},{"text":279,"config":587},{"href":281,"dataGaName":282,"dataGaLocation":462},{"title":297,"links":589},[590,592,594,596,598,600,602,606,611,613,615,617],{"text":304,"config":591},{"href":306,"dataGaName":299,"dataGaLocation":462},{"text":309,"config":593},{"href":311,"dataGaName":312,"dataGaLocation":462},{"text":317,"config":595},{"href":319,"dataGaName":320,"dataGaLocation":462},{"text":322,"config":597},{"href":324,"dataGaName":325,"dataGaLocation":462},{"text":327,"config":599},{"href":329,"dataGaName":330,"dataGaLocation":462},{"text":332,"config":601},{"href":334,"dataGaName":335,"dataGaLocation":462},{"text":603,"config":604},"Sustainability",{"href":605,"dataGaName":603,"dataGaLocation":462},"/sustainability/",{"text":607,"config":608},"Diversity, inclusion and belonging (DIB)",{"href":609,"dataGaName":610,"dataGaLocation":462},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":337,"config":612},{"href":339,"dataGaName":340,"dataGaLocation":462},{"text":347,"config":614},{"href":349,"dataGaName":350,"dataGaLocation":462},{"text":352,"config":616},{"href":354,"dataGaName":355,"dataGaLocation":462},{"text":618,"config":619},"Modern Slavery Transparency Statement",{"href":620,"dataGaName":621,"dataGaLocation":462},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"title":623,"links":624},"Contact Us",[625,628,630,632,637,642,647],{"text":626,"config":627},"Contact an expert",{"href":37,"dataGaName":38,"dataGaLocation":462},{"text":366,"config":629},{"href":368,"dataGaName":369,"dataGaLocation":462},{"text":371,"config":631},{"href":373,"dataGaName":374,"dataGaLocation":462},{"text":633,"config":634},"Status",{"href":635,"dataGaName":636,"dataGaLocation":462},"https://status.gitlab.com/","status",{"text":638,"config":639},"Terms of use",{"href":640,"dataGaName":641,"dataGaLocation":462},"/terms/","terms of use",{"text":643,"config":644},"Privacy statement",{"href":645,"dataGaName":646,"dataGaLocation":462},"/privacy/","privacy statement",{"text":648,"config":649},"Cookie preferences",{"dataGaName":650,"dataGaLocation":462,"id":651,"isOneTrustButton":91},"cookie preferences","ot-sdk-btn",{"items":653},[654,656,658],{"text":638,"config":655},{"href":640,"dataGaName":641,"dataGaLocation":462},{"text":643,"config":657},{"href":645,"dataGaName":646,"dataGaLocation":462},{"text":648,"config":659},{"dataGaName":650,"dataGaLocation":462,"id":651,"isOneTrustButton":91},"content:shared:en-us:main-footer.yml","Main Footer","shared/en-us/main-footer.yml","shared/en-us/main-footer",{"allPosts":665,"featuredPost":1464,"totalPagesCount":1483,"initialPosts":1484},[666,691,717,739,761,782,803,827,848,869,890,910,930,951,972,993,1012,1032,1053,1074,1094,1113,1131,1151,1170,1189,1208,1230,1250,1272,1291,1309,1327,1347,1366,1386,1406,1427,1445],{"_path":667,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":668,"content":676,"config":684,"_id":687,"_type":14,"title":688,"_source":16,"_file":689,"_stem":690,"_extension":19},"/en-us/blog/5-code-review-features",{"title":669,"description":670,"ogTitle":669,"ogDescription":670,"noIndex":6,"ogImage":671,"ogUrl":672,"ogSiteName":673,"ogType":674,"canonicalUrls":672,"schema":675},"How GitLab's 5 new code review features will make life easier","Code reviews are hard to get right. Here are five new features in our DevOps Platform designed to streamline code reviews and provide vital context.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749667400/Blog/Hero%20Images/lagos-techie-unsplash.jpg","https://about.gitlab.com/blog/5-code-review-features","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How GitLab's 5 new code review features will make life easier\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Brendan O'Leary\"}],\n        \"datePublished\": \"2021-09-09\",\n      }",{"title":669,"description":670,"authors":677,"heroImage":671,"date":679,"body":680,"category":681,"tags":682},[678],"Brendan O'Leary","2021-09-09","\n_This is the second in a series of blog posts looking at the challenges of code review and the ways a DevOps platform can help. Read the [first post](/blog/the-code-review-struggle-is-real-heres-what-you-need-to-know/)._\n\n## What is a code review, and why is it important?\n\nCode review can be one of the most deceivingly difficult things in delivering software faster. Given the high stakes involved, we've made some key additions to our DevOps Platform that focus on making the code review process as seamless and effective as possible. We believe the number one way to make code reviews effective is to provide context. \n\nToo often we think of [code review tool features](/topics/version-control/what-are-best-code-review-tools-features/) as only \"reading\" and commenting on others' code - but what a good code reviewer does is understand the entire context of the proposed change. Context-driven code reviews should include factors like the issue that spurred on the change, how the change impacts non-obvious things like code quality, security, and performance, and whether the code is maintainable after the change is in place.\n\n## Simplifying code reviews\n\nGiven all of that, we made the merge request the central point of change management and it's one of the key benefits of a DevOps Platform. Using a merge request allows code submitters and reviewers alike to have all of the information required to make the right decisions about a particular change. Making sure that everyone has the same information, and is as informed as possible about how a change will impact the project over all, leads to code reviews that are both quicker and more effective.  \n\nOver the last year we've added five features that help ease the code review pain. Here's a look at all of them:\n\n### 1) Meeting you where you are\n\nSome of the biggest code review changes involve meeting folks where they are - and allowing for a more natural feeling code review. As engineers, we spend most of our days glued to our IDE of choice. And we're used to code not just being static words on a screen, but also interacting and running that code to check its performance and outputs. That's why GitLab has brought a truly integrated experience to your development environment.\n\n**[Here's how to get started with a [DevOps platform](/topics/devops-platform/)]**\n\nIf you use Visual Studio Code as your main development environment like I do, you can now [view merge requests directly in VSCode](https://marketplace.visualstudio.com/items?itemName=GitLab.gitlab-workflow). In addition, you can [comment and see comments](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/issues/342) in that view as well as [checkout the branch directly from VSCode](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/issues/63). This familiar environment gives you all the benefits of GitLab MRs - CI/CD, security scanning, approval workflows - without having to leave your own development environment. \n\nBut what if you're not at your development box? Or you don't have this particular library or project installed and running locally?  Well there's a great solution for that - [Gitpod](https://gitpod.io) - and it also integrates directly with GitLab.  Gitpod allows you to have a working, containerized development environment in seconds. And now with GitLab 14.2, you can [launch a Gitpod workspace directly from the GitLab merge request](https://www.gitpod.io/blog/gitlab-mr-gitpod-integration).  That means with one button in GitLab you can go from a static code review into a running application with all of the proposed changes.\n\n### 2) Code quality notices built into the MR diff\n\nGitLab already brings [code quality](https://docs.gitlab.com/ee/ci/testing/code_quality.html), [security](https://docs.gitlab.com/ee/user/application_security/), [performance](https://docs.gitlab.com/ee/ci/testing/load_performance_testing.html), and [other metrics](https://docs.gitlab.com/ee/ci/testing/metrics_reports.html) directly into the merge request. But in GitLab 13.12, we also added the ability to see [code quality notices directly in the MR diff](https://docs.gitlab.com/ee/ci/testing/code_quality.html). This means that changes to code quality are presented right next to the offending code, making it quick and easy for reviewers to make suggestions about how to keep code quality top notch while shipping changes.\n\n![Code quality notice shown in-line with merge request diff](https://about.gitlab.com/images/blogimages/code_quality_mr_diff_report_v14_2.png)\n\n### 3) File-by-file reviews\n\nSometimes with changes it is nice to use the file explorer view and be able to see changes across multiple files. Other times you might want to do a thorough pass on *every* file to ensure you didn't miss anything. Toggling between seeing all of the changed files and one file at a time is a small but valuable feature that makes code reviews easier.\n\n![Animated image showing changing between show all and show one file at time view in a merge request](https://about.gitlab.com/images/blogimages/animated-single-file-review-example.gif)\n\n### 4) Check off a file as reviewed\n\nSpeaking of small but powerful features, one of my favorite features is something many would consider incredibly small.  But to that I would say - there are no small features, only small merge requests 😄!\n\n**[How to [get the most out of your DevOps platform](/topics/devops/seven-tips-to-get-the-most-out-of-your-devops-platform/)]**\n\nThe ability to check off files as reviewed has become a natural part of my code review workflow - even when the code I'm reviewing might be code I wrote myself! It allows me to focus more of my review time on the biggest impact changes, ignoring smaller changes or ones that don't directly impact the biggest concerns in a review. And in every review session I use it to make sure I've ACTUALLY reviewed every file...not that any reviewer would ever leave one out 😉.\n\n![Viewed check box checked and a file hidden as already reviewed](https://about.gitlab.com/images/blogimages/filed-viewed-merge-request.png)\n\n### 5) Reviewers vs. Assignee\n\nThe last improvement to code review in our DevOps Platform is the addition of \"reviewers\" as an option in a merge request, alongside the existing choice of \"assignee.\" This can help speed up code reviews by ensuring all team members who have to sign off on a merge request are informed and consulted while also making sure there is a clear responsibility on who will take the next action on a merge request, or be the one to actually click the \"merge when pipeline succeeds\" button.\n\nWe hope your teams will try these new and improved DevOps Platform code review features - and we're not done yet.  We'll be shipping improvements and updates to the code review process all of the time. And because everyone can contribute you can add your own ideas and suggestions into our DevOps Platform to make code reviews less painful and more effective.\n","devsecops",[9,683],"DevOps",{"slug":685,"featured":6,"template":686},"5-code-review-features","BlogPost","content:en-us:blog:5-code-review-features.yml","5 Code Review Features","en-us/blog/5-code-review-features.yml","en-us/blog/5-code-review-features",{"_path":692,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":693,"content":699,"config":711,"_id":713,"_type":14,"title":714,"_source":16,"_file":715,"_stem":716,"_extension":19},"/en-us/blog/accelerate-code-reviews-with-gitlab-duo-and-amazon-q",{"title":694,"description":695,"ogTitle":694,"ogDescription":695,"noIndex":6,"ogImage":696,"ogUrl":697,"ogSiteName":673,"ogType":674,"canonicalUrls":697,"schema":698},"Accelerate code reviews with GitLab Duo and Amazon Q","Use AI-powered agents to optimize code reviews by automatically analyzing merge requests and providing comprehensive feedback on bugs, readability, and coding standards.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750096976/Blog/Hero%20Images/Blog/Hero%20Images/Screenshot%202024-11-27%20at%204.55.28%E2%80%AFPM_4VVz6DgGBOvbGY8BUmd068_1750096975734.png","https://about.gitlab.com/blog/accelerate-code-reviews-with-gitlab-duo-and-amazon-q","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Accelerate code reviews with GitLab Duo and Amazon Q\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Cesar Saavedra\"}],\n        \"datePublished\": \"2025-06-02\",\n      }",{"title":694,"description":695,"authors":700,"heroImage":696,"date":702,"body":703,"category":704,"tags":705},[701],"Cesar Saavedra","2025-06-02","Code reviews are critical for catching bugs, improving code readability, and maintaining coding standards, but they can also be a major bottleneck in your workflow. When you're trying to ship features quickly, waiting for multiple team members to review your code can be frustrating. The back-and-forth discussions, the scheduling conflicts, and the time it takes to get everyone aligned can stretch what should be a simple review into days or even weeks.\n\nHere's where [GitLab Duo with Amazon Q](https://about.gitlab.com/blog/gitlab-duo-with-amazon-q-agentic-ai-optimized-for-aws/), our new offering that delivers agentic AI throughout the software development lifecycle for AWS customers, comes in to transform your review process. This intelligent, AI-powered solution can perform comprehensive code reviews for you in a fraction of the time it would take your human colleagues. By leveraging advanced agentic AI capabilities, GitLab Duo with Amazon Q streamlines your entire review workflow without sacrificing the quality and thoroughness you need. Think of it as having an always-available, highly skilled reviewer who can instantly analyze your code and provide actionable feedback.\n\n## How it works: Launching a code review\n\nSo how does GitLab Duo with Amazon Q actually work? Let's say you've just finished working on a feature and created a merge request with multiple code updates. Instead of pinging your teammates and waiting for their availability, you simply enter a quick command in the comment section: \"/q review\". That's it – just those two words trigger the AI to spring into action.\n\n![Triggering a code review using GitLab Duo with Amazon Q](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097002/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750097002096.png)\n\nOnce you've entered the command, Amazon Q Service immediately begins analyzing your code changes. You'll see a confirmation that the review is underway, and within moments, the AI is examining every line of your updates, checking for potential issues across multiple dimensions.\nWhen the review completes, you receive comprehensive feedback that covers all the bases: bug detection, readability improvements, syntax errors, and adherence to your team's coding standards. The AI doesn't just point out problems, it provides context and suggestions for fixing them, making it easy for you to understand what needs attention and why.\n\nThe beauty of this agentic AI approach is that it handles the heavy lifting of code review while you focus on what matters most: building great software. You get the benefits of thorough code reviews — better bug detection, consistent coding standards, and improved code quality — without the time sink. Your deployment times shrink dramatically because you're no longer waiting in review queues, and your entire team becomes more productive.\n\n## Why use GitLab Duo with Amazon Q?\n\nGitLab Duo with Amazon Q transforms your development workflow in the following ways:\n- Lightning-fast code reviews that don't compromise on quality\n- Consistent application of coding standards across your entire codebase\n- Immediate feedback that helps you fix issues before they reach production\n- Reduced deployment times that let you ship features faster\n- More time for your team to focus on creative problem-solving instead of repetitive reviews\n\nReady to see this game-changing feature in action? Watch how GitLab Duo with Amazon Q can revolutionize your code review process:\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/4gFIgyFc02Q?si=GXVz--AIrWiwzf-I\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n> To learn more about GitLab Duo with Amazon Q visit us at an upcoming [AWS Summit in a city near you](https://about.gitlab.com/events/aws-summits/) or [reach out to your GitLab representative](https://about.gitlab.com/partners/technology-partners/aws/#form).\n> \n> And make sure to join the GitLab 18 virtual launch event to learn about our agentic AI plans and more. [Register today!](https://about.gitlab.com/eighteen/)","ai-ml",[706,482,9,707,708,282,709,710],"AI/ML","product","features","AWS","tutorial",{"slug":712,"featured":91,"template":686},"accelerate-code-reviews-with-gitlab-duo-and-amazon-q","content:en-us:blog:accelerate-code-reviews-with-gitlab-duo-and-amazon-q.yml","Accelerate Code Reviews With Gitlab Duo And Amazon Q","en-us/blog/accelerate-code-reviews-with-gitlab-duo-and-amazon-q.yml","en-us/blog/accelerate-code-reviews-with-gitlab-duo-and-amazon-q",{"_path":718,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":719,"content":725,"config":733,"_id":735,"_type":14,"title":736,"_source":16,"_file":737,"_stem":738,"_extension":19},"/en-us/blog/better-code-reviews",{"title":720,"description":721,"ogTitle":720,"ogDescription":721,"noIndex":6,"ogImage":722,"ogUrl":723,"ogSiteName":673,"ogType":674,"canonicalUrls":723,"schema":724},"Better Code Reviews GitLab Style","Better Code Reviews - A selection of tools for your tool-belt when it comes to code reviews.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663502/Blog/Hero%20Images/paperclips.jpg","https://about.gitlab.com/blog/better-code-reviews","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Better Code Reviews GitLab Style\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"David O'Regan\"}],\n        \"datePublished\": \"2020-06-08\",\n      }",{"title":720,"description":721,"authors":726,"heroImage":722,"date":728,"body":729,"category":730,"tags":731},[727],"David O'Regan","2020-06-08","\n\n{::options parse_block_html=\"true\" /}\n\n\n\n> A love letter to anyone that's ever reviewed or been reviewed.\n\nThis blog post originally started as a thank-you message inside the GitLab slack channel `#thanks`, however, the scope of the message grew to such a degree that I wanted to take it a step further and see if I could not only thank the amazing people this post is dedicated to, but also hopefully share some of the amazing things they taught me to help *you*, dear reader.\n\nI have always been rather passionate about feedback. For as long as I can remember, I have always sought feedback on everything I was interested in. It's as true for me in software as it is for my non computer related hobbies like bodybuilding or grammar.....**cough cough**. Feedback is so important for every aspect of life, and in software it is no different. Feedback matters and in GitLab, we deliver most if not all of our feedback to one another via the code review.\n\nThis post is designed to deliver a selection of the most fantastic things I have seen in code reviews here at GitLab, with two goals:\n\n1. Acknowledge the people who work hard to ensure the feedback cycle they provide is as good as it can be, because at GitLab we like to [say thanks](https://handbook.gitlab.com/handbook/values/#say-thanks).\n1. Offer you, the reader, a selection of tools for your toolbelt when it comes to code reviews.\n\nEnter - **Better Code Reviews**.\n\n## Self Reviews - Details Matter\n\n> Before assigning MRs to the reviewer I practice a self-review to help the reviewer and the maintainer understand quirks and caveats of the MR. I am trying to anticipate their concerns/questions. As a maintainer I find it also very valuable. - Peter Leitzen ([@splattael](https://gitlab.com/splattael))\n\nWe often take for granted that details are hard. Moreover, we often take for granted that details in software are even harder. The majority of software consists of layers upon layers of deep abstractions and obscure logic that can be difficult, if not impossible, to really understand without spending a significant amount of time parsing it line by line.\n\nThis process is made even harder when the details or context are incorrect. Though it's natural for this to happen, humans are not spell checkers, nor do the majority of us like to revisit a piece of work a fourth or fifth time to ensure it's as correct as it can be. If we all did this, nothing would ever be delivered.\n\nBut - there is a sweet spot to be found for this dilemma in software where we can keep the velocity of delivery high, and also reduce the feedback cycle time through a small amount of dedicated effort to the details. We talk about some of the details [here in the responsibility of the merge request author](https://docs.gitlab.com/ee/development/code_review.html#the-responsibility-of-the-merge-request-author).\n\nFor the merge request author, step through a checklist. Here is mine. If you can't read my chicken-scratch handwriting, I'll type it out too:\n\n![merge-checklist](https://about.gitlab.com/images/blogimages/merge-checklist.png)\n\nBefore every feedback cycle:\n\n- Re-read every line\n- Test your code locally\n- Write a test for every change (or as many as you can)\n- Write a clear description and update it after each feedback cycle\n- Include at least one screenshot per change. More is better\n- Check, re-check and re-check your labels\n- Consider using a `~\"workflow::refinement\"` label for issues ahead of time like we do in the Monitor:Health team\n- Review the code as if you were the reviewer. Be proactive, answer the likely questions, and open followup issues ahead of time\n\nIf you want to see the last and most important part in action, check out one of our frontend maintainers Natalia Tepluhina([@ntepluhina](https://gitlab.com/ntepluhina)) pre-answer a question she knew would be asked in [one of her merge requests](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33587#note_353564612).\n\n## Conventional Comments - Communicate Intent\n\n>  **Shaming** This is horrible code. How about re-writing all of it so that it stops being that bad? - Frédéric Caplette ([@f_caplette](https://gitlab.com/f_caplette))\n\nOne of the hardest parts of getting a code review right is communicating the human touch. When we offer feedback and receive feedback, human habit creates cognitive distortion by defaulting to the most negative aspects of that feedback. At GitLab, we try to highlight that in our [value system](https://handbook.gitlab.com/handbook/values/#assume-positive-intent).\n\nIn the world of psychology, this is called **mental filtering**, and it's something that all humans have a tendency to do. Though in software this affliction can be more common, as working in software goes hand-in-hand with valuing yourself based on how intelligent others think you are.\n\nEnter [conventional comments](https://conventionalcomments.org/) by Paul Slaughter ([@pslaughter](https://gitlab.com/pslaughter)) - a well thought-out system for leaving comments in a useful way for both the reviewer and author of the merge request. It's so popular one amazing person made a [browser extension (chrome, firefox)](https://gitlab.com/conventionalcomments/conventional-comments-button) for it!\n\nSo why does adding a single bolded word to the top of a comment help with the human touch? Well, it's all about intent.\n\nWhen you start the comment with an eye-catching single word that defines the intent and tone for the comment, it gives the reader a chance to understand where your comment is coming from.\n\nLet's try an experiment. If you had submitted code for review, which comment would you prefer to read?\n\nOption one:\n\n```bash\nWhat do you think about X instead?\n```\n\nor option two:\n\n```bash\n**suggestion (non-blocking)**\n\nWhat do you think about X instead?\n```\n\nNow if you're anything like me, you took a preference to option two. It had context, communicated empathy, and was an invitation to try something different rather than a command.\n\nThe magic part of this comment is the first line `**suggestion (non-blocking)**`. Straightaway, before you even read the comment, you know the two most important things about it:\n\n1. It's a suggestion from the reviewer\n1. It's non-blocking, communicating it's more of a friendly suggestion then a hard change that's needed\n\nAnother massive advantage this style of commenting has: it allows merge request authors to understand the reviewer is neither trying to block nor act as a gatekeeper for their work. By highlighting what counts as a blocking and a non-blocking comment, merge authors get the full context of what the reviewer is trying to communicate.\n\nTo demonstrate this, let's try another thought experiment! You have submitted a merge request for review and your review comes back with eight comments.\n\n- **Scenario A: No context in comments.** All comments are treated equally because they lack context for what counts as a blocker and what doesn't.\n- **Scenario B:** Context added via conventional comments system.\n\nThe comments can be treated via priority:\n\n1. Blockers => What's needed to get the merge over the line.\n1. Non-blockers => What can be a separate merge or perhaps a discussion.\n\nNext time you're reviewing code, try using conventional comments and watch how it affects not only the way the merge request author feels about the review, but the way **you**, the reviewer, feel leaving the review. My guess is you'll feel a lot better.\n\nWe're currently looking at [integrating this feature directly into GitLab](https://gitlab.com/gitlab-org/gitlab/-/issues/26891) because we believe in making GitLab the best possible place for code reviews, and want you to have the best experience possible.\n\nIf you want to see a real-life example of some of Paul Slaughter's ([@pslaughter](https://gitlab.com/pslaughter)) awesome work using conventional comments, check out [his reviews of my community contributions](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/24897) here at GitLab. That empathy shines through.\n\n## The Patch File\n\n> Here's a patch file to better explain - Denys Mishunov ([@dmishunov](https://gitlab.com/dmishunov))\n\nWanna know a `git` secret? Patch files are the stuff of magic. If you want to read about them, [check the Git documentation for patches](https://git-scm.com/docs/git-format-patch).\n\n### How To Make A Patch File\n\nYou can make a patch file via your editor, or via the command line.\n\n#### Via The Editor\n\nRocking a nice fancy IDE or text editor? Most of them support patch files via plugins, or out of the box!\n\n- [VSCode](https://github.com/paragdiwan/vscode-git-patch)\n- [Webstorm](https://www.jetbrains.com/help/webstorm/using-patches.html)\n- [Atom](https://atom.io/packages/git-plus)\n- [Vim](https://vim.fandom.com/wiki/How_to_make_and_submit_a_patch) …life is what happens when you're trying to exit `vim`?\n\n#### Via The CLI\n\nOkay, you’ve made some commits, here’s your `git log`:\n\n```plaintext\ngit log --pretty=oneline -3\n* da33d1k - (feature_branch) Reviewer Commit 1 (7 minutes ago)\n* 66a84ah - (feature_branch) Developer 1 Commit (12 minutes ago)\n* adsc8cd - (REL-0.5.0, origin/master, origin/HEAD, master) Release 13.0 (2 weeks ago)\n```\n\nThis command creates a new file, `reviewer_commit.patch`, with all changes from the reviewer's latest commit against the feature branch:\n\n```plaintext\ngit format-patch HEAD~1 --stdout > reviewer_commit.patch\n```\n\n### Apply The Patch\n\nFirst, take a look at what changes are in the patch. You can do this easily with `git apply`:\n\n```plaintext\ngit apply --stat reviewer_commit.patch\n```\n\nJust a heads up! Despite the name, this command won't actually apply the patch. It will just show the statistics about what the patch will do.\n\nSo now that we've had a look, let's test it first, because not all patches are created equal:\n\n```plaintext\ngit apply --check reviewer_commit.patch\n```\n\nNo errors? Awesome! We can apply this patch without worry.\n\nTo apply the patch, you should use `git am` instead of `git apply`. The reason: `git am` allows you to sign off an applied patch with the reviewer's stamp.\n\n```plaintext\ngit am --signoff \u003C reviewer_commit.patch\nApplying: Reviewer Commit 1\n```\n\nNow run `git log` and you can see the `Signed-off-by` tag in the commit message. This tag makes it very easy to understand how this commit ended up in the code base.\n\n### Why to use them in code reviews\n\nSo now that you know how to make a shiny patch file, why would you use patch files as part of a code review process? There are a few reasons you might consider offering a patch file for a change you feel strongly about:\n\n1. It communicates you have invested a large amount of effort into understanding the author's solution and reasoning\n1. It demonstrates passion for reaching the best solution through teamwork\n1. It offers a willingness on the reviewer's part to accept responsibility for this merge past the point of just reading the code\n\nSome people might argue patch files are a cheeky way for a reviewer to force a change they would rather see make it into the code base, but I argue that anyone who has taken the time to check out a branch, run the project, implement a change, and then submit that change back for a discussion is embodying the value of collaboration to the fullest.\n\nWant to see a awesome example of a patch file in action? Check out one of our frontend maintainers Denys Mishunov ([@dmishunov](https://gitlab.com/dmishunov)) in action using a [patch file to its maximum potential](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31686#note_341534370)!\n\nWe believe so much in creating the best code review experience here at GitLab, we're looking into how can we make this system a [seamless part of the merge request and code review flow](https://gitlab.com/gitlab-org/gitlab/-/issues/220044).\n\n## Fairness\n\n> Fairness is a person's ability to rise above their own prejudice.\n\nFairness is a odd word. Chris Voss, a former FBI negotiator, said in his book [Never Split The Difference](https://www.goodreads.com/book/show/26156469-never-split-the-difference) that:\n\n> “Fair”—the most powerful word in any negotiation scenario. To become a great negotiator, you must earn the reputation of being a fair one.\n\nCode reviews can be viewed as a negotiation. It's you and another human being having a negotiation, based upon the idea that at the end, the result of this negotiation should be a selection of code that is both of value and of a high standard. While you might think that FBI negotiations and code reviews have little to do with one another, the concept being a fair negotiator often can be the most useful tool in your toolbox as both an author and reviewer.\n\nYou can actually see it mentioned twice in the [permissions to play in points 2 and 7](https://handbook.gitlab.com/handbook/values/#permission-to-play) guidelines here at GitLab:\n\n- \"Be dependable, reliable, fair, and respectful.\"\n- \"Seek out ways to be fair to everyone.\"\n\n### Author Fairness\n\nBeing fair as an author is the easier of the two. When you think of being fair as an author you need to adhere to a few simple Do's and Don'ts:\n\nDo:\n- Write a proper description with screenshots (can't stress this one enough)\n- Understand a reviewers point of view when they make suggestions\n- Pre-address strange parts of your merge (we all have them)\n- Be open to [collaboration](https://handbook.gitlab.com/handbook/values/#collaboration) on your work\n\nDon't:\n- \"plz merge\"\n- Forget to write a description with screenshots\n- Be closed off or take offense to suggestions\n- Forget to include any steps needed to get the build running or in other words(reduce burden where possible!)\n\nHonestly, it's pretty simple to be a fair author of a merge request if you use a small amount of empathy and remember that the person reviewing your code **gets nothing extra** for their time spend reviewing their code. They just want to help take your merge to the next level.\n\n### Reviewer Fairness\n\nBeing fair as a reviewers is a tad harder than being fair as an author. But why, I hear you ask? The issue is something called \"bias\" - or [unconscious-bias](https://handbook.gitlab.com/handbook/values/#unconscious-bias), as the handbook defines it.\n\nBias is, for better or for worse, something we all deal with when it comes to how we *want* things to be. We all have our own styles, preferences, and ideas on how software should be written:\n\n> Eslint be damned I want you to use double quotes!\n\nThis creates issues when it comes to code reviews, because it's normal for a lot of your own bias to bleed into a comment. You begin thinking in absolutes and the unresolved discussion count rises.\n\nLet me ask you something. Have you ever reviewed a merge request and found yourself saying things like:\n\n- \"It should be written like this?\"\n- \"Why would they do it like that?\"\n- \"I would have done it *this* way.\"\n- \"That's not how that should be done!\"\n\nWell, my friends, welcome to another common cognitive distortion called \"Should/must statements\". Do you want to be a better code reviewer? The next time you write a comment and it includes the word \"should\" or \"must\", pause right there and really think about why you felt the need to use that word. Sometimes it will be fair and warranted - such as if your company follows a set of coding conventions like we do at GitLab - but stay vigilant for when those statements are a thin veil for a personal preference. Ask yourself if you're being fair with your review. As a reviewer, if you find yourself in need of using a should/must statement, be sure to supply a reference to supporting documentation that is driving your statement.\n\nOne lesson I have learned through my own experience is that there is almost always a reason for something to be done the way it is. The fair response to something you don't agree with is to ask *why* it's being done like that, not saying it *must* be another way. That is how you become a fair and great negotiator.\n\n## The Follow Up\n\n> I feel like the follow up issue should become a first class citizen. - Sarah Yasonik ([@syasonik](https://gitlab.com/syasonik))\n\nLong merges suck. They just do. And while the concept of \"big doesn't always mean good\" might have started with food, it bleeds into the world of software development through merge requests that are too big. They also directly conflict one of our [main values](https://handbook.gitlab.com/handbook/values/#make-small-merge-requests) of iteration. In GitLab, we take this so seriously that [Danger Bot](https://docs.gitlab.com/ee/development/dangerbot.html) will ask you to break down merges that are over a certain size, helping developers champion the [value of iteration](https://handbook.gitlab.com/handbook/values/#iteration).\n\nLarge merge requests create huge amounts of complexity, they're hard to test, they're hard to reason about, they hard to maintain or extend.....and that's just for the author!\n\nSo what's worse than a large merge request? Reviewing a large merge request. If you've ever been pinged to review a merge request that was longer than 1000 lines, you understand what I am talking about. If it hasn't happened to you yet, count your lucky stars that your teammates live and breathe some good habits like simple solutions and iteration, and value a lack of complexity.\n\nThis creates a bigger problem than a complex reading exercise for the reviewer: it creates a context block. When a review grows past a certain amount of lines, it simply becomes too difficult to reason about without checking out the branch, booting the project and smoke testing. While smoke testing complex reviews are a great idea, it should **not** become the default ideal for reviewing.\n\nIf the merge request is too long, the code review is too complex / too long. The code rots, your merge conflicts grow, you can't iterate, you're constantly addressing breaking conflicts … and you're stuck for days, maybe weeks, maybe forever.\n\nSo how do we fix this? In the Monitor:Health team's iteration retrospective, my teammate Sarah Yasonik ([@syasonik](https://gitlab.com/syasonik)) raised a point where she suggested the follow up issue / merge become a first class citizen. I thought she was onto something amazing. If your merge is too long, or your reviews are taking too long, break your merge down, keep the reviews small, and offer follow-ups.\n\nTreat the follow-up merge as a first-class citizen. Do it right there *while reading the reviewer's feedback* instead of adding more code to a already too big merge! Do **not** make a already bloated merge even worse by adding more scope. Divide and conquer where possible.\n\nI think a lot of developers and reviewers find this process difficult because it's a contract of faith: \n\n- I, the author, promise to deliver a follow-up.\n- I, the reviewer, put myself on the line by taking your word that you will in fact fix this issue later.\n\nIt's scary, and lacks polish. I get it, but you should never let tomorrow's perfect stop today's progress because - spoiler alert - tomorrow isn't here, and we really only have today.\n\n### The Author Follow Up\n\nIf you offer a follow up, deliver it. It's your only rule but you cannot break it. Your credit for wilding the follow up resides solely in your consistent ability to deliver on your promises over time. As a author you should also work with your PMs and EMs to help prioritize the follow up as part of a wider team effort.\n\n### The Reviewer Follow Up\n\n- If you are offered a follow up, accept it with grace and trust the developer to make good on their promise.\n- Be open to suggesting follow ups as part of your review.\n- Be patient with people.\n- Allow for wiggle room, but know when to say no. (A follow-up for a non-critical issue is fine, but not a blatant break that won't add more lines or context.)\n\n## The Art Of The GIF\n\n>  If a Picture Speaks 1,000 Words a animated GIF Speaks 100,000.\n\nWhile this is the least technical aspect of the entire post it is perhaps the most interesting and the easiest to implement.\n\nDid you know that 93% of communication is nonverbal? I didn't, until I started seeing GIFs in code reviews. When I began to see them pop up in reviews, they deeply caught my attention, and I began to wonder why they had such a lasting impression on me as a developer.\n\nWords are powerful, but images are particularly powerful because of their ties to our emotions. Images have the potential to create powerful emotional responses, and when you see something that sparks a sense of positivity, it sets the tone for the entire review. You **understand fully** that the reviewer really cares and wants to communicate that care non-verbally.\n\nSo how do you use GIFs in your merge requests and code reviews? Well, you could [start with our handbook instructions](/handbook/product/making-gifs/), but the short and sweet version:\n\n1. Use a screen recorder to capture the video you want to show as a GIF.\n2. Grab yourself a copy of [gifify](https://github.com/vvo/gifify).\n3. GIF all day long!\n\n### GIFs That Show You Care\n\nI won't ever forget the first time I saw a [funny GIF in a code review](https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/1193#note_307290889). I never even made it to reading the comment, because all I could comprehend was this animated GIF of a thumbs-up and I remember thinking: *This merge would pass review. It would all be okay.* The sheer childlike giddy nature of seeing this image in action made me smile ear-to-ear. Every other comment could have been a rant about how awful my code was, but I wouldn't have cared.\n\nIf I can give you one piece of advice for your code reviews as a reviewer, use GIFs in a light-hearted way, because they are:\n\n- empathy-laden\n- soften the blow of a hard topic\n- foster positivity\n- make code reviews fun!\n\n![teamwork](https://media.giphy.com/media/vcHTRiZOglHNu/giphy.gif)\n\nWe're currently looking at making [Giphy a integrated feature here at GitLab](https://gitlab.com/gitlab-org/gitlab/-/issues/17379), making your code reviews even easier and more fun!\n\n## Tactical code reviews through the value of iteration\n\n> Can we make this smaller? - Clement Ho([@ClemMakesApps](https://gitlab.com/ClemMakesApps))\n\nOne thing I have noticed that help time and time again for better code reviews is the idea of breaking down a merge request into the smallest piece possible. A few people in my time here at GitLab have really put this across as a valuable way of working, but it was my frontend engineering manager Clement Ho([@ClemMakesApps](https://gitlab.com/ClemMakesApps)) that I really took notice championing this ideal. Given that I started paying close attention to this idea and began to notice benefits almost immediately when implementing the idea.\n\nIf we look at the GitLab value handbook's [suggestions iteration competency](https://handbook.gitlab.com/handbook/values/#iteration-competency) you can see that the value in small, digestible merge requests which translates into smaller code reviews:\n\n| Level | Demonstrates Iteration Competency by… |\n|","unfiltered",[9,732,537],"zero trust",{"slug":734,"featured":6,"template":686},"better-code-reviews","content:en-us:blog:better-code-reviews.yml","Better Code Reviews","en-us/blog/better-code-reviews.yml","en-us/blog/better-code-reviews",{"_path":740,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":741,"content":747,"config":755,"_id":757,"_type":14,"title":758,"_source":16,"_file":759,"_stem":760,"_extension":19},"/en-us/blog/bringing-ai-gitlab-repository",{"title":742,"description":743,"ogTitle":742,"ogDescription":743,"noIndex":6,"ogImage":744,"ogUrl":745,"ogSiteName":673,"ogType":674,"canonicalUrls":745,"schema":746},"GitLab and Tabnine: AI-powered code completion for GitLab repositories","Development teams can get a custom AI model based on their private code that enables knowledge sharing, reduced technical debt, and more.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749682249/Blog/Hero%20Images/blog_2757.png","https://about.gitlab.com/blog/bringing-ai-gitlab-repository","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLab and Tabnine: AI-powered code completion for GitLab repositories\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Brandon Jung\"}],\n        \"datePublished\": \"2022-03-02\",\n      }",{"title":742,"description":743,"authors":748,"heroImage":744,"date":750,"body":751,"category":752,"tags":753},[749],"Brandon Jung","2022-03-02","\n\nAs AI continues to become more ubiquitous throughout [every aspect of our lives](https://www.tabnine.com/blog/is-ai-pair-programming-really-going-to-help-me/), it should come as little surprise that programming has picked it up as a tool to help make developers more productive. Tabnine is integrating with GitLab to bring Tabnine's AI-powered code completion technology to GitLab repositories to improve the accuracy and speed of code development.\n\nWe believe that increased development velocity improves the developer’s working experience, accelerates feature release cadence, and enables teams to respond faster to market opportunities. Users can now get a custom AI model based on their private code that enables: \n\n- Knowledge sharing\n- Reduced technical debt\n- Faster code reviews\n- Faster onboarding and time to value\n\nThe value of a custom model is about helping a specific team with a specific mission be more productive. A team comes in many forms from the most simple [two pizza box team](https://docs.aws.amazon.com/whitepapers/latest/introduction-devops-aws/two-pizza-teams.html) to a large software company with hundreds of internal developers as well as thousands of external developers who contribute to a large shared [open source code base](/community/contribute/). What all these teams have in common is that they have a shared interest in a common code base. This code base for any digital company is one of the most important strategic assets and anything that helps them build it faster and more consistently requires serious consideration.\n\nGitLab has a robust platform for hosting code for private teams, so it is natural that we wanted to make it easier for teams to bring their development models together. Developers can now automate the creation of a custom model based on their private code. The process is outlined below and is seamless for the user as Tabnine will build, validate, and upload the private model for the whole team. New developers can now be added to the team and will immediately receive custom suggestions based on the codified best practices of the team. \n\nThis is the first of ongoing work that Tabnine is doing to support developers together with GitLab and we look forward to getting your feedback on how we can make it better for you individually and for your team.\n\nHere's how to get started: \n\n1. As a Tabnine for Teams user, login to [AI Code Completions for Developers & Teams](https://app.tabnine.com/profile/) \n2. Navigate to the “Team AI” tab\n3. Connect to your GitLab repositories\n4. Tabnine will build, test, and upload your private team model\n5. Enjoy your personalized Tabnine AI assistant\n\n![Getting started](https://about.gitlab.com/images/blogimages/tabnine1.png){: .shadow}\n\nThe GitLab partnership represents Tabnine's latest step towards the goal of an end-to-end development platform supporting all developers regardless of working environments, coding languages, or IDEs. [Share your feedback with Tabnine](https://forms.gle/vCHK5QRoyR5xt6Jg8) on our AI-powered code completion technology.\n\n","engineering",[683,754,9],"news",{"slug":756,"featured":6,"template":686},"bringing-ai-gitlab-repository","content:en-us:blog:bringing-ai-gitlab-repository.yml","Bringing Ai Gitlab Repository","en-us/blog/bringing-ai-gitlab-repository.yml","en-us/blog/bringing-ai-gitlab-repository",{"_path":762,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":763,"content":769,"config":776,"_id":778,"_type":14,"title":779,"_source":16,"_file":780,"_stem":781,"_extension":19},"/en-us/blog/browser-based-dast-feature-announcement",{"title":764,"description":765,"ogTitle":764,"ogDescription":765,"noIndex":6,"ogImage":766,"ogUrl":767,"ogSiteName":673,"ogType":674,"canonicalUrls":767,"schema":768},"Introducing browser-based DAST and integrated passive checks","We're working hard on reducing noise. Here's what you need to know about the status of our browser-based DAST offering today.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749682466/Blog/Hero%20Images/vek-labs-e8ofKlNHdsg-unsplash.jpg","https://about.gitlab.com/blog/browser-based-dast-feature-announcement","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Introducing browser-based DAST and integrated passive checks\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Isaac Dawson\"}],\n        \"datePublished\": \"2022-10-19\",\n      }",{"title":764,"description":765,"authors":770,"heroImage":766,"date":772,"body":773,"category":707,"tags":774},[771],"Isaac Dawson","2022-10-19","\n\nThe [DAST](/direction/secure/dynamic-analysis/dast/) and [Vulnerability Research](/handbook/engineering/development/sec/secure/vulnerability-research/) teams at GitLab are excited to announce we have fully [integrated passive checks](/releases/2022/08/22/gitlab-15-3-released/#browser-based-dast-passive-check-milestone) into our new [browser-based DAST analyzer](https://docs.gitlab.com/ee/user/application_security/dast/browser_based.html). Passive checks work by monitoring the network traffic to target applications while the web site is automatically crawled. This allows us to identify weaknesses that may exist without sending potentially disruptive network requests. This continues our effort to fully switch over to our browser-based analyzer for DAST in the coming months. If you are interested in using our new DAST analyzer please see our [documentation on how to configure a browser-based DAST scan](https://docs.gitlab.com/ee/user/application_security/dast/browser_based.html).\n\n## History of DAST at GitLab\n\nDAST was [officially launched](/releases/2018/01/22/gitlab-10-4-released/) as a part of the GitLab 10.4 release in January 2018. By utilizing the powerful OWASP [Zed Attack Proxy](https://www.zaproxy.org/) we were able to give our customers the ability to dynamically scan\ntheir web applications. From that initial minimal viable product, we have grown to the point where we are now running over a million scans a month.\n\nScanning web applications in the CI/CD context comes with challenges. Unlike [SAST](/direction/secure/static-analysis/sast/), which is relatively fast, dynamically scanning an application can take a significant amount of time. DAST is resource intensive as it needs to process each request and response to the target application. To ensure smooth operations for the majority of our customers we have to run under the assumption that our memory and CPU footprints should be as small as possible. Finally, and most likely the biggest pain point, is the disconnect that often occurs when trying to visualize or understand how a web application should be analyzed when one can not physically see any of the interactions between the scanner and the target application.\n\nZAP was originally built as a desktop application, meaning auditors could use it to see the target application while conducting their testing. Only by utilizing ZAP's scripting API could we make DAST scans viable in a CI/CD context. This surfaced some challenges: what is easy to configure in the UI may or may not be straightforward to adjust from a configuration file or a command line option. \n\nWhen reviewing our support tickets however, a very clear picture began to surface. Users were having the most problem with configuring authentication for their applications. This makes sense, as it is where the user interacts with the scanner the most. Modern applications almost require a browser to authenticate, due to relying on browser features like local or session storage. These features are commonly used for handling JSON Web Token (JWT) based authentication and authorization. \n\nIt should be noted that ZAP does have a browser based crawler extension, called AJAX Spider. This extension uses [Crawljax](https://github.com/crawljax/crawljax). GitLab provides this feature by supplying the correct CI/CD variable, but it is no longer recommended. AJAX Spider is however, only an extension, and does not represent a tight integration between the browser and the DAST tool. \n\n## A path forward\n\nWe needed a system where we could have full control over a browser to allow us to instrument interactions between a website and the DAST tool. A DAST tool which does not tightly integrate with a browser will be limited in its ability to fully interact with today's demanding web applications. Just some of the challenges of this are:\n\n- Single Page Applications (SPAs)\n- Complex, multi-step sign in features\n- Complex front-end frameworks  \n- Utilization of built-in browser features (e.g. usage of localStorage or sessionStorage) \n\nA new DAST tool based completely off instrumenting a browser and written in Go would give GitLab a lot more control going forward. What started as a side project during nights and weekends began to show some promise. The Vulnerability Research and DAST teams worked together to assess the viability of building out this DAST analyzer. To allow us to take advantage of new features without having to implement the entire engine, we opted to continue to use ZAP as the proxy. This means our analyzer is forwarding all the browser traffic through ZAP, but processing logic of crawling and passive checks are now done in our engine. While we've been relatively quiet on our progress, we've been incrementally rolling out new features with almost every release. The end goal is to completely replace ZAP with our own engine.\n\n## Where we are today\n\nOf course the biggest announcement is that we have fully switched over to using our own vulnerability check system for passive checks. These checks replace ZAP's \"passive\" checks. The Vulnerability Research team invested a lot of time looking over how each ZAP plugin worked and determined whether it was worth implementing, or if it should be implemented differently. Alert fatigue is a real concern we share with our customers. By reducing the noise (false positives) in our DAST offering, we hope to reduce the chance of our customers ignoring real findings. As such, our goal is to significantly reduce the noise that is usually associated with DAST scan results, and this is achieved through three different methods:\n\n1. Not implementing certain checks\n2. Reducing false positives (incorrect findings) \n3. Aggregating true positives (real findings)\n\nPoint one is worth expanding upon. DAST vulnerabilities are unique in that in some cases the fix for a vulnerability is reliant on the browser or user-agent being modified, and not  the target application. Browsers increase their security directly or have it increased by deprecating features that were used in attacks. Browsers deciding to disable Flash is a good example of this – what was a vulnerability yesterday may no longer be a vulnerability today. \n\nZAP's check for [Charset mis-match](https://www.zaproxy.org/docs/alerts/90011/) is another case in point. After [researching](https://gitlab.com/gitlab-org/gitlab/-/issues/331218) what was possible in 2022, it turns out this is no longer an issue worth reporting. Other DAST tools report similar issues that are no longer realistically exploitable or worth reporting, so this is not just an issue with ZAP. \n\nReducing false positives is another major initiative, and one that led us to create a rather unique system for creating new vulnerability checks. Traditionally, DAST tools use a plugin architecture of hardcoded vulnerability checks. While quick to implement, they can have the downside of being difficult to understand or error prone. They are also harder to implement in a standardized way. At GitLab we opted to use a configuration-file-based check system, much like today's SAST tools. \n\nFinally, aggregating true positives allows us to merge similar issues into a single finding. These types of issues are usually fixed by a single configuration change, such as adding a security header.\n\nOur passive checks are almost entirely written in YAML, using a custom specification that allows us to define a check as text. Where this is not feasible, reusable components are written that can be referenced by various checks. Below is an example check that looks for the `X-Content-Type-Options` header in HTTP response headers and reports if it is missing the `nosniff` value.\n\n```yaml\n",[775,708,9],"testing",{"slug":777,"featured":6,"template":686},"browser-based-dast-feature-announcement","content:en-us:blog:browser-based-dast-feature-announcement.yml","Browser Based Dast Feature Announcement","en-us/blog/browser-based-dast-feature-announcement.yml","en-us/blog/browser-based-dast-feature-announcement",{"_path":783,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":784,"content":790,"config":797,"_id":799,"_type":14,"title":800,"_source":16,"_file":801,"_stem":802,"_extension":19},"/en-us/blog/cascading-merge-requests-with-gitlab-flow",{"title":785,"description":786,"ogTitle":785,"ogDescription":786,"noIndex":6,"ogImage":787,"ogUrl":788,"ogSiteName":673,"ogType":674,"canonicalUrls":788,"schema":789},"How to adopt a cascading merge request strategy with GitLab Flow","This tutorial explains how to consolidate updates in a single branch and propagate them to other branches using ucascade bot.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749679851/Blog/Hero%20Images/cascade.jpg","https://about.gitlab.com/blog/cascading-merge-requests-with-gitlab-flow","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How to adopt a cascading merge request strategy with GitLab Flow\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Madou Coulibaly\"}],\n        \"datePublished\": \"2023-08-31\",\n      }",{"title":785,"description":786,"authors":791,"heroImage":787,"date":793,"body":794,"category":752,"tags":795},[792],"Madou Coulibaly","2023-08-31","\nGit offers a range of branching strategies and workflows that can be utilized to enhance organization, efficiency, and code quality. Employing a well-defined workflow helps foster a successful and streamlined development process. By implementing the [release branches using GitLab Flow](https://docs.gitlab.com/ee/topics/gitlab_flow.html#release-branches-with-gitlab-flow), you can effectively handle multiple product releases. However, when it comes to fixing bugs, it often becomes necessary to apply the fix across various stable branches such as `main`,  `stable-1.0`, `stable-1.1`, and `stable-2.0`. The process of applying the fix to multiple locations can be time-consuming, as it involves the manual creation of multiple merge requests.\n\nBy consolidating updates in a single branch and propagating them to other branches, the cascading merge approach establishes a central source of truth, reducing confusion and maintaining consistency. In this blogpost, we will guide you through setting up this approach for your GitLab project using [ucascade bot](https://github.com/unblu/ucascade).\n\n## Getting started\nTo get started, you'll need the following prerequisites:\n\n### Environment\n  - a GitLab project that implemented [Release Branches Strategy](https://docs.gitlab.com/ee/topics/gitlab_flow.html#release-branches-with-gitlab-flow)\n  - a Kubernetes cluster\n\n### CLI\n  - git\n  - kubectl\n  - docker\n\n### Project access tokens\nFollow the instructions on the [Project access tokens page](https://docs.gitlab.com/ee/user/project/settings/project_access_tokens.html#create-a-project-access-token) to create two project access tokens –`ucascade` and `ucascade-approver` – with the API scope in your GitLab project.\n\n![project access tokens](https://about.gitlab.com/images/blogimages/2023-06-22-cascading-merge-requests-with-gitlab-flow/pat.png){: .shadow.medium}\n\n## Deploy ucascade bot on Kubernetes\nFirst, create the `bots-fleet` namespace on Kubernetes.\n\n```\nkubectl create namespace bots-fleet\n```\n\nThen, create the `cascading-merge-secret` secret that contains the GitLab project access tokens created previously.\n\n```\nkubectl create secret generic cascading-merge-secret -n bots-fleet \\\n--from-literal=gitlab-host=https://gitlab.com \\\n--from-literal=gitlab-api-token=\u003CUCASCADE_PROJECT_ACCESS_TOKEN> \\\n--from-literal=gitlab-api-token-approver=\u003CAPPROVER_BOT_PROJECT_ACCESS_TOKEN>\n```\n\nOnce done, (fork and) clone the [Cascading Merge repository](https://gitlab.com/madou-stories/bots-fleet/cascading-merge) that contains the Kubernetes manifests for the bot and replace the `host` field in the `kube/ingress.yaml` file according to your Kubernetes domain.\n\n```yaml\napiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n  annotations:\n    kubernetes.io/ingress.class: nginx\n  name: ucascade\n  namespace: bots-fleet\nspec:\n  rules:\n  - host: ucascade.\u003CKUBERNETES_BASED_DOMAIN>\n    http:\n      paths:\n      - backend:\n          service:\n            name: ucascade\n            port:\n              number: 80\n        path: /\n        pathType: Prefix\n\n``` \n\nNow, you are ready to deploy the `ucascade` bot.\n\n```\nkubectl apply -f kube/\n```\n\nYou should see the following resources deployed on Kubernetes:\n\n![ucascade-k8s](https://about.gitlab.com/images/blogimages/2023-06-22-cascading-merge-requests-with-gitlab-flow/ucascade-k8s.png){: .shadow.medium}\n\n**Note:** The `ucascade` image is based on the [ucascade-bot](https://github.com/unblu/ucascade-bot) and is located in the [Container Registry](https://gitlab.com/madou-stories/bots-fleet/cascading-merge/container_registry) of the Cascading Merge repository.\n{: .note}\n\n## Create a GitLab webhook\nFollow the instructions on [the Webhooks page](https://docs.gitlab.com/ee/user/project/integrations/webhooks.html#configure-a-webhook-in-gitlab) to create a webhook with the following variables: \n  - **URL**: `\u003CUCASCADE_INGRESS_URL>/ucascade/merge-request`\n  - **Trigger**: `Merge request events`\n\n![webhook](https://about.gitlab.com/images/blogimages/2023-06-22-cascading-merge-requests-with-gitlab-flow/webhook.png){: .shadow.medium}\n\n## Configure your Cascading Merge rule\nCreate a file called ucascade.json at the root level of your GitLab project as defined in [configuration file](https://unblu.github.io/ucascade/tech-docs/11_ucascade-configuration-file.html#_configuration_file) and matched with your release definition.\n\n![configuration](https://about.gitlab.com/images/blogimages/2023-06-22-cascading-merge-requests-with-gitlab-flow/configuration.png){: .shadow.medium}\n\n## Testing the Cascading Merge\nNow create a branch and an MR from your default branch, make a change, and merge it. The ucascade bot will propagate the change to all other release branches by automatically creating cascading MRs. The following video demonstrates the process:\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/Ej7xf8axWMs\" title=\"Cascading Merge Approach\"\n  frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n# Additional resources\nFind more information about the `ucascade` bot in the [ucascade documentation](https://unblu.github.io/ucascade/index.html).\n\n_Special thank you to Jérémie Bresson for authoring and open sourcing this amazing bot!_\n",[109,9,796,710],"git",{"slug":798,"featured":91,"template":686},"cascading-merge-requests-with-gitlab-flow","content:en-us:blog:cascading-merge-requests-with-gitlab-flow.yml","Cascading Merge Requests With Gitlab Flow","en-us/blog/cascading-merge-requests-with-gitlab-flow.yml","en-us/blog/cascading-merge-requests-with-gitlab-flow",{"_path":804,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":805,"content":811,"config":821,"_id":823,"_type":14,"title":824,"_source":16,"_file":825,"_stem":826,"_extension":19},"/en-us/blog/cern-connect-global-researchers",{"title":806,"description":807,"ogTitle":806,"ogDescription":807,"noIndex":6,"ogImage":808,"ogUrl":809,"ogSiteName":673,"ogType":674,"canonicalUrls":809,"schema":810},"CERN uses GitLab to remove the obstacles around global researchers","Learn how GitLab helps particle physics laboratory CERN manage over 7,000 projects globally","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749670719/Blog/Hero%20Images/cern.jpg","https://about.gitlab.com/blog/cern-connect-global-researchers","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"CERN uses GitLab to remove the obstacles around global researchers\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Kim Lock\"}],\n        \"datePublished\": \"2018-10-12\",\n      }",{"title":806,"description":807,"authors":812,"heroImage":808,"date":814,"body":815,"category":816,"tags":817},[813],"Kim Lock","2018-10-12","\n\nCERN is the European Organization for Nuclear Research. Using highly sophisticated\ninstruments, the organization’s physicists and engineers study the fundamental particles\nthat are the building blocks of the universe. This organization was looking for a way to\novercome the challenges associated with managing thousands of projects with numerous contributors\nlocated all around the world.\n\nTo assist with these challenges, the [CERN IT department searched for a streamlined solution](https://about.gitlab.com/customers/cern/) for\ncode review. In addition to having the capacity to get a large number of projects and users up and\nrunning quickly, they were also looking for their selection to be easy for those users who are less\nexperienced with Git. GitLab met their requirements and they began utilizing these features.\n\nCERN chose to make the move to GitLab for their code hosting needs approximately three years ago. CERN\nhas long been a strong advocate for open source software, and solutions enabling data sovereignty. GitLab’s\nopen core, self-managed model was attractive to the organization because of these desires.\n\n### Today CERN has more than 12,000 users using GitLab and runs 120,000 CI jobs per month\n\n“It’s clearly a powerful tool to do our operations, code collaboration and record discussions on our\ndevelopment and deployment process. We can do more because we can handle more complex projects. As an\nindividual, I’m able to be involved with several large projects because I can rely on GitLab, and the\nother development tools that we have deployed around GitLab, to keep track of things. This is my perception\nas a GitLab user for three years: it’s not that I can do new things, but I can do more because of the\nefficiency of the tool,” said Alex Lossent, Version Control Systems Service Manager, CERN IT department\n\nThe team at CERN's IT department recently sat down with us to share the details of how GitLab is helping\nthem bridge the gaps of working and communicating in a global workspace. “We have this main analysis code on\nGitLab with millions of lines of code. Each team of physicists also has their own repositories with their\nspecific data analysis. And the on-premise nature of GitLab is really useful because we can access other CERN\nservices, data storage and other information that we wouldn’t have on GitHub,” Lukas Heinrich, a partner\nphysicist currently studying at New York University, explained.\n\nYou can learn more about CERN's story and how they are using GitLab in this case stuy [Particle physics laboratory uses GitLab to connect researchers from across the globe](https://about.gitlab.com/customers/cern/)\n","insights",[818,9,819,820],"user stories","collaboration","remote work",{"slug":822,"featured":6,"template":686},"cern-connect-global-researchers","content:en-us:blog:cern-connect-global-researchers.yml","Cern Connect Global Researchers","en-us/blog/cern-connect-global-researchers.yml","en-us/blog/cern-connect-global-researchers",{"_path":828,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":829,"content":835,"config":842,"_id":844,"_type":14,"title":845,"_source":16,"_file":846,"_stem":847,"_extension":19},"/en-us/blog/challenges-of-code-reviews",{"title":830,"description":831,"ogTitle":830,"ogDescription":831,"noIndex":6,"ogImage":832,"ogUrl":833,"ogSiteName":673,"ogType":674,"canonicalUrls":833,"schema":834},"The challenges of code reviews","The 2020 DevSecOps Report discovers that developers are bogged down by code reviews. Are they worth the trouble?","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663975/Blog/Hero%20Images/devsecopssurvey.png","https://about.gitlab.com/blog/challenges-of-code-reviews","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"The challenges of code reviews\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Suri Patel\"}],\n        \"datePublished\": \"2020-07-03\",\n      }",{"title":830,"description":831,"authors":836,"heroImage":832,"date":838,"body":839,"category":816,"tags":840},[837],"Suri Patel","2020-07-03","\n\n## Code review and quality challenges\n\nCode reviews are stressful. As a merge request owner, you're giving others an inside look at your abilities and thought processes. As a reviewer, there’s something quite daunting about serving as the last stop before code is merged to the main branch. When teams face uncertain processes, lengthy wait times, and lack of buy-in, an inherently difficult task can soon feel Sisyphean. In GitLab’s [2020 Global DevSecOps Survey](/developer-survey/previous/2020/), over 3600 software professionals shared their thoughts on code reviews, and the results reinforce that code reviews are a challenging aspect of software development.\n\n_Our [2022 Global DevSecOps Survey](/developer-survey/) has the latest insights from over 5,000 DevOps professionals. You can also compare it with [previous year surveys](/developer-survey/previous/)_\n\n## Why is code review important?\n\nCode reviews enable developers to more easily identify bugs, because they’re assessing the code with a fresh perspective. Shipping clean code decreases the likelihood of errors nestling into the main branch. Teams turn to code reviews as a way to share knowledge, mentor newer developers, and ease the burden of development. When everyone reviews code, there is no longer a single point of failure that can halt delivery and risk missing releases or business goals.\n\nStudies show that [code reviews increase collaboration](https://www.microsoft.com/en-us/research/publication/expectations-outcomes-and-challenges-of-modern-code-review/), because the process of working together to improve code quality creates a shared ownership of the codebase. Developers work towards a common goal rather than feel proprietary attachment to their lines.\n\n## Code reviews according to developers\n\nIn the 2020 DevSecOps Report, developers candidly shared their views on code reviews, with many highlighting the challenges of ensuring code quality standards. Here’s a look at what developers said about code reviews.\n\n| **How frequently does your team conduct code reviews?** |\n| Weekly |  48.9% |\n| Bi-weekly |  13.6% |\n| Monthly |  9.5% |\n\nMost respondents do code reviews weekly, indicating that teams are committed to making them part of their workflow.\n\n| **How do code reviews happen?** |\n| Messaging chat |  40.8% |\n| Offline |  28.6% |\n| Other |  20.9% |\n| Video |  9.7% |\n\nDocumentation is an important part of a successful code review. Authors should be able to refer to a checklist or assessment that highlights areas of improvement or excellence. Respondents indicated that the majority of code reviews occur in messaging chat or offline, which may enable written documentation.\n\n| **How do you prefer to do code reviews?** |\n| IDE | 44% |\n| Browser |  41.4% |\n| Code/text editor |  14.6% |\n\nConducting code reviews in integrated development environments and browsers is unsurprising, because there’s a low barrier to entry in participating and collaborating with others.\n\nMany respondents shared their thoughts about the specific challenges they face when doing code reviews.\n\n_“Code reviews can take a long time due to the lack of reviewers.”_\n\nWithout enough reviewers, code reviews can become overwhelming for the few people who make time for this task. Code reviews become a burdensome activity that can prevent certain team members from meeting goals and delivering.\n\n_“As an all-remote company, we haven't yet solved the problem of needing reviews from people in much different time zones and working hours. We have a strict code review process, and it often takes several days for the reviewer to respond to requests for review. Planning takes a while, and our code review process, while awesome, takes some time.”_\n\nWorking in a distributed team can have drawbacks, especially when waiting for domain experts or maintainers to review code. While processes are important in establishing workflow, it’s equally important not to slow down team members with process.\n\n_“Our code review process is disorganized. It took more time when reviewing the code and testing than expected.”_\n\nOn the other hand, not having an established review process can lead to stress, confusion, and pressure. Team members may dread code reviews due to the disorganization, which can lead to insufficient assessment.\n\n_“Some experts do not understand the importance of code review and regard it as a secondary task.”_\n\nWhen some team members do not value code review, they may deprioritize it and be reluctant participants. Collaboration is a key component in ensuring successful code reviews, and lack of buy-in can slowly erode morale.\n\n## Are code reviews worth it?\n\nBased on the frustration level found in the 2020 DevSecOps Survey, it’s hard not to wonder whether code reviews are worth the trouble. But all complaints aside, it’s clear that the review process is helpful.\n\n| **How valuable are code reviews?** |\n| Very valuable | 61.9% |\n| Moderately valuable |  33.3% |\n| They have no effect |  3.7% |\n\nCode reviews are worth the difficulties, because they help teams collaborate to maintain a clean codebase, learn from each other to develop new skills, and ensure that innovative solutions solve complex problems. In order for team members to feel like code reviews are valuable, IT leaders must invest time in establishing processes to ensure that everyone has the tools and knowledge to succeed.\n\n## Ready to learn more about code reviews?\n\nHere are a few resources to help you alleviate the challenges of code review.\n\n**[Read GitLab’s mandatory code review process →](https://docs.gitlab.com/ee/development/code_review.html)**\n\n**[Learn how to troubleshoot delays with GitLab’s Code Review Analytics tool →](/blog/troubleshoot-delays-with-code-review-analytics/)**\n\n**[Discover better code reviews GitLab style →](/blog/better-code-reviews/)**\n\n**[What blocks faster code releases? It starts with testing\n →](/blog/what-blocks-faster-code-release/)**\n\n**[Read about GitLab’s experience with Reviewer Roulette →](/blog/reviewer-roulette-one-year-on/)**\n",[9,841,683],"developer survey",{"slug":843,"featured":6,"template":686},"challenges-of-code-reviews","content:en-us:blog:challenges-of-code-reviews.yml","Challenges Of Code Reviews","en-us/blog/challenges-of-code-reviews.yml","en-us/blog/challenges-of-code-reviews",{"_path":849,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":850,"content":856,"config":863,"_id":865,"_type":14,"title":866,"_source":16,"_file":867,"_stem":868,"_extension":19},"/en-us/blog/checkmarx-integration",{"title":851,"description":852,"ogTitle":851,"ogDescription":852,"noIndex":6,"ogImage":853,"ogUrl":854,"ogSiteName":673,"ogType":674,"canonicalUrls":854,"schema":855},"Get the most out of the Checkmarx integration with GitLab","Make it easier for developers to find bugs and for dev and sec to get along. Here’s what you need to know about the GitLab/Checkmarx integration.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749681659/Blog/Hero%20Images/checkmarx.jpg","https://about.gitlab.com/blog/checkmarx-integration","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Get the most out of the Checkmarx integration with GitLab\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Valerie Silverthorne\"}],\n        \"datePublished\": \"2020-10-12\",\n      }",{"title":851,"description":852,"authors":857,"heroImage":853,"date":859,"body":860,"category":752,"tags":861},[858],"Valerie Silverthorne","2020-10-12","\n\nIn our 2020 Global DevSecOps survey, 65% of respondents said their organizations were shifting security left. Shifting left is the holy grail of [DevOps](/topics/devops/), certainly, but there’s reason to believe most organizations actually aren’t quite *left* enough: Less than 20% of respondents said developers were able to access either SAST or DAST scans from within their pipelines or IDEs.\n\nIt’s perhaps not surprising that, in the [same survey](/developer-survey/), security pros complained rather bitterly about developers finding too few bugs too late in the process.\n\nOne solution to this problem is to [integrate application security testing](/topics/devsecops/) earlier and actually within a development tool. During [our 2020 virtual user conference](/events/commit/), Commit, [James Brotsos](https://www.linkedin.com/in/jbrotsos/), a senior solutions engineer with [Checkmarx](https://www.checkmarx.com), walked attendees through the process of integrating his company’s security testing platform with GitLab.\n\n“(Integrating app security testing) really does free up time to focus on things that actually matter to developers, which is writing code,” James said during his presentation. “With this methodology, we are shifting far left into the software development life cycle. We still are providing governance and gating capabilities, constantly scanning the latest code and this replaces the need to scan it in the IDE.”\n\n## Getting started\n\nTo get the most out of an integrated security testing platform, James said companies should start by making a series of decisions: \n\nWhat do you want to scan? Commits or merge requests?\nWhen do you want to scan? Nightly, weekly, more often?\nHow do you want the data? Via the Checkmarx platform, emails, Slack messages, inside GitLab or through auto ticket creation?\n\n“We have an interactive security testing platform which is an agent that runs on a test server,” James explained. “It’s running your code, it monitors traffic driven from functional tests and it could run security types of queries on top of that. We provide… all these types of vulnerabilities and we train you how to fix them.”\n\nAt the heart of the GitLab integration with Checkmarx is CxFlow, a spring boot application that initiates scans and pursues results, James said. Scanning is initiated by integrating with [GitLab’s CI/CD](/topics/ci-cd/), or through a merge request or pushed code, triggering an already existing pipeline. That pipeline needs just a single edit to include the stage to execute a security scan.\n\nThe integration is completely customizable and developers can get what they need when they need it. CxFlow drives a result feedback loop so no manual intervention is required and developers can filter the types of defects created based on any filtering criteria. “The results are easy to consume in a way that developers want to consume them… and the results are actionable,” James said.\n\nWhen it comes to defect tracking, CxFlow solves the problem of having the same vulnerability type in the same file by creating just a single issue where the ticket automatically closes once its been dealt with. And developers can choose how they receive feedback: through GitLab’s security dashboard or issues, or through Jira, email, ServiceNow and Rally.\n\n## The nuts and bolts\n\nTo tie security scanning into GitLab, start by setting up the global variables that will allow access to the Checkmarx server. After that the CI/CD pipeline can kick off. Separate the Checkmarx stages from the GitLab CI file – you don’t want to “pollute” any existing YAML file set up by your DevOps team. Just include another YAML file with this stage or extension and that will allow you to have the Checkmarx-specific information which will kick off the CxFlow CLI.\n\nSo once the CxFlow starts to run inside that container, it will initiate a scan inside Checkmarx. The results will be sent back to CxFlow. “Depending on how you want to consume those results, we can update the security dashboard, we can update the issues, we can update the merge request, or we can update all three of them at the same time,” James said.\n\nCxFlow can also create issues automatically that can then be triaged to an epic or assigned to a specific user. “This way you can treat all security vulnerabilities as you would any other defect or any other kind of issue,” James said.\n\n“This is a pretty effortless option for the development teams to scan projects quickly,” James said. “There is no overhead when configuring and managing these builds. You can quickly automate the scan of multiple repositories and there's no overhead in configuring and managing all of these different repos that you might have.”\n\n## A deeper dive\n\nA more detailed look at this project can be found [on the Checkmarx website](https://checkmarx.atlassian.net/wiki/spaces/SD/pages/1929937052/GitLab+Integration) or watch the entire Commit presentation:\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube-nocookie.com/embed/W1Wk3PN0o1M\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\nCover image by [JJ Ying](https://unsplash.com/@jjying) on [Unsplash](https://unsplash.com)\n{: .note}\n",[862,9,841],"security",{"slug":864,"featured":6,"template":686},"checkmarx-integration","content:en-us:blog:checkmarx-integration.yml","Checkmarx Integration","en-us/blog/checkmarx-integration.yml","en-us/blog/checkmarx-integration",{"_path":870,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":871,"content":877,"config":884,"_id":886,"_type":14,"title":887,"_source":16,"_file":888,"_stem":889,"_extension":19},"/en-us/blog/debug-web-apps-quickly-within-gitlab",{"title":872,"description":873,"ogTitle":872,"ogDescription":873,"noIndex":6,"ogImage":874,"ogUrl":875,"ogSiteName":673,"ogType":674,"canonicalUrls":875,"schema":876},"Debug Web apps quickly within GitLab","Jam for GitLab, a browser extension, creates GitLab issues with critical context such as browser info, console/network logs, and reproduction steps - in one click.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099168/Blog/Hero%20Images/Blog/Hero%20Images/blog-image-template-1800x945%20%2810%29_arHGAEPyRHF7euCvaxE0S_1750099168482.png","https://about.gitlab.com/blog/debug-web-apps-quickly-within-gitlab","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Debug Web apps quickly within GitLab\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Ivanha Paz\"}],\n        \"datePublished\": \"2024-05-08\",\n      }",{"title":872,"description":873,"authors":878,"heroImage":874,"date":880,"body":881,"category":752,"tags":882},[879],"Ivanha Paz","2024-05-08","***Editor's note: From time to time, we invite members of the community to contribute to the GitLab Blog. Thanks to [Jam.dev](https://jam.dev/gitlab) for co-creating with us.***\n\nDebugging a Web app takes a village but gathering information about bugs as they happen can be challenging. Jam.dev launched the Jam for GitLab browser extension (available for Google Chrome, Arc, Opera, and Edge) that enables all DevSecOps team members to create comprehensive debugging reports, complete with instant replays of the bug, with a single click. \n\nThe reports, which are spun up as GitLab issues, include the context engineers need to find and fix bugs, including internet speed, browser information, console/network logs, and reproduction steps. Jam also parses GraphQL requests for errors which can be copied as cURL.\n\nJam for GitLab was built using GitLab's API so it is fully integrated with the DevSecOps platform. Here’s how Jam for GitLab works:\n\n1. Click on the Jam browser extension to record your screen and take a screenshot or replay a bug that just happened. \n\n![Create issue - gif 2](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099178/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750099177866.gif)\n\n2. Jam automatically generates a GitLab issue with all the technical debugging context.\n\n![Info collected - gif 1](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099178/Blog/Content%20Images/Blog/Content%20Images/Jam_for_GitLab_debugging_aHR0cHM6_1750099177867.gif)\n\n## Why we created Jam for GitLab\nLike so many of you, we are huge fans of GitLab. A lot of Jam users love and engage with the GitLab developer community. It’s one of Jam’s top 3 most requested integrations! And with their API, GitLab makes it easy for startups like us to build new tools in the GitLab ecosystem. Building for the GitLab community is an important milestone for the Jam team. \n\nJust like GitLab values efficiency, we want to make developers’ lives easier. We believe the best way to do it is by removing a lot of unnecessary barriers for collaboration between engineering and product. We share this vision with GitLab and all of you using it to improve the lives of your customers; and quite literally build the future. \n\nLike my teammate and Jam engineer, Arég, says, “The worst part of the job is trying to debug an existing system to understand why it’s not behaving the way people expect. But you can use Jam, and maybe it’ll be less terrible, and you’ll have more time to do the best part: building something new.”\n\nGitLab is where product teams come together to build what’s next. Not just engineers, but everyone involved in the software development lifecycle. It takes a powerful platform to enable this level of collaboration. We love what GitLab stands for, and it’s truly an honor to contribute to our shared mission by making debugging easier and faster.\n\nFrom all of us at Jam, thank you to the GitLab team for being such awesome people to work with and building a product we and millions around the world love.\n\n> Ready to dramatically cut your debugging time? [Get started with Jam today.](https://jam.dev/gitlab)\n\n*Paz is DevRel lead at Jam.*\n",[231,9,883],"DevSecOps",{"slug":885,"featured":6,"template":686},"debug-web-apps-quickly-within-gitlab","content:en-us:blog:debug-web-apps-quickly-within-gitlab.yml","Debug Web Apps Quickly Within Gitlab","en-us/blog/debug-web-apps-quickly-within-gitlab.yml","en-us/blog/debug-web-apps-quickly-within-gitlab",{"_path":891,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":892,"content":898,"config":904,"_id":906,"_type":14,"title":907,"_source":16,"_file":908,"_stem":909,"_extension":19},"/en-us/blog/developers-write-secure-code-gitlab",{"title":893,"description":894,"ogTitle":893,"ogDescription":894,"noIndex":6,"ogImage":895,"ogUrl":896,"ogSiteName":673,"ogType":674,"canonicalUrls":896,"schema":897},"4 Ways developers can write secure code with GitLab","GitLab Secure is not just for your security team – it’s for developers too. Learn four ways to write secure code with GitLab.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749666895/Blog/Hero%20Images/developers-write-secure.jpg","https://about.gitlab.com/blog/developers-write-secure-code-gitlab","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"4 Ways developers can write secure code with GitLab\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Vanessa Wegner\"}],\n        \"datePublished\": \"2019-09-03\",\n      }",{"title":893,"description":894,"authors":899,"heroImage":895,"date":901,"body":902,"category":816,"tags":903},[900],"Vanessa Wegner","2019-09-03","\nWriting secure code is a standard part of day-to-day development work, but\nsecurity often appears to be a roadblock instead of a critical piece of the\npuzzle. To make security efforts easier, [GitLab Secure](/stages-devops-lifecycle/secure/)\noffers a number of different tools that help developers identify and remediate vulnerabilities\nwithin their code, _as they’re writing it_. Our goal is to seamlessly integrate\nsecurity into your code writing practices so you’re better able to protect\nyour business from growing cybersecurity threats.\n\n## Testing\n\nThere are a variety of testing tools available to developers within GitLab.\nGenerally, they alert developers to vulnerabilities within their code and report\nthem within the merge request so developers can adjust their code as they\ngo. In addition to the testing methods outlined below, developers can also [use\nother tools outside of GitLab](https://handbook.gitlab.com/handbook/product/gitlab-the-product/#plays-well-with-others) by integrating\nthe results of your scanners with our merge request security reports.\n\n### Static application security testing\n\nOur [static application security testing](https://docs.gitlab.com/ee/user/application_security/sast/index.html)\n(SAST) tool scans the application source code\nand binaries to spot potential vulnerabilities before deployment. It uses open\nsource tools that are installed as part of GitLab. Vulnerabilities are shown\nin-line with every merge request and results are collected and presented as a\nsingle report.\n\n### Secret detection\n\n[Secret detection](https://docs.gitlab.com/ee/user/application_security/sast/#secret-detection)\nwithin GitLab is able to detect secrets and credentials that\nhave been unintentionally pushed to the repository. This check is performed by\na specific analyzer during the SAST job, runs regardless of the programming\nlanguage of your app, and displays results within the SAST report.\n\n### Dynamic application security testing\n\nOur [DAST tool](https://docs.gitlab.com/ee/user/application_security/dast/index.html)\nanalyzes your web application for known runtime\nvulnerabilities. It conducts live attacks against a review app and can be created for every\nmerge request as part of GitLab’s [CI/CD capabilities](/topics/ci-cd/). Users can provide HTTP\ncredentials to test private areas. Vulnerabilities are shown in-line with every\nmerge request.\n\n### Dependency scanning\n\n[Dependency scanning](https://docs.gitlab.com/ee/user/application_security/dependency_scanning/index.html)\nanalyzes external dependencies (e.g. libraries like Ruby gems) for known\nvulnerabilities on each code commit with GitLab CI/CD. This scan relies on open\nsource tools and on the integration with [Gemnasium](https://docs.gitlab.com/ee/user/project/import/index.html)\ntechnology (now part of\nGitLab) to show, in-line with every merge request, vulnerable dependencies\nin need of updating. Results are collected and available as a single report.\nDependency scanning also provides a list of your project’s dependencies with\ndifferent versions for languages and package managers supported by Gemnasium.\n\n### Container scanning\n\nIf you’re using GitLab CI/CD, [container scanning](https://docs.gitlab.com/ee/user/application_security/container_scanning/index.html)\nwill let you check Docker images (and containers) for\nknown vulnerabilities in the application environment. Analyze image contents\nagainst public vulnerability databases using the open source tool, [Clair](https://coreos.com/clair/docs/latest/),\nthat\nis able to scan any kind of Docker (or app) image. Vulnerabilities are shown\nin-line with every merge request.\n\n### License management\n\nUpon code commit, project dependencies are reviewed for [approved and blacklisted\nlicenses](https://docs.gitlab.com/ee/user/compliance/license_compliance/index.html)\ndefined by custom policies per project. Software licenses are\nidentified if they are not within policy, and new licenses are also listed if\nthey require a status designation. This scan relies on an open source tool,\nLicenseFinder, and license analysis results are shown in-line for every merge\nrequest for immediate resolution.\n\n### Code quality analysis\n\nWith the help of GitLab CI/CD, you can analyze your source code quality using\nGitLab [Code Quality](https://docs.gitlab.com/ee/ci/testing/code_quality.html).\nCode Quality uses [Code Climate Engines](https://codeclimate.com/)\nand runs in pipelines using a Docker image built into the Code Quality\nproject. Once the\nCode Quality job has completed, GitLab checks the generated report, compares the\nmetrics between the source and target branches, and shows the information\nwithin the merge request. With pipelines that enable concurrent testing and\nparallel execution, teams quickly receive insight about every commit, allowing\nthem to deliver higher quality code faster.\n\n### The Security Dashboard\n\nSecurity dashboards in GitLab exist at both the project and group level. The\ngroup dashboard provides an overview of all the security vulnerabilities in your\ngroups and projects. In the dashboard, developers are able to drill down into a\nvulnerability for further details, see which project it comes from and the file\nit’s in, and view various metadata to help analyze the risk.\n\nThe dashboard also allows viewers to\n[interact with vulnerabilities](https://docs.gitlab.com/ee/user/application_security/index.html#interacting-with-the-vulnerabilities)\nby creating an issue for them or dismissing them. For ease of use, vulnerabilities\nwithin the group Security Dashboard can be filtered by severity, confidence, report type, and project.\n\nIn addition to the vulnerability overview, the group Security Dashboard also\nprovides a timeline that displays how many open vulnerabilities your projects\nhad at various points in time. While security scans are automatically run for\neach code update, you’ll have some default branches that are infrequently\nupdated. To keep your Security Dashboard up to date on those branches, you can\nuse GitLab to [configure a scheduled pipeline](https://docs.gitlab.com/ee/ci/pipelines/schedules.html)\nto run a daily security scan.\n\n## What’s next for GitLab Secure?\n\nWhile we already have a number of ways to help you write secure code and build\nsecure products and services, we’re always looking for ways to give you more.\nHere are a few of the things we’re working on:\n\n### Interactive application security testing\n\nInteractive application security testing (IAST) checks the runtime behavior of applications by\ninstrumenting the code and\nchecking for error conditions. It is composed by an agent that lives inside the\napplication environment, and an external component, like DAST, that can interact\nand trigger unintended results.\n\n### Fuzzing\n\n[Fuzzing](/direction/secure/dynamic-analysis/fuzz-testing/)\nis a testing technique focused on finding flaws and vulnerabilities in\napplications by sending arbitrary payloads instead of valid input. The idea is to\ntrigger exceptions and unintended code paths that may lead to crashes and\nunauthorized operations. Once a possible problem – like a crash – is found,\nattackers can attempt to find the exact conditions needed to trigger the bug\nand see if they can be fine-tuned to obtain a useful result. (It is worth noting\nthat fuzzing is primarily intended for security teams because it requires more\ntime to execute. While fuzzing is a useful testing method, it should not be a\ndevelopment blocker).\n\n### Vulnerability database\n\nGitLab integrates access to proprietary and open source application security\nscanning tools. In order to maintain the efficacy of those scans, we strive to\nkeep their underlying vulnerability databases up to date.\n\n### Auto remediation\n\nVulnerabilities that require manual intervention to create a fix and push it to\nproduction have a time window where attackers have the ability to leverage the\nvulnerability. Auto remediation aims to automate the vulnerability solution flow and\nautomatically create a fix. The fix is then tested, and if it passes all the\ntests already defined for the application, it is deployed to production.\n\nPhoto by [Daniel McCullough](https://unsplash.com/@d_mccullough?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)\non [Unsplash](https://unsplash.com/search/photos/write?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)\n{: .note}\n",[862,683,109,9,775],{"slug":905,"featured":6,"template":686},"developers-write-secure-code-gitlab","content:en-us:blog:developers-write-secure-code-gitlab.yml","Developers Write Secure Code Gitlab","en-us/blog/developers-write-secure-code-gitlab.yml","en-us/blog/developers-write-secure-code-gitlab",{"_path":911,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":912,"content":918,"config":924,"_id":926,"_type":14,"title":927,"_source":16,"_file":928,"_stem":929,"_extension":19},"/en-us/blog/developing-gitlab-duo-how-we-are-dogfooding-our-ai-features",{"title":913,"description":914,"ogTitle":913,"ogDescription":914,"noIndex":6,"ogImage":915,"ogUrl":916,"ogSiteName":673,"ogType":674,"canonicalUrls":916,"schema":917},"Developing GitLab Duo: How we are dogfooding our AI features","As part of our blog series, we share real-world examples of how we integrate AI throughout our software development lifecycle and how we use metrics to gauge their success.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098360/Blog/Hero%20Images/Blog/Hero%20Images/blog-hero-banner-1-0178-820x470-fy25_7JlF3WlEkswGQbcTe8DOTB_1750098360821.png","https://about.gitlab.com/blog/developing-gitlab-duo-how-we-are-dogfooding-our-ai-features","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Developing GitLab Duo: How we are dogfooding our AI features\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"David O'Regan\"}],\n        \"datePublished\": \"2024-05-20\",\n      }",{"title":913,"description":914,"authors":919,"heroImage":915,"date":920,"body":921,"category":704,"tags":922},[727],"2024-05-20","***Generative AI marks a monumental shift in the software development industry, making it easier to develop, secure, and operate software. Our new blog series, written by our product and engineering teams, gives you an inside look at how we create, test, and deploy the AI features you need integrated throughout the enterprise. Get to know new capabilities within GitLab Duo and how they will help DevSecOps teams deliver better results for customers.***\n\n[GitLab Duo](https://about.gitlab.com/gitlab-duo/), our suite of AI-powered features, has transformed our internal engineering workflows, driving efficiency gains across our development process. As strong proponents of dogfooding and transparency, we wanted to showcase how our teams leverage AI, including standouts like GitLab Duo Code Suggestions and GitLab Duo Chat, daily to streamline development processes, reduce manual effort, and enhance productivity. You'll learn about the benefits we've experienced for highly technical teams like engineering to less technical teams such as technical writing and product management.\n\n> Discover the future of AI-driven software development with our GitLab 17 virtual launch event. [Watch today!](https://about.gitlab.com/seventeen/)\n\n## Real-world use cases\n\nOur teams have integrated [GitLab Duo's many features](https://about.gitlab.com/gitlab-duo/#features) into their daily routines. Here are some examples of how GitLab Duo is helping them carry out everyday activities.\n\n### Summarization and documentation\n- **Streamline the code review process:** Staff Backend Developer [Gosia Ksionek](https://about.gitlab.com/company/team/#mksionek) showcases the practical benefits of AI in her workflow by using GitLab Duo to streamline the code review process. She effectively utilizes GitLab Duo to [summarize merge requests](https://youtu.be/3SIhe8dgFEc), making it easier and faster to review code changes. In addition to summarizing merge requests, Gosia also leverages GitLab Duo to [answer coding questions](https://www.youtube.com/watch?v=6n0I53XsjTc) and [explain complex code snippets](https://www.youtube.com/watch?v=3m2YRxa1SCY). This enhances her productivity and helps her better understand and manage intricate codebases. Through these demonstrations, Gosia highlights how GitLab Duo can significantly improve efficiency and clarity in the development process, making it an invaluable tool for developers.\n\n\u003Ccenter>\n\nWatch Gosia use GitLab Duo Merge Request Summary:\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/3SIhe8dgFEc?si=Q8JG3Ix3K_THhbpv\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\nWatch Gosia use GitLab Duo to answer coding questions: \n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/6n0I53XsjTc?si=LA9VBHrgXpfJImSL\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\nWatch Gosia use GitLab Duo to explain complex code snippets:\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/3m2YRxa1SCY?si=oms3szKwZoz-4yeq\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n\u003C/center>\n\n- **Condense comment threads:** [Bartek Marnane](https://about.gitlab.com/company/team/#bmarnane), Vice President of Expansion Software Development, uses GitLab Duo to condense lengthy comment threads into concise summaries, ensuring all relevant details are captured when updating issue descriptions.\n\n- **Create new documentation:** [Taylor McCaslin](https://about.gitlab.com/company/team/#tmccaslin), Group Manager, Product - Data Science Section, leveraged GitLab Duo to [create new documentation for GitLab Duo itself](https://docs.gitlab.com/ee/user/ai_features.html), exemplifying a meta use case that enhances clarity and consistency and greatly reduces the time to document new features.\n\n- **Craft release notes:** [Amanda Rueda](https://about.gitlab.com/company/team/#amandarueda), Senior Product Manager for Product Planning, uses GitLab Duo to [craft brief, impactful summaries for release notes](https://gitlab.com/groups/gitlab-org/-/epics/10267), highlighting changes and their value to users. By using well-crafted prompts like below, Amanda supercharges her workflow and ensures that each release note is clear, concise, and user-focused, enhancing the overall communication and user experience:\u003Cbr>\u003Cbr>\n*“Please create a two sentence summary of this change, which can be used for our release notes. The tone should be conversational and should be in second person. The summary should include a description of the problem or change and be tied to the value we are creating for you, the user.”*\n\u003Cbr>\u003Cbr>\n    - Here are some examples of release notes co-created with GitLab Duo:\n      - [Expanded options for sorting your Roadmap](https://gitlab.com/gitlab-org/gitlab/-/issues/460492)\n      - [Issue Board Clarity now with Milestone & Iteration](https://gitlab.com/gitlab-org/gitlab/-/issues/25758)\n      - [Design Management Features Extended to Product Teams](https://gitlab.com/gitlab-org/gitlab/-/issues/438829)\n\n- **Optimize docs site navigation:** [Suzanne Selhorn](https://about.gitlab.com/company/team/#sselhorn), Staff Technical Writer, tapped GitLab Duo to [optimize the left navigation of documentation](https://docs.gitlab.com/ee/user/get_started/get_started_projects.html) by providing a workflow-based order of pages. Suzanne provided a list of features to GitLab Duo, which generated the optimal order, updating the left navigation to match. GitLab Duo also drafted the [Getting Started](https://docs.gitlab.com/ee/user/get_started/get_started_planning_work.html) documentation much faster than were she to use traditional, manual approaches.\n\n### Goal setting and team alignment\n- **Draft and refine OKRs:** [François Rosé](https://about.gitlab.com/company/team/#francoisrose), Engineering manager, Create:Code Review Backend, finds [GitLab Duo Chat](https://about.gitlab.com/blog/gitlab-duo-chat-now-generally-available/) invaluable for drafting and refining OKRs. By articulating objectives more clearly and effectively, François enhances goal setting and team alignment. Using Chat, François ensures that each OKR is precise, actionable, and aligned with the team's goals, thereby improving overall team performance and cohesion. Here is an example prompt he uses:\u003Cbr>\u003Cbr>\n\n    *\"Here is an OKR I am thinking of creating:*\n\n    *Objective: Retrospect on retrospectives, to foster a thriving team*\n\n    *KR: Measure retrospective satisfaction from 100% of team members*\n\n    *KR: Identify 3 improvements to the async retrospectives*\n\n    *KR: Implement 1 improvement*\n\n    *Please provide direct feedback on how to improve the formulation of this objective and these key results.\"*\n\u003Cbr>\u003Cbr>\n\n- **Streamlined hiring and recruitment processes:** Chat helped [Denys Mishunov](https://about.gitlab.com/company/team/#dmishunov), Staff Frontend Engineer, formulate a clear and concise text for updating the email template for technical interview candidates. The team collaborated on refining the communication to ensure candidates receive all necessary information using a merge request. This example showcased the practical application of AI tools in enhancing communication processes within the hiring workflow.\n\n### Incident response and configuration\n- **Summarize production incidents:** [Steve Xuereb](https://about.gitlab.com/company/team/#sxuereb), Staff Site Reliability Engineer, employs GitLab Duo to summarize production incidents and create detailed incident reviews, streamlining the documentation process.\n\n- **Create boilerplate `.gitlab-ci.yml` files:**  Steve also uses Chat to create boilerplate `.gitlab-ci.yml` files, which significantly sped up his workflow. [Chat](https://docs.gitlab.com/ee/user/gitlab_duo_chat.html) serves as a valuable partner for suggesting ideas. Additionally, [Code Explanation](https://docs.gitlab.com/ee/user/ai_features.html#code-explanation) provides detailed answers that are helpful during incidents, enhancing his productivity and understanding of the codebase.\n\n### Code generation and testing\n- **Full-stack development:** [Peter Hegman](https://about.gitlab.com/company/team/#peterhegman), Senior Frontend Engineer, has been using [Code Suggestions for his JavaScript and Ruby development](https://gitlab.com/gitlab-org/gitlab/-/issues/435783#note_1731321963). This highlights that Code Suggestions has become a powerful tool for developers moving across a full technical stack. \n\n- **Generate Python scripts:** Denys conducted [an experiment using GitLab Duo for a non-GitLab task](https://gitlab.com/gitlab-org/ai-powered/ai-framework/ai-experimentation). This example highlights the flexibility and utility of our AI tools beyond typical software development tasks.\n\n\u003Ccenter>\nWatch how Denys uses GitLab Duo to generate Python scripts to fetch content data and store it locally:\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/30ZTtk4K5yU?si=p5ZcFLg6dTZL5gFE\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n\u003C/center>\n\n### Research and support\n- **Generate test source code:**  [Michael Friedrich](https://about.gitlab.com/company/team/#dnsmichi), Senior Developer Advocate, uses GitLab Duo to generate test source code for CI/CD components. This approach has been shared in various talks and presentations, such as the recent Open Source @ Siemens event ([public slides](https://go.gitlab.com/duA2Fc)). Using GitLab Duo in this manner helps ensure that the code is consistent, well-documented, and aligned with our best practices. Check out his [Rust example](https://gitlab.com/components/rust#contributing).\n\n![Rust example](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098367/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750098367547.png)\n\n- **Streamline research tasks:** Our team members consistently turn to Chat when they have questions about GitLab features, streamlining their research and support tasks. Michael shared, \"When I have a question about GitLab features, I default to using Chat instead of opening 100 browser tabs. This workflow helps me assist users on our community forum efficiently. For instance, I recently [helped a user with SSH deployment](https://forum.gitlab.com/t/how-to-make-ssh-deployment-more-clear-in-gitlab/102051/4?u=dnsmichi) using this method.\" Using Chat not only saves time but also provides quick, accurate information, enhancing the support we offer to our community.\n\n### Feature testing\n- **Test new features:** Our engineers use GitLab Duo to test new features like [Markdown support in Code Suggestions](https://gitlab.com/gitlab-org/gitlab/-/issues/443365). One of our team members noted, \"I need to test Markdown support in Code Suggestions for writing blog posts and GitLab docs in VS Code. I saw it was merged for 17.0.\" By testing these features internally, we ensure they meet our quality standards before release.\n\n### Understanding external codebases\n- **Explain external projects:** GitLab Duo's `/explain` feature is particularly useful for understanding external projects imported into GitLab. This capability was highlighted in a recent livestream he did with open source expert Eddie Jaoude. Michael let us know, \"I use `/explain` on external projects to understand the source code. I pitched this idea for learning about open source projects, dependencies, etc. during the livestream.\" This feature is invaluable for developers who need to quickly grasp the functionality and dependencies of unfamiliar codebases, significantly improving their efficiency and understanding.\n\n\u003Ccenter>\nWatch Michael demo `/explain` during a livestream with Eddie Jaoude:\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/L2Mx8hOhkEE?si=R7W3v4EDqeJCaPOw\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n\u003C/center>\n\n## GitLab Duo's benefits\n\nThe integration of GitLab Duo has brought about numerous positive impacts, significantly enhancing our engineering and product development workflows:\n\n- Many tasks that previously required manual intervention are now automated, freeing up valuable time for our engineers. For example, summarizing long threads and creating boilerplate code are now more efficient, allowing our team to focus on more complex issues.\n- The time taken to document and summarize issues has decreased, allowing for quicker information dissemination and decision-making.\n- With AI-assisted code suggestions and explanations, our teams produce higher quality code with fewer errors and faster debugging processes. The integration of GitLab Duo into incident reviews and coding assistance has led to more efficient and effective code reviews.\n- Administrative tasks, such as drafting OKRs and creating release notes, have been streamlined. \n\nGitLab Duo has helped to not only improve our efficiency but also to enhance the quality and speed of our development processes, illustrating the transformative power of AI in software development.\n\n## What's next?\n\nWe are committed to further integrating AI into our workflows and continuously improving GitLab Duo features based on internal feedback and evolving needs. The ongoing collection of use cases and metrics with the [AI Impact analytics dashboard](https://about.gitlab.com/blog/developing-gitlab-duo-ai-impact-analytics-dashboard-measures-the-roi-of-ai/) will guide enhancements and ensure that GitLab Duo remains at the forefront of AI-driven development tools.\n\n![Dogfooding Duo - AI analytics dashboard](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098367/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750098367547.png)\n\n> [Get started using GitLab Duo today with our free trial.](https://about.gitlab.com/gitlab-duo/#free-trial)\n\n## Read more \"Developing GitLab Duo\"\n\n- [Developing GitLab Duo: AI Impact analytics dashboard measures the ROI of AI](https://about.gitlab.com/blog/developing-gitlab-duo-ai-impact-analytics-dashboard-measures-the-roi-of-ai/)\n- [Developing GitLab Duo: How we validate and test AI models at scale](https://about.gitlab.com/blog/developing-gitlab-duo-how-we-validate-and-test-ai-models-at-scale/)\n- [Developing GitLab Duo: Secure and thoroughly test AI-generated code](https://about.gitlab.com/blog/how-gitlab-duo-helps-secure-and-thoroughly-test-ai-generated-code/)\n- [Developing GitLab Duo: Blending AI and Root Cause Analysis to fix CI/CD pipelines](https://about.gitlab.com/blog/developing-gitlab-duo-blending-ai-and-root-cause-analysis-to-fix-ci-cd/)",[706,9,708,482,923],"workflow",{"slug":925,"featured":91,"template":686},"developing-gitlab-duo-how-we-are-dogfooding-our-ai-features","content:en-us:blog:developing-gitlab-duo-how-we-are-dogfooding-our-ai-features.yml","Developing Gitlab Duo How We Are Dogfooding Our Ai Features","en-us/blog/developing-gitlab-duo-how-we-are-dogfooding-our-ai-features.yml","en-us/blog/developing-gitlab-duo-how-we-are-dogfooding-our-ai-features",{"_path":931,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":932,"content":938,"config":945,"_id":947,"_type":14,"title":948,"_source":16,"_file":949,"_stem":950,"_extension":19},"/en-us/blog/efficient-code-review-tips",{"title":933,"description":934,"ogTitle":933,"ogDescription":934,"noIndex":6,"ogImage":935,"ogUrl":936,"ogSiteName":673,"ogType":674,"canonicalUrls":936,"schema":937},"How to carry out effective code reviews","From time management to unblocking, discover the secrets of more efficient code reviews.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749678861/Blog/Hero%20Images/pre-commit.jpg","https://about.gitlab.com/blog/efficient-code-review-tips","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How to carry out effective code reviews\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Phil Hughes\"}],\n        \"datePublished\": \"2020-09-08\",\n      }",{"title":933,"description":934,"authors":939,"heroImage":935,"date":941,"body":942,"category":816,"tags":943},[940],"Phil Hughes","2020-09-08","\n\nThis blog post was originally published on the GitLab Unfiltered blog. It was reviewed and republished on 2020-09-15.\n{: .alert .alert-info .note}\n\nLike most companies, code review at GitLab is a major part of our workflow. But it's clear from the results of our [2020 Global DevSecOps Survey](/developer-survey/) that code review can be a major reason for delayed releases and overall frustration. A vast majority of companies conduct code reviews (some even on a daily basis) but that doesn't mean it isn't a potential time sink.\n\n## How to perform a code review?\n\nBut code reviews can be done efficiently, and I know this since I've been a maintainer for 3 years. Here's a look at my top four tips for code review based on a tried and true routine that allows me to do effective code reviews and merge code quickly and efficiently to aid in others not being blocked by me. Of course, this is what works for *me* – your mileage may vary. Here's how I do it:\n\n### Tips for code review no.1 - Time management\n\nAn early start to my day makes it easy to start reviewing merge requests first thing. I set myself a time to start reviewing and I will keep at it until my GitLab \"to do\" list no longer has any merge requests that need reviewing. Mornings work for me; it's the time of the day when I can focus the most and get the reviews done with minimal distractions.\n\nGetting to reviews after this time is hard. I have other work that needs doing as well so once I've reviewed all merge requests on my list I leave anything new until the next day. Of course, as with all rules, it ends up getting broken. **Depending on the size of merge requests, I may make sure I review them before my day ends to make sure anyone in other timezones aren't blocked by me.**\n\n### Tips for code review no.2 - Unblock others first\n\nIt's not great for the author of a merge request to have to wait X hours/days before they get feedback. The sooner they get feedback, the sooner the merge request can be merged and shipped. Making authors wait just creates uncertainty and may mean that other work gets held up.\n\nThis is why I find it important for me to review a merge request as quickly as possible. At GitLab we have a [2  day Service Level Objective (SLO)](/handbook/engineering/workflow/code-review/#review-response-slo) for feedback from reviewers. For myself, I always try to do better than that and respond within a day.\n\n### 3. Tips for code review no.3 - Focus on the code, not the feature\n\nThis is going to be a point that could create a lot of discussion: Instead of focusing on the feature, focus on the code.\n\nA lot of the merge requests I review are across different groups, with features that I don't fully understand or with features I have no way to test. I could spend a lot of my time reading into the feature and the issue to understand what it is, but that means spending more time not reviewing everyone else's code. Also, if I did this with **every** merge request, it would be hard for me to keep to my time limit.\n\nWho is better to review the feature itself then? The product designer (UX) or the product manager both understand the feature being worked on and are better suited to help find bugs or guide the feature in the correct way. It is important that someone in the UX team review the feature to make sure it matches the designs and vision they had created for the feature. If a merge request has no UX review by the time I get to reviewing it, I will normally ask the author (or ask a product designer myself) to have the UX reviewed _before_ I merge the merge request.\n\nHowever, this point is also something I don't _always_ stick to. If a merge request is touching an area that I am familiar with and I can tell from the code that a bug exists, I will test it locally and provide as much feedback as I can to help the author understand the bug. The more you – as a reviewer – work with the code, the easier finding bugs through the code becomes. I have been working on the GitLab codebase for over 4 years, so seeing where bugs could arise through looking at the code has become natural to me.\n\n### Tips for code review no.4 - Seek to understand: Ask questions\n\nIt is easy to suggest changes to the code that I am reviewing, however sometimes what I suggest may not be right. It is important that instead of just suggesting a change, you always try to ask if the author thinks it is the right change. Having a conversation around a change helps both the reviewer and the author understand the existing code as well as the code being suggested. Maybe the suggestion had already been tried by the author. Being open to talk about it helps get to the final solution.\n\nSometimes however suggestions for changes happen around legacy code, i.e., code that has existed for a long time without being updated to match our documentation. In these cases, the conclusion may end up being that a technical debt issue be created. This is ok. We should strive for [boring solutions](https://handbook.gitlab.com/handbook/values/#boring-solutions) first but also understand that a more optimal solution may be required in the future.\n\n## To sum it up\n\nReviewing code efficiently is a skill that gets learnt the more you do it. Spending time coming up with a workflow that works for you is just as important. Over the years I have been reviewing code, I have stuck to these tips as closely as possible. Yet, I am far from perfect; I am constantly learning about new and different ways to optimise my workflow for code review. I would love to hear other tips and workflows. It is through discussions that we can improve and push ourselves to be the best that we can be.\n",[944,775,9],"frontend",{"slug":946,"featured":6,"template":686},"efficient-code-review-tips","content:en-us:blog:efficient-code-review-tips.yml","Efficient Code Review Tips","en-us/blog/efficient-code-review-tips.yml","en-us/blog/efficient-code-review-tips",{"_path":952,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":953,"content":959,"config":966,"_id":968,"_type":14,"title":969,"_source":16,"_file":970,"_stem":971,"_extension":19},"/en-us/blog/five-great-phabricator-features-inspired-gitlab",{"title":954,"description":955,"ogTitle":954,"ogDescription":955,"noIndex":6,"ogImage":956,"ogUrl":957,"ogSiteName":673,"ogType":674,"canonicalUrls":957,"schema":958},"5 Great Phabricator features that inspired GitLab","Take a deep dive into the Phabricator features that prompted GitLab to build new tooling around automation, integrated CI, and better code reviews.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749667482/Blog/Hero%20Images/cover-image-unsplash.jpg","https://about.gitlab.com/blog/five-great-phabricator-features-inspired-gitlab","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"5 Great Phabricator features that inspired GitLab\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Michael Friedrich\"}],\n        \"datePublished\": \"2021-08-13\",\n      }",{"title":954,"description":955,"authors":960,"heroImage":956,"date":962,"body":963,"category":299,"tags":964},[961],"Michael Friedrich","2021-08-13","\n\nInnovation often happens because competition sparks new ideas. We unpack how Phabricator inspired GitLab to add new features.\n\n## Phabricator explained\n\nTurning back time a bit, what exactly is Phabricator? Built on the concept of web-based applications, Phabricator enables developers to collaborate with code reviews, repository browser, change monitoring, bug tracking and wiki. On May 29, 2021, Phacility, the maintainer and sponsor of Phabricator [announced end-of-life](https://admin.phacility.com/phame/post/view/11/phacility_is_winding_down_operations/) and stopped maintaining Phabricator.\n\n[GitLab co-founder and CEO, Sid Sijbrandij](/company/team/#sytses) gives credit to Phabricator on [HackerNews](https://news.ycombinator.com/item?id=27334636):\n\n> Phabricator was an inspiration to me when starting GitLab. It is shutting down now. [Many of its features were years ahead of its time](https://news.ycombinator.com/item?id=27334511) and there was a lot of humor in the product. As a tribute to it shall we add Clowcoptarize as a way to merge? This would be an [opt in option introduced in GitLab 14.0](https://gitlab.com/gitlab-org/gitlab/-/issues/332215).\n\nIt got me curious: What are these inspirations Sid is referring to? Let's dive into GitLab's history together and see what we can learn.\n\n_Tip: Features in the [GitLab documentation](https://docs.gitlab.com/) often have a `Version History` box. You can use the issue URLs to dive deeper into feature proposals, discussions, etc._\n\n### Review workflows\n\nA typical engineering workflow is as follows: The engineering manager assigns a new issue as a task to a developer. The developer works in their preferred IDE – local in VS Code or in the [Gitpod](/blog/teams-gitpod-integration-gitlab-speed-up-development/) cloud environment. Changes happen in a new feature branch in Git, which gets pushed to the remote Git server for collaboration.\n\nThe Git branch is not ready yet and stays hidden in a potentially long list of branches. To keep better track of their feature branches, developers could copy-paste the branch name or URL into the related issue - which I did 10 years ago. The concept of a \"diff linked to a task for review\" in Phabricator, likewise a \"Git branch with commits linked to Merge Requests\" in GitLab was not invented yet. \n\nPhabricator inspired GitLab to create a [default workflow](https://secure.phabricator.com/phame/post/view/766/write_review_merge_publish_phabricator_review_workflow/) for reviews. The Phabricator workflow makes the review more dominant and squashes all changes into a single commit after the review is approved. There are upsides and downsides to automatically squashing commits. Squashing the commits could mean losing information from review history and create more discussion. Depending on the application architecture, the frequency of changes, and debugging requirements, this can be a good thing or a bad thing. GitLab allows you to choose to [squash commits](https://docs.gitlab.com/ee/user/project/merge_requests/squash_and_merge.html) before merging a MR and/or specifying the default project settings around squashing commits.\n\nPhabricator treated a MR (or what they call \"diff tasks\") as the single source of truth for tracking changes and the review history. We felt this was a great idea, and replicated the process of a \"diff task\" in Phabricator in GitLab MRs. One of the major upsides to GitLab's version is that collaboration and discussion that happened in issues and epics is still available even after the change is merged.\n\n#### Draft MR (or \"diff tasks\")\n\nMany times when a MR is created in GitLab, the branch requires additional work before it is ready to be merged. Phabricator introduced a [formal \"Draft\" / \"Not Yet Ready for Review\" state](https://secure.phabricator.com/T2543) in 2013 for \"diff tasks\", which helped keep track of work in this state. GitLab added [WIP MRs in 2016](/blog/feature-highlight-wip/), which we then renamed to draft merge requests in 2020. While `WIP` may make sense to some people, acronyms can exclude newcomers. We found `Draft` is more recognizable. To avoid confusion, GitLab [deprecated WIP and moved forward with draft merge requests](https://gitlab.com/gitlab-org/gitlab/-/issues/32692).\n\n#### Keep history in MRs for future debugging\n\nThe commit history in GitLab is enriched with links to the MR and the corresponding Git review history. In case of a production emergency, having everything documented allows for faster research and debugging.\n\nGitLab stores the MR short URL with `\u003Cnamespace>/\u003Cproject>!1234` in the merge commit message. Check the history of a [demo project for the Kubernetes agent](https://gitlab.com/everyonecancontribute/kubernetes/k8s-agent/-/commits/main/) to see how the merge commit is rendered.\n\n![GitLab history with MR commit links](https://about.gitlab.com/images/blogimages/phabricator-features-inspired-gitlab/gitlab_history_mr_metadata_link.png)\nGitLab commit history includes link to the MR.\n{: .note.text-center}\n\nThis raw information is stored in the Git repository, whereas the MR itself stays in GitLab's database backend. You can verify this by cloning a repository and inspecting the history with this command:\n\n```sh\n$ git log\n```\n\n![git log MR metadata](https://about.gitlab.com/images/blogimages/phabricator-features-inspired-gitlab/git_log_mr_merge_commit_metadata_link.png)\nMR metadata included in output from `git log` command.\n{: .note.text-center}\n\n### Code coverage in MRs\n\nCode coverage reports provide insight into how many lines of the source code are covered with unit tests. Reaching 100% test coverage is a developer myth - visualizing a decrease or increase can help monitor a trend in code quality. Phabricator implemented support for various languages with unit test engines and parsing the output, for example in [Golang](https://secure.phabricator.com/D12621).\n\nWith many different languages and report output formats, integrating code coverage reports into GitLab MRs was challenging. [GitLab launched the first iteration of code coverage reports in 2016](/blog/publish-code-coverage-report-with-gitlab-pages/), which generated the reports with CI/CD jobs and used GitLab pages to publish the HTML reports.\n\nIn this first iteration, the test coverage is parsed with a regular expression from the CI/CD job output, specified in the project settings or with the [coverage](https://docs.gitlab.com/ee/ci/yaml/#coverage) keyword inside the CI/CD job configuration. We can see this in the job view inside the [MR widget](https://docs.gitlab.com/ee/ci/pipelines/settings.html#add-test-coverage-results-to-a-merge-request) and as a coverage badge for the project. See the test coverage history by navigating into `Analytics > Repository`.\n\n![Test coverage as project badge in GitLab](https://about.gitlab.com/images/blogimages/phabricator-features-inspired-gitlab/gitlab_project_badge_test_coverage.png)\nThe test coverage badge in a GitLab project.\n{: .note.text-center}\n\nJUnit XML test reports were introduced as common format specification and added as an [MR widget in 2018](https://docs.gitlab.com/ee/ci/unit_test_reports.html). The test reports runs in the background, using CI/CD artifacts to upload the XML reports from the runner to the server, where the MR/pipeline view visualizes the coverage reports in a tab.\n\nThe generic JUnit integration also helped with customization requests to unit tests, updated CLI commands, or changed coverage report outputs to parse. GitLab provides [CI/CD template examples](https://docs.gitlab.com/ee/ci/examples/)\n\nThe missing piece for GitLab was having inline code coverage remarks inside MR diffs. It took about five years for [Sid's initial proposal for inline code coverage remarks](https://gitlab.com/gitlab-org/gitlab/-/issues/3708) to be implemented. In 2020, inline code coverage remarks were released in [GitLab 13.5](https://docs.gitlab.com/ee/user/project/merge_requests/test_coverage_visualization.html).\n\n![Test Coverage with Rust in GitLab](https://about.gitlab.com/images/blogimages/phabricator-features-inspired-gitlab/gitlab_mr_diff_inline_test_coverage.png)\nHow inline code coverage works in GitLab.\n{: .note.text-center}\n\nCheck out [this MR to practice verifying the test coverage](https://gitlab.com/everyonecancontribute/dev/rust-code-coverage-llvm/-/merge_requests/1/diffs?view=inline validating some Rust code). Make sure to select the inline diff view.\n\n### Automated workflows and integrated CI\n\nPhabricator provides [Herald](https://secure.phabricator.com/book/phabricator/article/herald/) as an automated task runner and rule engine to listen for changes. Herald can also be used to ensure [protected branches](https://docs.gitlab.com/ee/user/project/protected_branches.html) and [approval rules](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/rules.html#add-multiple-approval-rules) to enforce a strong permission model in development workflows. There are more examples in this [HackerNews post from 2016](https://news.ycombinator.com/item?id=12501025) and somehow, I feel like an explorer seeing many great GitLab features in similar ways. 🦊\n\n[GitLab CI/CD pipeline schedules](https://docs.gitlab.com/ee/ci/pipelines/schedules.html) remind me of the task runner, similarly to [webhooks](https://docs.gitlab.com/ee/user/project/integrations/webhooks.html) and the [REST API](https://docs.gitlab.com/ee/api/) being instrumented from CI/CD jobs. The pipeline schedules are also a great way to periodically regenerate caches and rebuild container images for cloud native deployments.\n\n[Harbormaster](https://secure.phabricator.com/book/phabricator/article/harbormaster/) is Phabricator's integration for CI. It's not built from multiple tools in the [DevOps](/topics/devops/) stack, but is instead fully integrated in the product.\n\nThe first version of GitLab CI was created in [November 2012](/company/history/). In 2015, a GitLab team member came up with the idea of combining SCM with CI and [the all-in-one DevOps platform was born](/blog/gitlab-hero-devops-platform/). Built-in CI/CD inspired for more features and fostered a better way to innovate together. The [new pipeline editor](/blog/pipeline-editor-overview/) is just one example of a streamlined way to configure CI/CD pipelines in GitLab.\n\nLet's throwback to 2017 and watch as we demonstrate how to take an idea to production in GitLab, using GKE:\n\n\u003Ciframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/39chczWRKws\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen>\u003C/iframe>\n\n\u003Cbr>\n\n### Work boards for issue management\n\nWork needs to be organized. Phabricator led the way with a board which allowed users to filter tasks and provide a more detailed view into planning and project management.\n\n![Phabricator work boards](https://about.gitlab.com/images/blogimages/phabricator-features-inspired-gitlab/phabricator_work_boards.png)\nInside Phabricator work boards.\n{: .note.text-center}\n\nGitLab users will recognize the similar look between Phabricator's work boards and GitLab [issue boards](https://docs.gitlab.com/ee/user/project/issue_board.html). In GitLab 14.1, we built on existing epic tracking and labeling to create [Epic boards](https://docs.gitlab.com/ee/user/group/epics/epic_boards.html) to keep teams organized and measure progress.\n\nIn Phabricator, users can drag and drop between columns, which automatically changes the work status for a particular task. This feature inspired the boards in GitLab to automatically change the labels in a [defined workflow](/blog/4-ways-to-use-gitlab-issue-boards/) by dragging and dropping between columns. Users can go a level deeper with scoped labels to switch between workflow states:\n\n* `workflow::design`\n* `workflow::planning breakdown`\n* `workflow::ready for development`\n* `workflow::in dev`\n* `workflow::verification`\n\nThe [GitLab engineering handbook](/handbook/engineering/workflow/#basics) documents the different workflows.\n\n![Epic boards in GitLab](https://about.gitlab.com/images/blogimages/phabricator-features-inspired-gitlab/gitlab_epic_boards.png)\nTake a look at the Epic boards in GitLab.\n{: .note.text-center}\n\n### Put it all together\n\nIn Phabricator, a diff task (in GitLab they're MRs) in the \"review\" state is linked to another task specifying the requirements. The UX needs to be clear so the relationship between the diffs can be accessed and understood. Unless necessary, the user shouldn't have to navigate manually. The context of the change review defines possible links to labels, states, dependent issues, diff tasks (MRs), and more.\n\nGitLab links [related issues](https://docs.gitlab.com/ee/user/project/issues/related_issues.html). If an issue is mentioned in a MR, or vice versa, [GitLab automatically links them](https://docs.gitlab.com/ee/user/project/issues/crosslinking_issues.html#from-merge-requests). The user also has the option to have the issue close automatically once a change is merged. Read a blog post from 2016 to learn more about [how issues and MRs can relate to each other in GitLab](/blog/gitlab-tutorial-its-all-connected/).\n\n![Linked issues and MRs in GitLab](https://about.gitlab.com/images/blogimages/phabricator-features-inspired-gitlab/gitlab_linked_issues_mrs.png)\nLinked issues and related MRs in GitLab.\n{: .note.text-center}\n\nUX work is challenging, and we continue to iterate to improve workflows in GitLab. For example, in GitLab 13.8, we reduced the number of clicks it takes to [download a CI/CD job artifact from the MR](https://gitlab.com/gitlab-org/gitlab/-/issues/37346).\n\n\n### Did we miss a feature Phabricator inspired?\n\nWhile writing this blog post, my research revealed more gems. For example, I found a proposal to add [visual graphs for issue dependencies](https://gitlab.com/gitlab-org/gitlab/-/issues/273597) in the [HN thread](https://news.ycombinator.com/item?id=27336818).\n\nWhich features from Phabricator are missing in GitLab? Let us know in the comments, create a new [feature proposal](https://gitlab.com/gitlab-org/gitlab/-/issues/new?issuable_template=Feature%20Proposal%20-%20lean) or start your [contribution journey](/community/contribute/) in a new MR right away! \n\nCover image by [Johannes Plenio](https://unsplash.com/photos/DKix6Un55mw) on [Unsplash](https://unsplash.com)\n{: .note}\n",[965,9,819],"CI",{"slug":967,"featured":6,"template":686},"five-great-phabricator-features-inspired-gitlab","content:en-us:blog:five-great-phabricator-features-inspired-gitlab.yml","Five Great Phabricator Features Inspired Gitlab","en-us/blog/five-great-phabricator-features-inspired-gitlab.yml","en-us/blog/five-great-phabricator-features-inspired-gitlab",{"_path":973,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":974,"content":980,"config":987,"_id":989,"_type":14,"title":990,"_source":16,"_file":991,"_stem":992,"_extension":19},"/en-us/blog/future-merge-requests-realtime-collab",{"title":975,"description":976,"ogTitle":975,"ogDescription":976,"noIndex":6,"ogImage":977,"ogUrl":978,"ogSiteName":673,"ogType":674,"canonicalUrls":978,"schema":979},"The future of merge requests: Real-time collaboration","We want to hear your thoughts on the future of merge requests and code review.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749666775/Blog/Hero%20Images/cover.jpg","https://about.gitlab.com/blog/future-merge-requests-realtime-collab","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"The future of merge requests: Real-time collaboration\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Pedro Moreira da Silva\"}],\n        \"datePublished\": \"2019-12-19\",\n      }",{"title":975,"description":976,"authors":981,"heroImage":977,"date":983,"body":984,"category":752,"tags":985},[982],"Pedro Moreira da Silva","2019-12-19","\n\nThis blog post was originally published on the GitLab Unfiltered blog. It was reviewed and republished on 2019-12-20.\n{: .alert .alert-info .note}\n\nWe want to share some of the work we’ve been doing in the [Source Code](https://handbook.gitlab.com/handbook/product/categories/#source-code-group) part of the product and get feedback on what could be the future of [merge requests](https://docs.gitlab.com/ee/user/project/merge_requests/) and [code review](/direction/create/code_review/).\n\n**Perhaps the best way is to walk you through a short visual story. You can** [**watch the recording (28 min)**](https://www.youtube.com/watch?v=KpdvIU6hv94) **or** [**jump to its text version**](#context) **below. In the end, if you’d like to share your thoughts, you can do so on the** [**feedback issue**][feedback-issue].\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube-nocookie.com/embed/KpdvIU6hv94\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n## Context\n\nIf you haven’t been following along our work on merge requests, let’s set the scene:\n1. In the next releases of GitLab, we’re shipping [**performance**](https://gitlab.com/groups/gitlab-org/-/epics/1417) **and** [**navigation**](https://gitlab.com/gitlab-org/gitlab/issues/33813) **improvements**, based on the user experience research we’ve been doing.\n1. We have also an exciting [**new Sourcegraph integration**](/blog/sourcegraph-code-intelligence-integration-for-gitlab/) which levels up the merge request interface allowing you to navigate code, jumping to definitions or finding references.\n1. **Other improvements** we’ve shipped over the past year include [multiple assignees](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html#multiple-assignees), [multiple approval rules](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/rules.html#multiple-approval-rules), [code owners](https://docs.gitlab.com/ee/user/project/codeowners/), and [suggest changes][suggest-changes] – all of these were based on research and user feedback (your feedback).\n\nThese are nice improvements but they are iterating on what we already have and are not substantially changing the code review workflow. Today’s merge request experience is pretty similar to what it was five years ago – we’ve improved it a lot but its fundamental structure is the same.\n\nWe’ve been hearing feedback from users and customers about how we might improve merge requests to solve harder problems and that may require rethinking what we’ve come to accept as the default. **The merge request is a significant place, where people collaborate, where knowledge is shared, where people grow in their skills, where code quality is ensured and improved.** As a result, significant time is spent in the merge request interface. So, we’ve been asking ourselves:\n\n> _How can we significantly decrease the cycle time, increase the efficiency of code review, and create better ways of collaborating?_\n\nTo simplify our approach, we have defined **three key questions** that have also surfaced through research and our own usage:\n1. **Catch up**: Understanding where the merge request is since I last looked at it, what needs my attention, what’s changed, and helping me review that difference more efficiently after first reviewing it.\n1. **Real time collaboration**: Many teams are in the same location or same time zone and have significant overlap. Even here at GitLab, an [all-remote company](/company/culture/all-remote/), most people who work together share a few of hours of overlap and are sometimes looking at the same things. So if people are coming to the same merge request, and working on it at the same time, how can we make that more efficient?\n1. **External discussions**: Working remotely, through [asynchronous communication](https://handbook.gitlab.com/handbook/communication/#introduction), is how we mainly communicate at GitLab. It’s something that we do quite well, but sometimes it’s better to work synchronously by just getting on a call and solve confusions, communicate, sketch things out, and then document those decisions. But unfortunately, the merge request doesn’t provide a natural way to do that. We use Zoom, we use Google Docs, and then we try to summarize in merge requests or issues. What if we could integrate all of that into the merge request?\n\nTo explain what we’ve been thinking about and how we could answer these questions, here is a **short visual story**. The following images are very low-fidelity mockups so that we can focus on ideas rather than dwelling on the details.\n\n## 1. Catch up\n\n> The story starts with me, as a reviewer, coming into a merge request and looking at my personal area at the top right corner.\n\n![](https://about.gitlab.com/images/blogimages/future-merge-requests-realtime-collab/step1.png){: .shadow.medium.center}\n\n> I can immediately see what has happened since I last reviewed the merge request: Two files with new changes to review and one comment that needs my attention. This comment may be someone that mentioned me, someone that replied to one of my comments, or maybe someone that resolved a thread I’m participating in.\n\n## 2. Smarter suggestions\n\n> I click the speech bubble icon to jump to that comment, where Katherine, the merge request author, and James, another reviewer, are participating. Hmm, this discussion is getting a bit convoluted... but since they are in other timezones, I’ll reply with my thoughts so they can read them in their own time. It also looks like we need specific expertise here. When I start @-mentioning, I see that André was the person who last changed this line of code (and he’s also a code owner of this file). He might have an idea why this was changed, so I’ll mention him in my comment.\n\n![](https://about.gitlab.com/images/blogimages/future-merge-requests-realtime-collab/step2.png){: .shadow.medium.center}\n\nToday in GitLab we already suggest people who are involved in the merge request or conversation, but this idea brings in new data and more clearly highlights why people are relevant.\n\n## 3. Real time collaboration\n\n> Meanwhile, I notice that Katherine and James are **looking at this merge request right now**, by seeing their avatars popping up at the top of the merge request – _very similar to how you would see someone in Google Docs looking at the same document that you are_. I also get a notification saying that Katherine mentioned me in a comment and that James is now replying to one of my comments.\n\n![](https://about.gitlab.com/images/blogimages/future-merge-requests-realtime-collab/step3.png){: .shadow.medium.center}\n\nI can see people interacting with the merge request in real time, I can notice their presence, but I’m not seeing what they’re typing or collaborating directly with them – we’re just going about doing our tasks separately. **The way we work may change if we expect an immediate response.** For example, if you notice someone is online, you might ask more open-ended questions because you know that the other person can respond more quickly versus writing a longer response that seeks to conclude the discussion faster. And this is helpful not only for people that work distributed and asynchronously but also for people that work in the same time zone, in the same location, in the same office, or even in the same room.\n\n**These presence indicators create certain expectations and give a sense of progress to the merge requests as well.** When you’re waiting on a code review, you don’t know if someone has looked at it or if the reviewers are close to finishing the review. This can save people from interrupting one another. This provides a sense of progress without needing someone to take an active measure to find out if progress is being made. This is important because progress is one of those things that we all want to feel when we’re waiting on someone or something else.\n\n> Back to the story... This is great timing! Since we’re all online maybe it’s time we jump on a call to clear up the discussions together and get back on track.\n\n![](https://about.gitlab.com/images/blogimages/future-merge-requests-realtime-collab/step4.png){: .shadow.medium.center}\n\n> By using this dropdown button next to the avatars, I can immediately start a shared session or invite the other participants to a video call, using Zoom (one of our favorite tools here at GitLab). Starting a Zoom meeting also starts a collaborative shared session in the merge request. **In the shared session we can follow each other and write comments together in real time.** I can now follow James and Katherine and see which files they are looking at, in which lines they’re commenting, and also what they’re writing, in real time. I can also ask to be followed if I want to focus all of the participants’ attention to a specific comment or file. I can even copy a link to this shared session and share it via our chat tool or email so that others can join without having to find the merge request.\n\n![](https://about.gitlab.com/images/blogimages/future-merge-requests-realtime-collab/step5.png){: .shadow.medium.center}\n\nBut the most important thing is the ability to **co-author and collaborate in real time on comments in the merge request**. Not only commenting on the changes but also in the merge request overview (comments that are not attached to specific lines). You can collaborate while you’re in a video call, on the phone, or just in the office next to each other.\n\n## 4. External discussions\n\n![](https://about.gitlab.com/images/blogimages/future-merge-requests-realtime-collab/step6.png){: .shadow.medium.center}\n\n> Collaborating in real time on the merge request allowed us to quickly reach a consensus. **And we could easily record everything we discussed in GitLab, instead of using separate tools.** Before ending the shared session, we add a joint comment with a summary and next steps.\n\nWe know that some teams do code reviews in meeting rooms, projecting the changes and all reviewing it together. Everyone’s got their laptops but they’re sort of looking at the same thing, but not quite. These abilities would allow everyone to take notes collaboratively, creating an interesting way of documenting. This is just one use case, there are likely many more use cases that we can solve here.\n\nYou'll notice that it looks a lot like a Google Doc, but on a merge request in GitLab. From a user experience standpoint, we must try to use metaphors and patterns that people have seen and used in other common tools. **Looking and behaving like Google Docs is a good thing because people can immediately relate and understand what these cursors and avatars mean.** But it’s about understanding these paradigms, not accepting them blindly. We strive to study and see if they fit into the situation at hand and if the users recall using this metaphor for this purpose. Using [boring solutions](https://handbook.gitlab.com/handbook/values/#boring-solutions) is part of our values at GitLab.\n\nToday we use Google Docs to take notes during our meetings but maybe this can replace the need to have all of these different tools open simultaneously while we’re on a video call. You can use your preferred tools, like a projector, to collaborate better depending on your work setting and what works best for you and your team, but in the end **everything is recorded in the same tool, in the same integrated environment that is GitLab.** There is no data duplication and it stops teams from using tools like Google Docs to record information that then gets replicated in merge requests and issues, instead the information can go directly into the single source of truth where the decision and discussion are relevant. If we can work out how to do this properly on merge requests we can perhaps apply it to issues and epics as well.\n\n## 5. Record decisions\n\n> Finally, in the shared session we realized that one of the changes must be documented for posterity so that we can prevent mistakes and clarify our decision. So I come back to the comment to commit it to the code base. **This adds the comment directly to the source file as a code comment.**\n\n![](https://about.gitlab.com/images/blogimages/future-merge-requests-realtime-collab/step7.png){: .shadow.medium.center}\n\nOne thing that we see happening a lot at GitLab and in other companies is people explaining a decision or why we shouldn’t touch this specific part of the code, in writing. This valuable content is usually left in comments, emails, or chat messages, when it should be a _code comment_. **Code comments allow explanations, decisions, and rationale to be left for posterity so that future authors can be aware of them.**\n\nOur [suggest changes feature][suggest-changes] in merge requests allows you to include suggestions as part of your line comments. These suggestions can then be applied directly to the file where the comment was made, replacing its contents with the suggestion. With the idea of \"Commit as file comment,\" this is slightly different, as you’d be applying the comment to the file itself, as a code comment.\n\nMoving the explanation into the actual file rather than leaving it as a comment in the merge request **makes it accessible wherever the code goes**. It’s in the Git repository, it has a timestamp, it’s part of the repository history, and it’s even in your desktop IDE. It means that if you refactor your repository, split this module out into another repository, the comment follows that line of code.\n\n## Conclusion\n\n**We’re not entirely sure how these ideas will be executed, if all of them are viable, or if they’re even good ideas.** That is why we’d love to hear your thoughts on the [**feedback issue**][feedback-issue]. Share with us what you like, what you don’t like, and what other ideas you have for code review. This short story doesn’t mean that we’re going through with these ideas but that we think they are possible directions to solve those big problems that we’ve been seeing with code review at GitLab.\n\nIf you visualize the communication tools as a spectrum, right now GitLab’s merge requests are similar to email: you’re sending \"emails\" you’re receiving \"emails\" and it’s not a real time discussion, you’re not seeing what other people are typing, you don’t know when you’re going to get a response. On the other end of the spectrum is Google Docs: You see exactly what people are typing in real time, and expectations are more clear. Somewhere closer to Google Docs, you have Slack, which as a chat tool is very much focused on synchronous communication (although it can also be used for asynchronous communication). **We want to be in the middle of this communication tools spectrum, not like a Google Doc, always on, always real time, but we also don’t want to stay as an \"email client for collaborating on code.\"** We want to be smarter than that, enabling collaboration at the right moments.\n\nOne question that has been raised is **privacy**: People feel concerned about revealing when they’re looking at a merge request. Privacy is also a big concern in the sense of \"peer pressure,\" people changing their behaviors because they know they can be observed by others. We have to find some middle ground between people that opt to be more private and quietly observe things, versus people that opt for maximum efficiency and prefer collaborating in real time when everyone is in the merge request. Another concern is how to **avoid interrupting** people's flow. We anticipate that these are some of the interesting challenges we will have to wrestle with and balance against helping teams work most efficiently.\n\nThese concerns are one of the main reasons why we are sharing our ideas. We realized that these are some of our blind spots and that there could be others, so **we need** [**your feedback**][feedback-issue]. There also might be other, even more amazing, crazy ideas that we haven’t thought of yet which would take merge requests to an exciting new place. **So don’t limit your feedback to the ideas that we’ve come up with, feel free instead to share ideas that you think would make the merge request an even better place to work and get your job done.**\n\nIf you’re interested in our macro strategy and plans of how we’re going to help you better manage, plan, and create in GitLab, take a look at our [Dev strategy](/blog/dev-strategy-review/).\n\n{::options parse_block_html=\"true\" /}\n\n\u003Ci class=\"fab fa-gitlab\" style=\"color:rgb(107,79,187); font-size:.85em\" aria-hidden=\"true\">\u003C/i>&nbsp;&nbsp;\nHelp shape the future of code review - [Share your feedback][feedback-issue]\n&nbsp;&nbsp;\u003Ci class=\"fab fa-gitlab\" style=\"color:rgb(107,79,187); font-size:.85em\" aria-hidden=\"true\">\u003C/i>\n{: .alert .alert-webcast}\n\nCover image by [Mitchell Luo](https://unsplash.com/@mitchel3uo) on [Unsplash](https://unsplash.com/photos/H3htK85wwnU)\n{: .note}\n\n[feedback-issue]: https://gitlab.com/gitlab-org/gitlab/issues/36119\n[suggest-changes]: https://docs.gitlab.com/ee/user/discussions/#suggest-changes\n",[9,819,986],"UX",{"slug":988,"featured":6,"template":686},"future-merge-requests-realtime-collab","content:en-us:blog:future-merge-requests-realtime-collab.yml","Future Merge Requests Realtime Collab","en-us/blog/future-merge-requests-realtime-collab.yml","en-us/blog/future-merge-requests-realtime-collab",{"_path":994,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":995,"content":1001,"config":1006,"_id":1008,"_type":14,"title":1009,"_source":16,"_file":1010,"_stem":1011,"_extension":19},"/en-us/blog/get-started-compliance-as-code",{"title":996,"description":997,"ogTitle":996,"ogDescription":997,"noIndex":6,"ogImage":998,"ogUrl":999,"ogSiteName":673,"ogType":674,"canonicalUrls":999,"schema":1000},"Why building compliance as code in DevOps will benefit your entire company","Read here on how to integrate compliance as code into your DevOps cycle and why it's important to have in your business","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749680734/Blog/Hero%20Images/compliance-as-code-header.jpg","https://about.gitlab.com/blog/get-started-compliance-as-code","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Why building compliance as code in DevOps will benefit your entire company\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Vanessa Wegner\"}],\n        \"datePublished\": \"2019-08-19\",\n      }",{"title":996,"description":997,"authors":1002,"heroImage":998,"date":1003,"body":1004,"category":816,"tags":1005},[900],"2019-08-19","\n\nCompliance, both regulatory and self-imposed, is another area where the shift-left\nmovement has taken hold. By building compliance into your workflow with compliance as code methods, your\nteam can save time while producing secure, low-risk code.\n\n## What is compliance as code?\n\nCompliance as code methods ensure that the correct regulatory or company\ncompliance requirements are fulfilled with zero-touch on the path to production.\nIt builds compliance into development and operations.\n\nThe utilization of compliance as code tools enable stakeholders to ensure that production procesesses are compliant by means of defining how resources must be configured. Such a structure often allows these tools to automatically adjust resources into a compliant state in order to meet these pre-defined compliance requirements.\n\nThis type of minimal-friction compliance is a crucial solution for large\nenterprises – especially those subject to complex regulation (such as enterprises\noperating in healthcare or financial services). By building compliance into the\n[DevOps lifecycle](/topics/devops/), you will streamline the workflow and save developers valuable\ntime during review and testing.\n\n## Benefits of compliance as code\n\nAdopting compliance as code brings a number of advantages and new operational capabilities. \n\n- **It’s easier to stay compliant during compliance rule change periods.** When a change happens in regulatory compliance frameworks, awareness and remediation of any issues happen more quickly because teams don’t have to manually overhaul processes or re-train.\n- **More natural alignment between developers and risk assessment teams.** There is more unity between teams when the compliance controls are already defined as code. It’s then possible to embed compliance rules into delivery processes and enable compliant delivery by default. \n- ** A lot of time and money saved.** Automation cuts out costly and time-consuming manual work. When automated compliance as code is in place, there’s a reduced risk of costly fines and data breaches. \n- **It’s all scalable.** Adopting compliance as code means adopting consistency across teams and an organization, regardless of size. This consistency prevents ambiguity and bottlenecks in maintaining compliance. \n\n## Challenges of compliance as code\n\nDevOps means experiencing changes often and quickly, and despite the benefits that automated compliance as code brings, it can also be a challenge. It can sometimes be difficult for security to keep up with the speed of change.\n\nAnd sometimes, even automated compliance as code isn’t perfect. It’s important to remember that there’s no cap on how careful you should be when it comes to DevOps compliance. Despite having automation in place, a pair or two of human eyes open to keep watch is still useful – even if it means a possible increase in human error. \n\n## How to impliment compliance as code\n\nAs [Jim Bird wrote for O’Reilly](https://www.oreilly.com/learning/compliance-as-code),\ncompliance as code policies must be defined up front, and will bring together\nmanagement, compliance, internal audit, PMO, and infosec leaders. This group\nwill work together to define rules and control workflows. Management also needs\nto understand how operational and other risks will be handled throughout the\npipeline.\n\nHow your company does establish compliance as code policies [will depend on how your team is structured](/topics/devops/build-a-devops-team/)\nbut regardless of how your teams interact, transparency is required. To ensure\nthat information is shared and decisions are made collaboratively, consider\nestablishing the following guidelines:\n\n- **Peer reviews**: The first review cycle for larger changes should be manual, to\nensure no changes are made without at least one other person verifying the\nchange. Reviewers can be assigned randomly to ensure the quality of review.\n- **Static application security testing**: [Static\n(or white box) testing](/blog/developer-intro-sast-dast/) should be done for every code change, in addition to\nmanual reviews.\n- **Subject matter expert reviews for high-risk code**: For code that the management team defines as\nhigh-risk (such as security code), changes should be reviewed by a subject matter\nexpert.\n- **Regulated access controls**: Management should keep access in check, both so that\nchanges aren’t made by a single engineer, and so that every change flows through\nthe workflow and can be reviewed by anyone with access to the dashboard.\n\n### Enhance technology with culture\n\nTechnology and processes will only work if your team cultures are aligned with your goal – and culture starts\nat the top. Team leaders should promote and exemplify a security-first\nmentality and openness to collaborative change. This will be a new way of\nthinking for some, but it will help teams adopt the shift-left trend, ultimately\nsaving everyone time and reducing business risk.\n\n### Compliance and open source\n\nIn 2015, [The Linux Foundation found that more than 60% of companies build products with open source software](https://www.linuxfoundation.org/blog/2015/06/why-companies-that-use-open-source-need-a-compliance-program/), but more\nthan half of those companies don’t have formal procedures in place to ensure their\nsoftware complies with open source licenses and regulations. Companies should\ncreate a free and open source software (FOSS) compliance program not only to\nabide by copyright notices and license obligations, but also to protect company\nIP and third-party source code from disclosure.\n\n## How we do compliance at GitLab\n\nWe [began our formalized compliance program](/blog/choosing-a-compliance-framework/)\ntowards the end of our Series C funding round, which was fairly early compared\nto other businesses of our size. The benefit of starting early was that we were\nable to implement security controls while we were still developing and evolving\nour operating processes, instead of retrofitting security to the business. The\nkey decision in our approach was choosing between independent or aggregate\nsecurity controls: We chose the aggregate route, leveraging [Adobe’s CCF](https://blogs.adobe.com/security/2017/05/open-source-ccf.html),\nrather than implementing industry frameworks individually. This allowed us to\nmitigate overlapping asks to GitLab teams, which enabled an agile and efficient\nprogram standup, and gave the compliance group internal credibility.\n\n## Compliance as code provides benefits across your ecosystem\n\nThere are benefits to everyone from the developer to the third-party auditor when compliance is baked into code from the beginning. These benefits include:\n- **Time saved**: Your\nteams will spend less time passing code fixes back and forth.\n- **Compliance transparency**: Management will\nunderstand where and how your software abides by compliance requirements.\n- **Routine reporting streamlines auditing**: Reports throughout the DevOps lifecycle provide documentation and proofs of\nrecord that will help management track and streamline any regulatory audit\nprocedures.\n\n## Common compliance as code tools\n\nGoogle Cloud Platform, Amazon Web Services, and Azure are all cloud services that can be used in compliance as code. And oftentimes, these tools are even more effective when paired with native tools. \n\nThrough proper tool adoption, the three core actions of a compliance strategy can be automated: prevention, detection, and remediation.\n\nCover image by [Hack Capital](https://unsplash.com/@hackcapital?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/search/photos/code?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)\n{: .note}\n",[819,9,683,862,775,923],{"slug":1007,"featured":6,"template":686},"get-started-compliance-as-code","content:en-us:blog:get-started-compliance-as-code.yml","Get Started Compliance As Code","en-us/blog/get-started-compliance-as-code.yml","en-us/blog/get-started-compliance-as-code",{"_path":1013,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1014,"content":1020,"config":1026,"_id":1028,"_type":14,"title":1029,"_source":16,"_file":1030,"_stem":1031,"_extension":19},"/en-us/blog/gitlab-suggested-reviewers",{"title":1015,"description":1016,"ogTitle":1015,"ogDescription":1016,"noIndex":6,"ogImage":1017,"ogUrl":1018,"ogSiteName":673,"ogType":674,"canonicalUrls":1018,"schema":1019},"Unblock code reviews with GitLab Suggested Reviewers","Identify the right reviewers more quickly, saving time and accelerating the software development lifecycle.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749666316/Blog/Hero%20Images/codereview2.png","https://about.gitlab.com/blog/gitlab-suggested-reviewers","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Unblock code reviews with GitLab Suggested Reviewers\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Itzik Gan Baruch\"}],\n        \"datePublished\": \"2023-09-21\",\n      }",{"title":1015,"description":1016,"authors":1021,"heroImage":1017,"date":1023,"body":1024,"category":704,"tags":1025},[1022],"Itzik Gan Baruch","2023-09-21","\nIn the world of software development, speed is of the essence. The faster you can merge your code, the quicker you can iterate, innovate, and deliver value to your users. However, there's a roadblock that often hinders this need for speed – the arduous process of finding the right reviewer for your merge request (MR).\n\nImagine this: You've just finished a brilliant piece of code that's ready to be integrated into your project. You're excited to see it in action, and so are your teammates. But before your masterpiece can join the project, it must go through the crucial stage of code review. Here's where the challenge begins.\n\nIn many development teams, finding the ideal reviewer can be a time-consuming task. You might need someone with expertise in a particular area, someone who's available at the moment, and someone who can provide insightful feedback promptly. The longer it takes to locate the right reviewer, the more your code languishes in review limbo, delaying the entire development cycle.\n\nAnd let's not forget the frustration of starting a review with the wrong person, only to realize that their insights aren't quite what you needed. Backtracking to find another reviewer can be a difficult process, compounding the delays and creating unnecessary bottlenecks.\n\nThis challenge becomes even more pronounced as software projects grow in size and complexity, especially when multiple teams are involved. Coordinating reviews across team boundaries can be a logistical nightmare. \n\nWhat's worse is that these delays often set off a chain reaction, leading to even more delays down the line, as other tasks and dependencies pile up, affecting not just the current MR but the entire project's timeline.\n\n![development graphic](https://about.gitlab.com/images/blogimages/2023-09-22-suggested-reviewers/code-review.png)\n\nIn this blog post, we'll introduce you to [GitLab Suggested Reviewers](https://docs.gitlab.com/ee/user/project/merge_requests/reviews/#suggested-reviewers). Suggested Reviewers is designed to streamline your MR workflow by ensuring that you connect with the right reviewers quickly and efficiently. Say goodbye to wasted time and welcome to a faster, more agile development cycle.\n\n## What is Suggested Reviewers?\nSuggested Reviewers leverages a machine learning algorithm that analyzes the changes in an MR and a project’s contribution graph to suggest reviewers with contextual knowledge. It generates a list of up to five suggested reviewers. The list is presented in the Reviewers dropdown in the merge request sidebar, empowering the author to immediately select available reviewers. These suggestions are contextual to the changes in the MR. Additional commits to MRs may change the reviewer suggestions, which are automatically updated in the reviewer dropdown list.\n\nIt also will display if a suggestion is a code owner or if they can merge the changes,helping drive towards action.\n\n![suggested reviewers](https://about.gitlab.com/images/blogimages/2023-09-22-suggested-reviewers/suggested-reviewers.png) \n\n## Key benefits of Suggested Reviewers\nHere are the key benefits of Suggested Reviewers.\n- **Time savings.** Suggested Reviewers eliminates the need for guesswork or manual reviewer selection. The feature automates the process, saving time for developers.\n- **Enhanced collaboration.** By connecting you with the right reviewers, Suggested Reviewers promotes collaboration and encourages knowledge sharing among team members.\n- **Improved code quality.** Suggested Reviewers enables developers to have the most qualified individuals review their code, resulting in better quality and more reliable software.\n- **Reduced bottlenecks.** Suggested Reviewers speeds up the review process and reduces bottlenecks by quickly identifying available and willing reviewers.\n- **Personalized suggestions.** Suggested Reviewers considers individual expertise and past interactions, providing tailored recommendations.\n\n## How to get started with Suggested Reviewers\n\nIn this blog post, we've explored how Suggested Reviewers transforms the development lifecycle. It's not just about faster code reviews; it's about faster, more efficient, and more collaborative software development from start to finish. \n\n> Learn more in our [Suggested Reviewers documentation](https://docs.gitlab.com/ee/user/project/merge_requests/reviews/#suggested-reviewers).\n",[9,819,706],{"slug":1027,"featured":6,"template":686},"gitlab-suggested-reviewers","content:en-us:blog:gitlab-suggested-reviewers.yml","Gitlab Suggested Reviewers","en-us/blog/gitlab-suggested-reviewers.yml","en-us/blog/gitlab-suggested-reviewers",{"_path":1033,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1034,"content":1040,"config":1047,"_id":1049,"_type":14,"title":1050,"_source":16,"_file":1051,"_stem":1052,"_extension":19},"/en-us/blog/how-to-provision-reviewops",{"title":1035,"description":1036,"ogTitle":1035,"ogDescription":1036,"noIndex":6,"ogImage":1037,"ogUrl":1038,"ogSiteName":673,"ogType":674,"canonicalUrls":1038,"schema":1039},"Deploying dynamic review environments with MRs and Argo CD","Here's how to use the Argo CD ApplicationSet to provision a ‘ReviewOps’ environment based on merge request changes.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749681920/Blog/Hero%20Images/kubernetes.png","https://about.gitlab.com/blog/how-to-provision-reviewops","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How to provision dynamic review environments using merge requests and Argo CD\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Joe Randazzo\"},{\"@type\":\"Person\",\"name\":\"Madou Coulibaly\"}],\n        \"datePublished\": \"2022-08-02\",\n      }",{"title":1041,"description":1036,"authors":1042,"heroImage":1037,"date":1044,"body":1045,"category":752,"tags":1046},"How to provision dynamic review environments using merge requests and Argo CD",[1043,792],"Joe Randazzo","2022-08-02","\nWe recently learned of a new contribution to the ApplicationSet in the Argo CD project, specifically the [Pull Request generator for GitLab](https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/applicationset/Generators-Pull-Request.md#gitlab) and decided to take it for a spin. What makes this interesting is now dynamic [review environments](https://docs.gitlab.com/ee/ci/review_apps/index.html) can be provisioned intuitively from the merge request (MR) using a [GitOps](/topics/gitops/) workflow. The benefit is code reviewers or designers can quickly review any app changes to your Kubernetes cluster all from within the merge request.\n\nIn traditional testing workflows, you may have pushed your changes into a development environment, waiting for the QA and UX team to pull those changes into their environment for further review, and then received feedback based on your small change. At this point, time was wasted between various teams with environment coordination or adding bugs to the backlog of the new changes. \n\nWith the combination of a merge request and review environments, you can quickly spin up a test environment based on the changes of your feature branch. This means the QA or UX team can suggest improvements or changes during the code review process without wasting cycles.\n\nThe introduction of the ApplicationSet has given greater flexibility to Argo CD workflows such as:\n\n- Allowing unprivileged cluster users to deploy applications (without namespace access)\n- Deploying applications to multiple clusters at once\n- Deploying many applications from a single monorepo\n- **And triggering review environments based on a pull request**\n\n### Let's review the ApplicationSet and the GitLab Pull Request Generator\n\nThe [Pull Request Generator](https://argo-cd.readthedocs.io/en/latest/operator-manual/applicationset/Generators-Pull-Request) will use the GitLab API to automatically discover new merge requests within a repository. Depending on the filter match of the MR, a review environment will then be generated.\n\n```yaml\napiVersion: argoproj.io/v1alpha1\nkind: ApplicationSet\nmetadata:\n  name: review-the-application\n  namespace: argocd\nspec:\n  generators:\n  - pullRequest:\n      gitlab:\n        project: \u003Cproject-id>\n        api: https://gitlab.com/\n        tokenRef:\n          secretName: \u003Cgitlab-token>\n          key: token\n        pullRequestState: opened\n      requeueAfterSeconds: 60\n  template:\n    metadata:\n      name: 'review-the-application-{{number}}'\n    spec:\n      source:\n        repoURL: \u003Crepository-with-manifest-files>\n        path: chart/\n        targetRevision: 'HEAD'\n        helm:\n          parameters:\n          - name: \"image.repository\"\n            value: \"registry.gitlab.com/\u003Cgroup-and-project-path>/{{branch}}\"\n          - name: \"image.tag\"\n            value: \"{{head_sha}}\"\n          - name: \"service.url\"\n            value: \"the-application-{{number}}.\u003Cip>.nip.io\"\n      project: default\n      destination:\n        server: https://kubernetes.default.svc\n        namespace: dynamic-environments-with-argo-cd\n```\n#### Fields\n\n* `project`: The GitLab Project ID\n* `api`: URL of GitLab instance\n* `tokenRef`: The secret to monitor merge request changes\n* `labels`: Provision review environments based on a GitLab label\n* `pullRequestState`: Provision review environments based on [MR states](https://docs.gitlab.com/ee/api/merge_requests.html)\n\nFilter options include GitLab labels, merge request state (open, closed, merged), and branch match. Templating options include merge request ID, branch name, branch slug, head sha, and head short sha.\n\nSee the latest [ApplicationSet documentation](https://argo-cd.readthedocs.io/en/latest/operator-manual/applicationset/Generators-Pull-Request/#gitlab) for additional details.\n\nFor this blog post, we explore using the Argo CD ApplicationSet to provision a “ReviewOps” environment based on merge request changes.\n\n### Prerequisites\n\nThe following tools are required for running this tutorial. Please install and/or configure them before getting started.\n\n- **Tools**\n  - GitLab v15.0+ \n  - Kubernetes cluster v1.21+\n  - Argo CD 2.5.0+\n- **CLI**\n  - kubectl v1.21+\n\n### Explore the Source Code\n\nFirst, let’s explore the [source code](https://gitlab.com/madou-stories/dynamic-environments-with-argo-cd) for the tutorial.\n\nThis GitLab group is composed of the 2 following projects:\n\n- `The Application`: contains the source code of a containerized application and its CI/CD pipeline\n- `The Application Configuration`: contains the application configuration (Kubernetes Manifests) managed by Helm\n\n![git-repository](https://about.gitlab.com/images/blogimages/2022-08-01-how-to-provision-reviewops/git-repository.png)\n\n### Setting up GitLab\n\n1. Create your GitLab Group and fork the [The Application](https://gitlab.com/madou-stories/dynamic-environments-with-argo-cd/the-application) and [The Application Configuration](https://gitlab.com/madou-stories/dynamic-environments-with-argo-cd/the-application-configuration) projects into it.\n\n2. In `The Application Configuration` project, edit the `**manifests/applicationset.yml**` as follows:\n\n  * `.spec.generators.pullRequest.gitlab.project`: The Project ID of `The Application`\n  * `.spec.template.spec.source.repoURL`: Git URL of `The Application Configuration`\n  * `.spec.template.spec.source.helm.parameters.\"image.repository\"`: Point to image repository, for example `registry.gitlab.com/\u003CYour_GitLab_Group>/the-application/{{branch}}`\n\n  Note: keep the {{branch}} string as is and replace \u003CYour_GitLab_Group> with the name of the group you created in step 1.\n\n  * `.spec.template.spec.source.helm.parameters.\"service.url\"`: Templated with `the-application-{{number}}.\u003CYour_Kube_Ingress_Base_Domain>`\n\n  Note: keep the {{number}} string as is and replace \u003CYour_Kube_Ingress_Base_Domain> with the base domain of your Kubernetes Cluster.\n\n3. Define the following CI/CD variables at the group level:\n\n   - `ARGOCD_SERVER_URL`, the Argo CD server address\n   - `ARGOCD_USERNAME`, the username of your Argo CD account\n   - `ARGOCD_PASSWORD`, the password of your Argo CD account\n   - `KUBE_INGRESS_BASE_DOMAIN`, the base domain of your Kubernetes Cluster\n\n   ![cicd-variables](https://about.gitlab.com/images/blogimages/2022-08-01-how-to-provision-reviewops/cicd-variables.png)\n\n4. Generate a Group access token to grant `read_api` and `read_registry` access to this group and its sub-projects.\n\n   ![group-access-token](https://about.gitlab.com/images/blogimages/2022-08-01-how-to-provision-reviewops/group-access-token.png)\n\n   Save the group access token somewhere safe. We will use it later.\n\n### Setting up Kubernetes\n\n1. Create a namespace called `dynamic-environments-with-argo-cd`.\n   ```shell\n   kubectl create namespace dynamic-environments-with-argo-cd\n   ```\n2. Create a Kubernetes secret called `gitlab-token-dewac` to allow Argo CD to use the GitLab API.\n   ```shell\n   kubectl create secret generic gitlab-token-dewac -n argocd --from-literal=token=\u003CYour_Access_Token>\n   ```\n3. Create another Kubernetes secret called `gitlab-token-dewac` to allow Kubernetes to pull images from the GitLab Container Registry.\n   ```shell\n   kubectl create secret generic gitlab-token-dewac -n dynamic-environments-with-argo-cd --from-literal=token=\u003CYour_Access_Token>\n   ```\n\n### Setting up Argo CD\n\n1. Create the Argo CD ApplicationSet to generate an Argo CD Application associated with a merge request.\n   ```shell\n   kubectl apply -f https://gitlab.com/\u003CYour_GitLab_Group>/the-application-configuration/-/raw/main/manifests/applicationset.yaml\n   ```\n\n### Update the source code\n\n1. In `The Application` project, create a GitLab issue, then an associated branch and merge request. \n2. In Argo CD, a new application is provisioned called `review-the-application` based on the new merge request event.\n\n   ![review-the-application-argocd](https://about.gitlab.com/images/blogimages/2022-08-01-how-to-provision-reviewops/review-the-application-argocd.png)\n\n3. In `The Application` project, edit the `index.pug` and replace `p Welcome to #{title}`  with `p Bienvenue à #{title}`.\n4. Commit into your recent branch which is going to trigger a pipeline run.\n5. In the CI/CD > Pipelines, you will find the following pipeline running on your merge request:\n\n   ![feature-branch-pipeline](https://about.gitlab.com/images/blogimages/2022-08-01-how-to-provision-reviewops/feature-branch-pipeline.png)\n\n   where,\n\n   - `docker-build`: builds the container image\n   - `reviewops`: configures and deploys the container into the review environment using Argo CD\n   - `stop-reviewops`: deletes the review environment\n\n6. Once completed, the `review-the-application` application in Argo CD is now synced.\n\n   ![review-the-application-synced](https://about.gitlab.com/images/blogimages/2022-08-01-how-to-provision-reviewops/review-the-application-synced.png)\n\n7. From the merge request, click on the `View app` button to access to your application.\n\n   ![view-app-button](https://about.gitlab.com/images/blogimages/2022-08-01-how-to-provision-reviewops/view-app-button.png)\n\n   The outcome should be as follows:\n\n   ![express-app](https://about.gitlab.com/images/blogimages/2022-08-01-how-to-provision-reviewops/express-app.png)\n\n8. You have succesfully provisioned a dynamic review environment based on your merge request! Once the merge request is closed, the environment will be automatically cleaned up.\n\n## To sum up\n\nHopefully this tutorial has been helpful and has inspired your GitLab + Argo CD workflows with review environments.\n\nWe'd love to hear in the comments on how this is working for you, as well as your ideas on how we can make GitLab a better place for GitOps workflows.\n",[9,537,683],{"slug":1048,"featured":6,"template":686},"how-to-provision-reviewops","content:en-us:blog:how-to-provision-reviewops.yml","How To Provision Reviewops","en-us/blog/how-to-provision-reviewops.yml","en-us/blog/how-to-provision-reviewops",{"_path":1054,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1055,"content":1061,"config":1068,"_id":1070,"_type":14,"title":1071,"_source":16,"_file":1072,"_stem":1073,"_extension":19},"/en-us/blog/introducing-markdown-live-preview",{"title":1056,"description":1057,"ogTitle":1056,"ogDescription":1057,"noIndex":6,"ogImage":1058,"ogUrl":1059,"ogSiteName":673,"ogType":674,"canonicalUrls":1059,"schema":1060},"GitLab's realtime Preview Markdown is an editor for everyone","With GitLab's new realtime Preview Markdown, technical and non-technical team members can more easily work together. Here's everything you need to know.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663397/Blog/Hero%20Images/logoforblogpost.jpg","https://about.gitlab.com/blog/introducing-markdown-live-preview","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLab's realtime Preview Markdown is an editor for everyone\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Parker Ennis\"}],\n        \"datePublished\": \"2021-09-21\",\n      }",{"title":1056,"description":1057,"authors":1062,"heroImage":1058,"date":1064,"body":1065,"category":754,"tags":1066},[1063],"Parker Ennis","2021-09-21","\n\nFostering better, more meaningful collaboration is an integral part of DevOps and a key part of what GitLab, the complete DevOps Platform, unlocks for developers and their teams. While many developers or engineers feel more comfortable working locally on their machines and spend a majority of their time using a CLI to push code changes, with GitLab you can also use the [Web Editor](https://docs.gitlab.com/ee/user/project/repository/web_editor.html) or [Web IDE](https://docs.gitlab.com/ee/user/project/web_ide/) to collaborate and edit content in a much easier, faster, and approachable way. \n\nStarting in [GitLab 14.2](https://about.gitlab.com/releases/2021/08/22/gitlab-14-2-released/), editing Markdown content in the Web Editor or Web IDE just got even better.\n\n### Introducing the real-time Preview Markdown editor\n\n[GitLab Flavored Markdown](https://docs.gitlab.com/ee/user/markdown.html) automatically renders Markdown content in an easy-to-read and easy-to-write plain text language. Although Markdown is inherently more “human-readable” and versatile when writing rich web content, Markdown files can become tricky to work with as they become more verbose and complex. \n\nEasy-to-read and easy-to-write means different roles with varying degrees of technical experience can collaborate on content more efficiently and seamlessly. However, previewing the rendered output of Markdown content to validate the accuracy of any changes has not been as intuitive, requiring an extra step to switch out of the Web IDE or Web Editor where the raw source code lives in order to view the changes from the Preview tab. Frequent context-switching back and forth between tabs to validate changes leads to wasted time and can be disruptive to the creative process while writing content.\n\nIn GitLab 14.2, now both the Web IDE and Web Editor include [an option to preview Markdown in real-time, in a single window](/releases/2021/08/22/gitlab-14-2-released/#create-split-markdown-preview). A side-by-side preview panel will display when editing Markdown with a click of a button that will toggle a split view panel in the editor and render the content on the page you’re working on as the changes are being made. \n\nHere’s an example of what this new functionality looks like:\n\n![Example of real-time Markdown Preview side-by-side panels](https://about.gitlab.com/images/blogimages/markdown-live-preview.png){: .shadow.small}\n\n#### How do I use it?\n\nIt’s very straightforward to start using the side-by-side preview. When you are editing any Markdown file, even a newly created one, you can right-click the editor and select **Preview Markdown** or use `Command/Control + Shift + P` to toggle a split-screen live preview of your Markdown content. From there, all you need to do is start writing or editing content and you’ll see your changes in real time!\n\n![Example of the Preview Markdown button in the static editor](https://about.gitlab.com/images/blogimages/markdown-live-preview-hotkey.png){: .shadow.small}\n\n#### Everyone can contribute\n\nAt GitLab, [everyone can contribute](/company/mission/#everyone-can-contribute) and we welcome feedback in any form. As we usher in the [new DevOps Platform era ](/blog/welcome-to-the-devops-platform-era/) and wave goodbye to the all-too-familiar \"DIY\" style of DevOps, we're excited to iterate and improve with our wider community. \n\n## What is Markdown?\n \nMarkdown is a lightweight markup language for formatting text using a plain editor text. It was created by John Gruber and Aaron Swartz in 2004. It is now one of the most popular markup languages and is used mainly by writers and programmers to help them take notes, write quickly, and develop website content without figuring out how to use the formatting toolbar in text editors. A big part of its appeal is that you don't have to have any knowledge of HTML to use Markdown to write and create web pages.\n \nMarkdown is platform-independent and can be used to create websites, documents, notes, books, presentations, emails, and more. \n \nThere is some school of thought that Markdown is easier to write than HTML, and it's easier for most people to read Markdown source than HTML source. In fact, experts say you can learn Markdown in as little as 10 minutes.\n \n## What is Markdown used for?\n \nMarkdown can be used to format code in GitLab. Creating a markdown file in GitLab requires creating a new file with the .md extension. Once in the new file, the code can be written in Markdown syntax. When the code is finished, you can commit the file to your Git repository.\nWhile not as feature-laden as Microsoft Word, Markdown lets you create basic documents and use a Markdown document authoring app to export formatted documents to PDFs or HTML files.\n \nUsing Markdown is different than using a [WYSIWYG](https://en.wikipedia.org/wiki/WYSIWYG) editor. For example, in an application like Word, changes are visible immediately. Markdown is different. When a Markdown-formatted file is created, you add Markdown syntax to the text to indicate which words and phrases should look different.\n \n[For example,](https://www.markdownguide.org/getting-started/) to distinguish a heading, add a number sign before it (e.g., # Heading One). Or add two asterisks before and after a phrase to put it in bold (e.g., **this text is bold**). \nBolden and italicize text in Markdown without needing the WYSIWYG interface.\n\n",[9,683,1067],"releases",{"slug":1069,"featured":6,"template":686},"introducing-markdown-live-preview","content:en-us:blog:introducing-markdown-live-preview.yml","Introducing Markdown Live Preview","en-us/blog/introducing-markdown-live-preview.yml","en-us/blog/introducing-markdown-live-preview",{"_path":1075,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1076,"content":1082,"config":1088,"_id":1090,"_type":14,"title":1091,"_source":16,"_file":1092,"_stem":1093,"_extension":19},"/en-us/blog/iteration-and-code-review",{"title":1077,"description":1078,"ogTitle":1077,"ogDescription":1078,"noIndex":6,"ogImage":1079,"ogUrl":1080,"ogSiteName":673,"ogType":674,"canonicalUrls":1080,"schema":1081},"Why small merge requests are key to a great review","Massive merge requests lead to more problems than solutions. We explain how embracing iteration can lead to a better experience for the code author and code review.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749681966/Blog/Hero%20Images/broken_wood.jpg","https://about.gitlab.com/blog/iteration-and-code-review","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Why small merge requests are key to a great review\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"David O'Regan\"}],\n        \"datePublished\": \"2021-03-18\",\n      }",{"title":1077,"description":1078,"authors":1083,"heroImage":1079,"date":1084,"body":1085,"category":752,"tags":1086},[727],"2021-03-18","\n\nThis post is adapted from a [GitLab Unfiltered blog post](/blog/better-code-reviews/) written by me, [David O'Regan](/company/team/#oregand). In [part one of our series](/blog/tips-for-better-code-review/), we explain the importance of fairness and empathetic thinking in code reviews and in [part two we explain why patch files bring added value to code reviews](/blog/patch-files-for-code-review/).\n{: .note .alert-info .text-center}\n\nThe [GitLab handbook defines iteration as doing the smallest thing possible to get it out as quickly as possible](https://handbook.gitlab.com/handbook/values/#iteration). If there was a single guiding principle I could suggest you lean into with your merge requests it would be iteration. At its heart, software is all about iteration. Software is about taking a large problem and breaking it down into smaller, more manageable problems. Like any other skill, iteration needs to be learned and practiced often to improve. The next time you're hitting the \"Submit merge request\" button, pause a moment and think if the merge you're about to submit could be be downsized.\n\n## Why smaller MRs are better\n\nThe only thing worse than writing a long merge request is reviewing a long merge request. This is why at GitLab, iteration (and by extension, [small merge requests](https://handbook.gitlab.com/handbook/values/#make-small-merge-requests)) is one of our driving values.\n\nWe even created a [DangerBot](https://docs.gitlab.com/ee/development/dangerbot.html) that will ask code authors to break down merge requests that are over a certain size.\n\nMassive merge requests can create technical problems for a code reviewer beyond added complexity. If a review goes beyond a certain number of lines, it simply becomes too difficult to reason through without checking out the branch, booting the project, and [smoke testing](https://en.wikipedia.org/wiki/Smoke_testing_(software)). While smoke testing complex reviews is a great idea, this process shouldn't become a habit for reviewing code. Big MRs can lead to merge conflicts, content rot, and other disasters.\n\n[Sarah Yasonik](/company/team/#syasonik), backend engineer on Monitor at GitLab, suggested that reviewers handle too-large or too-complicated merge requests by creating new, smaller MRs while reviewing, and reviewing the code in chunks. It's better to break up a too-big MR than to continue adding lines of code to an MR that is already too large.\n\n### The art of the follow-up\n\nAs the code author and code reviewer, there are a few best practices to abide by. Namely, if you are a code author and you offer a follow up review, be sure you always follow through on this promise.\n\nIf you are a code reviewer, here are four tips:\n\n*   Feel empowered to ask the code author for a follow up\n*   Accept any offers of a follow up graciously\n*   Be patient with code authors\n*   Know when it's best to reject a follow up offer\n\n## Practical tips for using iteration in code reviews\n\n### Why does iteration matter?\n\nThe smaller the merge request, the easier it is for the code reviewer to check. The idea of shipping small changes is consistent with GitLab's [iteration value](https://handbook.gitlab.com/handbook/values/#iteration). Clement Ho, my frontend engineering manager who has since left GitLab, was a major champion for iteration. Once I started paying close attention to how Clement broke down merge requests into small bites, I started to notice the benefits of iteration almost immediately. Iteration is so important to GitLab that CEO [Sid Sijbrandij](/company/team/#sytses) hosts [weekly office hours devoted to breaking down big projects](/handbook/ceo/#iteration-office-hours), and grades our team members on their [iteration competency](https://handbook.gitlab.com/handbook/values/#iteration-competency).\n\n### How small merge requests helps your reviewer\n\nIf iteration is all about releasing the [minimal viable change (MVC)](https://handbook.gitlab.com/handbook/values/#minimal-viable-change-mvc) in small merge requests, then it follows that engineers who fully embrace iteration will be shipping less code per merge request, to the delight of their reviewer.\n\nWe've all been there. We are assigned as a reviewer on an MR, and just as you're about to get comfortable you open the MR to see more than 1000 lines of code across multiple files. Time to refill your mug of coffee and get ready for a tiring review process.\n\nThe problems with large MRs should be obvious [if you've ever practiced self-reviews](/blog/tips-for-better-code-review/) or found yourself in this situation. Here are a few reasons why large MRs are indicative of bigger problems:\n\n*   Longer MRs have more lines of code\n*   There is the greater chance for brittle connections\n*   It becomes harder to follow the path of the solution/feature\n*   Screenshots usually cannot account for the volume of change\n*   It's much easier to miss bugs\n*   The author is sure to be left with lots of comments, which can be demoralizing\n\nIt's a simple concept, but one that is undervalued. Keep your merge requests small because:\n\n*   There are less lines of code to read\n*   Different contexts are separated into individual MRs\n*   The reviewer can follow along more easily\n*   It's easier to follow the path of a feature's development\n*   Less reviewer comments per MR is better for motivating the code author\n\nIn the end, we review code carefully at GitLab because we want to ensure that every release brings new value to our customers. If you have questions or comments about code reviews, creating smaller MRs, or iteration, leave us a comment on this blog post!\n\nGet more code review tips by reading the other blog posts in our series. In part one, we discuss [the role of fairness in code review](/blog/tips-for-better-code-review/) and in part two we share some [practical advice on using patch files](/blog/patch-files-for-code-review/).\n\n_Sara Kassabian contributed to this blog post._\n\nCover image by [Jon Sailer](https://unsplash.com/@eyefish73) on [Unsplash](https://unsplash.com/)\n{: .note}\n",[9,1087],"inside GitLab",{"slug":1089,"featured":6,"template":686},"iteration-and-code-review","content:en-us:blog:iteration-and-code-review.yml","Iteration And Code Review","en-us/blog/iteration-and-code-review.yml","en-us/blog/iteration-and-code-review",{"_path":1095,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1096,"content":1102,"config":1107,"_id":1109,"_type":14,"title":1110,"_source":16,"_file":1111,"_stem":1112,"_extension":19},"/en-us/blog/leading-scm-ci-and-code-review-in-one-application",{"title":1097,"description":1098,"ogTitle":1097,"ogDescription":1098,"noIndex":6,"ogImage":1099,"ogUrl":1100,"ogSiteName":673,"ogType":674,"canonicalUrls":1100,"schema":1101},"Leading SCM, CI and Code Review in one application","The most important tools for developers are SCM, CI and Code Review, and it is better to have them all together.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749679607/Blog/Hero%20Images/scm-ci-cr.png","https://about.gitlab.com/blog/leading-scm-ci-and-code-review-in-one-application","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Leading SCM, CI and Code Review in one application\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Itzik Gan Baruch\"}],\n        \"datePublished\": \"2020-09-30\",\n      }",{"title":1097,"description":1098,"authors":1103,"heroImage":1099,"date":1104,"body":1105,"category":730,"tags":1106},[1022],"2020-09-30","\n\n{::options parse_block_html=\"true\" /}\n\n\n\nGitLab enables streamlined CI, code reviews and collaboration at proven enterprise scale, making development workflows easier to manage and minimizing context switching required between tools in complex DevOps toolchains. Users can release software faster and outpace the competition with the ability to quickly respond to changes in the market.\n\nWatch this short video (3 minutes) to see a demo of the seamless flow developers having when using SCM, CI and Code Review in GitLab.\n\n\u003Ciframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/DvuqGA4FhXM\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen>\u003C/iframe>\n\n\nCover image by [NESA by Makers](https://unsplash.com/@nesabymakers) on [Unsplash](https://unsplash.com/)\n{: .note}\n",[109,9],{"slug":1108,"featured":6,"template":686},"leading-scm-ci-and-code-review-in-one-application","content:en-us:blog:leading-scm-ci-and-code-review-in-one-application.yml","Leading Scm Ci And Code Review In One Application","en-us/blog/leading-scm-ci-and-code-review-in-one-application.yml","en-us/blog/leading-scm-ci-and-code-review-in-one-application",{"_path":1114,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1115,"content":1120,"config":1125,"_id":1127,"_type":14,"title":1128,"_source":16,"_file":1129,"_stem":1130,"_extension":19},"/en-us/blog/many-meanings-multicloud",{"title":1116,"description":1117,"ogTitle":1116,"ogDescription":1117,"noIndex":6,"ogImage":832,"ogUrl":1118,"ogSiteName":673,"ogType":674,"canonicalUrls":1118,"schema":1119},"Understand the many meanings of multicloud","In our 2020 DevSecOps Survey we uncovered a number of different definitions of 'multicloud.' Here's how to make sense of it all.","https://about.gitlab.com/blog/many-meanings-multicloud","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Understand the many meanings of multicloud\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Valerie Silverthorne\"}],\n        \"datePublished\": \"2020-06-30\",\n      }",{"title":1116,"description":1117,"authors":1121,"heroImage":832,"date":1122,"body":1123,"category":816,"tags":1124},[858],"2020-06-30","\n\nWhat does multicloud mean? We've heard – and used – the term '[multicloud](/topics/multicloud/)' for a while now but, like most industry terms, it can be defined differently by different groups. So in our just released [2020 Global DevSecOps Survey](/developer-survey/) we asked 3652 people from 21 countries across 19 job categories what multicloud actually means to them.\n\nThe majority of respondents (36%) said multicloud means the ability to deploy some applications on Azure, some on AWS, and some on Google. Almost 35% said they thought it meant deploying applications across multiple cloud providers with different components on different clouds. And finally almost 29% said it meant being able to move an app from one cloud provider to another.\n\nIt got even more interesting when we asked them to describe how multicloud is used in their organizations. A clear majority aren't doing \"multicloud\" yet - their teams use one cloud provider only, or none at all. (For context, over 18% of survey respondents said their organizations are not currently using any cloud provider.)\n\n_We don't use multi cloud here. Not yet._\n\n_We will deploy to the cloud the customer requires. But the whole application sits on one cloud._\n\n_We don't, on purpose, because we do not subscribe to the vendor lock-in argument and therefore multi-cloud would require more resources than we feel it is worth._\n\nOthers took the term multicloud literally, saying their teams use several different platforms.\n\n_We have moved workloads from one provider to another to address performance issues._\n\n_Multiple clouds used for different purposes and some on prem hyperconverged thrown into the mix._\n\n_We use different cloud providers for different projects._\n\n_We use Digital Ocean + GCP + AWS_\n\nAnd some took multicloud further.\n\n_We're switching between providers while testing new functionalities for our innovative apps._\n\n_We built our own PaaS based on Kubernetes. This system could be deployed/provisioned on any K8S ready public cloud provider or to any other compatible hosting system._\n\n_For us \"multicloud\" means simultaneously using multiple cloud providers, not just ability to migrate apps between them._\n\n_We avoid vendor lock-in by being able to run on any cloud seamlessly_\n\n## Defining the stages of multicloud\n\nSo is there a single definition of multicloud? The answer is yes, but... Our CEO [Sid Sijbrandij](/company/team/#sytses) argues that multicloud isn't something static but rather a series of staged workflows that mean different things to organizations depending on where they are in their DevOps journey. His [maturity model](https://medium.com/gitlab-magazine/multi-cloud-maturity-model-2de185c01dd7) consists of seven stages, starting with everything on a single cloud and ending with true data portability in multiple clouds.\n\n[William Chia](/company/team/#williamchia), senior product marketing manager for cloud native and GitOps, suggests starting by asking the question \"Where are your workloads running?\" For many organizations the answer will be one workload is running on one cloud and another workload might be running in a different cloud – the team is using multiple clouds. This is an early stage of maturity on the journey to multicloud adoption. \n\nA team might want to be able to deploy the same workload to different clouds, a step that would help avoid vendor lock-in, provide backup coverage in case of failures, and perhaps offer some leverage that might help with costs, William explains. But there's a serious trade-off in that step because the engineering resources required to create a platform to deploy to multiple clouds are significant.\n\n\"The Utopian goal of getting to a place where you can have the same workloads on multiple clouds easily is not necessarily desirable for everyone or even the majority of people,\" William says. \"It costs a lot to do that and you need to have the engineering staff who understand both clouds. There's a high cost to multicloud.\"\n\nThe final stages of multicloud, which William says today represents just a small fraction of companies today, is where the same application is deployed to different clouds and workloads as well as data for can be dynamically shifted between multiple clouds. \n\nSo the often-used term \"multicloud\" does legitimately have evolving definitions and that will likely continue as DevOps matures. One step on the multicloud journey that unlocks powerful benefits with little overhead is the jump to [work***flow*** portability](/topics/multicloud/). While most companies aren't close to the highest reaches of multicloud maturity, almost any company can get started down the path. It's clear that the best implementations take into consideration the tradeoffs and choose right amount of multicloud for the task at hand.\n\n**Read more about multicloud:**\n\n[Leverage GitLab CI/CD to get the most out of multicloud](/blog/gitlab-ci-cd-is-for-multi-cloud/)\n\n[The role cloud-agnostic DevOps can play](/blog/ci-cd-the-ticket-to-multicloud/)\n\n[Seven best practices for multicloud security](/blog/multi-cloud-security/)\n",[9,841,683],{"slug":1126,"featured":6,"template":686},"many-meanings-multicloud","content:en-us:blog:many-meanings-multicloud.yml","Many Meanings Multicloud","en-us/blog/many-meanings-multicloud.yml","en-us/blog/many-meanings-multicloud",{"_path":1132,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1133,"content":1139,"config":1145,"_id":1147,"_type":14,"title":1148,"_source":16,"_file":1149,"_stem":1150,"_extension":19},"/en-us/blog/merge-request-reviewers",{"title":1134,"description":1135,"ogTitle":1134,"ogDescription":1135,"noIndex":6,"ogImage":1136,"ogUrl":1137,"ogSiteName":673,"ogType":674,"canonicalUrls":1137,"schema":1138},"Code review made easier thanks to merge request reviewers in GitLab 13.7","Code review is a critically important part of the software development, but it can be hard – and time consuming – to arrange. That's where our new merge request reviewers feature comes in. Here's what to look for in our 13.7 release.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749681664/Blog/Hero%20Images/merge_request_reviewers.jpg","https://about.gitlab.com/blog/merge-request-reviewers","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Code review made easier thanks to merge request reviewers in GitLab 13.7\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Daniel Gruesso\"}],\n        \"datePublished\": \"2020-10-13\",\n      }",{"title":1134,"description":1135,"authors":1140,"heroImage":1136,"date":1142,"body":1143,"category":754,"tags":1144},[1141],"Daniel Gruesso","2020-10-13","\n\nEdit: This feature was originally planned for the 13.5 release but has now been rescheduled to the 13.7 release in order to address some performance improvements.\n{: .alert .alert-info .note}\n\nRequesting a code review is an important part of contributing code to any software project. However, deciding _who_ should review your code and asking for a review are no easy tasks. Historically, teams making use of [merge requests](/solutions/continuous-integration/) for their code review needs have used the \"assignee\" field for both authors and reviewers but this makes it hard for others to determine who's doing what on a merge request; for example, consider a merge request with a single author and 2 reviewers. If all parties are on the “assignee” field at once, it is hard for an external user to find out who to reach out for something specific.\n\nThe back-and-forth between authors and reviewers causes the author to go through MR history to find the original reviewer as well as unnecessary assigning back and forth from everyone. Peers who are coming on to assist cannot easily find relevant players for this merge request. Lastly, the merge request author does not know if a reviewer has reviewed but not approved the changes, or if more work is needed from them.\n\n## GitLab code reviews\n\nWhether or not code is good quality can’t be taken on faith; code quality needs to be checked. GitLab makes it easy to collaborate on code reviews within a merge request.\nIn GitLab, users can assign one or more code reviewers to a source project. Collaboration in merge requests with GitLab reviewers helps deployments go more smoothly. The code reviewer option in GitLab is available on GitLab Premium and GitLab Ultimate.\n\n## Merge requests and code reviews\nThe merge request Reviewers feature in GitLab allows for a review of your work and to see the critique progress status. The “suggest changes” feature lets a colleague suggest alterations that the original author can choose to accept or not, just with the click of a button. And, of course, every change made to a block of code can be reviewed before it goes live.\n\n### Feature branches and code reviews\nCreating a new feature branch or new code automatically kicks off a merge request, and that is the place to request a code review. In the MR, inline code reviews can be performed either on a single line or multiple lines of code, and a reviewer can leave comments. A feature branch allows for changes to be made to the codebase without them moving onto the main default branch.\n\nAfter the merge request and code review are complete, feature branches can be deleted to keep the source code repository clean as possible. It’s also possible to add time tracking to an MR to discern how long the process, including the code review, takes from beginning to end.\n\nThe merge request widget helps delete these feature branches once a merge request and code review are done. This can be set up to happen as you create the initial MR by choosing the “delete source branch when merge request accepted” selection. That way, the branch gets deleted after the MR is merged.\n\n### Improving code reviews\n\nTo bridge these gaps, GitLab 13.7 introduces merge request \"reviewers,\" which easily allows authors to request a review as well as see the status of the review. By simply selecting one or more users from the \"reviewers\" field, the assigned reviewers will receive a notification of the request to review the merge request. This makes it easy to determine the relevant roles for the users involved in the merge request, as well as formally requesting a review from a peer.\n\n![Merge request reviewers](https://about.gitlab.com/images/blogimages/reviewers_sidebar.png){: .shadow.center}\nScreenshot from upcoming GitLab 13.7 release\n{: .note.text-center}\n\n### What's next\n\nFuture improvements include [suggesting the most relevant reviewers](https://gitlab.com/gitlab-org/gitlab/-/issues/195781) as well as [streamlining the approval rules](https://gitlab.com/gitlab-org/gitlab/-/issues/231244) experience when paired with reviewers.\n\nWe are excited to see this feature ship soon to GitLab.com and for self-managed users on October 22nd. As always, we encourage you to participate in the conversation by visiting the related [reviewers epic](https://gitlab.com/groups/gitlab-org/-/epics/1823) in the GitLab project.\n\nCover image by [Kevin Ku](https://unsplash.com/@ikukevk) on [Unsplash](https://unsplash.com/photos/w7ZyuGYNpRQ)\n{: .note}\n",[9,819],{"slug":1146,"featured":6,"template":686},"merge-request-reviewers","content:en-us:blog:merge-request-reviewers.yml","Merge Request Reviewers","en-us/blog/merge-request-reviewers.yml","en-us/blog/merge-request-reviewers",{"_path":1152,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1153,"content":1158,"config":1164,"_id":1166,"_type":14,"title":1167,"_source":16,"_file":1168,"_stem":1169,"_extension":19},"/en-us/blog/mr-reviews-with-vs-code",{"title":1154,"description":1155,"ogTitle":1154,"ogDescription":1155,"noIndex":6,"ogImage":977,"ogUrl":1156,"ogSiteName":673,"ogType":674,"canonicalUrls":1156,"schema":1157},"How to do GitLab merge request reviews in VS Code","Code review is critical to modern software development. We're making it easier by bringing merge request reviews right into VS Code.","https://about.gitlab.com/blog/mr-reviews-with-vs-code","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How to do GitLab merge request reviews in VS Code\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Tomas Vik\"}],\n        \"datePublished\": \"2021-01-25\",\n      }",{"title":1154,"description":1155,"authors":1159,"heroImage":977,"date":1161,"body":1162,"category":752,"tags":1163},[1160],"Tomas Vik","2021-01-25","\n\nThis post will give you an idea of how VS Code can aid your code review process. You'll get an overview of the features that GitLab VS Code Extension currently supports, as well as what we plan to introduce in the future.\n\nReviewing merge requests is a core part of GitLab: both the product (since [version 2.0.0](https://gitlab.com/gitlab-org/gitlab/blob/6a3621202e3f7274150862198f59d2579c326650/changelogs/archive.md#L7222), released in 2011) and the company. We recognize that certain review tasks are hard to do just by looking at the diff, and we strive to make them easier. One such task might be looking in the codebase for duplicated code or examples of a particular coding style.\n\nWe decided to aid code reviewers in two ways:\n\n## First way: The GitLab Web IDE\n\nFirst, we introduced the [Web IDE](/blog/introducing-gitlab-s-integrated-development-environment/), which helps our users work [with the codebase in the browser](/direction/create/ide/web_ide/#overview). You can quickly open multiple files, make changes, and commit them. The Web IDE is handy when you need to make a small change, or you don't have the project cloned locally.\n\nThe second way is more recent. We always wanted to bring the code review experience closer to code editors, where developers spend a large portion of their time. But the editor market is very fragmented (you find out the hard way if Emacs and Vim users meet at a party). And it isn't feasible to build GitLab support into all major editors (however, there are plenty of editor plugins maintained by the community[^1]). \n\n## Second way: Bringing code reviews into the editor\n\nRecently, as [VS Code gained a significant user share](https://insights.stackoverflow.com/survey/2019#development-environments-and-tools), it started to make sense to [commit to maintaining the GitLab VS Code extension](/blog/use-gitlab-with-vscode/), which was started as a community project by one, at the time, GitLab employee: [Fatih](https://gitlab.com/fatihacet). After an initial housekeeping period, we started chipping away tasks that will ultimately bring the code review experience into the editor.\n\nIn my previous post I talked about the great [VS Code Extension API](/blog/vscode-extension-development-with-gitlab/). This API gives extensions almost full control over the editor. When the API introduced commenting functionality two years ago, extensions could start contributing comments to the editor windows. These comments are shown similarly as comments on a Google Doc. Being able to natively show comments is perfect for reviewing code changes in the editor and other extensions that provide code reviews are already using this commenting API[^2].\n\n![Merge request review in VS Code](https://about.gitlab.com/images/blogimages/mr-reviews-with-vs-code/full-mr-review-screen.png){: .shadow.medium.center}\nMerge request review in VS Code\n{: .note .text-center}\n\nOver the last few milestones, we started showing MR changes in VS Code and even showing discussions on these. This means that you can open an MR in your editor and read through the code and comments without switching windows and context. I find this really useful because I can still interact with my editor the way I'm used to, even as I'm reviewing MRs. I can use full-text search to find if the MR duplicates existing code or I can open a different test file and compare whether the code style matches.\n\nCurrently, the interaction with MR is mostly read-only. That means you can see the changes and discussions, but you can't add or change comments, yet[^3]. But even in this current form, you can benefit from having the VS Code functionality so close to your review, especially for the initial understanding of the change.\n\n![VS Code supports Markdown in the comments](https://about.gitlab.com/images/blogimages/mr-reviews-with-vs-code/mr-review-long-comment.png){: .shadow.medium.center}\nVS Code supports Markdown in the comments\n{: .note .text-center}\n\n## What's next\n\nOver the next few milestones, we plan to make the commenting as interactive as you know it from the GitLab web interface. We'll start with editing existing comments, adding emoji reactions and resolving discussion threads. Lastly, we'll implement the full review functionality with creating comments and reviews[^4]. Each [iteration](https://handbook.gitlab.com/handbook/values/#iteration) will make the feature a bit more useful.\n\nI'm excited about the potential to stay in my editor for both creating and reviewing merge requests. I'm already using the current merge request review feature to get the initial understanding of what the MR tries to achieve. I can explore the related code more quickly in my editor. If you'd like to help us build the code review feature or just look at the current state of development, visit the [Merge Request Review epic](https://gitlab.com/groups/gitlab-org/-/epics/4607).\n\nYou can check out a walkthrough our initial proof of concept of merge request reviews in VS Code below:\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube-nocookie.com/embed/kKA6i8oqZAA\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n[^1]: [IntelliJ](https://plugins.jetbrains.com/plugin/7447-gitlab-integration-plugin), [Atom](https://atom.io/packages/search?q=gitlab), [vim](https://github.com/shumphrey/fugitive-gitlab.vim), [Emacs](https://github.com/nlamirault/emacs-gitlab), ...\n[^2]: [Jira and Bitbucket](https://marketplace.visualstudio.com/items?itemName=Atlassian.atlascode), [GitHub Pull Requests and Issues](https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github)\n[^3]: You can work around that by using the MR overview and commenting there.\n[^4]: [MR review: interacting with existing comments - POC](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/issues/269) and [MR review: new comments and reviews POC](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/issues/293) represent the initial investigation.\n\n[Cover image](https://art.ljubicapetkovic.com/cc-licensed/) by [Ljubica Petkovic](https://art.ljubicapetkovic.com), licensed under [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)\n{: .note}\n",[9,231,710],{"slug":1165,"featured":6,"template":686},"mr-reviews-with-vs-code","content:en-us:blog:mr-reviews-with-vs-code.yml","Mr Reviews With Vs Code","en-us/blog/mr-reviews-with-vs-code.yml","en-us/blog/mr-reviews-with-vs-code",{"_path":1171,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1172,"content":1178,"config":1183,"_id":1185,"_type":14,"title":1186,"_source":16,"_file":1187,"_stem":1188,"_extension":19},"/en-us/blog/patch-files-for-code-review",{"title":1173,"description":1174,"ogTitle":1173,"ogDescription":1174,"noIndex":6,"ogImage":1175,"ogUrl":1176,"ogSiteName":673,"ogType":674,"canonicalUrls":1176,"schema":1177},"How patch files can transform how you review code","We explain how to use patch files for better code review.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749672273/Blog/Hero%20Images/patch.jpg","https://about.gitlab.com/blog/patch-files-for-code-review","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How patch files can transform how you review code\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"David O'Regan\"}],\n        \"datePublished\": \"2021-03-15\",\n      }",{"title":1173,"description":1174,"authors":1179,"heroImage":1175,"date":1180,"body":1181,"category":752,"tags":1182},[727],"2021-03-15","\n\nThis post is adapted from a [GitLab Unfiltered blog post](/blog/better-code-reviews/) written by me, [David O'Regan](/company/team/#oregand). In [part one of our series](/blog/tips-for-better-code-review/), we explain the importance of fairness and empathetic thinking in code reviews.\n{: .note .alert-info .text-center}\n\n## Patch files\n\nWanna know a `git secret`? [Patch files](https://git-scm.com/docs/git-format-patch) are magic when it comes to code reviews. A [patch is a text file whose contents are similar to Git diff](https://www.tutorialspoint.com/git/git_patch_operation.htm) but along with code it contains metadata about commits, for example, a patch file will include commit ID, date, commit message, etc. We can create a patch from commits and other people can apply them to their repository.\n\n## How to use a patch file\n\nA patch file is useful for code review because it allows the reviewer to create an actionable piece of code that shares their thoughts with the MR author. The code author can then apply the suggestion directly to their merge request. Patch files foster collaboration because it essentially creates a paired programming session in the review process.\n\nThis lets other people check your changes in the git patch files for any corrections that need to be made before the changes truly go live. After everything has been checked and corrections made, the changes can be pushed to the main branch of the repository. \n\nOne of the [better examples of a simple patch file in action](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31686#note_341534370) comes from [Denys Mishunov](/company/team/#dmishunov), staff frontend engineer on the Create team.\n\n```bash\nIndex: app/assets/javascripts/projects/commits/components/author_select.vue\nIDEA additional info:\nSubsystem: com.intellij.openapi.diff.impl.patch.CharsetEP\n\u003C+>UTF-8\n===================================================================\n--- app/assets/javascripts/projects/commits/components/author_select.vue\t(revision 697d0734f1ae469a9a3522838e36b435d7cdf0be)\n+++ app/assets/javascripts/projects/commits/components/author_select.vue\t(date 1589356024033)\n@@ -110,6 +110,7 @@\n     \u003Cgl-new-dropdown\n       :text=\"dropdownText\"\n       :disabled=\"hasSearchParam\"\n+      toggle-class=\"gl-py-3\"\n       class=\"gl-dropdown w-100 mt-2 mt-sm-0\"\n     >\n       \u003Cgl-new-dropdown-header>\n\n```\n\nTo generate this suggestion, Denys pulled down the code he was reviewing and was able to offer a code solution based on his own testing. The patch file contains lots of valuable information, including the file affected, the date the revision was made, and the tool he used to generate the patch.\n\n## How to create a patch file\n\nYou can make a patch file using a web editor or with the command line. Read on to see how to create a patch file in GitLab both ways.\n\n### Patch files using a web editor\n\nIf you are rocking a nice fancy IDE or text editor, here's some good news: Most support patch files via plugins or out of the box. Here are some links to documentation on how to use patch files with different plugins: [VSCode](https://github.com/paragdiwan/vscode-git-patch), [Webstorm](https://www.jetbrains.com/help/webstorm/using-patches.html), [Atom](https://atom.io/packages/git-plus), and [Vim](https://vim.fandom.com/wiki/How_to_make_and_submit_a_patch).\n\n### Patch files using the command line\n\nOK command line users, you’ve made some commits, here’s your `git log`:\n\n```\ngit log --pretty=oneline -3\n\n* da33d1k - (feature_branch) Reviewer Commit 1 (7 minutes ago)\n\n* 66a84ah - (feature_branch) Developer 1 Commit (12 minutes ago)\n\n* adsc8cd - (REL-0.5.0, origin/master, origin/HEAD, master) Release 13.0 (2 weeks ago)\n\n``` javascript\n```\n\nThis command creates a new file, `reviewer_commit.patch`, with all changes from the reviewer's latest commit against the feature branch:\n\n```\n```git format-patch HEAD~1 --stdout > reviewer_commit.patch```\n\n### How to apply the patch\n\nFirst, take a look at what changes are in the patch. You can do this easily with `git apply`:\n\n```git apply --stat reviewer_commit.patch```\n```\n\nHeads up: Despite the name, this command won't actually apply the patch. It will just show the statistics about what the patch will do.\n\nSo now that we've had a look, let's test it first because not all patches are created equal:\n\n```\n```git apply --check reviewer_commit.patch```\n\nIf there are no errors we can apply this patch without worrying.\n\nTo apply the patch, you should use `git am` instead of `git apply`. The reason: `git am` allows you to sign off an applied patch with the reviewer's stamp.\n\ngit am --signoff &lt; reviewer_commit.patch\n\nApplying: Reviewer Commit 1\n\n``` javascript\n```\n\nNow run `git log` and you can see the `Signed-off-by` tag in the commit message. This tag makes it very easy to understand how this commit ended up in the codebase.\n\n### The benefits of patch files for code reviews\n\nSo now that you know how to make a shiny patch file, why would you use patch files as part of a code review process? There are a few reasons you might consider offering a patch file for a change you feel strongly about:\n\n*   It communicates you have invested a large amount of effort into understanding the author's solution and reasoning\n*   It demonstrates a passion for using teamwork to arrive at the best solution\n*   It shows the reviewer is willing to accept responsibility for this merge beyond just reading the code\n\nThere are a few alternatives to patch files for code reviews. GitLab has a [suggestion feature which allows the reviewer to suggest code changes using Markdown in a merge request](https://docs.gitlab.com/ee/user/discussions/#suggest-changes). The other option is to write raw code in Markdown right in the comment box. The downside is the reviewer doesn't have the option to test the code they are writing, making both of these options prone to error.\n\nIt is better to use a patch file because it involves the code reviewer in the review process in a collaborative way by default. In order to generate a patch, the reviewer must pull down the code, write the patch, test the change, and then submit it for the code author's consideration. Patch files increase the visibility for the reviewer and offers a fully collaborative experience for the code author.\n\nSome people might argue patch files are a cheeky way for a reviewer to force a change they would rather see make it into the codebase, but I believe that anyone who has taken the time to check out a branch, run the project, implement a change, and then submits that change back for a discussion is fully embracing collaboration.\n\nGitLab is evaluating whether to make patch files [part of the code review and merge request workflow](https://gitlab.com/gitlab-org/gitlab/-/issues/220044).\n\nLearn more about [the role of fairness in code review in part one of our blog series](/blog/tips-for-better-code-review/). Up next we explain why shipping small merge requests is in line with our iteration value.\n",[9,1087],{"slug":1184,"featured":6,"template":686},"patch-files-for-code-review","content:en-us:blog:patch-files-for-code-review.yml","Patch Files For Code Review","en-us/blog/patch-files-for-code-review.yml","en-us/blog/patch-files-for-code-review",{"_path":1190,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1191,"content":1196,"config":1202,"_id":1204,"_type":14,"title":1205,"_source":16,"_file":1206,"_stem":1207,"_extension":19},"/en-us/blog/pre-commit-post-deploy-is-dead",{"title":1192,"description":1193,"ogTitle":1192,"ogDescription":1193,"noIndex":6,"ogImage":935,"ogUrl":1194,"ogSiteName":673,"ogType":674,"canonicalUrls":1194,"schema":1195},"Pre-commit and post-deploy code reviews are dead","In a world with Git, pre-commit and post-deploy code reviews are relics that can be eliminated from your workflow.","https://about.gitlab.com/blog/pre-commit-post-deploy-is-dead","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Pre-commit and post-deploy code reviews are dead\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Aricka Flowers\"}],\n        \"datePublished\": \"2019-01-31\",\n      }",{"title":1192,"description":1193,"authors":1197,"heroImage":935,"date":1199,"body":1200,"category":752,"tags":1201},[1198],"Aricka Flowers","2019-01-31","\nPre-commit and post-deploy reviews have been the industry standard for ensuring that code is functioning as intended. But with Git around, are these methods still needed?\n\nLet’s take a step back and look at how they work.\n\n### Pre-commit reviews require that code is checked for bugs before it is committed\n\nOur CEO [Sid Sijbrandij](/company/team/#sytses) says pre-commit reviews makes sense because new code is evaluated before it is introduced into the code base. But with distributed version control, he says, you can essentially [do the same thing on Git branches](https://docs.gitlab.com/ee/topics/gitlab_flow.html). Prior to Git, branches were too pricey to use regularly in [version control systems](/topics/version-control/) like Subversion.\n\n### Post-deploy reviews periodically check for areas of improvement in the code base\n\nPost-deploy reviews are typically done on a periodic basis as a way to check certain areas of the code base and decide if improvements can be made. This method doesn’t make sense, according to Sid, because \"The code has already proven itself in production ... so you’re reluctant to make changes to it.\" Additionally, the idea of occasionally reviewing your code base is not really needed:\n\n\"If there's technical debt in there, at least it's not affecting other code,\" Sid explains. \"There's a certain interest you pay on technical debt, and it has to do with how much it spreads the technical debt to your code base. Code that is not doing much, meaning it's being executed but it's not changing much, well at least it's not influencing other code. You're always going to have tech debt, and you're always going to have a limited time during which you can review and fix things. Focus on the code that's active, that's probably the best place to focus.\"\n\n### Git branches are more efficient\n\nUsing Git branches to ensure that code is safe to introduce into the code base improves efficiencies when compared to pre-commit and post-deploy reviews, says Sid, who finds the former to be hard to track.\n\n\"Pre-commit code reviews were a bit awkward because you didn't have a good way to refer to it. It was in the tool, but you didn't have a SHA or definite way to refer to that version. And it was hard to know what CI it ran against because there wasn't a SHA. So by doing it post-commit, you have it in versions and it's much easier to see what you referred to. But with code review after deploy, the mindset was, 'If it works, you move on.'\n\n> \"If you change it, there's extra risk; if you don't change it, it's extra tech debt – and you always have to choose between the two.\"\n\n\"You're not going to be as vigilant to technical debt building up and it's harder to request that someone change something that’s working. If you change it, there's extra risk; if you don't change it, it's extra tech debt – and you always have to choose between the two. With pre-deploy code reviews, you don't have to make that choice …  [With what we have now], I think pre-commit and post-deploy code reviews are dead, and code should be reviewed on a branch before it's deployed to production.\"\n\nWhat do you think: Are pre-commit and post-deploy reviews a thing of the past? Tweet us @GitLab!\n{: .alert .alert-gitlab-purple.text-center}\n\nPhoto by [Caspar Camille Rubin](https://unsplash.com/photos/fPkvU7RDmCo?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on Unsplash\n{: .note}\n",[9,796,923],{"slug":1203,"featured":6,"template":686},"pre-commit-post-deploy-is-dead","content:en-us:blog:pre-commit-post-deploy-is-dead.yml","Pre Commit Post Deploy Is Dead","en-us/blog/pre-commit-post-deploy-is-dead.yml","en-us/blog/pre-commit-post-deploy-is-dead",{"_path":1209,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1210,"content":1215,"config":1224,"_id":1226,"_type":14,"title":1227,"_source":16,"_file":1228,"_stem":1229,"_extension":19},"/en-us/blog/pursuing-faster-time-to-merge-for-wider-community-contributions",{"title":1211,"description":1212,"ogTitle":1211,"ogDescription":1212,"noIndex":6,"ogImage":1058,"ogUrl":1213,"ogSiteName":673,"ogType":674,"canonicalUrls":1213,"schema":1214},"Pursuing faster time-to-merge for wider community contributions","How introducing more explicit contribution stages lowered the time it takes to merge a community contribution.","https://about.gitlab.com/blog/pursuing-faster-time-to-merge-for-wider-community-contributions","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Pursuing faster time-to-merge for wider community contributions\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Nick Veenhof\"}],\n        \"datePublished\": \"2022-09-13\",\n      }",{"title":1211,"description":1212,"authors":1216,"heroImage":1058,"date":1218,"body":1219,"category":1220,"tags":1221},[1217],"Nick Veenhof","2022-09-13","\n\nOne of GitLab's core strategies is to [build on our open core\nstrength](/company/strategy/#2-build-on-our-open-core-strength). We believe that building a\nstrong community of contributors is key to the long-term success of GitLab. We believe in a [dual-flywheel\nstrategy](/company/strategy/#dual-flywheels) that focuses on both product contributions from\nwithin our GitLab engineering team and community contributions. \n\nOur goal is to grow to 1000 contributors per month. The saying is that \"All roads lead to Rome,\" but of course not all of those roads are the most efficient ways to get there. To succeed, contributing to GitLab must be a rewarding and incentivizing experience that\nmotivates contributors to come back. One of the strategic choices we made in the [contributor\nsuccess](https://about.gitlab.com/handbook/marketing/developer-relations/contributor-success/) team is the route of being as\nresponsive and clear as we can about the next steps, using processes and automation. \n\n## Problem statement\n\nSo where do we start? On average GitLab has over [550 open merge\nrequests](https://gitlab.com/groups/gitlab-org/-/merge_requests?scope=all&state=opened&label_name[]=Community%20contribution).\nWe wanted to focus on the _ready enough_ problem. When is an MR ready for review? And when is an MR still in development? In\nboth cases collaboration is required, but having a formal handoff — meaning this contribution is ready for a review — helps in\nunderstanding who is blocked from moving forward. Before a merge request can find its way into GitLab, it needs to get a\nreview from at least one maintainer.\n\nHow do we know when to ask specific maintainers of our product areas to put their focus on reviewing these merge requests? When is a merge request _ready enough_ for a thorough review? What does _ready enough_ even mean?\n\nSome OSS communities use crowdsourced reviews for contributions to make sure the project maintainers don’t need to take on everything by themselves. For example, in the Drupal community there is the concept of [Reviewed and Tested by the Community](https://www.drupal.org/community/contributor-guide/task/triage-the-drupal-core-rtbc-queue). At GitLab we have MR coaches and community help to make sure everything is as ready as can be before involving the maintainers.\n\nThe GitLab bot and our MR coaches try to assist the wider community contributors on their way. We also had a ping-pong label that tried to signify if a community contributor had reacted and it was ‘ping ponged 🏓’ back to the GitLab team members. This pingpong label didn’t take the context into account. It was a great iterative and [boring solution](https://handbook.gitlab.com/handbook/values/#boring-solutions) to know who was up next (the author or the reviewer). But it had a lot of false-positives and caused confusion to both the maintainers and the community contributors.\n\nSo where do we go from here? How do we get a better grasp on this _ready enough_ problem? Let’s start by asking for help from our recommended reading list, [High-Output Management](/handbook/leadership/high-output-management/). Author Andrew S. Grove states: “A very important way to increase productivity is to arrange the work flow inside our black box so that it will be characterized by high output per activity, which is to say high-leverage activities.”\n\n## Introducing workflow labels\n\nFor a while, GitLab team members were using workflow labels to signify the state of a merge request. It wasn’t always used across all teams, but they were available. More specifically we’re looking at the following labels:\n\n- `workflow::ready for review`\n- `workflow::in dev`\n- `workflow::blocked`\n\nEach wider community contributor is now [able to change these labels themselves](https://docs.gitlab.com/ee/development/contributing/#contribution-flow). By using `@gitlab-bot ready`, it sets the state to `workflow::ready for review` and assigns a reviewer. The reviewer is able to set it back to `workflow::in dev` if there are still items to be addressed. Other wider community members can also leave comments or suggestions for improvement, and then [set the label](https://about.gitlab.com/handbook/engineering/quality/triage-operations/#reactive-label-command) back to `workflow::in dev`, or set other labels to help triage these merge requests.\n\n## What have we learned so far?\n\nWe started using this system over two months ago. We now know that around 20% of MRs on average are in a \"ready for review\"\nstate. Those contributors are blocked and waiting for an answer to either continue to improve the merge request or get\nit merged if there are no more comments left. We also noticed that some merge requests were not getting a lot of\nattention. We did an async retrospective and feedback session with the GitLab team members and the wider community in order to find an answer on how we can\n[improve the time it takes before a review is made](https://gitlab.com/gitlab-com/www-gitlab-com/-/issues/13718) for\ncontributions that were ready for a review. We’re still processing that feedback, but are looking to try some of these\nsuggestions, learn from them, and iterate. Even though GitLab cannot promise timely reviews, we can certainly try to\nbuild in mechanisms, and understand where we see limits, to navigate towards better processes. When we started out, we\nhad a median time of 17 days that an MR was in the ready for review state. Today that median time has been reduced to five days!\n\nThe median Open Community MR Age (OCMA) has also dropped from 139 days in April to 78 days in August. Maybe it is a\ncoincidence that we reached an all-time high of 126 contributors in August? Either way, all of the steps allowed our amazing wider\ncommunity contributors to get 440 merge requests merged in a single month! I’m certain this change contributed, among other\nchanges and initiatives, to that record. We will keep learning as we progress. It certainly allowed us to take a peek\ninto our little black box.\n\n## What’s next?\n\nNext up is to continue our iterations and move further towards automation. Right now it is up to the reviewer to set the\nstatus back to `workflow::in dev` whenever there is something left to address. We notice that this is not always changed\nback when it’s actually needed. It is also causing false-positives with reviewers and our wider community members.\nThe Contributor Success team is looking into how this can be automated. If you’d like to help, the automation happens in\nthe [Triage Ops project](https://gitlab.com/gitlab-org/quality/triage-ops/) and the Contributor Success [issue\nqueue](https://gitlab.com/gitlab-com/quality/contributor-success/-/issues) is open for everyone!\n\nWe’re also looking into a new program called [Leading\nOrganizations](https://gitlab.com/gitlab-com/www-gitlab-com/-/merge_requests/110700) which rewards recurring\ncontributors, and their organizations, with a review time objective of four business days. This would lead us to even\nshorter review cycle times and give those organizations that contribute to GitLab a competitive advantage to stay\nleaders in their domain. The faster we can innovate together, the faster our dual flywheel will spin. Together we go to\ninfinity and beyond. Together we can build software fast.\n\n\n\n\n","open-source",[9,1222,1223],"contributors","open source",{"slug":1225,"featured":6,"template":686},"pursuing-faster-time-to-merge-for-wider-community-contributions","content:en-us:blog:pursuing-faster-time-to-merge-for-wider-community-contributions.yml","Pursuing Faster Time To Merge For Wider Community Contributions","en-us/blog/pursuing-faster-time-to-merge-for-wider-community-contributions.yml","en-us/blog/pursuing-faster-time-to-merge-for-wider-community-contributions",{"_path":1231,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1232,"content":1238,"config":1244,"_id":1246,"_type":14,"title":1247,"_source":16,"_file":1248,"_stem":1249,"_extension":19},"/en-us/blog/reviewer-roulette-one-year-on",{"title":1233,"description":1234,"ogTitle":1233,"ogDescription":1234,"noIndex":6,"ogImage":1235,"ogUrl":1236,"ogSiteName":673,"ogType":674,"canonicalUrls":1236,"schema":1237},"Reviewer Roulette: (Just about) one year on","Learn how Reviewer Roulette has evolved at GitLab over the last year.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749672195/Blog/Hero%20Images/play-reviewer-roulette.jpg","https://about.gitlab.com/blog/reviewer-roulette-one-year-on","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Reviewer Roulette: (Just about) one year on\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Nick Thomas\"}],\n        \"datePublished\": \"2019-10-23\",\n      }",{"title":1233,"description":1234,"authors":1239,"heroImage":1235,"date":1241,"body":1242,"category":752,"tags":1243},[1240],"Nick Thomas","2019-10-23","\nJust over a year ago, [Dennis Tang](/company/team/#dennis)\nintroduced us to [Reviewer Roulette](/blog/play-reviewer-roulette/).\nThis was a shiny new tool designed to help us to find reviewers for our code.\nAt the time, our engineering department had around 150 people in it. At GitLab,\n[all our engineers are reviewers](/handbook/engineering/workflow/code-review/#reviewer),\nbut reviews were being unevenly distributed across them.\n\nA year on, and with more than 380 people in engineering available to review,\nwe're still using a form of Reviewer Roulette – but its implementation, and how\nwe interact with it, has changed significantly. So, what's changed, and what's\nstayed the same?\n\n## The good\n\nFirst off, roulette works really well. Code reviews can be time-consuming, and\nthey're a major part of quality control at GitLab, so it's crucial that we\ndistribute the load – research shows that [review quality nosedives](https://smartbear.com/learn/code-review/best-practices-for-peer-code-review/)\nif you spend too much time doing it. It's even more\nimportant for our maintainers. We try to maintain a ratio of engineers to maintainers of around\n4:1, but if half of the reviews go to a quarter of the maintainers, some will\nexperience it as 6:1, while others will experience it as 2:1.\n\nAlso, people could become familiar with certain reviewers and maintainers and\nhabitually assign their work to the same people. This means that people who had\nbeen maintainers for longer tended to get more reviews. Without the\nrandomization effect of Reviewer Roulette, this led to the creation of knowledge\nsilos, where knowledge about a particular subject would be concentrated in a few\nindividuals, rather than being spread across the organization.\n\nRoulette solved this for us with almost no cognitive load, and could scale\neffortlessly as our engineering team expands significantly. Sometimes, I first\nlearned someone new had joined the company through a review suggestion. The\nnumber and type of reviews a merge request needed was also increasing – I might\nneed to find a reviewer and maintainer for frontend, backend, QA, database,\ndocumentation, and UX concerns before merging. It's a lot to keep track of\nmanually!\n\n## The bad\n\nDespite the advantages of Reviewer Roulette, I used it inconsistently after a\nfew months, and never actually contributed any improvements to the code. The\nintegration with Slack didn't fit my workflow very well because a chat channel\nis the last place I want to be when working on code! I like to treat Slack as\nthe [informal, asynchronous](https://handbook.gitlab.com/handbook/communication/#slack) communication\nchannel it is designed to be, but it is too easy to be sidetracked by ongoing\nconversations when popping in to get a reviewer recommendation.\n\nThen, we began running into deployment problems, and sometimes Reviewer Roulette\njust wasn't available at all. It only took a few failed attempts before I fell\nout of the habit of trying to use it, and we never did get around to making the\ndeployment work with Auto DevOps.\n\nIt turns out that I wasn't the only one having trouble with this iteration of Reviewer Roulette – we found\nthat backend reviews were [very unevenly distributed](https://gitlab.com/gitlab-org/gitlab-foss/issues/53119#note_111796691). Reviewer Roulette wasn't being used widely enough across GitLab for us to experience\nall the benefits, and as we geared up to add many more maintainers, fixing\nthis tool became very important.\n\n## The fix\n\nIn the interim, staff backend engineer on Delivery, [Yorick Peterse](/company/team/#yorickpeterse), introduced\n[Danger bot](https://github.com/danger/danger) into GitLab's CI pipeline and\nused it to enforce a fine set of coding standards that we couldn't quite express\nwith Rubocop.\n\nThe new bot would leave polite messages on our MRs, asking us to write\n[better commit messages](https://docs.gitlab.com/ee/development/contributing/merge_request_workflow.html#commit-messages-guidelines),\nor to seek database review if we'd changed any files in `db/`. That last part got me\nthinking: Why couldn't the Danger bot pick a potential database reviewer for us at the same\ntime? What was stopping it from detecting backend, frontend, or documentation\nchanges, and using Reviewer Roulette to choose reviewers and maintainers right there in\nthe merge request?\n\n[Very little, it turned out](https://gitlab.com/gitlab-org/gitlab/merge_requests/13506#note_175449376):\n\n![Reviewer Roulette in Action](https://about.gitlab.com/images/blogimages/roulette-review.jpg)\n\nBy making Reviewer Roulette happen automatically in the merge request itself, we\nremoved all the barriers that were preventing us from using the tool. I no longer had to be\non Slack to find a reviewer, instead the list was right there in the merge request as\nI went to change the assignee. Danger was guaranteed to run on every pipeline –\nthere were no deployments or environments to worry about, and if it broke,\nfixing it was automatically [high priority](/handbook/engineering/workflow/#broken-master).\n\nContributing changes also became much easier – the code was right there in the\nGitLab repository, and changes took effect immediately (again, no deployments!).\n\n## What's next?\n\nThe ChatOps version of Reviewer Roulette needed access to GitLab's Slack\nworkspace to use and so it wasn't available to most of our community contributors\nbeyond the [core team](/handbook/marketing/developer-relations/core-team/). Moving Reviewer Roulette to Danger doesn't really solve this\nproblem – it doesn't work well on forks of the `gitlab-org/gitlab` project so\ncommunity contributors don't benefit. This problem is something I'd really\nlike to fix in the future, not least because I work on a fork of GitLab\nday-to-day as well.\n\nDanger is a good tool but it does have [some limitations](https://docs.gitlab.com/ee/development/dangerbot.html) –\nin particular, [`danger local`](https://danger.systems/guides/troubleshooting.html#i-want-to-work-locally-on-my-dangerfile)\ndoesn't work for GitLab. This slows down development, since you have to commit\nand push changes to your merge request before you can see the effects.\n\nAnother big problem is that this most recent iteration of Reviewer Roulette only\nworks for the `gitlab` project. None of our satellite projects - `gitaly`,\n`gitlab-workhorse`, `gitlab-pages`, `gitlab-runner`, etc. – can use this\nversion of Reviewer Roulette. Similarly, [users of GitLab haven't\nbenefited from the work we've been doing on Roulette](https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/24938#note_141874188).\nIdeally, we would have built this as a feature within GitLab itself, so everyone\ncould benefit from the tool.\n\nBy building Reviewer Roulette in Danger we've been able to protype and rapidly iterate\nto a solution that is working very well for the `gitlab` project. The next steps\nare to turn Reviewer Roulette [into a feature](https://gitlab.com/groups/gitlab-org/-/epics/1823) that all users of GitLab can benefit from, perhaps by leveraging the [CODEOWNERS file](https://gitlab.com/gitlab-org/gitlab/issues/12137).\n\nDo you have any ideas on how we can better integrate Reviewer Roulette into GitLab? Let us know by commenting [in the epic](https://gitlab.com/groups/gitlab-org/-/epics/1823)\nor by opening a new issue!\n\n[Cover photo](https://unsplash.com/photos/w6OniVDCfn0) by Krissia Cruz on [Unsplash](https://unsplash.com/search/photos/roulette).\n{: .note}\n",[9,923,683],{"slug":1245,"featured":6,"template":686},"reviewer-roulette-one-year-on","content:en-us:blog:reviewer-roulette-one-year-on.yml","Reviewer Roulette One Year On","en-us/blog/reviewer-roulette-one-year-on.yml","en-us/blog/reviewer-roulette-one-year-on",{"_path":1251,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1252,"content":1257,"config":1266,"_id":1268,"_type":14,"title":1269,"_source":16,"_file":1270,"_stem":1271,"_extension":19},"/en-us/blog/second-law-of-complexity-dynamics",{"title":1253,"description":1254,"ogTitle":1253,"ogDescription":1254,"noIndex":6,"ogImage":1058,"ogUrl":1255,"ogSiteName":673,"ogType":674,"canonicalUrls":1255,"schema":1256},"How pursuit of simplicity complicates container-based CI","Simplicity always has a certain player in mind - learn how to avoid antipatterns by ensuring simplicity themes do not compromise your productivity by over-focusing on machine efficiencies.","https://about.gitlab.com/blog/second-law-of-complexity-dynamics","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"When the pursuit of simplicity creates complexity in container-based CI pipelines\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Darwin Sanoy\"}],\n        \"datePublished\": \"2022-05-24\",\n      }",{"title":1258,"description":1254,"authors":1259,"heroImage":1058,"date":1261,"body":1262,"category":752,"tags":1263},"When the pursuit of simplicity creates complexity in container-based CI pipelines",[1260],"Darwin Sanoy","2022-05-24","\n\nIn a GitLab book club, I recently read \"[The Laws of Simplicity](http://lawsofsimplicity.com/),\" a great book on a topic that has deeply fascinated me for many years. The book contains an acronym that expresses simplicity generation approaches: SHE, which stands for \"shrink, hide, embody.\" These three approaches for simplicity generation all share a common attribute: They are all creating illusions - not eliminations.\n\nI've seen this illusion repeat across many, many realms of pursuit for many years. Even in human language, vocabulary development, jargon, and acronyms all simply encapsulate worlds of complexity that still exist, but can be more easily referenced in a compact form that performs SHE on the world of concepts.\n\nAny illusion has a boundary or curtain where in front of the curtain the complexity can be dealt with by following simple rules, but, behind the curtain, the complexity must be managed by a stage manager. \n\nFor instance, when the magic show creates the spectre of sawing people in half, what appears to be a simple box is in fact an exceedingly elaborate contraption. Not only that, but the manufacturing process for an actual simple box and the sawing box are markedly different in terms of complexity. The manufacturing of complexity and its result are essentially the tradeoff for what would be the real-world complexity of actually sawing people in half and having them heal and stand up unharmed immediately afterward.\n\nTo bring this into the technical skills realm, consider that when you leverage a third-party component or API to add functionality, you only need to know the parameters to obtain the desired result. The people maintaining that component or API must know the quantum mechanics detail level of how to perform that work in a reliable and complete way.\n\nDocker containers are a mechanism for embodying complexity, and are used in scaled applications and within container-based CI. When a [CI/CD](/topics/ci-cd/) automation engineer uses container-based CI, it is possible to make things more complex and more expensive when attempting to do exactly the opposite.\n\nAt its core, this post is concerned with how it can happen that pursuing a simpler world through containers can turn into an antipattern - a reversal of desired outcomes - many times, without us noticing that the reversal is affecting our productivity. The prison of a paradigm is secure indeed.\n\n### The Second Law of Complexity Dynamics\n\nOver the years I have come to believe that the pursuit of reducing complexity has similar characteristics to [The Second Law of Thermodynamics](https://www.grc.nasa.gov/www/k-12/airplane/thermo2.html). The net result of a change between mass and energy results in the the same net amount of mass and energy, but their ratio and form have changed. In what I will coin \"The Second Law of Complexity Dynamics,\" complexity is similarly \"conserved,\" it is just reformed.\n\nIf complexity is not eliminated by simplifying efforts, we reduce its impact in a given realm by changing the ratio of complexity and simplicity on each side of one or more curtains. But alas, complexity did not die, it just hid and is now someone else's management challenge. It is important not to think of this as cheating. There is no question that hiding complexity carries the potential for massive efficiency gains when the world behind the hiding mechanisms becomes the realm of specialty skills and specialists. When it truly externalizes the complexity management for one party, the world becomes more simple for that party.\n\nHowever, the devil is in the details. If the hypothesis of \"no net elimination of complexity\" is correct, it is then important where the complexity migrates to. If it migrates to another part of the same process that must also be managed by the same people, then it may not result in a net gain of efficiency. If it migrates out of a previously embodied realm, then, in the pusuit of simplicity, we can actually reduce our overall efficiency when the process is considered as a whole.\n\n### Container-based CI pipelines as a useful case in point\n\nI see the potential for efficiency reversals to crop up in my daily work time and again, and an interesting place where I've seen it lately is in the tradeoff of linking together hyper-specialized modules of code in containers for CI versus leveraging more generalized modules.\n\nIn creating container-based pipelines, I experience the potential for an efficiency reversal I have to consciously manage.\n\nContainers make a simplicity tradeoff by design. They create a full runtime environment for a very single purpose but in doing so they strip back the container internals so far that general compute tasks are difficult inside them. If you step behind their \"complexity embodying\" curtain into the container, their simplistic environment can require more complex code to operate within.\n\nIn GitLab CI pipelines that utilize containers, all the scripts of jobs run inside the containers that are specified as their runtime environment. When one selects a specialized container - such as the alpine git container or the skopeo image management container - the code is subject to the limitations of the shell that container employs (if it has one at all).\n\nContainers were devised to be hyper-specialized, purpose-specific runtimes that assure they can always run and run quickly for scaled applications. However, for many containers this means no shell or a very stripped back shell like busybox sh. It frequently also means not including the package manager for the underlying Linux distribution.\n\nTime and again, I've found myself degrading the implementation of my shell code in key ways that make it more complex, so that it can run under these stripped back shells. In these cases, I do not benefit from the complexity hiding of newer versions of advanced shells like Bash v5. One of the areas is advanced Bash shell expansions, which embody a huge world of complex parsing and avoid a bunch of extraneous utilities. And another is advanced if and case statement comparison logic that processes regular expressions without external utilities and performs many other abstracted comparisons. There are many other areas of the language where this comes into play, but these two stand out.\n\n![](https://about.gitlab.com/images/blogimages/second-law-of-complexity-dynamics-container-pipeline-tradeoffs.png)\n\nSo by having a simpler shell like busybox sh, the simplicities of advanced shell features become *unhidden* and join my side of the curtain. Now I have to manage them in my code. But then, guess what? No package manager means the inability to install other Linux utilities and languages extensions that I could also employ to push that same complexity back out of my space. And, of course, it means installing Bash v5 would be difficult as well.\n\nSo the simplicity proposition of a tightly optimized purpose-specific container can reverse the purported efficiency gains in the very important realm of the code I have to write. It also means I frequently have to break up my code into multiple jobs to utilize the specializations of these containers in a sequence or to transport the results of a specialized container into a fuller coding environment. This increases the complexity of the pipeline as I now have to pass artifacts and variable data from one job to another with a host of additional YAML directives, and sometimes deploy infrastructure (e.g., [Runner caching](https://docs.gitlab.com/ee/ci/caching/#:~:text=For%20runners%20to%20work%20with,GitLab.com%20behave%20this%20way)).\n\nIn the case of CI using containers, when the simplicity tradeoffs move complexity to things I do not maintain, such as base containers, operating system packages, and full shell environments, into things I do maintain, such as CI YAML and Shell Script code, then I am also inheriting long-term complexity maintenance. In the cloud, we know this as undifferentiated heavy lifting.\n\nInterestingly, the proliferation of specialized containers can also require more machine resources and can lengthen processing time as containers are retrieved from registries and loaded and artifacts and source code are copied in and out of each job-based container.\n\n### Simplicity target: Efficiency\n\nIt's easy to lose sight of the amount of human effort and ingenuity being applied to knowing and managing the coding structure, rather than being applied to solving the real automation problems of the CI pipeline. The net complexity of the pipeline can also mean it is hard to maintain an understanding of it even if you are working in it every day - and for newcomers onboarding, it can be many weeks before they fully understand how the system works.\n\nOf course, I can create my own containers for CI pipelines, but now I've added the complexity of container development and continuous updates of the same in order for my pipeline code to be operational and stay healthy. I am still behind the curtain for that container. For teams whose software is not itself containerized, the prospect of learning to build containers just for CI can create a lot of understandable friction to adopting a container-based CI development process. This friction may be unnecessary if we make a key heuristic adaptation.\n\n### Walking the tightwire above the curtain\n\nSo how do I manage the tensions of these multiple worlds of complexity when it comes to container-based pipelines to try to avoid efficiency reversals in the net complexity of the pipeline?\n\nIt is simple. I will describe the method and then the key misapplied heuristic and how to adjust it.\n\n1. I hold that the primary benefits of container-based CI are a) dependency isolation by job (so that you don’t have a massive and brittle CI build machine specification to handle all possible build requirements), and b) clean CI build agent state by obtaining a clean container copy for each job. These benefits do not imply having to abide by microservices container resource planning and doing so is what creates an antipattern in my productivity.\n\n2. I frequently use a Bash 5 container (version pegged if need be) where all the complexity that advanced shell capabilities embody for me stay behind the curtain.\n\n3. Instead of running a hyper-minimalized container for a given utility, I do a runtime install of that utility (gasp!) in a container that has my rich shell. I utilize version pegging during the install if I feel version safety is paramount on the utility. Alternatively, if a very desirable runtime of some type is difficult to setup and does not have a package, I look for a container that has a package manager that matches a packaged version of the runtime and also allows me to install my advanced scripting language if needed.\n\n4. If, and only if, the net time of the needed runtime installs exceeds the net pipeline time to load a string of specialized containers (with artifact handling) plus my time to develop and manage a pipeline dependency in the form of a custom container, then do I consider possibly creating a pipeline specific container.\n\n5. Through this process a balancing principle also emerges. Since I have been doing runtime installs as a development practice, I have actually already MVPed what a pipeline specific container would need to have installed. I can literally copy the installation lines into a Docker file if I wish. I can also notice if I have commonality across multiple pipelines where it makes sense to create a multi-pipeline utility container.\n\nIn a recent project, following these principles caused me to avoid the skopeo container and instead install it on the Bash 5 container using a package manager.\n\nIf your team is big into Python or PowerShell as your CI language, it would make sense to start with recent releases of those containers. The point is not advanced Bash -but an advanced version of your general CI scripting language that prevents you from creating work arounds in your code for problems that are well-solved in publicly available runtimes.\n\nKeep in mind that this adjustment is very, very focused on containers **in CI pipelines**, which, by nature, reflect general compute processing requirements where many vastly different operations are required in a pipeline. I am not advocating this approach for true microservices applications where, by design, a given service has very defined purpose and characteristics and, at scale, massively benefits from the machine efficiency of hyper-minimalized, purpose-specific granularity.\n\n### Misapplied heuristics\n\nFrequently when a pattern has an inflection point at which it becomes an antipattern, it is due to misapplying the heuristics of the wrong realm. In this case, I believe, that normal containerization patterns for microservices apps are well founded, but they apply narrowly to \"engineered hyper-specialized compute\" of a granule we call \"a microservice\" (note the word \"micro\" applies to the scope of compute activities). Importantly, they apply because the process itself is designed as hyper-specialized around a very specific task. The container contents (included dependencies), immutability principle (no runtime change), and the runtime compute resources can be managed exceedingly minimally because of the small and highly specific scope of computing activities that occur within the process.\n\nThis is essentially the embodiment of the 12 Factor App principle called “[VIII. Concurrency](https://12factor.net/concurrency),” which asserts that scaling should be horizontal scaling of the same minimalized process, not vertical scaling of compute resources inside a given process. If the system experiences 10x work for a particular activity, we create 10 processes, we do not request 10x memory and 10x CPU within one running process. Microservices architecture tightly controls the amount of work in each request so that it is hyper-predictable in its compute resource requirements and, therefore, scalable by adding identical processes.\n\nCI compute, by nature, is the opposite of hyper-specialized. Across build, test, package, deploy, etc., etc., there are many huge variations in required machine resources of memory, CPU, network I/O and high-speed disk access and, importantly, included dependencies. The generalized compute nature also occurs due to varying inputs so the same defined process might need a lot more resources due to the nature of the raw input data. For example, varying input volume (e.g. a lot versus few data items) or varying input density (e.g. processing binary files versus text files). \n\nIt is the process that is being containerized that holds the attribute of generalized compute (bursty on at least some compute resources) or hyper-specialized (narrow definition of work to be done and therefore well-known compute resources per unit of completed work). Containerizing a process that exhibits generalized compute requirements is useful, but planning the resources of that container as if containerizing it has transformed the compute requirements into hyper-minimalized is the inflection point at which it becomes an antipattern, actually eroding the sought-after benefits we set out to create.\n\nIn the model I employ for leveraging containers in CI, the loosening of the hyper-specialization, immutablility (no-runtime installs), and very narrow compute resources principles of microservices simply reflects the real world in that CI compute as a whole exhibits the nature of generalized, not hyper-specialized, compute characteristics.\n\n> Another realm where this seems true is desired state configuration management technologies - also known as “Configuration as Code”. It is super simple if there are pre-existing components or recipes for all that you need to do but as soon as you have to build some for yourself, you enter a world of creating imperative code against a declarative API boundary (there's the \"embodiment\" curtain - the declarative API boundary). Generally, if you have not had to implement imperative code to process declaratively, this new world takes some significant experience to become proficient.\n\n### Iterating SA: Experimental improvements for your next project\n\n1. In general, favor simplicity boundaries that reduce your work, especially in the realm of undifferentiated heavy lifting. In the realm of container-based CI, this includes having a rich coding language and a package manager to acquire additional complexity embodying utilities quickly and easily.\n\n2. In general, be suspicious of an underlying antipattern if you have to spend an inordinate amount of time coding and maintaining workarounds in the service of simplicity. In the realm of container-based CI, this would be containers that are ultra-minimalized around microservices performance characteristics when they don’t hyper-scale as a standing service within CI.\n\n3. In general, stand back and examine the net complexity of the code and frameworks that will have to be maintained by yourself or your team and check if you’ve made tradeoffs that have a net negative tax on your efficiency. When complexity that can be managed by machines enters your workspace at high frequency, then you have a massive antipattern of human efficiency.\n\n4. It is frequent that when the hueristics being applied create negative human efficiency they also create negative machine efficiency. Watch for this effect in your projects. The diagram in the post shows that over-minimalized containers can easily lead to using a lot more of them - all of which has machine overhead as well.\n\nIf the above resonates, CI pipeline engineers might want to consider loosening the \"microservices\" heuristics of hyper-specialization, ultra-minimalization,  and immutability (no dynamic installs) for CI pipeline containers in order to ensure that the true net complexity level of the code they have to maintain is in balance and their productivity is preserved.\n\n### Appendix: Working examples of this idea\n\n- [AWS CLI Tools in Containers](https://gitlab.com/guided-explorations/aws/aws-cli-tools) has both Bash and PowerShell Core (on Linux OS) available so that one container set can suit the automation shell preference of both Linux and Windows heritage CI automation engineers.\n\n- CI file [installs yq dynamically](https://gitlab.com/guided-explorations/gl-k8s-agent/gitops/envs/world-greetings-env-1/-/blob/main/.gitlab-ci.yml#L47-48) in the Bash container, but then [only installs the heavier jq and skopeo](https://gitlab.com/guided-explorations/gl-k8s-agent/gitops/envs/world-greetings-env-1/-/blob/main/.gitlab-ci.yml#L63) if needed by the work implied, which demonstrates a way to be more efficient even when runtime installs are desired.\n\n- [Bash and PowerShell Script Code Libraries in Pure GitLab CI YAML](https://gitlab.com/guided-explorations/ci-cd-plugin-extensions/script-code-libraries-in-pure-gitlab-ci-yaml) shows how to have libraries of CI script code available to every container in a pipeline without encapsulating the libraries in a container themselves and with minimalized CI YAML complexity compared to YAML anchors, references, or extends. While the method is a little bit challenging to setup, from then on out it pays back by decoupling scripting libraries from any other pipeline artifact.\n\n- [CI/CD Extension Freemarker File Templating](https://gitlab.com/guided-explorations/ci-cd-plugin-extensions/ci-cd-plugin-extension-freemarker-file-templating) shows the install is very quick and only affects one job and still version pegs the installed utility.\n",[965,1264,710,9,1265],"CD","solutions architecture",{"slug":1267,"featured":6,"template":686},"second-law-of-complexity-dynamics","content:en-us:blog:second-law-of-complexity-dynamics.yml","Second Law Of Complexity Dynamics","en-us/blog/second-law-of-complexity-dynamics.yml","en-us/blog/second-law-of-complexity-dynamics",{"_path":1273,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1274,"content":1280,"config":1285,"_id":1287,"_type":14,"title":1288,"_source":16,"_file":1289,"_stem":1290,"_extension":19},"/en-us/blog/speed-up-code-reviews-let-ai-handle-the-feedback-implementation",{"title":1275,"description":1276,"ogTitle":1275,"ogDescription":1276,"noIndex":6,"ogImage":1277,"ogUrl":1278,"ogSiteName":673,"ogType":674,"canonicalUrls":1278,"schema":1279},"Speed up code reviews: Let AI handle the feedback implementation","Discover how GitLab Duo with Amazon Q automates the implementation of code review feedback through AI, transforming a time-consuming manual process into a streamlined workflow.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659604/Blog/Hero%20Images/Screenshot_2024-11-27_at_4.55.28_PM.png","https://about.gitlab.com/blog/speed-up-code-reviews-let-ai-handle-the-feedback-implementation","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Speed up code reviews: Let AI handle the feedback implementation\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Cesar Saavedra\"}],\n        \"datePublished\": \"2025-06-10\",\n      }",{"title":1275,"description":1276,"authors":1281,"heroImage":1277,"date":1282,"body":1283,"category":704,"tags":1284},[701],"2025-06-10","You know that feeling when you've just submitted a merge request and the code review comments start rolling in? One reviewer wants the labels updated, another asks for side-by-side layouts, someone else requests bold formatting, and don't forget about that button color change. Before you know it, you're spending hours implementing feedback that, while important, takes you away from building new features. It's a time-consuming process that every developer faces, yet it feels like there should be a better way.\n\nWhat if you could have an AI assistant that understands code review feedback and automatically implements the changes for you? That's exactly what [GitLab Duo with Amazon Q](https://about.gitlab.com/blog/gitlab-duo-with-amazon-q-agentic-ai-optimized-for-aws/) brings to your development workflow. This seamless integration combines GitLab's comprehensive DevSecOps platform with Amazon Q's advanced AI capabilities, creating an intelligent assistant that can read reviewer comments and converts them directly into code changes. Instead of manually addressing each piece of feedback, you can let AI handle the implementation while you focus on the bigger picture.\n\n## How GitLab Duo with Amazon Q works\n\nWhen you're viewing a merge request with reviewer comments, you'll see feedback scattered throughout your code. Let's take the examples from earlier in this article: maybe you've received a request to update a form label here, a suggestion to display fields side-by-side there, or a note about making certain text bold. Each comment represents a task that normally you'd need to handle manually.\n\n![feedback on an MR](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749673634/Blog/Content%20Images/1-show-comment.png)\n\nWith GitLab Duo with Amazon Q, you can simply enter the `/q dev` quick action in a comment. This prompts Amazon Q to analyze all the feedback and start modifying your code automatically. The AI agent understands the context of each comment and implements the requested changes directly in your codebase.\n\n![/q dev function prompting Amazon Q to analyze feedback](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749673634/Blog/Content%20Images/2-invoke-q-dev.png)\n\nOnce Amazon Q processes the feedback, you can view all the updates in the \"Changes\" tab of your merge request. Every modification is clearly visible, so you can verify that the AI agent correctly interpreted and implemented each piece of feedback. You can then run your updated application to confirm that all the changes work as expected — that form label is updated, the fields are displayed side-by-side, the text is bold, and yes, that button is now blue.\n\nWatch the code review feedback process in action:\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/31E9X9BrK5s?si=ThFywR34V3Bfj1Z-\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\nProcessing code review feedback is a necessary but time-intensive part of software development.  GitLab Duo with Amazon Q evolves this manual process into an automated workflow, dramatically reducing the time between receiving feedback and implementing changes. By letting AI handle these routine modifications, you're free to focus on what really matters — building innovative features and solving complex problems.\n\nWith GitLab Duo with Amazon Q, you can:\n- Eliminate hours of manual feedback implementation\n- Accelerate your code review cycles\n- Maintain consistency in how feedback is addressed\n- Reduce context switching between reviewing comments and writing code\n- Ship features faster with streamlined deployment times\n\n> #### To learn more about GitLab Duo with Amazon Q visit us at an upcoming [AWS Summit in a city near you](https://about.gitlab.com/events/aws-summits/) or [reach out to your GitLab representative](https://about.gitlab.com/partners/technology-partners/aws/#form).\n\n## GitLab Duo with Amazon Q resources\n\n- [GitLab Duo with Amazon Q: Agentic AI optimized for AWS generally available](https://about.gitlab.com/blog/gitlab-duo-with-amazon-q-agentic-ai-optimized-for-aws/)\n- [GitLab and AWS partner page](https://about.gitlab.com/partners/technology-partners/aws/)\n- [GitLab Duo with Amazon Q documentation](https://docs.gitlab.com/user/duo_amazon_q/)\n- [What is agentic AI?](https://about.gitlab.com/topics/agentic-ai/)\n- [Agentic AI guides and resources](https://about.gitlab.com/blog/agentic-ai-guides-and-resources/)",[707,708,482,709,9,710],{"slug":1286,"featured":91,"template":686},"speed-up-code-reviews-let-ai-handle-the-feedback-implementation","content:en-us:blog:speed-up-code-reviews-let-ai-handle-the-feedback-implementation.yml","Speed Up Code Reviews Let Ai Handle The Feedback Implementation","en-us/blog/speed-up-code-reviews-let-ai-handle-the-feedback-implementation.yml","en-us/blog/speed-up-code-reviews-let-ai-handle-the-feedback-implementation",{"_path":1292,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1293,"content":1298,"config":1303,"_id":1305,"_type":14,"title":1306,"_source":16,"_file":1307,"_stem":1308,"_extension":19},"/en-us/blog/the-code-review-struggle-is-real-heres-what-you-need-to-know",{"title":1294,"description":1295,"ogTitle":1294,"ogDescription":1295,"noIndex":6,"ogImage":832,"ogUrl":1296,"ogSiteName":673,"ogType":674,"canonicalUrls":1296,"schema":1297},"The code review struggle is real. Here's what you need to know","If it's time for a DevOps Platform, don't forget the role code review plays. Our 2021 Global DevSecOps Survey showed why it's both critical and tricky to get right.","https://about.gitlab.com/blog/the-code-review-struggle-is-real-heres-what-you-need-to-know","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"The code review struggle is real. Here's what you need to know\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Valerie Silverthorne\"}],\n        \"datePublished\": \"2021-09-03\",\n      }",{"title":1294,"description":1295,"authors":1299,"heroImage":832,"date":1300,"body":1301,"category":681,"tags":1302},[858],"2021-09-03","\n_Our [2022 Global DevSecOps Survey](https://about.gitlab.com/developer-survey/previous/2022/) is out now! Learn the latest in DevOps insights from over 5,000 DevOps professionals._\n\nWhen making a list of the reasons to consider moving to a DevOps Platform, don't forget about code review, a critical piece of the process that's also an incredible source of frustration and delays to developers and their teams.\n\nIn our [2021 Global DevSecOps Survey](/developer-survey/), respondents told us code quality was the number one reason they chose DevOps. But, when asked what was most likely to delay a product release, code review – vital to code quality – was one of the top four culprits (the others were testing, planning and code development). \n\nThe fact that code review is a pain point is hardly surprising, given that it can often require context-switching, communication, collaboration, and of course subject matter expertise. At a time when it's never been more urgent to release secure code as quickly as possible, it's not a stretch to think code reviews can feel like a hard stop to some teams, particularly if the process is not integrated into an existing workflow.\n\n**[Here's everything you need to know about a [DevOps Platform](/topics/devops-platform/)]**\n\n## Why code review is painful\n\nIn fact, when we asked our survey respondents to tell us in their own words what they struggle with when it comes to code review, they had \\*a lot\\* to say on the subject.\n\n*\"Code reviews can take a long time due to the lack of reviewers.\"*\n\n*\"Many people find it a chore to review code.\"*\n\n*\"We have a strict code review process and it often takes several days for the reviewer to respond to requests for review.\"*\n\n*\"Code review takes time and every developer has to explain how they achieved what they did.\"*\n\n*\"Developers are sometimes unaware they have to do code reviews. They aren't sure how to perform them and if they are effective. Sometimes they are skipped so the process can go through.\"*\n\n*\"Finding someone for code review can be hard (1-day average). After that, business tests take time to be completed (2-4 days on average).\"*\n\n[Code review is tricky](/blog/challenges-of-code-reviews/), but almost 60% of those surveyed said the reviews were \"very valuable\" in ensuring code quality and security. And it's not like teams aren't actually tackling code review: In 2021 close to 45% of respondents said they review code weekly, and 22% do it every other week – a 14% jump from 2020.\n\n**[Your organization needs a DevOps Platform team. [Here's why](/topics/devops/how-and-why-to-create-devops-platform-team/)]**\n\nBut anecdotal data tells a slightly different story, from developers saying their teams do no code review at all, to code reviews so comprehensive they include every merge request, ticket, or pull. Many developers said they review code daily, or even multiple times a day. Survey takers said code reviews were most likely conducted using online chat, with developers showing a strong preference for reviewing code in an IDE rather than a browser.\n\n## Better code reviews\n\nAt GitLab we pride ourselves in dogfooding our DevOps Platform, so of course we spend a lot of time thinking about how to [improve our code review process](/blog/better-code-reviews/). We've had a lot of success [using smaller merge requests](/blog/iteration-and-code-review/), as just one example.\n\nOur survey takers told us they were on the same continuous improvement journey – many spent the past year [evaluating how to make their code reviews and other DevOps stages more efficient](/blog/efficient-code-review-tips/). One respondent offered a detailed look:\n\n*\"We evaluated the team and did value stream mapping and finalized the desired state. In most of the cases we found the team needs an automated pipeline for faster delivery and immediate feedback so that they can act fast rather than later. We also moved security left so that developers can fix security issues fast. And we also made sure developers are doing code review in a collaborative way through pull requests.\"*\n\nAnother team focused exclusively on reducing its dependence on code review:\n\n*\"(We are no longer) relying on code review to have caught all the test scenarios. We now use a coverage scanning tool to tell us if we've got it all.\"*\n\n## More code reviews > less code reviews\n\nThe struggle is real, but so is the importance. Despite a lot of complaining about code review, developers remained adamant about its importance in DevOps. When we asked devs what they wish they could do more of, code review was at the top of the list, with more than 1000 survey takers indicating they wish they could do way more code reviews than they're doing at present.\n\nIn our next blog post, we'll outline five ways GitLab's DevOps Platform has made code reviews easier.\n\n_Our [2022 Global DevSecOps Survey](/developer-survey/) is out now! Learn the latest in DevOps insights from over 5,000 DevOps professionals._\n",[9,683,841],{"slug":1304,"featured":6,"template":686},"the-code-review-struggle-is-real-heres-what-you-need-to-know","content:en-us:blog:the-code-review-struggle-is-real-heres-what-you-need-to-know.yml","The Code Review Struggle Is Real Heres What You Need To Know","en-us/blog/the-code-review-struggle-is-real-heres-what-you-need-to-know.yml","en-us/blog/the-code-review-struggle-is-real-heres-what-you-need-to-know",{"_path":1310,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1311,"content":1316,"config":1321,"_id":1323,"_type":14,"title":1324,"_source":16,"_file":1325,"_stem":1326,"_extension":19},"/en-us/blog/tips-for-better-code-review",{"title":1312,"description":1313,"ogTitle":1312,"ogDescription":1313,"noIndex":6,"ogImage":722,"ogUrl":1314,"ogSiteName":673,"ogType":674,"canonicalUrls":1314,"schema":1315},"How to write a more thoughtful code review","The best code reviews are empathetic and fair. We explain best practices for providing feedback.","https://about.gitlab.com/blog/tips-for-better-code-review","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How to write a more thoughtful code review\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"David O'Regan\"}],\n        \"datePublished\": \"2021-03-09\",\n      }",{"title":1312,"description":1313,"authors":1317,"heroImage":722,"date":1318,"body":1319,"category":752,"tags":1320},[727],"2021-03-09","\n\nThis post is adapted from a [GitLab Unfiltered blog post](/blog/better-code-reviews/) written by [David O'Regan](/company/team/#oregand).\n{: .note .alert-info .text-center}\n\nFeedback matters to our personal and professional lives and software is no different. We deliver most if not all of our feedback to one another at GitLab using code reviews. We’re sharing some of our tools for you to add to your toolbelt when it comes to code reviews. In this post (the first of a three-part series) we share communication strategies for authors and reviewers.\n\n## Remember: Details matter for self-reviews\n\nAt GitLab, the [responsibility for the code lies with the merge request author](https://docs.gitlab.com/ee/development/code_review.html#the-responsibility-of-the-merge-request-author). We suggest code authors create a checklist to ensure that your i’s are dotted and your t’s are crossed before requesting a review. Here is an example MR checklist:\n\nBefore every feedback cycle:\n\n*   Re-read every line.\n*   Test your code locally.\n*   Write a test for every change (or as many as you can).\n*   Write a clear description and update it after each feedback cycle.\n*   Include at least one screenshot per change. More is better.\n*   Check and re-check your [labels](https://docs.gitlab.com/ee/user/project/labels.html). Then check them again.\n*   Consider using a ~\"workflow::refinement\" label for issues ahead of time as we do in the [Monitor:Health team](/handbook/engineering/development/ops/monitor/respond/). Read the documentation to [learn more about scoped labels](https://docs.gitlab.com/ee/user/project/labels.html#scoped-labels).\n*   Review the code as if you were the reviewer. Be proactive, answer the likely questions, and open follow-up issues ahead of time.\n*   If you want to see the last and most important part in the action, see how one of our frontend maintainers [Natalia Tepluhina](/company/team/#ntepluhina) [pre-answered a question she knew would be asked in one of her merge requests](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33587#note_353564612).\n\n## Communicate with good intentions\n\nOne of the hardest parts of getting a code review right is communicating the human touch. When we give and receive feedback, human habit can create cognitive distortion by defaulting to the most negative aspects of that feedback. At GitLab, we try to highlight the importance of assuming positive intent by incorporating it in our [value system](https://handbook.gitlab.com/handbook/values/#assume-positive-intent).\n\n### How the conventional comments system can help in code review\n\nTo give feedback more effectively, try the [conventional comments system](https://conventionalcomments.org/), which was developed by senior frontend engineer, [Paul Slaughter](/company/team/#pslaughter). The conventional comments system calls for writing comments in a way that is useful for the reviewer and author of the merge request. It's so popular that one person made a browser extension (Chrome, Firefox) for it.\n\nThe convention comment system calls for starting a comment with a single, eye-catching word that defines the intent and tone for the comment. This method gives the reader a chance to understand where your comment is coming from.\n\nLet's try an experiment. If you submitted code for review, which comment would you prefer to read?\n\nOption one: What do you think about X instead?\n\nOption two: **suggestion (non-blocking)**\nWhat do you think about X instead?\n\nYou likely chose option two because it provided context for the comment, communicated empathy, and was framed as an invitation to try a different approach, instead of being written as a command or mandatory change.\n\nThe magic part of this comment is the first line **suggestion (non-blocking)**. Straight away, before you even read the comment, you know the two most important things about it:\n\n*   It's a suggestion from the reviewer\n*   It's non-blocking. Which means it's more of a friendly suggestion than a hard change that's necessary for the stability of the code.\n\nAnother advantage to this style of commenting is it allows merge request authors to understand the reviewer is not blocking their work. By highlighting what counts as a blocking and non-blocking comment, merge authors get the full context of what the reviewer is trying to communicate.\n\nFor example, you have submitted a merge request for review and your review comes back with eight comments.\n\nThe first option has no context in the comments. All comments are treated equally because they lack context for what counts as a blocker and what doesn't.\n\nOption two contextualizes comments using the conventional comments system. The comments can be treated by priority:\n\n*   Blockers: What needs to get the merge over the line.\n*   Non-blockers: What can be a separate merge or perhaps will spark a discussion.\n\nNext time you're reviewing code, try using the conventional comments approach. Pay attention to how it affects the way the merge request author responds to the review but also how you, the reviewer, feel leaving the review. We are considering integrating this feature directly into GitLab because we believe in making GitLab the best possible place for code reviews.\n\nIf you want to see a real-life example of some of Paul's work using conventional comments, check out [his reviews of my community contributions](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/24897) here at GitLab – you’ll see his empathy really shines through.\n\n## The role of \"fairness\" in code review\n\nIn many ways, code review is a form of negotiation, where the result of the negotiation is a selection of code that's valuable and held to a high standard. Central to being a good code reviewer (and good negotiator) is fairness. In fact, being a fair negotiator is often the most useful tool for code authors and code reviewers.\n\nFairness is actually mentioned twice in the [permissions to play guidelines](https://handbook.gitlab.com/handbook/values/#permission-to-play) at GitLab:\n\n*   \"Be dependable, reliable, fair, and respectful.\"\n*   \"Seek out ways to be fair to everyone.\"\n\n### How to be a fair author\n\nIn many ways, being a fair author is the easiest. Here are a few simple Dos and Don'ts to remember:\n\n**Do:**\n\n*   Write a proper description with screenshots (can't stress this one enough!)\n*   Understand a reviewer’s point of view when they make suggestions\n*   Address any strange parts of your merge upfront (we all have them)\n*   Be [open to collaboration](https://handbook.gitlab.com/handbook/values/#collaboration) on your work\n\n**Don't:**\n\n*   \"plz merge\"\n*   Be closed off or take offense to suggestions\n*   Forget to include any steps necessary for the build to run (or in other words, reduce the burden where possible)\n\nHonestly, it's pretty simple to be a fair author of a merge request. Even the smallest amount of empathy goes a long way, particularly when you remember that the person reviewing your code gets nothing extra for their efforts. They just want to help take your merge to the next level.\n\n### How to be a fair reviewer\n\nBeing fair as a reviewer is a bit more challenging because every individual has opinions or biases about how a piece of code should be written. Bias is something we all deal with when it comes to how we want things to be because we all have our own styles, preferences, and ideas about how software should be written.\n\nBias can create problems when it comes to code reviews because it's common for personal preferences to emerge when reviewing someone else's code. The typical reviewer might catch themselves thinking in absolutes, and the number of unresolved comments grows.\n\nIf you have ever reviewed a merge request and found yourself thinking things like:\n\n*   \"It should be written like this\"\n*   \"Why would they do it like that?\"\n*   \"I would have done it this way\"\n*   \"That's not how that should be done!\"\n\nIf this sounds familiar, then you may have fallen victim to a common cognitive distortion: Should/must statements.\n\nIt is important for any reviewer to remember that just because a code author wrote code in a different style or manner from you, doesn't mean that the code is written incorrectly. If you catch yourself writing a review comment that includes the words \"should\" or \"must\" then you ought to take a step back and think about whether your suggestions are coming from a place of fairness or a place of bias. Ask yourself: Is the use of absolutes warranted here? Sometimes it will be both fair and warranted. One example is if your company follows a set of coding conventions like we do at GitLab. Stay vigilant for times when those statements are a thin veil for a personal preference.\n\nIf you do need to use a should/must statement, be sure to back up your assertions with documentation to help the code author understand why a change must be made.\n\nTypically, the fair response to something you don't agree with is to ask _why_ an author wrote code this way, instead of saying it must be another way.\n\nThis is part one of a three-part series on code review. Up next we will be explaining why patch files are a useful tool for reviewers.\n\nIf you have questions or comments about code reviews, creating smaller MRs, or iteration, leave us a comment on this blog post!\n\n_Sara Kassabian contributed to this blog post._\n\nCover image by [Jackson Simmer](https://unsplash.com/@simmerdownjpg) on [Unsplash](https://unsplash.com/photos/Vqg809B-SrE).\n{: .note}\n",[9],{"slug":1322,"featured":6,"template":686},"tips-for-better-code-review","content:en-us:blog:tips-for-better-code-review.yml","Tips For Better Code Review","en-us/blog/tips-for-better-code-review.yml","en-us/blog/tips-for-better-code-review",{"_path":1328,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1329,"content":1335,"config":1341,"_id":1343,"_type":14,"title":1344,"_source":16,"_file":1345,"_stem":1346,"_extension":19},"/en-us/blog/top-10-ways-machine-learning-may-help-devops",{"title":1330,"description":1331,"ogTitle":1330,"ogDescription":1331,"noIndex":6,"ogImage":1332,"ogUrl":1333,"ogSiteName":673,"ogType":674,"canonicalUrls":1333,"schema":1334},"Top 10 ways machine learning may help DevOps","Is machine learning part of your DevOps plan? Here are some ways ML could fit right in.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749668426/Blog/Hero%20Images/retrospectivesgitlabpost.jpg","https://about.gitlab.com/blog/top-10-ways-machine-learning-may-help-devops","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Top 10 ways machine learning may help DevOps\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"GitLab\"}],\n        \"datePublished\": \"2022-02-14\",\n      }",{"title":1330,"description":1331,"authors":1336,"heroImage":1332,"date":1338,"body":1339,"category":816,"tags":1340},[1337],"GitLab","2022-02-14","_This post is meant as a general introduction to DevOps and machine learning, but does not represent GitLab’s roadmap with ModelOps. Read more about [our ModelOps plans](/blog/introducing-modelops-to-solve-data-science-challenges/)._\n\nLike a superhero’s cape, machine learning can enhance the innate powers of your DevOps program. \n\nYes, it’s early days, and no, machine learning can’t do everything you may want it to – yet. But if you [start using ML tools now](/topics/devops/the-role-of-ai-in-devops/), you’ll be poised to make it a full-fledged participant in your DevOps team as the technology continues to mature. Here are some things ML can help with today.\n\n1. **Make sense of your test data.** Whether it’s regression, unit, functional, or user acceptance testing, ML can help sort through the data generated from those tests, find patterns, figure out the coding problems that caused any bugs, and alert the troops. \n\n2. **Manage your help-desk alerts.** You can teach ML about the factors that make up different types of alerts and automatically route alerts to the best-qualified (mostly human) problem-solver, be it the service desk or a networking guru. Some ML systems can also fix problems without human intervention, based on rules you create.\n\n3. **Put the security into “DevSecOps.”** ML algorithms can, in real time, look through the massive amount of information generated from your security software and network logs and determine if there’s a breach long before a human could. The ML software compares the usual network-traffic baseline to what it’s seeing currently and detects when there’s an attack, or it can tell you if the amount of code in an app or system has suddenly grown to double its size when it shouldn’t have. ML can also triage the problems it finds, as well as take actions to correct security issues based on your guidelines. Further, ML tools can also help ensure your governance rules are followed and create a detailed audit trail.\n\n4. **Gather user requirements.** Natural language processing has come a long way, and can collect, validate, and track documents to streamline the process of figuring out what users are asking for. The technology can also help detect incomplete requirements or wonky timelines and can translate user wants and needs into highly technical project requirements. This makes the entire project-management process more efficient.\n\n5. **Help with pesky dev details.** No, not to replace developers, of course – at least not yet. But ML can learn from past apps you’ve created to recommend security guardrails and how to make software scale and perform better, among other things. Developers definitely see this trend coming, and in [GitLab’s 2021 Global DevSecOps Survey](/developer-survey/), around a third said that an understanding of AI or ML is the most important skill for their future careers. ML-powered code completion tools are already on the market, which provide suggestions for app developers.\n\n6. **Automate testing and create test data.** ML can automatically create the tests you need for QA and the test cases they’re based on, generate and manage test data, and automate code reviews. Natural language processing can help you review test cases and eliminate duplicates, as well as identify gaps in test coverage. Teams will continue to use machine learning models to [make test automation smarter](https://www.forrester.com/blogs/predictions-2021-software-developers-face-mounting-pressure/) , Forrester Research predicts.\n\n7. **Reduce complexity and allow better communication throughout the software chain.** ML can smooth out the rough edges among teams responsible for different parts of the process, and act as an Esperanto of sorts to allow people to speak to each other using the same language. No more, “It worked on my machine.” \n\n8. **Save time on manual provisioning.** Sure the cloud makes this easier, but ML can provision what it thinks you’ll need before you actually need it. \n\n9. **Improve software and product quality.** ML can help find issues like resource leaks, wasted CPU cycles, and other problems, so you can optimize your code before it hits production. At Facebook, [a bug detection tool](https://www2.deloitte.com/us/en/insights/focus/signals-for-strategists/ai-assisted-software-development.html/#:~:text=AI%20is%20helping%20to%20make%20better%20software%20Professionals%20are%20using,in%20design,%20development,%20and%20deployment&text=Artificial%20intelligence%20isn't%20writing,develop%20and%20test%20custom%20software.) predicts defects and suggests remedies that prove correct 80% of the time, Deloitte reports. And the IEEE ran a study from Google X about an ML method that [predicts failures of individual components](https://ieeexplore.ieee.org/document/7448033) that was “far more accurate than the traditional MTBF approach.” \n\n10. **Integrate your workflows and allow continuous improvement.** Some DevOps teams are using ML to analyze all development, operational, and test tools to find any gaps, as well as where pieces of the pipeline need to be better integrated and where APIs are still needed. ML algorithms can help teams figure out why some projects go very well, and others don’t. You can use ML to monitor your monitors and make sure they’re fully operational. Further, ML continues to learn from its training models – both the ones you provide and those it learns on its own as it goes – to continue to help you provide better products and services over time. And when you get down to it, isn’t that the whole point of technology?\n\n_Our [2022 Global DevSecOps Survey](/developer-survey/) is out now! Learn the latest in DevOps insights from over 5,000 DevOps professionals._",[683,9,841,706],{"slug":1342,"featured":6,"template":686},"top-10-ways-machine-learning-may-help-devops","content:en-us:blog:top-10-ways-machine-learning-may-help-devops.yml","Top 10 Ways Machine Learning May Help Devops","en-us/blog/top-10-ways-machine-learning-may-help-devops.yml","en-us/blog/top-10-ways-machine-learning-may-help-devops",{"_path":1348,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1349,"content":1355,"config":1360,"_id":1362,"_type":14,"title":1363,"_source":16,"_file":1364,"_stem":1365,"_extension":19},"/en-us/blog/top-reasons-for-software-release-delays",{"title":1350,"description":1351,"ogTitle":1350,"ogDescription":1351,"noIndex":6,"ogImage":1352,"ogUrl":1353,"ogSiteName":673,"ogType":674,"canonicalUrls":1353,"schema":1354},"Top reasons for software release delays","In our 2022 Global DevSecOps survey, DevOps pros shared their frustrations with software releases, including security's shift left and complicated code reviews.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664070/Blog/Hero%20Images/cloudwatch-gitlab-incident-management-bg.jpg","https://about.gitlab.com/blog/top-reasons-for-software-release-delays","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Top reasons for software release delays\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Valerie Silverthorne\"}],\n        \"datePublished\": \"2022-08-30\",\n      }",{"title":1350,"description":1351,"authors":1356,"heroImage":1352,"date":1357,"body":1358,"category":681,"tags":1359},[858],"2022-08-30","\n_What’s the most likely reason for a software release delay?_\n\nFrom 2019 through 2021, respondents to our Global DevSecOps Surveys _always_ blamed software testing. This year, however, was dramatically different.\n\nMore than 5,000 DevOps practitioners took our [2022 Global DevSecOps Survey](https://about.gitlab.com/developer-survey/previous/2022/), and, for the first time, they offered five equally valid reasons why releases might be tardy: code development, code review, security analysis, test data management, and, of course, testing. \n\nProcesses and priorities are clearly changing in DevOps teams today, and they’re affecting release delays. Here’s how to understand the forces at work.\n\n> Join us at [GitLab Commit 2022](/events/commit/) and connect with the ideas, technologies, and people that are driving DevOps and digital transformation.\n\n## Code development and code review\n\nOver the past three years, code development and code review were the second- and third-ranked culprits for release delays. That’s to be expected: No one ever said code development was easy and code reviews have always been problematic.\n\nDevelopers report [a myriad of challenges with code review](/blog/the-code-review-struggle-is-real-heres-what-you-need-to-know/): It’s too labor intensive, no one is available to do it, and the culture often doesn’t support the process. But in this year’s survey, 76% of developers said they find code reviews “very” or “somewhat” valuable, and a majority said code review was one of the key steps in DevOps they wish they could do more of. All told, 27% of developers review code weekly while another 21% review it daily or with every commit.\n\nClearly, code review is important but [it takes work](/blog/tips-for-better-code-review/) to make them happen more efficiently. One up-and-coming solution that could help make code reviews easier is artificial intelligence. Our survey found 31% of DevOps teams use AI for code review today, more than double the percentage in 2021. GitLab is also excited about the possibilities found in AI’s close cousin machine learning – we’re using it to [improve the code review process](/blog/the-road-to-smarter-code-reviewer-recommendations/). \n\n## Keeping software secure\n\nCreating safe code requires security testing and the frustration around this step is both real and longstanding. Security has nearly always [been seen as a “blocker”](/blog/developer-security-divide/) when it comes to software development in general and software releases in particular. In our 2022 survey, though, priorities have changed. Security is now the top area DevOps teams plan to invest in this year, and a majority of developers report that the most difficult part of their job is keeping software secure. Here’s just a sample of what developers had to say about the challenges of their roles today: \n\n_We are trying to keep up with the latest tools and security for optimal performance and privacy._\n\n_We are trying to build applications that are secure and stable._\n\n_It is challenging to keep it secure and keep it updated._\n\n_Cyber security attacks are the biggest challenge facing us today._\n\n_Data security, data security, I repeat, data security._\n\nThe focus on security isn’t just talk, either. More than 50% of DevOps teams are running SAST, DAST, and container scans, all dramatic increases from 2021. But at the same time, this is the fourth year security pros have continued to blame developers for finding too few bugs too late in the process. Security is a developer performance metric for many teams, but sec team members say it is still very hard to get devs to actually fix bugs, a trend we’ve seen reflected over and over.\n\nIn other words, it’s complicated enough to make the potential of delays unsurprising.\n\n## Managing the test data\n\nToo much test data is one of those good and bad problems to have: 47% of DevOps teams we surveyed report full test automation, nearly double the percentage from last year, and more security scans are being run too. More than half of survey takers (53%) are testing their code as it’s being written, up 21% from last year.\n\nAll those tests result in a data management problem most teams aren’t actually set up to handle. Here’s one example: Less than one-third of teams are able to put DAST and SAST results into a developer’s workflow/IDE and those percentages remain stubbornly low year after year. \n\nTesting momentum and automation are growing by leaps and bounds, but teams now need better ways to evaluate, communicate, and act on the data.\n\n## The tricky nature of software testing\n\nSoftware testing has often worn the “DevOps scapegoat” mantle, and perhaps for good reason. Getting testing just right is critical, but it’s also elusive. There are so many kinds of tests teams can run, test automation requires a big process and culture investment, and test results are often seen as “flaky,” “noisy,” and “late” by busy developers not enthused about context switching or inaccurate results. \n\nBut there are a couple of promising signs: As we saw in 2021, developer respondents told us again this year that testing is high on their list of tasks they would like to do more of. And artificial intelligence is also making inroads: About 37% of teams are using AI/ML to test their code (a 23-point jump from 2021) and 20% more are planning to add it to their DevOps practice this year.\n\nWant to understand more about software release delays and DevOps best practices? Read our [2022 Global DevSecOps Survey](/developer-survey/).\n",[841,9,1067,683],{"slug":1361,"featured":6,"template":686},"top-reasons-for-software-release-delays","content:en-us:blog:top-reasons-for-software-release-delays.yml","Top Reasons For Software Release Delays","en-us/blog/top-reasons-for-software-release-delays.yml","en-us/blog/top-reasons-for-software-release-delays",{"_path":1367,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1368,"content":1374,"config":1380,"_id":1382,"_type":14,"title":1383,"_source":16,"_file":1384,"_stem":1385,"_extension":19},"/en-us/blog/transform-code-quality-and-compliance-with-automated-processes",{"title":1369,"description":1370,"ogTitle":1369,"ogDescription":1370,"noIndex":6,"ogImage":1371,"ogUrl":1372,"ogSiteName":673,"ogType":674,"canonicalUrls":1372,"schema":1373},"Transform code quality and compliance with automated processes","Learn how GitLab Premium features address the technical debt and security vulnerability challenges that plague traditional approaches.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749660151/Blog/Hero%20Images/blog-image-template-1800x945__26_.png","https://about.gitlab.com/blog/transform-code-quality-and-compliance-with-automated-processes","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Transform code quality and compliance with automated processes\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Jessica Hurwitz\"}],\n        \"datePublished\": \"2024-12-13\",\n      }",{"title":1369,"description":1370,"authors":1375,"heroImage":1371,"date":1377,"body":1378,"category":707,"tags":1379},[1376],"Jessica Hurwitz","2024-12-13","While manual code review processes may suffice for a small team, as DevSecOps teams scale, the processes create significant bottlenecks that impede software development velocity and quality. Often slow, inconsistent, and frequently failing to catch critical vulnerabilities, the manual approach leads to technical debt and increased security risks.\n\nTo mitigate risks and drive innovation, organizations must prioritize automated code quality and compliance systems. The financial implications of poor code management are substantial, with technical debt consuming up to 40% of IT budgets ([McKinsey Digital: Tech Debt Report](https://www.mckinsey.com/capabilities/mckinsey-digital/our-insights/tech-debt-reclaiming-tech-equity)) and software vulnerabilities costing an average of $4.88 million per security breach ([IBM Cost of a Data Breach Report](https://www.ibm.com/reports/data-breach)). \n\nModern software development requires a strategic approach to code management and compliance that goes beyond traditional review processes. With more robust review systems and compliance controls, organizations can innovate and secure software faster than their competitors.\n\n## The power of code review and approval processes\n\nAccording to the [GitLab 2024 Global DevSecOps Report](https://about.gitlab.com/developer-survey/), C-level executives rank code quality as one of the top benefits of DevSecOps. With executives recognizing code quality as a strategic priority, systematic review processes have emerged as a cornerstone of modern development practices. \n\n[Code review](https://about.gitlab.com/topics/version-control/what-is-code-review/) processes benefit developers through knowledge sharing, the discovery of bugs earlier in the process, and improved security. However, developers say the top changes that could be made to improve job satisfaction are increasing automation and collaboration, according to our survey.\n\nAs code quality and code review processes are embedded into the software development lifecycle, focusing on systems that remove manual code review and enhance collaboration across teams will help keep developer workflows running smoothly. \n\n### Code review processes increase collaboration and development speed\n\nThe improvement in organizational efficiency can be seen in this example with [Airbus Intelligence](https://about.gitlab.com/customers/airbus/), a leader in the geospatial industry. The development teams at Airbus struggled with inefficient processes and needed tools that could help their team collaborate efficiently across the globe. After adopting GitLab Premium, Airbus quickly noticed the improvement in code quality. \n\nGitLab CI’s built-in security testing meant developers could identify bugs and vulnerabilities before they reached production. Instead of spending a full day setting up for production and doing manual tests, those simple tasks are now automated. \n\nAirbus’ release time dramatically decreased from 24 hours to just 10 minutes. \n\n“What used to happen is we would touch one part of the code and it would break another part. Now, each time a developer pushes code, we can immediately identify problems,” said Logan Weber, Software Automation Engineer at Airbus Defense and Space, Intelligence.\n\n### Features that enable higher code quality\n\nPowerful GitLab Premium features like [Multiple Approvers for Merge Requests](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/rules.html), [Code Quality](https://docs.gitlab.com/ee/ci/testing/code_quality.html) checks integration with third-party code quality solutions, and [Protected Branches](https://docs.gitlab.com/ee/user/project/repository/branches/protected.html), enable companies to innovate faster than their competitors. \n\nBy reducing review cycle times while strengthening code integrity and compliance, DevSecOps teams address both the technical debt and security vulnerability challenges that plague traditional approaches. These security benefits help teams like AirBus Intelligence develop faster, more secure solutions.  \n\n## Why enhanced compliance controls matter\n\nThe implementation of effective code compliance strategies is constantly evolving due to [changing regulations](https://about.gitlab.com/blog/meet-regulatory-standards-with-gitlab/), and keeping up with these regulations is a challenge for most companies. \n\nBy developing code compliance strategies and automated control mechanisms, companies ensure that quality and compliance policies are met. \n\nFor Airbus Intelligence, security and vulnerability scans built into integration testing enabled teams to catch security and compliance issues earlier in the process.\n\n[Continuous integration](https://about.gitlab.com/topics/ci-cd/#what-is-continuous-integration-ci) gives teams visibility into more projects and allows all team members to manage deployments. Expanded access controls improve cross-team collaboration and accountability. \n\n### Features that increase accountability \n\nGitLab Premium's [advanced compliance controls](https://about.gitlab.com/solutions/security-compliance/) create an unbroken chain of accountability throughout the development process, enabling organizations to systematically track and validate every code change.\n\nUsers have greater auditability of any change and can track commits. This is in addition to strict [access controls](https://docs.gitlab.com/ee/administration/settings/visibility_and_access_controls.html) that provide specific people with the ability to push and merge changes. With [audit logs](https://docs.gitlab.com/ee/user/compliance/audit_event_types.html), users can track and review changes and activities within the repository.\n\n## Ship software faster with GitLab Premium\n\n“It’s simple. All teams operate around this one tool. Instantly, that made communication easier. We wouldn’t be where we are today if we didn’t have GitLab in our stack,” according to Airbus' Weber.\n\nGitLab Premium represents more than just a tool — it's a comprehensive approach to software engineering that empowers development teams to deliver high-quality, secure, and efficient software solutions. \n\n> #### Discover why [customers are upgrading to GitLab Premium](https://about.gitlab.com/pricing/premium/why-upgrade/).",[965,9,482,707,862,708],{"slug":1381,"featured":6,"template":686},"transform-code-quality-and-compliance-with-automated-processes","content:en-us:blog:transform-code-quality-and-compliance-with-automated-processes.yml","Transform Code Quality And Compliance With Automated Processes","en-us/blog/transform-code-quality-and-compliance-with-automated-processes.yml","en-us/blog/transform-code-quality-and-compliance-with-automated-processes",{"_path":1387,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1388,"content":1394,"config":1400,"_id":1402,"_type":14,"title":1403,"_source":16,"_file":1404,"_stem":1405,"_extension":19},"/en-us/blog/troubleshoot-delays-with-code-review-analytics",{"title":1389,"description":1390,"ogTitle":1389,"ogDescription":1390,"noIndex":6,"ogImage":1391,"ogUrl":1392,"ogSiteName":673,"ogType":674,"canonicalUrls":1392,"schema":1393},"Troubleshoot delays with our Code Review Analytics tool","Introduced in GitLab 12.7, Code Review Analytics can help you dig deeper into slow-moving merge requests.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749681140/Blog/Hero%20Images/code_review_analytics.png","https://about.gitlab.com/blog/troubleshoot-delays-with-code-review-analytics","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Troubleshoot delays with our Code Review Analytics tool\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Chris Ward\"}],\n        \"datePublished\": \"2020-03-18\",\n      }",{"title":1389,"description":1390,"authors":1395,"heroImage":1391,"date":1397,"body":1398,"category":754,"tags":1399},[1396],"Chris Ward","2020-03-18","\n\nModern software development moves fast. Development teams can fix issues and have a release deployed to customers within minutes, all fed through a continuous testing, build, and deployment process. Thanks to containerization, development teams can experiment with new techniques and technologies for particular application services, without affecting an application as a whole.\n\nBut with this speed and potential pace of change, it's easy to lose sight of what matters: Are any of these changes important for customers and their needs, or do they bring any business value? This is what [Value Stream Analytics](https://docs.gitlab.com/ee/user/analytics/value_stream_analytics.html) hopes to answer.\n\nDrawing on lessons learned from the lean movement, delivery teams, engineering managers, and directors are applying \"[value stream mapping](https://en.wikipedia.org/wiki/Value-stream_mapping)\" to understand and optimize delivery of value, from the time an idea is born to its impact on the business in production. GitLab's analytics capabilities provide near real-time insights into the flow of value through the team's value stream without requiring complex system integrations, configuration, or add-on tools.\n\nAt the highest project overview level Value Stream Analytics ([since GitLab 12.3](/releases/2019/09/22/gitlab-12-3-released/#analytics-workspace), and previously called \"cycle analytics\") helps measure the velocity of development cycles in your team, and the time it takes them from planning to monitoring for each project. Currently, it tracks the seven stages to make calculations, and the associated feature:\n\n-   **Issue (Tracker)**: Time to schedule an issue (by milestone or by adding it to an issue board)\n-   **Plan (Board)**: Time to first commit\n-   **Code (IDE)**: Time to create a merge request\n-   **Test (CI)**: Time it takes GitLab CI/CD to test your code\n-   **Review (Merge Request/MR)**: Time spent on code review. Measures the median time taken to review the merge request that has the closing issue pattern, between its creation and until it's merged.\n-   **Staging (Continuous Deployment)**: Time between merging and deploying to production\n-   **Total (Total)**: Total lifecycle time. That is the velocity of the project or team. Previously known as production.\n\nIf the Value Stream Analytics feature shows that reviews are your team's most time-consuming step or your team agrees that code review is moving too slowly, then it's time to dig deeper. [GitLab 12.7](/releases/2020/01/22/gitlab-12-7-released/#code-review-analytics) introduced [Code Review Analytics](https://docs.gitlab.com/ee/user/analytics/code_review_analytics.html) to help you dig deeper into slow-moving merge requests and understand what is causing delays. \n\nIn our 2019 and 2020 [developer surveys](/developer-survey/), delays in code review featured near the top of developer process painpoints. Code review is not as time consuming as testing (the unanimous winner in 2019 and 2020), but respondents aknowledged they need more help to speed up the code reviews. This initial release of Code Review Analytics is a first step toward providing greater insight into delays and bottlenecks during the code review process.\n\nYou can find the Code Review dashboard under the menu for your project, then _Project Analytics > Code Review_. The view is a table of open merge requests with at least one non-author comment, and review time is measured from the first non-author comment. You can also see a summary of the changes introduced by the merge request, the number of comments, commits, and the approvers needed. The default sort order is from the oldest merge request, but you can filter results using the search box above the table. By highlighting aged Code Reviews, teams are encouraged to complete work-in-process rather than picking up new items from the backlog and to dispose of the \"inventory\" waste of unmerged commits.\n\n![Code analytics dashboard](https://about.gitlab.com/images/blogimages/code_review_analytics.png){: .shadow.medium.center}\n\nClicking the title of the merge request takes you to a normal merge request view where you can recap the discussions and activity so far to debug problems such as:\n\n-   If there are many comments or commits, perhaps the code is too complex.\n-   If a particular author is involved, maybe more training is required.\n-   If no or few comments and approvers appear, your team may be understaffed or may be in the habit of starting new work instead of assisting teammates to close MRs and deliver features.\n\nWe will be bringing improvements and more features to code review analytics over the coming months, and in the meantime we welcome your feedback.\n\n### About the guest author\n\n_Chris is a freelance technical communicator for numerous developer-focused companies. Happy creating text, videos, courses, and interactive learning experiences, in his spare time he writes games and interactive fiction._\n",[9,708,1087],{"slug":1401,"featured":6,"template":686},"troubleshoot-delays-with-code-review-analytics","content:en-us:blog:troubleshoot-delays-with-code-review-analytics.yml","Troubleshoot Delays With Code Review Analytics","en-us/blog/troubleshoot-delays-with-code-review-analytics.yml","en-us/blog/troubleshoot-delays-with-code-review-analytics",{"_path":1407,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1408,"content":1414,"config":1421,"_id":1423,"_type":14,"title":1424,"_source":16,"_file":1425,"_stem":1426,"_extension":19},"/en-us/blog/unreview-a-year-later-how-gitlab-is-being-transformed-by-ml-powered-code-review",{"title":1409,"description":1410,"ogTitle":1409,"ogDescription":1410,"noIndex":6,"ogImage":1411,"ogUrl":1412,"ogSiteName":673,"ogType":674,"canonicalUrls":1412,"schema":1413},"GitLab transforms code review with machine learning tools","Learn how last year's acquisition has resulted in impactful features for the One DevOps Platform.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749668002/Blog/Hero%20Images/pg-gear.jpg","https://about.gitlab.com/blog/unreview-a-year-later-how-gitlab-is-being-transformed-by-ml-powered-code-review","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"UnReview a year later: How GitLab is transforming DevOps code review with ML-powered functionality\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Taylor McCaslin\"}],\n        \"datePublished\": \"2022-06-02\",\n      }",{"title":1415,"description":1410,"authors":1416,"heroImage":1411,"date":1418,"body":1419,"category":681,"tags":1420},"UnReview a year later: How GitLab is transforming DevOps code review with ML-powered functionality",[1417],"Taylor McCaslin","2022-06-02","\n\nA little over a year ago, [GitLab acquired UnReview](/press/releases/2021-06-02-gitlab-acquires-unreview-machine-learning-capabilities.html), a machine learning-based solution for automatically identifying [relevant code reviewers](/stages-devops-lifecycle/create/) and distributing review workloads and knowledge. Our goal is to integrate UnReview’s ML-powered code review features throughout GitLab, the One DevOps Platform. We checked in with Taylor McCaslin, principal product manager, ModelOps, at GitLab, to find out the impact UnReview has had so far and what comes next.\n\n**The idea of applying machine learning to code review was already underway at GitLab before the UnReview acquisition. What was it about ML/AI and automation that seemed a good fit for the code review process? How did the UnReview acquisition affect that strategy?**\n\nThe acquisition of UnReview gave GitLab a practical way to get started with a really focused value proposition that was obvious to the platform. ML/AI is a lot more than just having a useful algorithm. UnReview and its team gave GitLab talent with experience building MLOps pipelines and working with production DataOps workflows. As a source code management ([SCM](/solutions/source-code-management/)) and continuous integration ([CI](/topics/ci-cd/)) platform, MLOps and DataOps are key ambitions for our ModelOps stage. UnReview is the foundational anchor of our AI Assisted group, and we anticipate developing more ML-powered features with the base that we’ve built integrating UnReview into our One DevOps platform. If it’s something you manually set today within GitLab, we’ll consider suggestions and automations: suggested labels, assignees, issue relationships, etc. You can learn more about our plans on our [AI Assisted direction page](/direction/modelops/ai_assisted/).\n\n> You’re invited! Join us on June 23rd for the [GitLab 15 launch event](https://page.gitlab.com/fifteen) with DevOps guru Gene Kim and several GitLab leaders. They’ll show you what they see for the future of DevOps and The One DevOps Platform.\n\n**There were [three specific objectives with the UnReview project](/handbook/engineering/development/data-science/ai-assisted/projects/unreview/#overview) when you first started:**\n- **Eliminate the time wasted manually searching for an appropriate code reviewer to review code changes.**\n- **Make optimum recommendations that consider the reviewers’ experience and optimize the review load across the team, which additionally facilitates knowledge sharing.**\n- **Provide analytics on the state of code review in the project, explaining why a particular code reviewer is recommended.**\n\n**Have you had to change or add to these in any way?**\n\nWe now have Suggested Reviewers running for external beta customers as well as dogfooding it internally. We’ve learned a lot about what makes a good code reviewer. Some of the obvious things like context with the changed files and history of committing to that area of code are obvious. But there are less obvious things like what type of code someone has experience with (front-end or back-end).\n\nWe’re finding the concept of recency interesting: the idea that people who more recently interacted with files and functions may be better suited to review the code. Also, people leave companies, and that’s usually not something that can be inferred by the source graph, so we’re working on merging additional GitLab activity data with the recommendation engine.\n\nIn addition, we’re thinking a lot about bias in our recommendations. For example, a senior engineer likely has the most commits across a project, but we don’t always want to recommend a senior engineer. The more we work with the algorithm and recommendations, the more nuanced we find it.\n\nNot every organization does code review the same way, so we’re considering building different models for those that have no process versus organizations that have very rigid and hierarchical reviewer requirements. We also have to consider how recommendations interact with other features of the platform like code owners, maintainer roles, and commit access.\n\nWe’ve never been more excited about the potential of machine learning within GitLab. Some of the feedback we’ve had from beta customers are “this feels like magic” and that honestly encapsulates what we’re going for. Sometimes the right code reviewer is just a feeling that you can’t quite put your finger on. Through data and a little bit of magic, we may see Suggested Reviewers help speed up workflows, and cut down on back and forth and wasted time trying to find someone to do a great review of your code.\n\n**Introducing ML-powered features can come with challenges, especially being GitLab’s first data science feature. Can you speak to some of those challenges and how the team overcame them?**\n\nIt has been about a year since we closed the transaction. During that time period we’ve introduced a lot of new concepts to GitLab. Access to real-time data within the feature with DataOps extraction and cleaning of platform activity data. We have an end-to-end MLOps pipeline running 100% within GitLab CI that extracts, builds, trains, and deploys the UnReview model, and new observability metrics to know if the whole system is working. These are all foundational concepts that we’ve had to build from the ground up.\n\nAlso, we’ve introduced Python to the GitLab tech stack and have to develop new engineering standards and hiring interview practices to find the right talent for this team. We’re now turning the corner of this foundational work and I anticipate that relatively soon we’ll release Suggested Reviewers fully integrated with the platform and UI.\n\nMilestones have been part of the way we’ve sliced up the integration work. We have a variety of internal milestones we’ve been tracking against, including porting the model into GitLab SCM and CI, building the Dataops and MLOps pipelines, and internal and external customer betas. It’s helpful to have these milestones to know what’s most important at any given time and not to get overwhelmed with all the moving pieces. We’re paving a new path with ML-powered features at GitLab, and once we’re done we’ll have a repeatable process and template to replicate over and over with new data science-powered features.\n\n**What has been the most surprising thing you’ve encountered or learned since UnReview first debuted?**\n\nCode Reviewers are foundational to the software development lifecycle. We thought this would be a really straightforward feature, but it turns out people REALLY care about recommendations. People hate bad suggestions so when the recommendations are wrong, the feedback is fast and furious. But when it’s right, it feels like magic. That really surprised me how positively people respond to a great suggestion.\n\nA lot of GitLab users have asked me what our success metric is for Suggested Reviewers. It should just feel like magic. Maybe you don’t know why someone was chosen, but you just feel they were the right person to review the change. And hopefully that leads to a more thoughtful code review, reduces the back and forth of trying to find someone to review your code, and ultimately creates a better experience end-to-end. A lot of engineers dread code reviews; we want to change that. I hope Suggested Reviewers can take the pain out of the experience and make it something engineers look forward to. That’s the feeling we’re trying to create with our recommendations. Obvious but magic.\n\n**What’s next for UnReview specifically and DevOps code review more generally? Where do you see the next big advances happening?**\n\nWe’re just scratching the surface. There are so many opportunities for recommendations and automations across the platform. We have a lot of data at GitLab, from the source graph, contribution history, CI builds, test logs, security scans, and deployment data. We believe all of this can be integrated together. I’m particularly excited about what we’re calling [Intelligent Code Security](/direction/modelops/ai_assisted/#categories). The idea is that we will be able to look at your source code as you’re writing it, analyze it for security vulnerabilities, and not only suggest fixes to common security flaws, but also apply that change, run your CI, confirm the build succeeds, confirm the vulnerability was resolved, and possibly even deploy that change, all automatically.\n\nImagine the future where your code gets more secure automatically while you sleep. That sounds wild, but we have the data to power [a feature like this in the future](/direction/modelops/ai_assisted/#categories). Suggested Reviewers is just the beginning. We haven’t seen many DevOps platforms fully embrace the data, code, and activity data that they have in a material way. I think we’ll see a lot more in this space moving forward as development platforms identify the massive opportunities to drive efficiencies and remove the frustrating parts of software development from the process.\n",[683,9,965,231,706],{"slug":1422,"featured":6,"template":686},"unreview-a-year-later-how-gitlab-is-being-transformed-by-ml-powered-code-review","content:en-us:blog:unreview-a-year-later-how-gitlab-is-being-transformed-by-ml-powered-code-review.yml","Unreview A Year Later How Gitlab Is Being Transformed By Ml Powered Code Review","en-us/blog/unreview-a-year-later-how-gitlab-is-being-transformed-by-ml-powered-code-review.yml","en-us/blog/unreview-a-year-later-how-gitlab-is-being-transformed-by-ml-powered-code-review",{"_path":1428,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1429,"content":1434,"config":1439,"_id":1441,"_type":14,"title":1442,"_source":16,"_file":1443,"_stem":1444,"_extension":19},"/en-us/blog/what-blocks-faster-code-release",{"title":1430,"description":1431,"ogTitle":1430,"ogDescription":1431,"noIndex":6,"ogImage":832,"ogUrl":1432,"ogSiteName":673,"ogType":674,"canonicalUrls":1432,"schema":1433},"What blocks faster code releases? It starts with testing","Our 2020 DevSecOps Survey found testing was the number one reason for release delays, but planning and code reviews were also challenges. Here’s what you need to know.","https://about.gitlab.com/blog/what-blocks-faster-code-release","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"What blocks faster code releases? It starts with testing\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Valerie Silverthorne\"}],\n        \"datePublished\": \"2020-05-29\",\n      }",{"title":1430,"description":1431,"authors":1435,"heroImage":832,"date":1436,"body":1437,"category":816,"tags":1438},[858],"2020-05-29","\nOur [2022 Global DevSecOps Survey](https://about.gitlab.com/developer-survey/previous/2022/) is out now! Learn the latest in DevOps insights from over 5,000 DevOps professionals.\n\nFirst, the good news: do DevOps right and you’ll release code faster. In fact, 83% of our [2020 Global DevSecOps Survey](/developer-survey/) respondents said code heads out the door more quickly thanks to a successful DevOps practice.\n\nBut we also asked survey takers what was most likely to delay their code, and their responses highlighted some of the toughest challenges DevOps practitioners face. When it comes to delays, 47% said testing was the culprit, while 39% said planning, and 28% said code review.\n\nAt a time when faster software releases are perhaps even more critical than ever before, it may be helpful for your organization to take a hard look at what blocked our 3652 respondents from 21 countries across 19 job categories. Test, planning, and code reviews are essential steps in DevOps, but as our survey responses show, they can easily turn into black holes of time and frustration.\n\n## The trouble with testing\n\nLet’s just say it: Testing is hard. A key component of successful DevOps, testing is apparently the hill many teams die on – repeatedly. In [our 2019 survey](/blog/global-developer-report/) 49% of all respondents pointed their fingers squarely at test as the primary cause of delays, and it’s discouraging that the percentage was only slightly smaller this year.\n\n_\"We are slow and do not test very well. We do Big Bang deployments.\"_\n\nThe trouble with testing boils down to essentially two issues: there are never enough tests done and automating testing is tricky. We asked developers to assess their tasks and to tell us what they should be doing but are not. The vast majority of them said they weren’t doing enough testing, period.\n\n_\"Not enough tests (or none) and then the code doesn’t work in production. Some collaborators have poor IT skills.\"_\n\n_\"Too little testing done too late.\"_\n\n_\"We need more test cases to cover 100% of everything.\"_\n\nJust 12% of survey takers told us their teams had full test automation and about 25% said they either have nothing set up or are only beginning the automation journey.\n\nThere are a few glimmers of hope. For starters, teams that have cracked the test automation code told us about the concrete benefits.\n\n_\"We do [TDD (test driven development)](https://www.agilealliance.org/glossary/tdd/). QA and dev act as a team. We have automated tests running parallel with developing code.\"_\n\nAnd 16% of survey respondents either have a \"bot\" reviewing their code or have an AI/ML tool in place for testing. It's early days for AI-powered testing, clearly, but the results are intriguing.\n\n## The truth about planning\n\nTesting may be technically challenging but planning is also a significant stretch for many development teams. A developer shared that work happened \"without much planning\" and that was a common refrain.\n\nOne reason for a perceived or real lack of planning could lie in the fact that many software teams use hybrid development methodologies, each of which have their own (not necessarily compatible) planning practices. Feedback from survey takers seemed to support this.\n\n_\"Planning is in the form of some teams doing waterfall and others doing 'wagile.''\"_\n\n_\"Planning is somewhat heavyweight and a little less than agile.\"_\n\nFor many of our survey takers, there was just overall frustration with the planning process.\n\n_\"Poor planning leads to a lot of doubling back.\"_\n\n## The paradox of code reviews\n\nThere is no question code reviews are critical to DevOps success. Almost 50% of all our respondents conduct them weekly and a significant percentage do them twice a week or even daily. But they’re also a source of frustration when it comes to getting code out the door quickly. Code reviews at some companies can require too many people, or not enough people, or too much \"paperwork.\"\n\n_\"We have a strict code review process and it often takes several days for the reviewer to respond to requests for review.\"_\n\n_\"Code review takes time and every developer has to explain how he achieved what he did.\"_\n\n_\"Code reviews can take a long time due to the lack of reviewers.\"_\n\nCode reviews are cumbersome but 95% of our respondents said they’re either very or moderately valuable for ensuring code quality and security. The trick is to just figure out how to streamline them, and one survey taker offered his organization’s strategy: \"Each merge request is code reviewed by a peer; there is no team code review.\"\n\nOur [2022 Global DevSecOps Survey](/developer-survey/) has the latest insights from over 5,000 DevOps professionals. You can also compare it with [previous year surveys](/developer-survey/previous/)\n",[9,841,683],{"slug":1440,"featured":6,"template":686},"what-blocks-faster-code-release","content:en-us:blog:what-blocks-faster-code-release.yml","What Blocks Faster Code Release","en-us/blog/what-blocks-faster-code-release.yml","en-us/blog/what-blocks-faster-code-release",{"_path":1446,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1447,"content":1453,"config":1458,"_id":1460,"_type":14,"title":1461,"_source":16,"_file":1462,"_stem":1463,"_extension":19},"/en-us/blog/what-is-gitlab-flow",{"title":1448,"description":1449,"ogTitle":1448,"ogDescription":1449,"noIndex":6,"ogImage":1450,"ogUrl":1451,"ogSiteName":673,"ogType":674,"canonicalUrls":1451,"schema":1452},"The problem with Git flow","Learn why Git flow complicates the lifecycle and discover an alternative to streamline development.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749681121/Blog/Hero%20Images/whatisgitlabflow.jpg","https://about.gitlab.com/blog/what-is-gitlab-flow","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"The problem with Git flow\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Suri Patel\"}],\n        \"datePublished\": \"2020-03-05\",\n      }",{"title":1448,"description":1449,"authors":1454,"heroImage":1450,"date":1455,"body":1456,"category":1220,"tags":1457},[837],"2020-03-05","\n  \u003Cscript type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"BlogPosting\",\n    \"mainEntityOfPage\": {\n      \"@type\": \"WebPage\",\n      \"@id\": \"https://about.gitlab.com/blog/what-is-gitlab-flow/\"\n    },\n    \"headline\": \"The problem with Git flow\",\n    \"description\": \"Learn why Git flow complicates the lifecycle and discover an alternative to streamline development.\",\n    \"image\": \"https://about.gitlab.com/images/blogimages/whatisgitlabflow.jpg\",\n    \"author\": {\n      \"@type\": \"Organization\",\n      \"name\": \"GitLab\"\n    },\n    \"publisher\": {\n      \"@type\": \"Organization\",\n      \"name\": \"\",\n      \"logo\": {\n        \"@type\": \"ImageObject\",\n        \"url\": \"\"\n      }\n    },\n    \"datePublished\": \"2020-03-05\"\n  }\n  \u003C/script>\n\nSometimes, you can have too much of a good thing. That’s certainly true with [Git flow](https://nvie.com/posts/a-successful-git-branching-model/), a well-known software development workflow that offers several options but can bog down users.\n\nWe developed [GitLab Flow](/topics/version-control/what-is-gitlab-flow/) as the solution to eliminate messy complexity and streamline the development process. [GitLab Flow](/topics/version-control/what-is-gitlab-flow/) brings issue tracking to the Git workflow, simplifying the process and removing confusion.\n\n## The problem with Git flow\n\nTo understand how GitLab Flow works, it’s helpful to start by looking at the problems it tries to solve. In Git flow, there are two main pain points, both of which involve unnecessary branch switching.\n\nGit flow forces developers to use the `develop` branch rather than the `master` or default branch. Because most tools default to using the master, there’s a significant amount of branch switching involved. Another frustrating aspect are `release` and [hotfix](https://stackoverflow.com/questions/46729813/how-to-use-a-Gitflow-hotfix-branch) branches, which are overkill for most organizations and completely unnecessary in companies practicing continuous integration and continuous delivery.\n\nThat brings us to GitLab Flow, a simpler workflow and branching model that keeps everything simple and inclusive.\n\n## GitLab Flow: a streamlined branching strategy\n\nGitLab Flow is a simpler alternative to Git flow that combines feature-driven development and feature branches with issue tracking. GitLab Flow integrates the Git workflow with an issue tracking system, offering a simple, transparent, and effective way to work with Git.\n\nGitLab Flow is an approach to make the relationship between the code and the issue tracker more transparent. Each change to the codebase starts with an issue in the issue tracking system. When you’re done coding or want to discuss the code, you can open a merge request. When the code is ready, the reviewer will merge the branch into master, creating a merge commit that makes this event easily visible in the future. Using GitLab Flow, teams can deploy a new version of code by merging master into a `production` branch, enabling them to quickly identify what code is in the production environment. In this workflow, commits only flow downstream, ensuring that everything is tested in all environments.\n\nGitLab Flow prevents the overhead of releasing, tagging, and merging that accompanies Git flow.\n\nGitLab Flow in a nutshell:\n- All features and fixes first go to master\n- Allows for `production` or `stable` branches\n- Bug fixes/hotfix patches are cherry-picked from master\n\nRead more on here [GitLab Flow best practicies](/topics/version-control/what-are-gitlab-flow-best-practices/)\n\n## Breaking down the 10 stages of software development\n\nGitLab Flow is a way to move from the idea stage to production, all while keeping everyone informed and productive. We identified [10 key stages](/topics/version-control/what-is-gitlab-flow/#stages-of-software-development) of the development process that must happen in order for software to get into production. GitLab Flow makes it easy to account for all of them, while continuing to provide full visibility into the development lifecycle.\n\nBroadly speaking, GitLab Flow is broken down into three main areas: `feature` branch, `production` branch, and `release` branch.\n\nA `feature` branch is where the serious development work occurs. A developer creates a feature or bug fix branch and does all the work there rather than on a master branch. Once the work is complete, the developer creates a merge request to merge the work into the master branch.\n\nThe `production` branch is essentially a monolith – a single long-running production `release` branch rather than individual branches. It’s possible to create a tag for each deployable version to keep track of those details easily.\n\nThe last piece, the `release` branch, is key if you release software to customers. With every new release, you’ll create a stable branch from master and decide on a tag. If you need to do a patch release, be sure to cherry-pick critical bug fixes first, and don’t commit them directly to the stable or long-lived branch.\n\n## Follow the rules\n\nWant to get the most out of GitLab Flow? Our CEO [Sid Sijbrandij](/company/team/#sytses) came up with [11 rules teams should always follow to achieve maximum efficiency](/topics/version-control/what-are-gitlab-flow-best-practices/). The article is worth a read in its entirety, but here are a few rules that are timely reminders of the importance of testing, even in a [CI environment](/solutions/continuous-integration/):\n\n* **Test all commits**: Don’t wait to test until everything has been merged into `master`. Test commits along the way to catch problems earlier in the process.\n* **And run _all_ tests on all the commits**, even if you have to run tests in parallel.\n* **Code reviews > merging into `master`.** Why wait? \"Don’t test everything at the end of the week,\" Sid writes. \"Do it on the spot, because you'll be more likely to catch things that could cause problems, and others will also be working to come up with solutions.\"\n\n## Take a deep dive\n\nTake a look at GitLab Flow in action! 🍿\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube-nocookie.com/embed/InKNIvky2KE\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n\n\nCover image by [Fabio Bracht](https://unsplash.com/@bracht?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/photos/_z0DiiaIhB4)\n{: .note}\n",[796,923,9],{"slug":1459,"featured":6,"template":686},"what-is-gitlab-flow","content:en-us:blog:what-is-gitlab-flow.yml","What Is Gitlab Flow","en-us/blog/what-is-gitlab-flow.yml","en-us/blog/what-is-gitlab-flow",{"_path":1465,"_dir":244,"_draft":6,"_partial":6,"_locale":7,"seo":1466,"content":1472,"config":1477,"_id":1479,"_type":14,"title":1480,"_source":16,"_file":1481,"_stem":1482,"_extension":19},"/en-us/blog/15-git-tips-improve-workflow",{"title":1467,"description":1468,"ogTitle":1467,"ogDescription":1468,"noIndex":6,"ogImage":1469,"ogUrl":1470,"ogSiteName":673,"ogType":674,"canonicalUrls":1470,"schema":1471},"15 Git tips to improve your workflow","Learn how to compare commits, delete stale branches, and write aliases to save you some time. It's time to dust off your command line and Git busy!","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749681222/Blog/Hero%20Images/git-15th-anniversary-cover.png","https://about.gitlab.com/blog/15-git-tips-improve-workflow","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"15 Git tips to improve your workflow\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Suri Patel\"}],\n        \"datePublished\": \"2020-04-07\",\n      }",{"title":1467,"description":1468,"authors":1473,"heroImage":1469,"date":1474,"body":1475,"category":1220,"tags":1476},[837],"2020-04-07","\n\nThis year, [Git](https://git-scm.com/) celebrates its 15th anniversary, and we’ve been excitedly posting some thoughts about its creation and impact — from sharing our experience at [Git Merge 2020](/blog/git-merge-fifteen-year-git-party/), discussing [the problem with Git flow](/blog/what-is-gitlab-flow/), or highlighting the newest Git feature [Partial Clone](/blog/partial-clone-for-massive-repositories/).\n\nWhether you’re just getting started with Git, or you know your way around a command line, it’s always nice to brush up on your skills, which is why we’ve gathered 15 methods to improve your Git-based workflow.\n\n### 1. Git aliases\n\nOne of the most impactful ways to improve your daily workflow is to create aliases for common commands to save you some time in the terminal.\n\nYou can use the following commands to create aliases for the most-used Git commands, `checkout`, `commit` and `branch`.\n\n```\ngit config --global alias.co checkout\ngit config --global alias.ci commit\ngit config --global alias.br branch\n```\n\nInstead of typing `git checkout master`, you only need to type `git co master`.\n\nYou could also edit these commands or add more by modifying the `~/.gitconfig` file directly:\n\n```\n[alias]\n    co = checkout\n    ci = commit\n    br = branch\n```\n\n### 2. See the repository status in your terminal’s prompt\n\nIf you’d like to visualize the status of your repository, you can run `git-prompt.sh`\n(you can [download it](https://github.com/git/git/blob/master/contrib/completion/git-prompt.sh) and follow the\ninstructions to use it in your system). If you're using Linux\nand have installed Git with your package manager, it may already be\npresent on your system, likely under `/etc/bash_completion.d/`.\n\nYou can replace your standard shell prompt with something a bit more exciting:\n\n![Git shell prompt](https://about.gitlab.com/images/blogimages/git-tricks/git-shell-info.png){: .shadow}\n\n_Taken from oh-my-zsh's [themes wiki](https://github.com/robbyrussell/oh-my-zsh/wiki/Themes#kafeitu)._\n\n### 3. Compare commits from the command line\n\nA simple way to compare the differences between commits or versions of the same file is to use the `git diff` command.\n\nIf you want to compare the same file between different commits, you run the following:\n\n```\n$ git diff $start_commit..$end_commit -- path/to/file\n```\n\nIf you want to compare the changes between two commits:\n\n```\n$ git diff $start_commit..$end_commit\n```\n\nThese commands will open the diff view inside the terminal, but if you prefer to use a more visual tool to compare your diffs, you can use `git difftool`. [Meld](https://meldmerge.org/) is a useful viewer/editor to visually compare diffs.\n\nTo configure Meld:\n\n```\n$ git config --global diff.tool git-meld\n```\n\nTo start viewing the diffs:\n\n```\n$ git difftool $start_commit..$end_commit -- path/to/file\n# or\n$ git difftool $start_commit..$end_commit\n```\n\n### 4. Stashing uncommitted changes\n\nIf you’re ever working on a feature and need to do an emergency fix on the project, you could run into a problem. You don’t want to commit an unfinished feature, and you also don’t want to lose current changes. The solution is to temporarily remove these changes with the Git stash command:\n\n```\n$ git stash\n```\n\nThe git stash command hides changes, giving you a clean working directory and the ability to switch to a new branch to make updates, without having to commit a meaningless snapshot in order to save the current state.\n\nOnce you’re done working on a fix and want to revisit your previous changes, you can run:\n\n```\n$ git stash pop\n```\n\nAnd your changes will be recovered. 🎉\n\nIf you no longer need those changes and want to clear the stash stack, you can do so with:\n\n```\n$ git stash drop\n```\n\n### 5. Pull frequently\n\nIf you’re using [GitLab Flow](/solutions/gitlab-flow/), then you’re working\non feature branches. Depending on how long your feature takes to implement, there might be several changes made to the master branch. In order to avoid major conflicts, you should frequently pull the changes from the master branch to your branch to resolve any conflicts as soon as possible and to make merging your branch to master easier.\n\n### 6. Autocomplete commands\n\nUsing [completion scripts](https://github.com/git/git/tree/master/contrib/completion), you can quickly create the commands for `bash`, `tcsh` and `zsh`. If you want to type `git pull`, you can type just the first letter with `git p` followed by \u003Ckbd>Tab\u003C/kbd> will show the following:\n\n```\npack-objects   -- create packed archive of objects\npack-redundant -- find redundant pack files\npack-refs      -- pack heads and tags for efficient repository access\nparse-remote   -- routines to help parsing remote repository access parameters\npatch-id       -- compute unique ID for a patch\nprune          -- prune all unreachable objects from the object database\nprune-packed   -- remove extra objects that are already in pack files\npull           -- fetch from and merge with another repository or local branch\npush           -- update remote refs along with associated objects\n```\n\nTo show all available commands, type `git` in your terminal followed by\n\u003Ckbd>Tab\u003C/kbd>+ \u003Ckbd>Tab\u003C/kbd>.\n\n### 7. Set a global `.gitignore`\n\nIf you want to avoid committing files like `.DS_Store` or Vim `swp` files,\nyou can set up a global `.gitignore` file.\n\nCreate the file:\n\n```bash\ntouch ~/.gitignore\n```\n\nThen run:\n\n```bash\ngit config --global core.excludesFile ~/.gitignore\n```\n\nOr manually add the following to your `~/.gitconfig`:\n\n```ini\n[core]\n  excludesFile = ~/.gitignore\n```\nYou can create a list of the things you want Git to ignore. To learn more, visit the [gitignore documentation](https://git-scm.com/docs/gitignore).\n\n### 8. Enable Git’s autosquash feature by default\n\nAutosquash makes it easier to squash commits during an interactive rebase. It can be enabled for each rebase using `git rebase -i --autosquash`, but it's easier to turn it on by default.\n\n```bash\ngit config --global rebase.autosquash true\n```\n\nOr manually add the following to your `~/.gitconfig`:\n\n```ini\n[rebase]\n  autosquash = true\n```\n\n### 9. Delete local branches that have been removed from remote on fetch/pull\n\nYou likely have stale branches in your local repository that no longer exist in the remote one. To delete them in each fetch/pull, run:\n\n```bash\ngit config --global fetch.prune true\n```\n\nOr manually add the following to your `~/.gitconfig`:\n\n```ini\n[fetch]\n  prune = true\n```\n\n### 10. Use Git blame more efficiently\n\nGit blame is a handy way to discover who changed a line in a file. Depending on what you want to show, you can pass different flags:\n\n```\n$ git blame -w  # ignores white space\n$ git blame -M  # ignores moving text\n$ git blame -C  # ignores moving text into other files\n```\n\n### 11. Add an alias to check out merge requests locally\n\nA [merge request](https://docs.gitlab.com/ee/user/project/merge_requests/) contains all the history from a repository, and the additional\ncommits added to the branch associated with the MR. You can check out a public merge request locally even if the source project is a fork (even a private fork) of the target project.\n\nTo check out a merge request locally, add the following alias to your `~/.gitconfig`:\n\n```\n[alias]\n  mr = !sh -c 'git fetch $1 merge-requests/$2/head:mr-$1-$2 && git checkout mr-$1-$2' -\n```\n\nNow you can check out a merge request from any repository and any remote. For example, to check out the merge request with ID 5 as shown in GitLab\nfrom the `upstream` remote, run:\n\n```\ngit mr upstream 5\n```\n\nThis will fetch the merge request into a local `mr-upstream-5` branch and check\nit out. In the above example, `upstream` is the remote that points to GitLab\nwhich you can find out by running `git remote -v`.\n\n### 12. An alias of `HEAD`\n\nBreaking news: `@` is the same as `HEAD`. Using it during a rebase is a lifesaver:\n\n```bash\ngit rebase -i @~2\n```\n\n### 13. Resetting files\n\nYou’re modifying your code when you suddenly realize that the changes you made are not great, and you’d like to reset them. Rather than clicking undo on everything you edited, you can reset your files to the HEAD of the branch:\n\n```\n$ git reset --hard HEAD\n```\n\nOr if you want to reset a single file:\n\n```\n$ git checkout HEAD -- path/to/file\n```\n\nNow, if you already committed your changes, but still want to revert back, you can use:\n\n```\n$ git reset --soft HEAD~1\n```\n\n### 14. The `git-open` plugin\n\nIf you’d like to quickly visit the website that hosts the repository you’re on, you’ll need `git-open`.\n\n[Install it](https://github.com/paulirish/git-open#installation) and take it for a spin by cloning a repository from\n[GitLab.com](https://gitlab.com/explore). From your terminal, navigate to the\nrepository and run `git open` to be transferred to the project’s page on\nGitLab.com.\n\nThe plugin works by default for projects hosted on GitLab.com, but you can also use it\nwith your own GitLab instances. In that case, set up the domain name with:\n\n```bash\ngit config gitopen.gitlab.domain git.example.com\n```\n\nYou can open different remotes and branches if they have been set up. You can learn more by checking out the [examples section](https://github.com/paulirish/git-open#examples).\n\n### 15. The `git-extras` plugin\n\nIf you want to elevate Git with more commands, try out the\n[`git-extras` plugin](https://github.com/tj/git-extras), which includes `git info` (show\ninformation about the repository) and `git effort` (number of commits per file).\n\n## Learn more about Git\n\nWe’re excited to announce that [Brendan O’Leary](/company/team/#brendan), senior developer evangelist, will create 15 videos to celebrate Git's anniversary over the next several months. He’ll focus on a variety of topics, from rebasing and merging to cherry-picking and branching. Take a look at the first video in the series. 🍿\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube-nocookie.com/embed/9oDNBuive-g\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\nCover image by [Brooke Lark](https://unsplash.com/@brookelark?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/s/photos/birthday?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)\n{: .note}\n",[796,923,9],{"slug":1478,"featured":6,"template":686},"15-git-tips-improve-workflow","content:en-us:blog:15-git-tips-improve-workflow.yml","15 Git Tips Improve Workflow","en-us/blog/15-git-tips-improve-workflow.yml","en-us/blog/15-git-tips-improve-workflow",5,[666,691,717,739,761,782,803,827,848],1754424508056]