ForgeFeed Specifications

Repository Discovery via WebFinger

A repository refers to a version control managed source code which MAY be browsable over HTTP or accessed with specific tooling.

Repository URI

A repository URI identifies a VCS resource and optionally the host that is resides on. The value serves to contain enough information such that a client with a simple URL parser may easily parse the identifier. A repository URI MUST be a valid RFC7565 URI. The slug and hostname parts MUST match the URI path specification as defined in RFC3986-3.3 while the hostname, if specified, must match RFC3986-3.2.2.

repository-uri = prefix slug hostname

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

Slug

The Slug represents a unique string that identifies a repository at a particular code forge. Repository refers to a VCS managed codebase of some kind, e.g. a Git repository.

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=repository://spartacus/game
https://example.org/.well-known/webfinger?resource=repository://spartacus/game@example.org

Parsing

An example parser written in the Python programming language. Any programming language which implements a valid RFC7565 parser should be sufficent for reading a project URI.

from urllib.parse import urlparse

def from_string(text):
    url = urlparse(text)
    if url.scheme != "repository": # schema must be repository://
        raise Exception("Wrong scheme, should be repository://")
    if not url.path:
        raise Exception("Missing slug part")
    split = url.path.split("@", 1)
    if len(split) == 2:
        domain = urlparse(f"ignore://{split[1]}")
        return (split[0], domain.netloc)
    return (split[0], None)

Relation Types

The following Relation Types are available for use within a repository resource.

http://forge-feed.org/rel/avatar
http://forge-feed.org/rel/clone
http://forge-feed.org/rel/description
http://forge-feed.org/rel/label
http://forge-feed.org/rel/license
http://forge-feed.org/rel/ticketing-system

http://forge-feed.org/rel/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"
}

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

Clone links define how one can download a copy of the remote software onto their own server.

{
    "rel": "http://feed-forge.org/rel/clone",
    "href": "https://example.org/example/spartacus",
    "properties": {
        "http://feed-forge.org/ns/vcs-type": "git"
    }
}

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

A short text representation of the repository.

{
  "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"
  }
}

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

A short text based category which can be used for searching.

{
  "rel": "http://forge-feed.org/rel/label",
  "properties": {
    "http://feed-forge.org/ns/label": "text-adventure"
  }
}

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

A license SPDX identifier and link to the license's full text.

{
  "rel": "http://feed-forge.org/rel/license",
  "href": "https://example.com/example/spartacus/tree/LICENSE",
  "properties": {
    "http://feed-forge.org/ns/spdx-identifier": "GPL-2.0-or-later"
  }
}

http://forge-feed.org/rel/ticketing-system

Links to issue tracking systems.

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

Property Identifiers

The following property identifiers are available for use within a repository resource.

http://forge-feed.org/ns/label
http://forge-feed.org/ns/project-uri
http://forge-feed.org/ns/spdx-identifier
http://forge-feed.org/ns/vcs-type

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

A short text based category which can be used for searching.

http://feed-forge.org/ns/spdx-identifier

Refers to a valid SPDX identifier, see license-list

http://feed-forge.org/ns/vcs-type

Identifies VCS types, valid strings are:

bzr (GNU Bazaar) bazaar.canonical.com
darcs (Darcs) darcs.net
fossil (Fossil) fossil-scm.org
git (Git) git-scm.com
hg (Mercurial) mercurial-scm.org
pijul (Pijul) pijul.org
svn (Apache Subversion) subversion.apache.org

Example Repository WebFinger 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 repository:

GET https://example.org/.well-known/webfinger?resource=repository:spartacus/game
{
  "subject": "repository:spartacus/game",
  "aliases": [
    "https://example.org/spartacus/game"
  ],
  "links": [
    {
      "rel": "http://webfinger.net/rel/avatar",
      "href": "https://example.org/stylized-logo.png"
    },
    {
      "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://feed-forge.org/rel/clone",
      "href": "https://example.org/spartacus/game",
      "properties": {
        "http://feed-forge.org/ns/vcs-type": "git"
      }
    },
    {
      "rel": "http://forge-feed.org/rel/license",
      "href": "https://example.com/spartacus/game/tree/LICENSE",
      "properties": {
        "spdx-identifier": "GPL-2.0-or-later"
      }
    },
    {
      "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"
      }
    }
  ]
}

Security

Repositories which are not publicly available should not be identifiable by making webfinger queries at all. A repository 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=repository:spartacus/game
200
GET https://example.org/.well-known/webfinger?resource=repository:example/private-repository
404
GET https://example.org/.well-known/webfinger?resource=repository:example/non-existent-repository
404