Forks of Forks

Jonas Brømsø - Jan 22 '23 - - Dev Community

As a maintainer of an open source project. I love when people use it and/or contribute. This mean that the project prove useful and perhaps bring value to somebody other than myself. The projects I am involved in are mostly because they scratch an itch of mine and the projects I initiate myself are always focused on something I need, if others can use it is just a plus.

I am not so concerned with how many are using my projects, but it makes me happy when I receive feedback like PRs or issues and I do my best to accommodate, but I am not chasing users or adoption in that sense, since most of what I do is small side-projects and not grand scale framework or platform endeavors.

On GitHub we have stars, which is a good indicator of how popular or at least how bookmarked your project is, somebody made a mark and showed interest at some point in time. Issues is another indicator that others are using your project, since you might receive requests, bug reports, questions etc. All coming from a place of interest and motivation. Last but not least an important metric is of course PRs, when somebody takes the time to sit down to patch or improve your project via code or documentation.

All of these are different ways you can contribute to an open source project and they all play a role in the life cycle an open source project. In order to contribute with code you most often have to create a fork in order to create pull requests (PRs). The fork is a very interesting phenomenon, which I want to touch on in this post.

I have mentioned this on several occasions that I am not the original author of the GitHub Action GitHub Spellcheck Actions, but I am a heavy Markdown producer and a generator of many spelling errors, so this was a very interesting project to me. At some point I took over the reins of the project and now I maintain it.

Sometime ago received an issue for the project, well a few months ago, but please bare with me. The issue was the ability to share some common components between projects using git submodules. I was thinking about it for a long time and was on the brink of indicating that it was a wont-fix. This is however not something I enjoy doing and it is really last resort. When people take the time to contact me, I prefer to provide them with a positive answer, I might not implement what they need, but at least a work around or a pointer to another tool or project which might help them out, can be an option when applicable.

Coincidentally I was looking at the forks of GitHub Spellcheck Actions. Many of the forks are from users which have contributed over time. And their forks are still around. What had caught by eye was that there was forks of forks. This sparked my curiosity and I decided to have a look at the forks of forks to see if I could find out why there was forks of the forks instead of the original repository.

You can quite easily see the forks of your project if there are any. The project mentioned above has around 39 forks at the time of writing.

The brief review brought to issues to my attention:

  1. It was indicated that the original repository did not support a certain feature in the form of support of more languages
  2. A feature had been implemented to save a part of the configuration in a specified place instead of in a default place

I evaluated the original project, since I fell like I had touched on the particular topic of controlling the path to the configuration file. And yes, in release 0.9.0 it had been implemented.

But I could see from the forks of forks that I was missing an aspect. The local dictionary, which was part of the configuration, was stuck in the root of the project repository in all of the mentions in the documentation and examples for the action.

GitHub Actions are convenience for packaging tooling for execution on the GitHub platform or using a local runner etc. As you can see on the GitHub Marketplace this mean that a lot of actions are wrapping of common and useful tools to adapt to the GitHub toolbox and toolchain. The same goes for GitHub Spellcheck Actions, it is an implementation based on PySpelling a nifty tool to do spelling checks on Python, Markdown, Text files etc.

This mean that the core functionality is not maintained by be me via the GitHub Action, I am just maintaining the GitHub Action part, which is basically:

  • a shell script
  • a Docker image
  • Some documentation

This mean that when issues are raised, they have to be evaluated whether the are related to the action or to the core component: PySpelling.

Luckily the maintainer of the core component, keeps a keen eye on the action repository and help people out, sometimes before I have seen that an issue has been raised (timezone differences).

If you revisit the two issues, which seemed to be the main driver for the forks of forks, it seemed that these could be categorized as issues with the action. So I did some testing and read up on the documentation of PySpelling. PySpelling is very flexible and it's configuration is very complex or can become very complex. What struck me was that PySpelling actually supported a lot of languages, I have just always focused on the Markdown part, since spelling in code, is not really something that I concern my self with, the documentation is much more my focus.

Supported languages (filters in PySpelling):

  • C++
  • HTML
  • JavaScript
  • Markdown
  • ODF
  • OOXML
  • Python
  • CSS
  • Text
  • XML

REF: https://facelessuser.github.io/pyspelling/pipeline/

I had an older repository from a prototype I did and it contained some JavaScript and HTML. After some experimentation, I got the configuration working for checking the spelling of JavaScript and a HTML files.

Going over the documentation for PySpelling for the above implementation let me to the second part.

With config_path introduced with the GitHub Action in 0.9.0, you could move the main configuration if the action to your .github/ directory to keep it out of the root. Inside the configuration, where you point to the local dictionary (the wordlist as it is referred to), you could specify a path. So it is quite easy to just:

  1. Put your wordlist in .github/
  2. Set the path in your Spellcheck configuration as: .github/wordlist.txt

So both issues addressed I discovered via the forks of forks can actually be handled via the original repository, at least since version 0.9.0 for the configuration file placement. I actually believe that the support for the many languages have been around for quite some time with PySPelling, but since this is not my implementation I am not sure.

The forks or forks originate from a fork, of course. This fork pointed to a third issue.

PySpelling has had a default configuration file for a long time: .pyspelling.yml or .pyspelling.yaml. When the GitHub action was started in introduced another convention: spellcheck.yaml. So the action was actually not compatible with the core component. I do not know the rationale behind this, I regard it as a design flaw, but I do see the challenge in regard to this. Luckily a contributor has addressed this exact issue and with release 0.27.0, support for the default PySpelling configuration file was introduced.

To revisit the issue that was raised about pushing the configuration to a directory which could be handled as a git submodule. This could actually be handled for both the configuration and the custom dictionary (wordlist), by using the flexible configuration of the GitHub action and the core component PySpelling.

By reviewing the forks of forks, I was let to a solution and I could help a user of the project. Next up is updating the documentation, so that this flexibility becomes more obvious and perhaps it can help others.

This leads me back to the ways of contributing I mentioned in the beginning of this post.

  • A request in the form of an issue was raised and a solution was found, the documentation updates will improve the project
  • The first of the two issues demonstrated via the forks of forks, can be addressed I believe via configuration of the core component, the documentation should highlight this and the overall project improve with this documentation update
  • The second of the two issues demonstrated via the forks of forks, have been addressed via a direct contribution via a PR to the project

I have by no means problems with people forking projects without contributing back. The projects are out there to be used. I most however admit, that I would have preferred if the users forking the project had reached out and challenged the project and perhaps we could have come up a solution to the mentioned issue together.

Currently there are several actions available on the GitHub Markedplace, which are basically the same project. Nobody ever hurt from a little competition, but collaboration and contributions are IMHO a much more efficient and constructive endeavor.

So the next time you fork a project, do consider what it will take for you to contribute back. I can only speak for myself and GitHub Spellcheck Actions

  1. We have a good track record of resolving issues
  2. We have a good track record of accepting PRs
  3. We take care of the maintenance of the action, updating requirements and dependencies
  4. We keep the documentation up to date

I am not sure you could call in a community, but there is a little tribe around the action, keeping things going and alive - and we always have room for more.

I am undecided on whether I should reach out the to relevant forks mentioned above, it is not that it matters that they exist, but I would love for the changes to have gone upstream, so we could have consolidated the efforts. Contribution is what keeps projects going and keep them from going stale and it the long run perhaps the next maintainer is one of the contributors, if I loose interest, start making less spelling errors (not likely) or decide to change focus to some of my other side-projects.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .