Maintaining a mature, reasonably-popular Django open-source package is boring. There, I've said it.
Creating a new package? That's fun.
Writing blog posts about this cool new tool you've been playing with? That's fun.
But a medium-size package, that does what is needed, and does not require any new features - all you have to look forward to is dealing with the upgrade treadmill.
A new Django release has just been published? Here's a comprehensive list of what the package maintainer might have to do:
- Run the unit tests, just to be sure that we're starting from a clean base.
- Run tox - testing against every valid Python+Django combination - for the same reason.
- Enable deprecation warnings with
export PYTHONWARNINGS=defaultand re-run unit tests again. If there are any warnings, fix them. If any code was changed, add to theCHANGELOG.txta line "Fixed deprecation warnings" and commit. - Determine the full list of currently supported Python+Django releases. Update the
tox.inifile to match. - Update
setup.pyand.github/workflows/ci.ymlwith list of supported Python versions. - Update the
CHANGELOG.txtwith 2 lines "Removed support for Python XX and Django XX" and "Added support for Python XX and Django XX". - Read any
requirements.txtin this project; read the changelogs of any required libraries. Determine the minimum version of required libraries that match the full list of currently supported Python+Django releases. Finally, update therequirements.txtfile. - Re-run tox. If there are any errors, investigate. Fix, test. Repeat loop until all tests pass.
- Add new entries in the
CHANGELOG.txtthat summarise the changes. - Commit all changes.
- Push code to Github repository.
- Monitor the Github Actions CI pipeline.
- Finally - cut a new release and send it to Pypi.
And the above is boring. You'll never go into a job interview and impress the person sitting opposite you with a "I ran the tests with Deprecation Warnings enabled". You'll never make a presentation at a DjangoCon on this subject and get a standing ovation.
The result is that many packages get slowly neglected. I'm guilty of this - several year ago I took on the job of maintaining django-photologue, and I've not been very proactive recently. A one-year gap before the recent spat of commits.
And I note that django-photologue itself depends on 4 packages, one of which - django-sortedm2m - has not had a commit in 2 years, and a second - factory-boy - has got a "Project status" issue open.
So... what to do?
Recently I've been playing around with LLMs, trying to figure out useful use cases. Of course, like many devs, I use Claude daily in my paying job.
Here I turned my attention to the question "Can a LLM help maintain a crufty old Open Source project?".
And well, for me, the answer is a resounding yes.
The task list that I gave above is almost impossible to automate with traditional scripts (in Python or other). Too many edge cases, too many ambiguities... but for a LLM, following a clearly-specified "runbook" is a perfect use case.
So I played with applying it to django-photologue. To be transparent, there was quite a bit of setup work - for example:
- telling the LLM exactly how to run the unit tests.
- how to download the results of the latest CI run from Gitlab Actions.
- where to find the list of currently-supported Django releases.
- and more.
But eventually I put together a runbook for a LLM to follow and perform the "upgrade treadmill".
I then branched from an earlier commit of django-photologue (before I started upgrading to the latest Django/Python), copy-and-pasted the shiny new AGENTS.md with the runbook, and told it "go and make django-photologue compatible with currently supported Django versions".
30 mins of churning, occasional prompting "want me to make this change?" and the task was done, including a number of code changes to deal with Deprecation Warnings.
And I was very happy with the result. It makes upgrades easy. I can set the LLM on the task, walk away to do something else, and just check in when the terminal bell rings for attention.
Maintaining an existing open source project will never be fun, but now it's a bit less boring.