ForgeFeed Specifications

Project Discovery via WebFinger

A project refers to a software project which may contain multiple repositories as well as other resources such as mailing lists, bug trackers, links to chatrooms, etc. NOTE that some forges do not make a distinction between a project and a repository. If your forge does not then you MAY choose to expose repositories as a project with a single repository resource link.

Project URI

A project URI identifies a software project and optionally the host that is resides on. This value is similar to RFC7565. The slug and hostname part MUST match the URI path specification as defined in RFC3986-3.3 while the hostname, if specified, must match RFC3986-3.2.2.

project-uri = prefix slug hostname

prefix      = "project:"
slug        = rfc3986-path
hostname    = [@ rfc3986-hostname]

Slug

The Slug represents a unique string that identifies a project at a particular code forge.

Hostname

If the hostname part is missing then the address of the server receiving the query is assumed. For example the following two queries are equivalent:

https://example.org/.well-known/webfinger?resource=project:spartacus
https://example.org/.well-known/webfinger?resource=project:spartacus@example.org

TODO: Make this an actual spec, for now, some Python:

from urllib.parse import urlparse, quote_plus

def from_string(text):
    url = urlparse(text)
    if not url.path:
        return (None, None)
    split = url.path.split("@", 1)
    if len(split) == 2:
        return (split[0], split[1])
    return (split[0], None)

def to_string(slug, domain=None):
    if domain:
        return quote_plus(f"project:{slug}@{domain}")
    else:
        return quote_plus(f"project:{slug}")

Properties

http://forge-feed.org/rel/repository

Reference to a VCS managed code repository.

http://feed-forge.org/ns/chatroom

Hint describing the backing type of chatroom. See uri-schemes.

matrix
irc
xmpp

Avatar

Forges that allow users to configure a logo can expose this information as an avatar for use in other applications.

{
  "rel": "http://webfinger.net/rel/avatar",
  "href": "https://example.org/stylized-logo.png"
}

Homepage

Link to an HTTP representation of the project homepage.

{
  "rel": "http://feed-forge.org/rel/homepage",
  "href": "https://example.org/example/spartacus"
}

Description

A short text representation of the project.

{
  "rel": "http://example.org/rel/description",
  "titles": {
    "en-us": "A Text Adventure Written in FORTRAN 77",
    "es": "Una Aventura de Texto Escrita en FORTRAN 77"
  }
}

Links to chatrooms: IRC, Matrix, XMPP, etc.

{
  "rel": "http://feed-forge.org/rel/chatroom",
  "href": "ircs://irc.libera.chat/#spartacus-game",
  "properties": {
    "http://feed-forge.org/ns/chatroom": "irc"
  }
}

Mailing Lists

Links to associated mailing lists, forms, etc.

{
    "rel": "http://feed-forge.org/rel/mailing-list",
    "href": "mailto://list-name@mail.example.org",
    "properties": {
        "http://feed-forge.org/ns/mailing-list-subscribe": "mailto://subscribe+list-name@mail.example.org",
        "http://feed-forge.org/ns/mailing-list-unsubscribe": "mailto://unsubscribe+list-name@mail.example.org"
    }
}

Ticketing Systems

Links to issue tracking systems.

{
    "ref": "http://forge-feed.org/rel/ticketing-system",
    "href": "https://example.org/bugs",
}

Links of code repositories associated with this software project.

{
  "rel": "http://example.org/rel/repository",
  "href": "https://example.org/example/spartacus",
  "properties": {
    "http://forge-feed.org/rel/repository": "repository:example/spartacus"
  }
}

Example Multi-Repository Query

A WebFinger query may be used to identify detailed information about a public repository at a particular forge. Here is an example response about a fictitious project which has two code repositories associated with it as well as chat links, and a bug tracking system.

GET https://example.org/.well-known/webfinger?resource=project:spartacus

{
  "subject": "project:spartacus",
  "aliases": [
    "https://example.org"
  ],
  "links": [
    {
      "rel": "http://webfinger.net/rel/avatar",
      "href": "https://example.org/stylized-logo.png"
    },
    {
      "rel": "http://feed-forge.org/rel/homepage",
      "href": "https://code.example.org/spartacus"
    },
    {
      "rel": "http://forge-feed.org/rel/description",
      "titles": {
        "en-us": "A Text Adventure Written in FORTRAN 77",
        "es": "Una Aventura de Texto Escrita en FORTRAN 77"
      }
    },
    {
      "rel": "http://forge-feed.org/rel/chatroom",
      "href": "ircs://irc.libera.chat/#spartacus-game",
      "properties": {
        "http://feed-forge.org/ns/chatroom": "irc"
      }
    },
    {
      "rel": "http://forge-feed.org/rel/ticketing-system",
      "href": "https://example.org/bugs"
    },
    {
      "rel": "http://forge-feed.org/rel/label",
      "properties": {
        "http://feed-forge.org/ns/label": "fortran"
      }
    },
    {
      "rel": "http://forge-feed.org/rel/label",
      "properties": {
        "http://feed-forge.org/ns/label": "text-adventure"
      }
    },
    {
      "rel": "http://forge-feed.org/rel/repository",
      "href": "https://code.example.org/spartacus/spartan-engine",
      "titles": {
        "en-us": "The Spartan Game Engine"
      },
      "properties": {
        "http://forge-feed.org/rel/repository-uri": "repository:spartacus/game-engine"
      }
    },
    {
      "rel": "http://forge-feed.org/rel/repository",
      "href": "https://code.example.org/spartacus/game",
      "titles": {
        "en-us": "Implementation of the Spartacus Text Adventure game"
      },
      "properties": {
        "http://forge-feed.org/rel/repository-uri": "repository:spartacus/game"
      }
    },
    {
      "rel": "http://forge-feed.org/rel/repository",
      "href": "https://code.example.org/spartacus/game",
      "titles": {
        "en-us": "Promotional Website for the Spartacus Game"
      },
      "properties": {
        "http://forge-feed.org/rel/repository-uri": "repository:spartacus/www"
      }
    }
  ]
}

Example Single Repository Query

Here is an example of a project with only a single repository associated with it.

{
  "subject": "project:fuu/bar",
  "links": [
    {
      "rel": "http://forge-feed.org/rel/repository",
      "href": "https://code.example.org/fuu/bar",
      "titles": {
        "en-us": "Baz Qux"
      },
      "properties": {
        "http://forge-feed.org/rel/repository-uri": "repository:fuu/bar"
      }
    }
  ]
}

Security

Projects which are not publicly available should not be identifiable by making webfinger queries at all. A project which is private MUST return the same response as a repository which does not exist when making a webfinger request.

GET https://example.org/.well-known/webfinger?resource=project:example/spartacus
200
GET https://example.org/.well-known/webfinger?resource=project:example/private-project
404
GET https://example.org/.well-known/webfinger?resource=project:example/non-existent-project
404