tl;dr Patchbot is a tool to automate the distribution of patches to your own Git repositories and helps to reduce technical debt.
Technical debt is a common problem in software development and just like financial debt there may be good or bad reasons for it, but an accumulation of technical debt may lead to unrecoverable risks.
Innovation and rapid development is a catch-22 situation here, since this may increase technical debt causing a loss on innovation and development speed.
There are many ways to acknowledge, address, and pay off technical debt eventually. However, the hardest part is to work against the “No, not right now“ conation.
Real World Examples
I had to face this issue some time ago, when numerous Git repositories I manage were affected by some general decisions.
- Streamline the name of the Changelog file to comply with recommended naming patterns
- Add a configuration file needed to introduce a new code quality tool
- The main domain address of the organisation changed - reflect this in documentation and meta files
Ideas how solve these:
- Open an issue for each project repository, wait until solved – Large overhead, what happens if the project is quiet?
- Add these tasks to a
project health checklist,
and one of these tasks needs to be done every time a project is opened
- How to check that a task is solved everywhere and no longer necessary?
- Do a walkthrough - get it done
- This… is… monotonous… and requires all attention over a period of time
Those are small issues. But a lot of work to implement them in all projects. All proposed solutions have a great potential for the omnious “No, not right now” excuse.
However, there was a keyword: »monotonous«… Wait… 🤔 This could be automated!
First step: Write a patch script to apply the changes.
A patch is a set of changes to a computer program or its supporting data designed to update, fix, or improve it.
It is not possible solve the requirements with a Git patch file, since they require conditions or depend on other tools. A custom migration script will do however.
Second step: Write a bot to run the patch script against all repositories.
A (internet) bot is a software application that runs automated tasks (scripts) over the Internet.
The bot needs to checkout every selected repository, create a feature branch, run the patch script, commit the changes, push the branch. Let's do it.
I build a prototype and used it to solve the given tasks.
Patch + Bot = Patchbot
Now, this a not a completely new area. I write migration scripts all the time when I refactor projects. I delete them as soon as they are executed though. Tomas Votruba calls these one-time migration scripts »Mandala Scripts«. I love this synonym.
Since the purpose of my patch scripts was to reuse them across many repositories I designed a lean file structure which encourages this concept. ♻
Create a new repository which will contain a collection of all patch scripts.
composer create-project pixelbrackets/patchbot-skeleton
Each patch directory always contains at least a PHP script named
and a commit message named
Pass the name of the patch directory as
patch-name and the Git repository as
repository-url to the patchbot script.
Run the following command to apply the patch script in directory
to the repository
./vendor/bin/patchbot patch --patch-name=template --repository-url=https://git.example.com/repository
Repeat the same command with different repository URLs to distribute the patch to them as well.
Patchbot creates a random name for the feature branch and uses the default
branch as base. When you want to create the feature branch based on a different
development, and declare a fixed name for the feature branch,
feature-1337-add-license-file, you may run this command:
./vendor/bin/patchbot patch --source-branch=development --branch-name=feature-1337-add-license-file --patch-name=template --repository-url=https://git.example.com/repository
Patchbot uses a feature branch and does not commit into existing branches right away. When you reviewed the feature branch and all tests are successful then you can use Patchbot again to merge the branch though.
Example command to merge branch
./vendor/bin/patchbot merge source=bugfix-add-missing-lock-file --target=main --repository-url=https://git.example.com/repository
This script is Open Source, so please use, patch, extend or fork it.
Contributions are welcome!