flak rss random

adding activitypub to humungus

I added ActivityPub support to humungus using the vocabulary defined by ForgeFed so now I can follow my commits with honk. Statements dreamed up by the utterly deranged.

federated code

I self host my code, as one should.

humungus was originally supposed to be just a web frontend for existing repos. It shows diffs and commits. But it’s very limited on the write side. I don’t need a website to create issues, and I don’t want to deal with having to allow randos to create accounts, who probably aren’t interested anyway. But if you can use an existing federated identity to comment on projects, and maybe I’ll see it, that seems reasonable. It’s low friction for you and low effort for me.

There’s also email, etc., for that. But then I have to run a listserv, and if somebody creates a fork, as they should, then they have to run a listserv, etc.

I like AP over SMTP for development because it’s easier to join a project or ticket on an adhoc basis. Getting a week old email from before you subscribed to the list into your email client is annoying. AP conveniently provides web accessible versions of all messages. In theory.

Which brings us to an ActivityPub extension, ForgeFed. In practice, nobody is using ForgeFed, which is still in development, but the spec seems far enough along I can implement the relevant portions. So I did.

humungus doesn’t have any concept of projects or teams (or issues, or ...) but it does have repositories and commits. It’s not hard to create json representations for them, and we’re halfway to federation. The “hard” part is handling follow requests, but having some code already written for that purpose, it’s just a helicopter drop away.

helicopter drop

The majority of the code was simply copied from azorius, another project that federates. In theory this code could be a modular library of some variety, but I think the interface abstraction then starts to take over.

For example, there’s a file, deliver.go, that handles deliveries and retries. It needs to talk to a persistent store, which it currently does via variables like stmtAddDelivery which is just a prepared statement. It needs signing keys. It needs a means to connect to the network. It needs a logging facility. Turning all of these dependencies inside out would probably double the size of the file. And trying to use it in the application would require that much code again for setup and initialization.

For better or worse, implementing even the basics of ActivityPub requires lots of moving bits, few of which are particularly large, but all of which are intertwined. But once you’ve written the ball of string, it’s easy to copy it around. If this had been abstracted, I’d just be copying the boilerplate factory constructor around.

The good news is the helicopter drop worked really well. I copied all the necessary files, fedi.go, activity.go, deliver.go, etc., deleted the parts for activities we don’t care about here (Page, Note, etc.), and then added Repository and Commit.

This is a somewhat unfashionable definition of code library now, but I think the wisdom of the ancients has some merit. You have some useful code you keep around in your library, and you include it into your programs as needed, but in doing so, you literally copy it into the program.

honk side

On the honk side, adding support for Commit was little more than another switch case fall through. I also added highlighting to the diff text so it’s pretty.

People like to complain that there’s too many AP objects and it’s too hard to support them all. At some level, they’re all the same. The type property provides some hints as to preferred presentation, but you can get pretty far without any special processing.


humungus was originally developed to be read only, so it took a while to get the unveil paths corrected to allow for write operation.

There was a kinda widespread security issue recently with ActivityPub servers processing activities unexpectedly found in user uploaded files. Peril of user content. Obviously a concern for code hosting as well, which provides upload capabilities at predictable paths. Fixed with a simple check to deny requests with the Accept header set for anything inside the repo.

And that was about it. Only a few hours work.


Well, it seems to work. I can federate messages from my server to another program running on the same host.

The reference implementation of ForgeFed, Vervis, seems to be down more than it’s up, and the flagship instance doesn’t federate anyway. The presumed other leading implementation, Forgejo, isn’t even self hosting. So who knows how complete interoperability is. They also seem to be focused on some VCS called git, whatever that is.

Posted 26 Apr 2024 06:51 by tedu Updated: 26 Apr 2024 06:51
Tagged: activitypub project