 I don't know about you, but I love the feeling of getting to hit the merge button on my pull request and sending it off to production. That's the ultimate goal as a software engineer, right? To get our code out into the world on prod. However, unless you're living life on the edge, there's a big hurdle you have to overcome before getting to push that merge button, getting approvals on our pull request. Before we dive in, I want to give y'all a little background on myself. I'm Kara. I'm based in Nashville, Tennessee, and I have two adorable dogs, Maggie and Franklin. Before tech, I pursued a career as a ballerina, and then I worked as a music publicist. But in 2016, I enrolled in a front-end engineering boot camp, and I've been in tech ever since. I'll do a little plug here. I spoke about my career journey and why non-traditional developers are amazing at EmberConf in 2020, so you should go and check that out on YouTube. Now I work as a user interface engineer at CrowdStrike, a cybersecurity company aiming to stop breaches. And as a UI engineer, I write and look at a lot of pull requests, and I've seen both good and bad PRs. But what even makes a pull request good? Let's take a look at this totally real PR. This is not a good pull request, but why? First, glancing at the title doesn't really give you an idea of what happened in this PR, other than some things were fixed and some other things were added. But that's okay, let's take a look at the description. We're told a little bit more information about what has gone on here, a component and some mock data were added, but we're given no instructions on where we can even find this new component in the UI or how to test it. Last, but not least, even though it seems like a pretty straightforward change, seeing over 1,300 change lines of code would imply otherwise. As a reviewer looking at this pull request, we really have nothing to go off of and are left in the dark. And the sad part of this is that, unfortunately, I've seen pull requests that look exactly like this. And in the long run, you're only making the PR process longer for your reviewers by not taking the time and effort to put a little bit more description into your PR. Pull requests are telling the story of your changes. They're a conversation between you and your reviewers. And as the author of that story, you want to make sure the process of reviewing your pull request is as easy as possible. It's vital that our PRs give everything to our reviewers that they may need. They should concisely describe our motives and thoughts behind our changes, all the while preemptively answering any questions our reviewers may have. Just like a good story, our pull request should begin with an outline of its chapters. In our case, our chapters are our commits. We've all seen commit messages that provide absolutely no insight into what has gone on. But each commit message should show a progression in your pull request story. The subject line of your commit should give an overview of the changes that were made, while the body should provide additional context like why it made that decision, any possible future implications, and then a reference to the ticket or issue number. Using conventional commits can help provide even more at a glance insight. This is where the commit subject line includes various prefixes that follow semantic versioning. You can use feet for a feature or fix, but it can also include items like test, chore, or style. Here's a great example of a descriptive commit message from the Ember Core repo. The subject line, Update Error Message Instructions is easily understandable. The author could have left the commit at that, but they went into further detail in the body of the commit message, explaining why that change needed to be made. Now, anyone looking at this commit gets the full story of what was happening. Having explicit commit messages is important, but in order for your story to be understood, they need to be organized in a way that makes sense. It'd be extremely confusing to someone if a book had Chapter 2 before Chapter 1. You'd have no idea what was going on. You want to make sure that your reviewers can easily follow the story you're telling about your changes. You're probably sitting there saying, Kara, well, I may have a fix that I need to implement later when I'm writing my code, or what if I need to refactor something. That's totally OK. The great thing is that as developers, we have the power to rewrite history with rebasing. If you aren't familiar with rebasing, it allows you to rework your commits. You can change the order, rewrite, rewrite your commit messages, or even squash two or more commits together. Your commit history can go from something that looks like this, jumping around from implementing new components to adding mock data and PR fixes, to something like this that is much easier for anyone looking at your code to follow. This history gives a clear outline of what has occurred in each commit. It shows a clear path that the developer was taking. You can see that one-off commits like fixing the form and applying feedback from the review were squashed into the commits where those changes make sense. Now looking at the commit history, reviewers are able to easily follow the author's development process, and anyone looking at this in the future can easily dive in and know what to expect on each commit. If our commits are the chapters to our poll request, then our actual code implementations and changes are the story itself. And it's important that we pay attention to the size of our story. There's a computer programming principle called the single responsibility principle. It states that every module, class, or function and computer programming should have responsibility over a single part of that program's functionality, and it should encapsulate that part. All of that module, class, or function services should be narrowly aligned with that responsibility. It's basically stating that a single module, class, or function should only focus on one thing. It should only have one responsibility. This same concept applies to poll requests. You would think that a PR that touches a lot of files would receive more comments than a smaller PR, but a study of a Cisco systems programming team revealed that developers should review no more than 200 to 400 lines of code at a time. Beyond 400 lines of code, the ability to find defects diminishes. So by breaking a larger poll request into several smaller lines, you're actually increasing the chance that you'll receive feedback and the potential for your reviewers to catch a bug that may have been overlooked. Here is a great example of keeping a poll request small from the Ember learning team. An issue was created to fix some of the API links in the guides. The catch was that this needed to happen in the docs for multiple versions. The developer that took on this task created a single PR request for each version where the links were updated. They easily could have made this one PR, although it would have been pretty large with a lot of file changes. But by opening one poll request per version, they're enabling the reviewers to easily be able to parse the changes and look for any issues or misspots. Breaking down a poll request sounds straightforward, but it can definitely sometimes be daunting. How do we know when a poll request is getting too big and should be separated? So say you're starting a new project on your team, and that includes generating a lot of boilerplate code. That starting code should be its own poll request. This is because you'll be adding a lot of files at once, and you'll want your reviewers to be able to look through each of those files to make sure that everything that is needed is included. After generating all of that boilerplate code, now it's time to start on the index page for that project and generate some luck data. That work can be separated into its own poll request as well. By having each poll request concentrated on a singular task, you're allowing your reviewers to focus on one thing at a time. They're not getting bogged down trying to put together pieces of what's really going on with a million files changed. So we've covered the chapters to our PR story and the story itself, but what's a good story without an introduction? That's where our title and description come in. A poll request title is the first bit of information you are providing to your reviewers for what they're about to look at. It needs to give a concise overview of what is happening in the PR. One of the most common mistakes I see is using the last commit message as a title of your poll request. But this is only giving a brief peek into your story and not explaining the entirety of your changes. Here you can see two great examples again from the Ember learning team. The first example, US CSS instead of utility classes from ES Note to allow HTML to be backwards compatible, is to the point explaining what changed and even gives a quick explanation of why. The second example, upgrade to latest Ember and make 3.16 the lowest supported version does this as well. You're even alerted to the fact that this poll request is going to contain a breaking change, which is extremely important information that reviewers need to know upfront. The description is where you can provide even more detail for your viewers or anyone looking at your poll request in the future. Something important to keep in mind when writing your description is that you shouldn't assume the reader's prior knowledge of the area of the code base you're working in. It is your job as the author to provide that context to them. You can do this through including information on the what, why, and how of your changes. What changes were made, why you made those changes, and how the reviewers should test them. The what should provide explicit details on the changes in your poll request. Remember how our commits are the outline of our story? Well, this is where that outline comes into play. Use your commit messages as a baseline for explaining your changes to your reviewers. Expand on what you previously wrote with a bit more detail. This section of your description should also include any lingering to-dos linked to their follow-up ticket. Remember that you want to cover all of your bases in your poll request, so it's important to provide the context of what has happened or has not yet happened within your poll request to your reviewers. The why section of your PR explains the reasoning behind your changes, including any architectural decisions you made and any possible implications from those decisions. This can include user stories for why the specific feature was added, thoughts behind refactoring you did, or even explaining your entire thought process on your changes. You should also link to the ticket or issue that your PR addresses to provide even more context to your reviewers. Lastly is the how. How are your reviewers supposed to test your code? You can provide all the details about what you changed and why, but your reviewers probably don't know the steps to actually reproduce your changes in a demo environment. Go through the steps of demoing your code changes and write each of those in a list for your reviewers. You want to be as explicit as possible. Provide direct links for the route they need to test and any feature flags or permissions they may need. You also want to make sure those exact scenarios you want tested or laid out. For example, certain steps your reviewers may need to show an error state. You want to detail the exact interaction that will need to happen. Here's a well-written description for an update to the Ember website. It's still a work in progress, so it's not totally ready to be reviewed, but it combines a lot of what we've been talking about. At the top is a link to the corresponding issue. Then the developer goes into a list of what exactly was implemented in the pull request and why those changes needed to happen. They dive even deeper by listing the remaining requirements that need to be addressed and provide additional notes to encourage feedback. And once this PR is ready to be taken out of a work in progress status and ready to be fully reviewed, the only thing that would make it even better is to add the exact testing steps reviewers can take to make sure that the language switcher is working as expected in a test environment. A way to enhance your pull request description even more is by adding a visual aspect. According to the Visual Teaching Alliance, visuals transmit information faster than spoken or written words. We can get a sense of the visual scene in less than one-tenth of a second, and visuals are processed 60,000 times faster in the brain than text. Think about when you're putting together a piece of furniture. There's written out instructions, but there's also visuals to help you. You actually see a picture of the base of furniture along with diagrams of where you need to drill and add screws. We all poke fun at IKEA's drawings of how to put together furniture, but honestly, that's a lot easier to parse than complicated instructions being written out with no visuals of all the different parts. Adding a screenshot of the before and after of your changes and highlighting the differences can help your reviewers process your changes even faster. And you don't even need to download software to do this. You can simply take a screenshot on your Mac by pressing Command-Shift-4 and highlight the area where you want a screenshot. You're then able to use the markup feature to draw a square or circle around what you've added or changed. I like to often draw an arrow to kind of draw attention to it more and add a brief description on the screenshot itself. You can take this even a step further by recording your screen through something like QuickTime and actually walk your reviewers through your changes. This is great when your reviewers may not be as familiar with the area of the code base you're working on. You taking the extra five minutes to record a demo can save your reviewers 15 minutes of trying to get up to speed with what you're doing. And the thing I really love about recording a walkthrough is that your reviewers get to hear your voice and see a live demo. We're living in an asynchronous world and those small things really make a difference in helping your reviewers fully understand what's going on in your PolarClust. Our peer is officially done now, right? Not exactly. Before adding any reviewers to my PolarClust, I become my own reviewer. I look through each of my commits to make sure they're linear and self-explanatory and take a look through my code as well. During this process, I often catch most simple mistakes like a leftover console log. While doing this, I also annotate my own PolarClust. Have you ever been reading a book and left yourself notes in the margins? This is the same thing before your reviewers. While reviewing your own changes, comment on specific lines of code that may leave your reviewers with questions. You can use this to explain why you chose to do something a particular way, like if the direction you decided to go was a little outside of the norm, or you can highlight a specific line of code to get more input on. Here's an example of doing this from a PolarClust for the Ember website. The author went through and commented on their PolarClust to clarify any areas where reviewers may have questions. This is going from the language switcher that kind of talked about earlier. So they actually go into a bit more detail on why they implemented this translation as one line instead of translating each individual segment of the string. Further on in that PolarClust, the author explains why the additions they made to the package.json file were necessary. Pointing out these types of changes in your PolarClust were imperative. And doing so through commenting on your own PR helped shed even more light on them. Now that you've put together the story of your PolarClust, added your reviewers and officially opened your PR. You would think that things end there. However, the conversation around your changes are only just beginning. The entire point of a PolarClust is to get eyes on your code so others can catch bugs or provide feedback. And an essential part of the PolarClust process is responding to that feedback. PolarClust are a story and you should be having conversations around that story with your reviewers. When receiving that feedback, you wanna make sure that you're understanding the reviewer's perspective. They're commenting to learn more about what you've done and to help you grow as a developer. It's okay to get comments on your PolarClust and you shouldn't view that as a negative thing or take it personally. Honestly, I take it more personally if I receive zero comments on a PR. I want that feedback because it's pushing me to become a better developer and helping me think more outside of my box. If your reviewer makes a comment that you don't quite understand, then ask for clarification. However, PolarClust are not the place to be debating about certain implementations. These conversations can easily get out of hand and overthrow the original objective of your PR, which is to get it reviewed and merged. If you catch that happening, take the conversation off of the PolarClust and into a face-to-face or virtual meeting. The important part of this is to update your PolarClust with any decisions that are made during that meeting. Again, you wanna be completely transparent on your PRs. You wanna make sure that the outcome of this meeting and any decisions are there for your reviewers to be able to be made aware of. Also remember that not all suggestions need to be implemented. Feel free to provide any clarification to reviewers on your decisions behind certain changes if they have questions. This is where becoming your own reviewer and annotating your own PolarClust ahead of time really comes into handy, comes in handy. By doing this, you're making it easier for your reviewers to understand your changes and eliminating the need for that back and forth that could happen. Whether you only get one or two comments or 10, you wanna make sure that you reply to every single one. PolarClust should not be merged until every comment has been addressed, whether that's implementing a suggestion or not. If you do apply a suggestion from a reviewer, be sure to acknowledge that. Give it a thumbs up. Something I really love about GitHub and GitLab is that they both have a resolve comment feature in their PolarClust. This allows you to let your reviewer know that you've acknowledged their suggestion, have put it into effect, and it's no longer a concern. By clicking that resolve comment button, or if that's not an option, simply liking their comment or replying with a thumbs up emoji, you're actually making it easier on both yourself and your reviewer to know that their comment has been addressed. Plus, this is a great way to keep track of what you have or have not yet gotten to in your PolarClust feedback. Not all comments will be within the scope of your PolarClust though. Ultimately, it's your decision what is and is not within scope. But if something is outside of the scope, then you need to create a follow-up ticket. The key, as we've been saying to Great PolarClust, is being completely transparent. Explain to your reviewer why their suggestion is out of scope and include the link to the follow-up ticket where it will be addressed. So after all the comments are addressed, it's finally time you get to push the merge button. You've accomplished your goal of merging your code to production. And that's another ticket marked off your to-do list. Now it's just time to start that process entirely over again with a new ticket. Thank you all so much for listening to my talk and enjoy the rest of EmberConf.