[{"data":1,"prerenderedAt":796},["ShallowReactive",2],{"/en-us/blog/better-code-reviews":3,"navigation-en-us":40,"banner-en-us":440,"footer-en-us":450,"blog-post-authors-en-us-David O'Regan":690,"blog-related-posts-en-us-better-code-reviews":705,"assessment-promotions-en-us":747,"next-steps-en-us":786},{"id":4,"title":5,"authorSlugs":6,"body":8,"categorySlug":9,"config":10,"content":14,"description":8,"extension":26,"isFeatured":12,"meta":27,"navigation":28,"path":29,"publishedDate":20,"seo":30,"stem":34,"tagSlugs":35,"__hash__":39},"blogPosts/en-us/blog/better-code-reviews.yml","Better Code Reviews",[7],"david-oregan",null,"unfiltered",{"slug":11,"featured":12,"template":13},"better-code-reviews",false,"BlogPost",{"title":15,"description":16,"authors":17,"heroImage":19,"date":20,"body":21,"category":9,"tags":22},"Better Code Reviews GitLab Style","Better Code Reviews - A selection of tools for your tool-belt when it comes to code reviews.",[18],"David O'Regan","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663502/Blog/Hero%20Images/paperclips.jpg","2020-06-08","{::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```shell\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```shell\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```shell\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```shell\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```shell\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](https://handbook.gitlab.com/handbook/product/product-processes/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|\n",[23,24,25],"code review","zero trust","GitOps","yml",{},true,"/en-us/blog/better-code-reviews",{"title":15,"description":16,"ogTitle":15,"ogDescription":16,"noIndex":12,"ogImage":19,"ogUrl":31,"ogSiteName":32,"ogType":33,"canonicalUrls":31},"https://about.gitlab.com/blog/better-code-reviews","https://about.gitlab.com","article","en-us/blog/better-code-reviews",[36,37,38],"code-review","zero-trust","gitops","_VNKHfE1jQ5eJouM_uq09SYKoWdQ2ggMTeSWvIbQ-Ig",{"data":41},{"logo":42,"freeTrial":47,"sales":52,"login":57,"items":62,"search":370,"minimal":401,"duo":420,"pricingDeployment":430},{"config":43},{"href":44,"dataGaName":45,"dataGaLocation":46},"/","gitlab logo","header",{"text":48,"config":49},"Get free trial",{"href":50,"dataGaName":51,"dataGaLocation":46},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":53,"config":54},"Talk to sales",{"href":55,"dataGaName":56,"dataGaLocation":46},"/sales/","sales",{"text":58,"config":59},"Sign in",{"href":60,"dataGaName":61,"dataGaLocation":46},"https://gitlab.com/users/sign_in/","sign in",[63,90,185,190,291,351],{"text":64,"config":65,"cards":67},"Platform",{"dataNavLevelOne":66},"platform",[68,74,82],{"title":64,"description":69,"link":70},"The intelligent orchestration platform for DevSecOps",{"text":71,"config":72},"Explore our Platform",{"href":73,"dataGaName":66,"dataGaLocation":46},"/platform/",{"title":75,"description":76,"link":77},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":78,"config":79},"Meet GitLab Duo",{"href":80,"dataGaName":81,"dataGaLocation":46},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":83,"description":84,"link":85},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":86,"config":87},"Learn more",{"href":88,"dataGaName":89,"dataGaLocation":46},"/why-gitlab/","why gitlab",{"text":91,"left":28,"config":92,"link":94,"lists":98,"footer":167},"Product",{"dataNavLevelOne":93},"solutions",{"text":95,"config":96},"View all Solutions",{"href":97,"dataGaName":93,"dataGaLocation":46},"/solutions/",[99,123,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":46},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[108,112,115,119],{"text":109,"config":110},"CI/CD",{"href":111,"dataGaLocation":46,"dataGaName":109},"/solutions/continuous-integration/",{"text":75,"config":113},{"href":80,"dataGaLocation":46,"dataGaName":114},"gitlab duo agent platform - product menu",{"text":116,"config":117},"Source Code Management",{"href":118,"dataGaLocation":46,"dataGaName":116},"/solutions/source-code-management/",{"text":120,"config":121},"Automated Software Delivery",{"href":105,"dataGaLocation":46,"dataGaName":122},"Automated software delivery",{"title":124,"description":125,"link":126,"items":131},"Security","Deliver code faster without compromising security",{"config":127},{"href":128,"dataGaName":129,"dataGaLocation":46,"icon":130},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[132,136,141],{"text":133,"config":134},"Application Security Testing",{"href":128,"dataGaName":135,"dataGaLocation":46},"Application security testing",{"text":137,"config":138},"Software Supply Chain Security",{"href":139,"dataGaLocation":46,"dataGaName":140},"/solutions/supply-chain/","Software supply chain security",{"text":142,"config":143},"Software Compliance",{"href":144,"dataGaName":145,"dataGaLocation":46},"/solutions/software-compliance/","software compliance",{"title":147,"link":148,"items":153},"Measurement",{"config":149},{"icon":150,"href":151,"dataGaName":152,"dataGaLocation":46},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[154,158,162],{"text":155,"config":156},"Visibility & Measurement",{"href":151,"dataGaLocation":46,"dataGaName":157},"Visibility and Measurement",{"text":159,"config":160},"Value Stream Management",{"href":161,"dataGaLocation":46,"dataGaName":159},"/solutions/value-stream-management/",{"text":163,"config":164},"Analytics & Insights",{"href":165,"dataGaLocation":46,"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":46,"dataGaName":174},"/enterprise/","enterprise",{"text":176,"config":177},"Small Business",{"href":178,"dataGaLocation":46,"dataGaName":179},"/small-business/","small business",{"text":181,"config":182},"Public Sector",{"href":183,"dataGaLocation":46,"dataGaName":184},"/solutions/public-sector/","public sector",{"text":186,"config":187},"Pricing",{"href":188,"dataGaName":189,"dataGaLocation":46,"dataNavLevelOne":189},"/pricing/","pricing",{"text":191,"config":192,"link":194,"lists":198,"feature":278},"Resources",{"dataNavLevelOne":193},"resources",{"text":195,"config":196},"View all resources",{"href":197,"dataGaName":193,"dataGaLocation":46},"/resources/",[199,232,250],{"title":200,"items":201},"Getting started",[202,207,212,217,222,227],{"text":203,"config":204},"Install",{"href":205,"dataGaName":206,"dataGaLocation":46},"/install/","install",{"text":208,"config":209},"Quick start guides",{"href":210,"dataGaName":211,"dataGaLocation":46},"/get-started/","quick setup checklists",{"text":213,"config":214},"Learn",{"href":215,"dataGaLocation":46,"dataGaName":216},"https://university.gitlab.com/","learn",{"text":218,"config":219},"Product documentation",{"href":220,"dataGaName":221,"dataGaLocation":46},"https://docs.gitlab.com/","product documentation",{"text":223,"config":224},"Best practice videos",{"href":225,"dataGaName":226,"dataGaLocation":46},"/getting-started-videos/","best practice videos",{"text":228,"config":229},"Integrations",{"href":230,"dataGaName":231,"dataGaLocation":46},"/integrations/","integrations",{"title":233,"items":234},"Discover",[235,240,245],{"text":236,"config":237},"Customer success stories",{"href":238,"dataGaName":239,"dataGaLocation":46},"/customers/","customer success stories",{"text":241,"config":242},"Blog",{"href":243,"dataGaName":244,"dataGaLocation":46},"/blog/","blog",{"text":246,"config":247},"Remote",{"href":248,"dataGaName":249,"dataGaLocation":46},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":251,"items":252},"Connect",[253,258,263,268,273],{"text":254,"config":255},"GitLab Services",{"href":256,"dataGaName":257,"dataGaLocation":46},"/services/","services",{"text":259,"config":260},"Community",{"href":261,"dataGaName":262,"dataGaLocation":46},"/community/","community",{"text":264,"config":265},"Forum",{"href":266,"dataGaName":267,"dataGaLocation":46},"https://forum.gitlab.com/","forum",{"text":269,"config":270},"Events",{"href":271,"dataGaName":272,"dataGaLocation":46},"/events/","events",{"text":274,"config":275},"Partners",{"href":276,"dataGaName":277,"dataGaLocation":46},"/partners/","partners",{"backgroundColor":279,"textColor":280,"text":281,"image":282,"link":286},"#2f2a6b","#fff","Insights for the future of software development",{"altText":283,"config":284},"the source promo card",{"src":285},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758208064/dzl0dbift9xdizyelkk4.svg",{"text":287,"config":288},"Read the latest",{"href":289,"dataGaName":290,"dataGaLocation":46},"/the-source/","the source",{"text":292,"config":293,"lists":295},"Company",{"dataNavLevelOne":294},"company",[296],{"items":297},[298,303,309,311,316,321,326,331,336,341,346],{"text":299,"config":300},"About",{"href":301,"dataGaName":302,"dataGaLocation":46},"/company/","about",{"text":304,"config":305,"footerGa":308},"Jobs",{"href":306,"dataGaName":307,"dataGaLocation":46},"/jobs/","jobs",{"dataGaName":307},{"text":269,"config":310},{"href":271,"dataGaName":272,"dataGaLocation":46},{"text":312,"config":313},"Leadership",{"href":314,"dataGaName":315,"dataGaLocation":46},"/company/team/e-group/","leadership",{"text":317,"config":318},"Team",{"href":319,"dataGaName":320,"dataGaLocation":46},"/company/team/","team",{"text":322,"config":323},"Handbook",{"href":324,"dataGaName":325,"dataGaLocation":46},"https://handbook.gitlab.com/","handbook",{"text":327,"config":328},"Investor relations",{"href":329,"dataGaName":330,"dataGaLocation":46},"https://ir.gitlab.com/","investor relations",{"text":332,"config":333},"Trust Center",{"href":334,"dataGaName":335,"dataGaLocation":46},"/security/","trust center",{"text":337,"config":338},"AI Transparency Center",{"href":339,"dataGaName":340,"dataGaLocation":46},"/ai-transparency-center/","ai transparency center",{"text":342,"config":343},"Newsletter",{"href":344,"dataGaName":345,"dataGaLocation":46},"/company/contact/#contact-forms","newsletter",{"text":347,"config":348},"Press",{"href":349,"dataGaName":350,"dataGaLocation":46},"/press/","press",{"text":352,"config":353,"lists":354},"Contact us",{"dataNavLevelOne":294},[355],{"items":356},[357,360,365],{"text":53,"config":358},{"href":55,"dataGaName":359,"dataGaLocation":46},"talk to sales",{"text":361,"config":362},"Support portal",{"href":363,"dataGaName":364,"dataGaLocation":46},"https://support.gitlab.com","support portal",{"text":366,"config":367},"Customer portal",{"href":368,"dataGaName":369,"dataGaLocation":46},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":371,"login":372,"suggestions":379},"Close",{"text":373,"link":374},"To search repositories and projects, login to",{"text":375,"config":376},"gitlab.com",{"href":60,"dataGaName":377,"dataGaLocation":378},"search login","search",{"text":380,"default":381},"Suggestions",[382,384,388,390,394,398],{"text":75,"config":383},{"href":80,"dataGaName":75,"dataGaLocation":378},{"text":385,"config":386},"Code Suggestions (AI)",{"href":387,"dataGaName":385,"dataGaLocation":378},"/solutions/code-suggestions/",{"text":109,"config":389},{"href":111,"dataGaName":109,"dataGaLocation":378},{"text":391,"config":392},"GitLab on AWS",{"href":393,"dataGaName":391,"dataGaLocation":378},"/partners/technology-partners/aws/",{"text":395,"config":396},"GitLab on Google Cloud",{"href":397,"dataGaName":395,"dataGaLocation":378},"/partners/technology-partners/google-cloud-platform/",{"text":399,"config":400},"Why GitLab?",{"href":88,"dataGaName":399,"dataGaLocation":378},{"freeTrial":402,"mobileIcon":407,"desktopIcon":412,"secondaryButton":415},{"text":403,"config":404},"Start free trial",{"href":405,"dataGaName":51,"dataGaLocation":406},"https://gitlab.com/-/trials/new/","nav",{"altText":408,"config":409},"Gitlab Icon",{"src":410,"dataGaName":411,"dataGaLocation":406},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":408,"config":413},{"src":414,"dataGaName":411,"dataGaLocation":406},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":416,"config":417},"Get Started",{"href":418,"dataGaName":419,"dataGaLocation":406},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":421,"mobileIcon":426,"desktopIcon":428},{"text":422,"config":423},"Learn more about GitLab Duo",{"href":424,"dataGaName":425,"dataGaLocation":406},"/gitlab-duo/","gitlab duo",{"altText":408,"config":427},{"src":410,"dataGaName":411,"dataGaLocation":406},{"altText":408,"config":429},{"src":414,"dataGaName":411,"dataGaLocation":406},{"freeTrial":431,"mobileIcon":436,"desktopIcon":438},{"text":432,"config":433},"Back to pricing",{"href":188,"dataGaName":434,"dataGaLocation":406,"icon":435},"back to pricing","GoBack",{"altText":408,"config":437},{"src":410,"dataGaName":411,"dataGaLocation":406},{"altText":408,"config":439},{"src":414,"dataGaName":411,"dataGaLocation":406},{"title":441,"button":442,"config":447},"See how agentic AI transforms software delivery",{"text":443,"config":444},"Watch GitLab Transcend now",{"href":445,"dataGaName":446,"dataGaLocation":46},"/events/transcend/virtual/","transcend event",{"layout":448,"icon":449},"release","AiStar",{"data":451},{"text":452,"source":453,"edit":459,"contribute":464,"config":469,"items":474,"minimal":679},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":454,"config":455},"View page source",{"href":456,"dataGaName":457,"dataGaLocation":458},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":460,"config":461},"Edit this page",{"href":462,"dataGaName":463,"dataGaLocation":458},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":465,"config":466},"Please contribute",{"href":467,"dataGaName":468,"dataGaLocation":458},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":470,"facebook":471,"youtube":472,"linkedin":473},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[475,522,574,618,645],{"title":186,"links":476,"subMenu":491},[477,481,486],{"text":478,"config":479},"View plans",{"href":188,"dataGaName":480,"dataGaLocation":458},"view plans",{"text":482,"config":483},"Why Premium?",{"href":484,"dataGaName":485,"dataGaLocation":458},"/pricing/premium/","why premium",{"text":487,"config":488},"Why Ultimate?",{"href":489,"dataGaName":490,"dataGaLocation":458},"/pricing/ultimate/","why ultimate",[492],{"title":493,"links":494},"Contact Us",[495,498,500,502,507,512,517],{"text":496,"config":497},"Contact sales",{"href":55,"dataGaName":56,"dataGaLocation":458},{"text":361,"config":499},{"href":363,"dataGaName":364,"dataGaLocation":458},{"text":366,"config":501},{"href":368,"dataGaName":369,"dataGaLocation":458},{"text":503,"config":504},"Status",{"href":505,"dataGaName":506,"dataGaLocation":458},"https://status.gitlab.com/","status",{"text":508,"config":509},"Terms of use",{"href":510,"dataGaName":511,"dataGaLocation":458},"/terms/","terms of use",{"text":513,"config":514},"Privacy statement",{"href":515,"dataGaName":516,"dataGaLocation":458},"/privacy/","privacy statement",{"text":518,"config":519},"Cookie preferences",{"dataGaName":520,"dataGaLocation":458,"id":521,"isOneTrustButton":28},"cookie preferences","ot-sdk-btn",{"title":91,"links":523,"subMenu":532},[524,528],{"text":525,"config":526},"DevSecOps platform",{"href":73,"dataGaName":527,"dataGaLocation":458},"devsecops platform",{"text":529,"config":530},"AI-Assisted Development",{"href":424,"dataGaName":531,"dataGaLocation":458},"ai-assisted development",[533],{"title":534,"links":535},"Topics",[536,541,544,549,554,559,564,569],{"text":537,"config":538},"CICD",{"href":539,"dataGaName":540,"dataGaLocation":458},"/topics/ci-cd/","cicd",{"text":25,"config":542},{"href":543,"dataGaName":38,"dataGaLocation":458},"/topics/gitops/",{"text":545,"config":546},"DevOps",{"href":547,"dataGaName":548,"dataGaLocation":458},"/topics/devops/","devops",{"text":550,"config":551},"Version Control",{"href":552,"dataGaName":553,"dataGaLocation":458},"/topics/version-control/","version control",{"text":555,"config":556},"DevSecOps",{"href":557,"dataGaName":558,"dataGaLocation":458},"/topics/devsecops/","devsecops",{"text":560,"config":561},"Cloud Native",{"href":562,"dataGaName":563,"dataGaLocation":458},"/topics/cloud-native/","cloud native",{"text":565,"config":566},"AI for Coding",{"href":567,"dataGaName":568,"dataGaLocation":458},"/topics/devops/ai-for-coding/","ai for coding",{"text":570,"config":571},"Agentic AI",{"href":572,"dataGaName":573,"dataGaLocation":458},"/topics/agentic-ai/","agentic ai",{"title":575,"links":576},"Solutions",[577,579,581,586,590,593,597,600,602,605,608,613],{"text":133,"config":578},{"href":128,"dataGaName":133,"dataGaLocation":458},{"text":122,"config":580},{"href":105,"dataGaName":106,"dataGaLocation":458},{"text":582,"config":583},"Agile development",{"href":584,"dataGaName":585,"dataGaLocation":458},"/solutions/agile-delivery/","agile delivery",{"text":587,"config":588},"SCM",{"href":118,"dataGaName":589,"dataGaLocation":458},"source code management",{"text":537,"config":591},{"href":111,"dataGaName":592,"dataGaLocation":458},"continuous integration & delivery",{"text":594,"config":595},"Value stream management",{"href":161,"dataGaName":596,"dataGaLocation":458},"value stream management",{"text":25,"config":598},{"href":599,"dataGaName":38,"dataGaLocation":458},"/solutions/gitops/",{"text":171,"config":601},{"href":173,"dataGaName":174,"dataGaLocation":458},{"text":603,"config":604},"Small business",{"href":178,"dataGaName":179,"dataGaLocation":458},{"text":606,"config":607},"Public sector",{"href":183,"dataGaName":184,"dataGaLocation":458},{"text":609,"config":610},"Education",{"href":611,"dataGaName":612,"dataGaLocation":458},"/solutions/education/","education",{"text":614,"config":615},"Financial services",{"href":616,"dataGaName":617,"dataGaLocation":458},"/solutions/finance/","financial services",{"title":191,"links":619},[620,622,624,626,629,631,633,635,637,639,641,643],{"text":203,"config":621},{"href":205,"dataGaName":206,"dataGaLocation":458},{"text":208,"config":623},{"href":210,"dataGaName":211,"dataGaLocation":458},{"text":213,"config":625},{"href":215,"dataGaName":216,"dataGaLocation":458},{"text":218,"config":627},{"href":220,"dataGaName":628,"dataGaLocation":458},"docs",{"text":241,"config":630},{"href":243,"dataGaName":244,"dataGaLocation":458},{"text":236,"config":632},{"href":238,"dataGaName":239,"dataGaLocation":458},{"text":246,"config":634},{"href":248,"dataGaName":249,"dataGaLocation":458},{"text":254,"config":636},{"href":256,"dataGaName":257,"dataGaLocation":458},{"text":259,"config":638},{"href":261,"dataGaName":262,"dataGaLocation":458},{"text":264,"config":640},{"href":266,"dataGaName":267,"dataGaLocation":458},{"text":269,"config":642},{"href":271,"dataGaName":272,"dataGaLocation":458},{"text":274,"config":644},{"href":276,"dataGaName":277,"dataGaLocation":458},{"title":292,"links":646},[647,649,651,653,655,657,659,663,668,670,672,674],{"text":299,"config":648},{"href":301,"dataGaName":294,"dataGaLocation":458},{"text":304,"config":650},{"href":306,"dataGaName":307,"dataGaLocation":458},{"text":312,"config":652},{"href":314,"dataGaName":315,"dataGaLocation":458},{"text":317,"config":654},{"href":319,"dataGaName":320,"dataGaLocation":458},{"text":322,"config":656},{"href":324,"dataGaName":325,"dataGaLocation":458},{"text":327,"config":658},{"href":329,"dataGaName":330,"dataGaLocation":458},{"text":660,"config":661},"Sustainability",{"href":662,"dataGaName":660,"dataGaLocation":458},"/sustainability/",{"text":664,"config":665},"Diversity, inclusion and belonging (DIB)",{"href":666,"dataGaName":667,"dataGaLocation":458},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":332,"config":669},{"href":334,"dataGaName":335,"dataGaLocation":458},{"text":342,"config":671},{"href":344,"dataGaName":345,"dataGaLocation":458},{"text":347,"config":673},{"href":349,"dataGaName":350,"dataGaLocation":458},{"text":675,"config":676},"Modern Slavery Transparency Statement",{"href":677,"dataGaName":678,"dataGaLocation":458},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":680},[681,684,687],{"text":682,"config":683},"Terms",{"href":510,"dataGaName":511,"dataGaLocation":458},{"text":685,"config":686},"Cookies",{"dataGaName":520,"dataGaLocation":458,"id":521,"isOneTrustButton":28},{"text":688,"config":689},"Privacy",{"href":515,"dataGaName":516,"dataGaLocation":458},[691],{"id":692,"title":693,"body":8,"config":694,"content":696,"description":8,"extension":26,"meta":700,"navigation":28,"path":701,"seo":702,"stem":703,"__hash__":704},"blogAuthors/en-us/blog/authors/david-oregan.yml","David Oregan",{"template":695},"BlogAuthor",{"name":18,"config":697},{"headshot":698,"ctfId":699},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659853/Blog/Author%20Headshots/oregand-headshot.png","oregand",{},"/en-us/blog/authors/david-oregan",{},"en-us/blog/authors/david-oregan","CX5gLc3Gs5FrmvpMNVkBtC5zRi3vj8l3wJGnW0iSa6Y",[706,717,732],{"content":707,"config":715},{"title":708,"description":709,"authors":710,"heroImage":712,"date":713,"body":714,"category":9},"CEO Shadow Takeaways from Jacie","Recap of my experience in the CEO Shadow Program.",[711],"Jacie Bandur","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664102/Blog/Hero%20Images/gitlab-values-cover.png","2021-05-18","\n\n{::options parse_block_html=\"true\" /}\n\n\nHi! I’m Jacie Bandur. I completed GitLab’s CEO Shadow program from 2021-04-26 through 2021-05-07. It was a really enlightening experience. I generally work in Learning and Development and consider myself a lifelong learner. I can’t even explain how much I learned in such a short about of time. I learned a lot about the business. I learned a lot about the product. But learned even more about the importance of iteration in everything we do.\n\n### Qualifications to Participate\n\nI wanted to start this off with touching on qualifications to participate in the program.\n\nI am the type of person that has gone through most of my life thinking I’m not qualified for things. I’m not qualified for that job, that promotion, that program. The list goes on and on.\n\nWhen I saw the [CEO Shadow program](/blog/ceo-shadow-impressions-takeaways/) kick off in 2019, I really wanted to participate. I was a little intimidated. Who wouldn’t be, spending 2 weeks with the CEO of any company? But time passed and all the sudden it was 2021 and I had not taken any steps to participating in the program.\n\nIf you are sitting there waiting for someone to tell you that you are qualified to participate in this program, I’m not big on giving “pep talks,” but here’s me telling you - You are qualified for this program. There’s never going to be a good or perfect time to do it. Tell your manager you want to do the CEO Shadow program. Stop waiting. Sign up today.\n\nNote: Take a look at the [eligibility](https://handbook.gitlab.com/handbook/ceo/shadow/#eligibility) section of the CEO Shadow page for more information on signing up.\n\n### Pre-Program Tips\n\nThere are many things recommended for shadows to do pre-program outlined on the CEO Shadow handbook page. As I was going through the program there were things that I thought helped me (or would have helped me).\n\nHere are my top 6 recommendations:\n\n1. Make sure your team knows you will be unavailable for 2 weeks. This isn’t a program that can or should be done alongside your normal day to day work. I found catching up from the 2 weeks away kind of difficult because I was trying to keep up on what was going on and I had a bunch of half done things.\n1. Talk with people who have done the shadow program - schedule at least 3 coffee chats with CEO Shadow Alumni.\n1. Have food that is easy to eat quickly. Sid’s meetings are back to back most days, so you will have small amounts of time to eat throughout the day. Sid does eat during calls, which you are welcome to do, too, but if you are taking notes, it is difficult to eat. And this will make you realize why speedy meetings are so important!\n1. Listen to the [Executive Leadership LinkedIn Learning course](https://www.linkedin.com/learning/executive-leadership/).\n1. Be prepared to ask questions. When doing the program virtually, there isn’t a ton of time for asking questions, so when one would come up, I would add it to a note on my computer and ask if there was ever time with just the shadows and Sid.\n1. Take at least 1 day off after the program. Take even a couple of days off if you can! This is recommended on the handbook page, but I can’t stress this enough.\n\n\n### Takeaways\n\n**Group Conversations**\n\nI’ve been at GitLab for almost 4 years. When I joined, I made it a point to attend as many GC’s as I could. I had gotten out of the habit of attending Group Conversations. After attending them again for 2 weeks, I realized how important they are to understand better what is going on across the business. Everything in the organization is so intertwined. It’s helpful to understand what other teams are working on and succeeding in.\n\n**Feedback**\n\nWe should all be giving and receiving feedback often. We have a whole [handbook page on giving and receiving feedback](https://handbook.gitlab.com/handbook/people-group/guidance-on-feedback/). Read the handbook page and watch the videos, as well. Practice giving feedback. I recommend using the [1-1 agenda](https://handbook.gitlab.com/handbook/leadership/1-1/suggested-agenda-format/) Sid uses, because Feedback is an essential piece of that agenda, and it makes feedback more of a routine thing.\n\n**Biggest Takeaway**\n\nWe have an incredible team here at GitLab, from Engineering to Product to Sales to People and all the groups in between. There are so many great ideas. I observed the constant reinforcement by Sid to start with something small and build on it. You can ALWAYS make something more complex. It’s hard to go back to something more simple when you start with something complex.\n\nA couple of quotes that I heard from Sid during the program that reinforced this point:\n\n- “Every complex system evolves from a simple system that worked.”\n- “It’s very clear what is the simple solution. We can always make it more complicated as we go on.”\n\nI know they are very similar, but they happened in different meetings on different days, so the point was reinforced repeatedly.\n\nDuring the program, I reflected on the projects that I’am working on. How many of them am I trying to do too much on before releasing. Probably all of them. When I’m working on projects in the future, I will break them down into smaller, more doable chunks. Iteration is hard - it’s a skill to be practicing constantly.\n\n\n### Overall\n\nOverall, the program was really insightful and impactful. If you haven’t participated in it yet, I cannot encourage you enough to do so!\n",{"slug":716,"featured":12,"template":13},"ceo-shadow-recap",{"content":718,"config":730},{"title":719,"description":720,"authors":721,"heroImage":723,"date":724,"body":725,"category":9,"tags":726},"Why I love contributing to GitLab","Making small meaningful changes is what it's all about.",[722],"Austin Regnery","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749679501/Blog/Hero%20Images/new-feature.png","2021-05-11","It was mid-morning on a Tuesday in February, and I had 10 minutes in between meetings. So I decided to try and solve a pain point of mine.\nYou see, I had to memorize this HTML snippet to create a collapsible section in GitLab Issue descriptions and comments, but I kept forgetting it. Was it `summary` or `section`? I could never remember.\n```html\n\u003Cdetails>\n\u003Csummary>Insert Title\u003C/summary>\nHidden content\n\u003C/details>\n```\nEven though it is not vanilla Markdown, GitLab knows how to interpret some HTML. I used this formatting trick fairly often since full-page screenshots can occupy a lot of screen space, which leads to excessive scrolling.\nSo I decided to poke around our codebase to see how the other Markdown shortcuts worked. To my surprise, it was pretty straightforward. Each shortcut had a simple text input that mapped to each button. This implementation was simple to replicate since I just needed to copy/paste and replace a few words.\n![Image of Vue and Haml files with editor shortcuts](https://about.gitlab.com/images/blogimages/why-i-love-contributing-to-gitlab/vue-haml.png){: .shadow}\nThe Vue and Haml files with the new shortcut\n\nI started a branch and began hacking away at the code. Now, I would never call myself a Software Engineer, but I like to try and make things from time to time. I was able to add a new shortcut to the toolbar to insert this code snippet for me in less than 10 minutes. No more memorizing! Making contributions like this is what makes working at GitLab so special.\nNow, it wasn't ready for production, but I at least had something that worked. I shared it with my UX colleagues in Slack, and it started to gain traction with several up-votes and few constructive comments on how to make it better.\nWith the functionality flushed out, a few other designers helped me get a better icon added to our SVG library. Using clear iconography is critical for communicating information more clearly.\n| Initial Icon | Final Icon |\n| - | - |\n| ![SVG of chevron right icon](https://about.gitlab.com/images/blogimages/why-i-love-contributing-to-gitlab/chevron-right.svg) | ![SVG of details block icon](https://about.gitlab.com/images/blogimages/why-i-love-contributing-to-gitlab/details-block.svg) |\n\nThe last thing to do was resolve my failing tests, and I had several teammates help me do that.\n![Gif of the shortcut being used](https://about.gitlab.com/images/blogimages/why-i-love-contributing-to-gitlab/demo.gif)\n\nToday [this change](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54938) merged! Now I solved a pain point for me and others. It took a few months to go from idea to production, but the effort was super low. I'd say the return on my initial investment, 10 minutes, is super high.\n> Having a direct impact on a product was never an option for me before joining GitLab.\n\n![Image of participants in the Merge Request](https://about.gitlab.com/images/blogimages/why-i-love-contributing-to-gitlab/participants.png)\n\n\nThank you to everyone that helped me deploy this\n",[727,728,729],"UX","product","AWS",{"slug":731,"featured":12,"template":13},"why-i-love-contributing-to-gitlab",{"content":733,"config":745},{"title":734,"description":735,"authors":736,"heroImage":738,"date":724,"body":739,"category":9,"tags":740},"Placebo Lines on the Pipeline Graph","Have you noticed the connecting lines missing on your pipelines lately? Here's why",[737],"Sam Beckham","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749679507/Blog/Hero%20Images/ci-cd.png","\n\n{::options parse_block_html=\"true\" /}\n\n\n\nHave you ever pressed the close door button on the elevator, in the hope that you'll save a few precious seconds?\nOr got frustrated at the person stood next to you at the cross-walk, neglecting to press the button?\nWell, maybe they know something you don't, or perhaps you know this already.\nMany buttons in our society lie to us.\n[David McRaney](https://youarenotsosmart.com/2010/02/10/placebo-buttons/) dubbed these, \"Placebo buttons\" and they're everywhere.\nThose elevator doors won't close any faster and the cross-walk button has no effect on the lights.\nThe only lights they control are the lights on the buttons themselves.\nThey give you the feedback you crave, but that's all they're doing.\n\nThese placebos aren't constrained to the physical world, they're prevalent in [UI design](/blog/the-evolution-of-ux-at-gitlab/) too.\nFrom literal placebo buttons like [YouTube's downvote](https://www.quora.com/Does-downvoting-a-comment-on-YouTube-even-do-anything), to more subtle effects like Instagram always [pretending to work](https://www.fastcompany.com/1669788/the-3-white-lies-behind-instagrams-lightning-speed), or progress bars that have a [fixed animation](https://www.theatlantic.com/technology/archive/2017/02/why-some-apps-use-fake-progress-bars/517233/).\nThey're everywhere if you know where to look.\n\nAt GitLab, we created a placebo of our own in one of our core features; the pipeline graph.\n\nThose of you who have used our pipeline graph, will be familiar with its appearance.\nThere's a series of jobs, grouped by stages, connected by a series of lines depicting the relationships between the jobs.\nBut these lines might be lying to you.\nThese lines are indiscriminately drawn between each job in a stage, regardless of their relationship.\nThese lines are placebos.\n\n![The old pipeline rendering with lines connecting every job in a stage](https://about.gitlab.com/images/blogimages/placebo-lines_old-graph.png)\n\nThis wasn't a problem to begin with.\nA basic pipeline has several jobs across a handful of stages.\nJobs in each stage would run parallel to each other, but each stage would run sequentially.\nIn the image shown above, all the jobs in the test stage would trigger at the same time. Once those jobs had finished, all the jobs in the build stage would trigger.\nWe used rudimentary CSS to draw lines connecting each job in one stage to each job in the next.\nThese lines weren't calculated based on their connections, but still reflected the story they were telling.\n\nSince the introduction of `needs` relationships in [v12.2](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/47063), pipelines got a bit more complicated.\nNow you could configure a job in a later stage to trigger as soon as a job in an earlier stage completed.\nLooking at our old example, we could set the API deployment to run as soon as our spec tests passed.\nThis skips the remaining tests and the entire build stage, turning our lines into pretty little liars.\n\nWe had many internal discussions about these lines, and how to show the relationships between jobs.\nThere's the [`needs` visualization](https://docs.gitlab.com/ee/ci/directed_acyclic_graph/#needs-visualization), which does an excellent job of displaying these relationships, but the main pipeline graph was still inaccurate.\nFor the past few months, we've been [refactoring the pipeline graph](https://gitlab.com/gitlab-org/gitlab/-/issues/276949), giving it a new lease of life and fixing some of its issues along the way.\nOne of those issues were the faked lines.\nIn the new version, we can accurately draw lines between jobs.\nLines that actually depict the relationships jobs have with each other.\nNow the lines no-longer lie!\n\n![The newer pipeline graph showing the correct needs links between jobs](https://about.gitlab.com/images/blogimages/placebo-lines_new-graph.png)\n\nThe above image shows an unreleased version of the pipeline graph.\nYou can see the lines drawn between the jobs to show that the `deploy:API` job can start as soon as the `rspec` job is successful.\nSomething the old lines (shown earlier in this post) would have been unable to depict.\n\nOne unfortunate downside of this is that these lines can be quite expensive to calculate.\nThey're actual DOM nodes, drawn deliberately and placed precisely.\nOn smaller graphs this isn't a problem, but some of our initial tests have found pipelines with a potential 8000+ job connections.\nThat kind of calculation would grind the browser to a halt, and nobody wants that.\n\nAt GitLab, we believe in boring solutions.\nWe make the simple change that sets us on the path towards where we want to be.\nShip it, get feedback, and iterate.\nSo that's what we did.\nIn the first phase of this rollout, we shipped the new pipeline graph with no lines connecting the jobs.\nWe don't have to worry about the expensive calculations, and we still get to roll out the refactored pipeline graph.\n\n![The current (v13.11) pipeline graph showing no links between jobs](https://about.gitlab.com/images/blogimages/placebo-lines_current-graph.png)\n\nWe know some of you will miss them, but fear not.\nBoring solutions are just technical debt if you don't iterate on them.\nSo the [improved lines are coming](https://gitlab.com/groups/gitlab-org/-/epics/4509) in a future release, along with several other improvements to the pipeline graph.\nWe're already starting to roll out the new [Job Dependencies](https://gitlab.com/gitlab-org/gitlab/-/issues/298973) view which shows the jobs in a (much closer to) execution order.\nStay tuned for more updates, and watch [Sarah Groff Hennigh Palermo's talk](https://www.youtube.com/watch?v=R2EKqKjB7OQ) for the technical side of this effort and a deeper dive into some of the decisions we made.\n",[741,742,743,744],"CI","frontend","agile","design",{"slug":746,"featured":12,"template":13},"placebo-lines-on-the-pipeline-graph",{"promotions":748},[749,763,774],{"id":750,"categories":751,"header":753,"text":754,"button":755,"image":760},"ai-modernization",[752],"ai-ml","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":756,"config":757},"Get your AI maturity score",{"href":758,"dataGaName":759,"dataGaLocation":244},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":761},{"src":762},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":764,"categories":765,"header":766,"text":754,"button":767,"image":771},"devops-modernization",[728,558],"Are you just managing tools or shipping innovation?",{"text":768,"config":769},"Get your DevOps maturity score",{"href":770,"dataGaName":759,"dataGaLocation":244},"/assessments/devops-modernization-assessment/",{"config":772},{"src":773},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":775,"categories":776,"header":778,"text":754,"button":779,"image":783},"security-modernization",[777],"security","Are you trading speed for security?",{"text":780,"config":781},"Get your security maturity score",{"href":782,"dataGaName":759,"dataGaLocation":244},"/assessments/security-modernization-assessment/",{"config":784},{"src":785},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"header":787,"blurb":788,"button":789,"secondaryButton":794},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":790,"config":791},"Get your free trial",{"href":792,"dataGaName":51,"dataGaLocation":793},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":496,"config":795},{"href":55,"dataGaName":56,"dataGaLocation":793},1772652066212]