In which I explore this idea and think about how to do a proof of concept.

The Fediverse

The Fediverse is a network of server instances that speak the same protocol and can exchange infomation about what user are doing. This is interesting because the user of these services can choose the best suitable provider for his/her needs and if none is available he/her can run its own.

ActivityPub

The protocol implemented by a Fediverse instance can be one of many but there is one which has been backed by the w3c and it’s called ActivityPub.

ActivityPub comprises both a server to server and a client to server protocol but they achieve different goal. The server to server protocol definition is useful for federation and the client to server ensures compatibility between different client/server combination. They are called the Federation Protocol and Social API.

Federation

Federation solves the problem of distributing activities of users, whichever server they are using, between different servers. This is what we are focusing on now.

To make things easier to reason about here are two examples.

  1. EMail is federated, every user on every server/provider can send an email to another user on another server/provider by using an identifier known as email address

  2. GitHub (or GitLab) is not federated, interactions between users are limited to the extents of GitHub (GitLab) services. There are interesting ways to go beyond this services using things like webhooks but that do not provide much of a foundation to cross borders.

Social coding on the fediverse

To solve the social coding problem on the fediverse we have to make sure that social interactions and software development can happen on the same platform the user is on without tying other users.

Mailing lists for software project are a true social coding federated platform but their experience is not on par with services like GitHub/GitLab (or maybe is the other way round).

At the bare minimum of our problem there is the ability to attach a patch to a discussion about some software. This is usually very simple to do on a mailing list, prepare an email explaining your patch and attach the diff. The discussion happens as a mail exchange mediated by the mailing list. On the other hand I have to make an account on the service the project I would like to contribute is, fork the project, prepare my commits, make a request to pull from my head and then discuss. This is still simple enough and every new commit on my fork appears on the discussion.

I happen to run Gitea as a web interface to the Git software for version control and in the last days I discovered that it exposes HTTP APIs for many interesting features.

Can we make use of this API to create a federated experience for Gitea?

POCOGTFO

At the bare minimum I want to add comments on other people instancesand add a request-pull based on my fork.

Recieving updates

Let’s say that there is a server recieving updates using the Activitypub Federation Protocol and that I provide access to API on my Gitea instance, what can I expect it to do?

WARNING: I only glanced at the HTTP API description and I tend to interpret things so this may not be a faithful representation of what the API expects.

There is the ability to create a pull request on an arbitrary repository using some of Git references.

{
  "assignee": "string",
  "base": "string",
  "body": "string",
  "head": "string",
  "labels": [
    0
  ],
  "milestone": 0,
  "title": "string"
}

So we could create a new pull request specifying the base against which we are comparing (I guess a branch name) and an head which I presume is a reference to a fork in some format that git can understand.

So let’s say that I send this

{
  "assignee": "",
  "base": "head",
  "body": "make foo bar and bar foo",
  "head": "http://foo.edoput.it/bar/master",
  "labels": [
    0
  ],
  "milestone": 0,
  "title": "WIP: foo bar bar foo"
}

I guess that this could work, expecially if we can use URLS compatible with git for the head value.

There is still the problem for access control but I guess the Fediverse developers have already worked on this and I just have to read a little more.

We can also create issues using the API and comment on an issue thread so maybe we can have the foundations for converting Activitypub messages to actions on Gitea.

Posting updates

To make this possible we have to use Gitea hooks, code that is triggered by actions, to send some data to our Activitypub server.

This is an example of what get’s pushed when using a hook

{
  "secret": "3gEsCfjlV2ugRwgpU#w1*WaW*wa4NXgGmpCfkbG3",
  "ref": "refs/heads/develop",
  "before": "28e1879d029cb852e4844d9c718537df08844e03",
  "after": "bffeb74224043ba2feb48d137756c8a9331c449a",
  "compare_url": "http://localhost:3000/gitea/webhooks/compare/28e1879d029cb852e4844d9c718537df08844e03...bffeb74224043ba2feb48d137756c8a9331c449a",
  "commits": [
    {
      "id": "bffeb74224043ba2feb48d137756c8a9331c449a",
      "message": "Webhooks Yay!",
      "url": "http://localhost:3000/gitea/webhooks/commit/bffeb74224043ba2feb48d137756c8a9331c449a",
      "author": {
        "name": "Gitea",
        "email": "someone@gitea.io",
        "username": "gitea"
      },
      "committer": {
        "name": "Gitea",
        "email": "someone@gitea.io",
        "username": "gitea"
      },
      "timestamp": "2017-03-13T13:52:11-04:00"
    }
  ],
  "repository": {
    "id": 140,
    "owner": {
      "id": 1,
      "login": "gitea",
      "full_name": "Gitea",
      "email": "someone@gitea.io",
      "avatar_url": "https://localhost:3000/avatars/1",
      "username": "gitea"
    },
    "name": "webhooks",
    "full_name": "gitea/webhooks",
    "description": "",
    "private": false,
    "fork": false,
    "html_url": "http://localhost:3000/gitea/webhooks",
    "ssh_url": "ssh://gitea@localhost:2222/gitea/webhooks.git",
    "clone_url": "http://localhost:3000/gitea/webhooks.git",
    "website": "",
    "stars_count": 0,
    "forks_count": 1,
    "watchers_count": 1,
    "open_issues_count": 7,
    "default_branch": "master",
    "created_at": "2017-02-26T04:29:06-05:00",
    "updated_at": "2017-03-13T13:51:58-04:00"
  },
  "pusher": {
    "id": 1,
    "login": "gitea",
    "full_name": "Gitea",
    "email": "someone@gitea.io",
    "avatar_url": "https://localhost:3000/avatars/1",
    "username": "gitea"
  },
  "sender": {
    "id": 1,
    "login": "gitea",
    "full_name": "Gitea",
    "email": "someone@gitea.io",
    "avatar_url": "https://localhost:3000/avatars/1",
    "username": "gitea"
  }
}

I think we have all the informations for creating an update on behalf of the user to be shared to other servers. There is information about the commits, the authors, the repository and git references to distribute informations about branches and commits.

Conclusions

In my opinion we can have this, it’s in our reach and I really hope that someone already thought about it more than me.

Maybe this can raise enough interest to spark some discussion from the Fediverse people to collaborate in this direction. There is more work to do than I described and many many details that I have omitted with too much hand waving but I would like to see what happens next.