At the root of the forge, we find users and organizations. Each of them have several projects which contains repositories, issues, pull requests, milestones, releases, topics, ci and labels.

Note: a repository is a Git repository and a project contains one or several Git repositories.

For example:

forge/users/
     ...
     20.json
     20.id
     20/projects/
                1.json
                1.id
                1/issues/
                        3.json
                        3.id
                        3/comments/
                                  7.json
                                  7.id
                                  7/attachments/
                                              20.json
                                              20.id
                1/pull_requests/
                               6.json
                               6.id
                1/releases/
                          1.json
                          1.id
                          1/assets/
                                 10.json
                                 10.id
                1/labels/
                        2.json
                        2.id
                        3.json
                1/milestones/
                            8.json
                            8.id
                            9.json
                1/topics/
                        1.json
                        1.id
                        3.json
                1/repositories/
                             vcs.json
                             vcs/ (bare git repository)
                             vcs.wiki.json
                             vcs.wiki/ (bare git repository)
      30.json
      ...
forge/organizations/
     ...
     80.json
     80.id
	 80/projects/
	 ...
forge/topics/
     1.json
	 1.id
	 ...
forge/objects/
     ...
     aa/fb/116a0e7674d9d4f79826690c9ba07b47209d8cbdd6fc17432a8d77c688ce
     da/14/64fd7ceaf38ff56043bc1774af4fb5cb83ef5358981d78de0b8be5a6fbcb

At each level of the hierarchy a JSON file (named after the index property: index.json) describes the resource. There is then a folder named after the index property which contains a representation of all its sub-hierarchy.

At each level, folder names correspond to the JSON files containing the schema; this schema describes the structure of each JSON files in this folder. In the example above, forge/users/20/projects/1/issues/3.json is described by the schema issue.json.

Reactions (emojis) are described by the reaction.json file, but it would be space consuming to create a json file for each reaction in a comment. For this reason, reactions are directly included to the json file of the comment. Keeping this in mind, the same decision is applied for review comments or labels.

Object storage

A number of resources include objects that are opaque. For instance an issue comment can contain an attachment with a screenshot to illustrate its content.

The object JSON does not contain the object but the hexadecimal representation of the SHA-256 of its content. The SHA-256 of the object is a reference relative to the objects directory with following hierarchy:

  • a subdirectory named with the characters at position 0 and 1

  • a subdirectory named with the characters at position 2 and 3

  • a file named with the characters from 4 to 63

Repository

A repository is the code but it also comes with a JSON file that describes each sub folders. In the previous example, the project has two Git repositories, one for the code (forge/users/20/projects/1/repositories/vcs) and another for the wiki (forge/users/20/projects/1/repositories/vcs.wiki).

References

A reference is a path (relative or absolute) to a resource.

For instance the reference of the poster of an issue could be /forge/users/8435.

Resources do not cross reference each other, directly or indirectly, unless they are on the same path. If a resource X has a reference to a resource Y, it is guaranteed that the resource Y does not have a reference to the resource X, unless X and Y are in the same path.

For instance the resource /A/B/X can reference the resource /A/B/Y but the resource /A/B/Y cannot reference the resource /A/B/X. Howver, the resource /X/Y can reference the resouce /X and the resource /X can reference the resource /X/Y because they are on the same path.

Missing resources

When a resource is missing from a forge, either because it is not implemented or because it has been disabled, it is an empty set.

For instance, if the releases unit of a Forgejo instance is disabled for a given project, the releases resource will be present and empty.

Remapped identifier

Each resource may be associated with a remapped identifier stored in a matching file with the extension .id. For instance 12.json may have a sibling 12.id file that contains the identifier allocated to the resource when it is imported in the destination repository.

The problem it solves is that, for example, the first time an issue is mirrored from a remote forge to a local forge, it is created and given an identifier.

A week later, the issue is refreshed on the local forge to get modifications from the remote forge, the identifier of the issue must be matched to the local forge with the identifier of the issue on the remote forge.

CI

The CI associated with a project is usually configured within the repository of a project. For instance .gitlab-ci.yml is interpreted by a GitLab runner that runs the software it contains. When importing a such project in a GitLab instance, the project can also be associated with a runner using the API.