Moving my to-dos from text files to tickets

For most of my life, text files and sheets of paper were my go to solution for organizing tasks. This did not change when caldav interfaces for tasks came up, as this did not really solve any problem: Text files are already easily synchronized via unison. Having to run a separate server (or worse, trusting evil1 cloud companies) and relying on internet connection only meant more overhead for no gain. It also meant that the tooling would include more boilerplate code, as reading and writing files is pretty simple in almost all programming languages.

The beauty of KISS tooling

There are usually just three commands:

  • t ls [optional filters] to list all to-dos, numbered, each on a new line
  • t do <number> to mark this to-do as done and remove it from the list
  • t add <something you have to do> to add a to-do item

You can think of adding meta-information like tags (I like prepending them with a +) or projects or dates and what have you. And most of the things then can easily be filtered.

There were thousands of tool doing essentially this. It is fun and easy to create your own tool, so much so that "writing a to-do list app" is one of the first things many people do in a new programming language. The code is worthless, but the tools are not. It is a great trade.

git hosting platforms transformed project management

For a long time, issue tracker and version control were separated, and it took a dedicated effort to have your changes in code point back at issues that were being solved.

In the 2010s or so something wonderful happened: Platforms like github and gitlab started to integrate issue trackers with the version control. Now suddenly, issue trackers were more than just a collection of to-dos, they became part of the documentation and code of projects. And as such, they became more useful than my shoddy to-do list scripts.

This was kind of annoying. On one hand, having a command like t ls was simple and you easily got a nice overview of all the things you have to do. On the other hand, in a web interface, you could also add further descriptions to tasks, have code linked, have people comment. But you could never get the same overview as in a terminal.

For a long time this fragmented my workflow; I had still my text based to-do list for, well, to-do items. I have several git based issue trackers such as forgejos and gitlabs, and back then, github. And then I struggled keeping both in view, so I made daily to-do lists on paper, on which I manually created a merged view of those things. While I do enjoy writing by hand, this was not a workflow that sparked joy.

The meta repo management idea

In 2021 I had to work on multiple projects in multiple git hosting environments. CI/CD were still being figured out by many and the friction of workflows was felt across many projects. Some companies lacked good workflow engineering, gave up and went back to mono repos for all their stuff.

At that time I truly wished for just some meta-repo-management to which I could connect all my other repos and reflect issues and code into this. Of course, I was not going to program that, but I dabbled a bit around with using a gitea instance (it was shortly before they turned evil and forgejo had to fork gitea) and mirroring projects into it.

It was a glorious mess and in the end, just not worth the effort. At first it was nice, but there were several problems First there was a steady influx of new projects that would have needed to be integrated. Since there are more important considerations than my own comfort, such as uptime, integrity and testing workflows, it was not an option to just move every project to a mono repo.

Second, issue integration was not that great. I think it only worked for a subset of the repos I tried to connect.

Third, it was still stretching all items across multiple projects and it still did not give me the overview I wanted.

Finally, due to gitlabs unnecessary token expiration policies, keeping this in sync was not really feasible.

Everything is an API now; going back to the command line

Since I have been working with kubernetes for a long time now, I have grown accustomed to the modern version of the POSIX philosophy: everything is an HTTP API.

In particular, nowadays every halfway serious tool now exposes a nice API you can actually use, usually even well documented. What is even better, you don't even need to write the boilerplate code yourself anymore, but can just let your GPU do the job and then cross reference some of the API documentation.

Which now afforded me to go back to a workflow that actually works and combines the best of both worlds.

My personal to-do management

On my laptop I run a forgejo instance in kubernetes. I have one repository configured to be the main repository to be used, as well as some repositories (with an alias name) for things that are projects in their own.

The usage message tells basically everything:

Usage:
  t ls                              list open tickets (default repo)
  t ls @infra                       list open tickets from 'infra' repo
  t ls --all                        list open tickets from all repos
  t ls <filter> [+label] [@repo]    filter by text and/or labels
  t add <title> [+label] [@repo]    create a new ticket
  t do <ref>                        close a ticket
  t close <ref>                     close a ticket (alias)

Ticket references:
  42                                ticket #42 in default repo
  infra#42                          ticket #42 in 'infra' repo

Examples:
  t ls auth +bug                    title contains 'auth', label 'bug'
  t ls @infra +urgent               'infra' repo, label 'urgent'
  t add Fix login +bug              create in default repo
  t add @infra Fix server +ops      create in 'infra' repo
  t do 42                           close #42 in default repo
  t do infra#51                     close #51 in 'infra' repo
  t show infra#51                   show #51 in 'infra' repo
  t edit <ref>                      edit ticket body in $EDITOR

For labels I use the labels that have been configured in forgejo for the project. It is even possible to query the label color, so by using a nearest color search (it really does not matter if one does geometric distance or fancy visual color distance) I can even display the labels in their respective colors. It is possible, so why not do it. The script is written in python and the only dependency it has is the requests library, which is a sensible choice in my opinion, as basically every script I write uses it.

One thing I particularly like is t edit <ref>, which opens the ticket's description in my editor, similar to crontab -e, and writes it back if any change is detected.

Possibly at some point I also add features for displaying comments and adding comments, but for now I am somewhat happy with the t edit feature.

My work to-do management

My work to-do management is considerably simpler, because at work I do interact much more with the web interface. There I only have

Usage:
  g ls                              list all open issues across groups
  g ls <filter> [+label ...]         filter by title and/or labels

Examples:
  g ls auth                          title contains 'auth'
  g ls +bug                          issues with label 'bug'
  g ls login +bug +urgent            title 'login', labels 'bug' and 'urgent'
  g show <ref>                      show full issue details
  g show group/backend/api#7        show issue #7 in sciebo/backend/api

I configure no aliases except for my top-group (to save screen estate). Showing an issue displays it similar to a blog post in markdown format:

$ g show group/subgroup#42
group/subgroup#42 This is the title of the issue
Assignees: None
URL: <the url to the issue in gitlab>
Labels: <comma separated list of labels>

This is the content of the ticket, just as you would see in the edit window.

Here I do see more use for comment functionality. I explicitly do not have a g do option because most tickets should be closed automatically by merging their fixes.

Since there are a lot of tickets and gitlabs are sometimes a bit slow, I consider adding some caching here sometime, but the main issue is, of course, to first decide on a sensible caching strategy.

Some takeaways

I am very happy with the setup right now. Having all issue trackers available in somewhat uniform command line tools also means that I can easily get an overview of everything. Bash tooling means even when I forget some feature, I can easily create it on the fly.

Moving this to a web based setup would now be pretty trivial, but since I am much more happy with command line operation, why bother. Using gitea to accomplish this was essentially just the lazy attempt to avoid writing the API interaction myself. Furthermore, I suspect people who prefer using a web interface are not the people that have to oversee many projects across several platforms anyway.

In the past I probably would have hated doing things like this, because not using files is so dirty. But nowadays, using an API is essentially the KISS way to do things and one would have to go to extra lengths to not use an API.


  1. to be fair, at that point in time, they were not evil yet 

blogroll

social