My first major open source project contribution was merged Friday night. I completed a major overhaul of the BeeWare website, and the changes are now live. I am beyond ecstatic. I started this in August 2024, and even accounting for the huge break in the middle, it took me approximately six weeks of work to complete.
This is really my second contribution, but the first contribution was simply fixing a typo in a tutorial. I removed an "s" from a word that should have been singular. It counts! But it's definitely not "major" by any stretch of the imagination.
For anyone interested, here is the pull request. (A pull request is the method to contribute to a project whose code is hosted on GitHub.) By the numbers, I changed 449 files, and made 3,734 additions and 4,402 deletions. (The additions refer to modified or added lines of code, and the deletions to removed lines of code.) If this sounds like a lot, it's because it is. I don't think I have any way to view my previous contributions sorted by these metrics, but I'm almost certain that I've never come close.
My first experience with the BeeWare folks as a group was at PyCon US 2024. I decided at the Sprints that I wanted to learn something new. After talking to a friend about my options, I ended up at the BeeWare Sprint. There, the project lead, Russ, suggested I try out the BeeWare tutorial. I made it about halfway through before my brain was overloaded, but that meant I had a little app on my phone that accepted a name, and replied with "Hello, name!", which was pretty exciting in itself. As I worked through the tutorial, I watched others working on contributions to the project. Russ and his team were incredibly welcoming and supportive to everyone, regardless of their experience levels. They helped anyone who needed it, including folks who had never used Git or GitHub. It didn't matter how many or what type of questions someone had. The amount of effort that went into ensuring anyone who wanted to could contribute to BeeWare was impressive and amazing.
While going through the tutorial, I found a typo, and since the whole project is on GitHub, I was able to put together a pull request to fix it. When you get your first contribution to BeeWare merged at the Sprints, you earn a challenge coin. (When a pull request is "merged", it means the contribution is accepted and applied to the project.) Russ merged my pull request, and awarded me the challenge coin via a handshake. If I'm being completely honest, I nearly began crying. Granted, there were a lot of feelings contributing to this, including those stemming having left behind an amazing community when I left my last job. This was the first time a community felt like home since that time, and I had been welcomed into it.
I immediately wanted to be a bigger part of it, and told Russ as much. I didn't know enough Python to contribute to the codebase, but I was really good at documentation, and thought that might be something I could help with. He said that was definitely a place that they could use help. We agreed to chat after the conference to sort out the specifics. In the meantime, I started looking into their documentation. I found the website difficult to navigate, and found it difficult to find the documentation that might need to be worked on. When we finally got on a call, I mentioned this, and Russ said the website was something that had been bugging him for a long time, but he didn't have the cycles to update it. I asked if that would be a better initial use of my time, and he said it would absolutely be helpful. In my mind, it would be as straightforward as rearranging some things. Even with my very limited HTML, Jinja and CSS experience, I decided to take it on.
The website uses a content management system (CMS) called Lektor, which is basically a static site generator, which meant it was, in a very minimal way at least, similar to my personal site. The code syntax was enough similar to Jinja that I was able to mostly figure out what was going on in the code itself. Beyond that, though, I would end up learning a lot of new things about Lektor that weren't like anything I'd ever worked with.
There was a lot of rearranging involved, but it came with a caveat. Russ has a policy that no link should ever become a dead link, which is to say, all old links should redirect to the new location of the content, or at the very least, redirect to something useful. I ended up talking this through with my friend Jeff, and suggested that a script to parse a particular directory that I thought was the only place needing redirects would be helpful. He took it a whole different direction, and ended up writing a script that parsed the Git history on the pull request, figured out where things had moved, and generated the redirect file at the old location. Initially, I thought it was broken because it returned over 70 updates, when I was expecting about 25. It turns out if Jeff hadn't written this script for me in the way he wrote it, I would have missed out on two-thirds of the redirects. There were a few sections I moved that had a massive number of subsections that I had missed entirely.
The review process started out a bit rough for me. To be clear, Russ did nothing wrong. He was kind throughout the review. The issue I was having was that he was treating me like a seasoned developer, while this was almost literally my first project contribution since my job, and definitely the biggest I'd ever done. Most of this situation involved me trying a few things, and Russ countering some part of them with a different idea he had. As this project is his, this made perfect sense. And, in general, I imagine for a lot of folks, a reviewer not wasting any time and getting straight to the point is quite desirable. For me, though, it became clear that I needed more positive feedback. This would, under no circumstances, take the place of the constructive feedback. Code reviews cannot move forward without the reviewer being clear about what they need. I assumed, and it would turn out rightfully so, that Russ was implying that part of what I was doing was correct by not commenting on it, and only commenting on the things needing changes. I spent many years dealing with a "no news is good news" feedback situation, it never worked for me, and I realised that I certainly didn't want to deal with it in my volunteering capacity. If I was going to continue with this project, this needed to be addressed. So, I gathered the courage to ask Russ if we could have an incredibly awkward call. He was, of course, happy to do so. For me, awkward didn't begin to cover it. I would have to make myself incredibly vulnerable to express my needs to basically a stranger. This is not an easy thing to do. Add into that, that this is a somewhat professional situation, and, while it shouldn't be, showing emotion professionally is discouraged at best. Add into that, that I respected Russ and what he did, and had no interest in causing him to have a diminished viewpoint of me. Admittedly, I was able to reach out to a mutual friend to verify that I wasn't stepping into a trap with this. I already knew this, but having someone who actually knew Russ tell me that was the case gave me a bit of confidence. I ended up writing up what I wanted to say, knowing I would struggle in the actual call. I explained to him that I was not a seasoned developer, and that I needed a different kind of feedback than he was providing. I clarified that he had done nothing wrong, and that the issue here was my needs as a new contributor were different than he might have expected. I also explained that repeatedly tossing out ideas and having them countered was becoming disheartening, as it was making me feel like I was not able to do things properly. Finally, I made it clear that I could understand if this was simply his way of doing things, and that there was nothing wrong with that, but that it wasn't something that would work for me long-term, and I would not be able to continue to contribute if that was the case. Russ was 10000% receptive. He explained exactly what I assumed about where he was coming from. He also explained that he thought we were on the same page with tossing out ideas to see if they would work or not, because he hadn't been entirely clear to himself on what he wanted out of a website update to begin with. I said I understood that on some level, but the lack of explicit positive feedback was leading to my difficulties. He said it was important to him to make sure I feel welcomed and supported, and that he would do what he could to augment his reviews with more positive feedback. The conversation was incredibly productive, and I felt entirely heard and understood. I am deeply adamant about communication being critical to affecting change in any individual or community. I also harbor no delusions that it will always be this well received or effective. This community and its project leads are special in that way. I want to be able to tell you to always be willing to express your needs in situations like this, but I struggle to do so because I absolutely cannot guarantee you'll be safe doing so or that there will be any reasonable response to your request. I genuinely believe communication is needed in all situations, but I greatly understand it's not always viable for everyone. I shared this situation in hopes that, where possible, others will find the courage to do the same, knowing that in the right situations, it can be a positive experience.
The very next review was exactly what I needed: positive feedback on what was right, concrete goals, and clear changes requested. However, this is when I hit a wall. I had a lot going on in the rest of my life, and needed to take a break from the project. I reached out to Russ to let him know that the review was exactly what I was looking for, but that I needed to step away for a bit. As expected, he understood. As time went on, I would look at the PR, get overwhelmed, and decide not to pick it back up at that time. Part of the issue was that one of the requested changes was to find, in the text, all references to links I had updated and update the reference. The links all had redirects, but Russ reasonably wanted the text references to be the updated links. If you recall, I had changed over 70 links. And there were a lot of references to different parts of the site in text. There were two other requested changes as well: a CSS consistency issue, and a deep Lektor issue. Russ offered to handle both of those if needed. The CSS issue looked straightforward enough, but the Lektor issue was definitely outside my wheelhouse. I decided I would only ask for his help once I had completed the bits I was capable of. But that meant getting past the hurdle of the links.
Eventually, I returned to Jeff for help. We both thought he could modify his script to find outdated links in text content and update them. After about an hour and a half, he had gotten nowhere useful, and suggested that it would need to be done manually. He was able to provide me with a list of the redirects we created, though, and this gave me a starting point. So, a couple of weeks ago, armed with the list, I sat down and manually searched the entire project for all 70+ updated links and replaced every reference I found with the updated link. I verified my work multiple times before submitting it, and after going through the submission one more time, still found one link I had messed up. Pro-tip: Always quadruple check your work when it involves find-and-replace. Turns out find-and-replace is only as smart as the text and parameters that you give it, and the results can end up being overly aggressive if you're not explicit.
The CSS bits turned out to be as straightforward as I expected. There was a consistency issue between two pages, and I was able to copy the syntax from the correct page to the inconsistent page and the issue basically resolved itself. For the most part. I noticed on the correct page that there was a weird bit of whitespace below one element in a list of elements, and I couldn't sort out why it wasn't present in all the elements. I also found it strange that Russ hadn't mentioned it, as he noticed all of the other inconsistencies. I mentioned it to my housemate who decided to take a crack at it. We found it wasn't present in Edge on Windows, but it was present in Firefox. This led me to believe that it wasn't present for whatever browser Russ was using either. I was prepared to pretend it didn't exist. As a total shot in the dark, I happened to bring it up on a group call to a bunch of folks who do web stuff, assuming nothing would come of it. Less than five minutes later, the issue was identified and a magical CSS incantation was provided to apply appropriate spacing exactly where I wanted it. (Thank you so much to Chris and Marijke!) I was super excited to be able to submit the CSS changes with the oddity fixed as well.
With everything else addressed, I was finally ready to let Russ know that he would need to handle the Lektor issue he had identified. Most of this is over my head, and while I was at least able to figure out how to edit it, I certainly didn't understand it enough to address the issue he had called out. Lektor uses "data models" as.. templates? sort of?.. (again, a bit over my head so my explanation is going to be rough here).. and I had simplified the website itself, removing an entire layer of complication, but I had apparently added a data model, which didn't make sense to him. It turns out I hadn't added one, but I had modified and used one that was no longer necessary for a significant part of my changes. He was able to simplify things to use a different template that was used by multiple other pages, and remove the individual one I had been using. I'm deeply glad I decided not to attempt that part of the change request, as what he wanted was definitely outside my wheelhouse.
Following his additions, Russ marked the pull request as approved, but asked that I go over his changes before he merged it. Friday afternoon, I did so, and let him know that everything looked good to me. Friday night, it was merged.
This experience has ultimately been fantastic on so many levels. I found a welcoming, supportive community that feels like home. I found an open source project to which I can contribute. I found a group of people who are as excited about what they're doing as I am to be a part of it, led by someone who not only cares about the project, but also cares very deeply about everyone involved. The entire team is always up for helping folks out, teaching how to use and contribute to BeeWare, and supporting those who want to learn and help. I'm quite passionate about all of these things, and I found a place where my passion and skills are greatly appreciated. I know my positive experience with all of this is, as a general concept, not unique, and that is utterly amazing. It's one thing for me to have found all of this, it's another thing entirely to know others are finding the same thing.
I will be chatting with Russ next week to figure out what's next for me with BeeWare. There's still plenty to be done with the website, but there's also the original need for documentation improvements. I'll find out soon where my assistance will be most useful. I'm really hoping to help out at the BeeWare Sprints this year at PyCon US. I still don't know enough about BeeWare's codebase to help there, but my knowledge of the contribution process should put me in a good position to help folks who are new to everything with their initial setup. I'll definitely be asking if this is even something they're interested in.
I'm looking forward to becoming a regular contributor. Really, though, my ultimate goal is to be able to welcome others into the community and support them in the same way I was welcomed and supported. The more I learn and contribute, the better I will be able to achieve this.
Onto the next thing!