Project Documentation Guide

Documentation is an important aspect to any software project. LF-Releng provides some recommended tools for projects to get setup with their own documentation and we will attempt to describe them in this guide.


The main tools recommended to generate docs is Sphinx and reStructuredText. Sphinx is a tool for generating documentation from a set of reStructuredText documents.

LF provides lfdocs-conf as a convenience package that will pull in the most common documentation dependencies and configuration for your project. global-jjb provides job templates that can build and publish the documentation.


Typically every project like ONAP, OpenDaylight, OPNFV, etc… have a “documentation” project. This project provides a gateway to all documentation for the project and typically is the index page of any project’s url.

Project-specific documentation will configure as subprojects in ReadTheDocs and are available at

Linking between projects are possible via intersphinx linking.

Bootstrap a New Project

Bootstrap your project with documentation by following these steps.

  1. Setup lfdocs-conf with the Install Procedures.

  2. Add project to ReadTheDocs following instructions here

    Open a Helpdesk ticket if you require assistence here.

  3. Create RTD Generic Webhook

    Follow the steps described in the rtd-jobs documentation then record the rtd-build-url and rtd-token for the next step.

  4. Add the rtd jobs to your project

    Open up your project.yaml in the ci-management repo and add this section:

    - project:
        name: PROJECT
          - '{project-name}-rtd-jobs'
        project-pattern: PROJECT
        rtd-build-url: RTD_BUILD_URL
        rtd-token: RTD_TOKEN

    Project name in Gerrit converting forward slashes (/) to dashes (-).


    Project name as defined in Gerrit.


    This is the generic webhook url from Refer to the above instructions to generate one. (Check Admin > Integrations > Generic API incoming webhook)


    The unique token for the project Generic webhook. Refer to the above instructions to generate one. (Check Admin > Integrations > Generic API incoming webhook)

    More details on rtd job template configuration and parameters is available here.


    If lfdocs-conf patches are already merged then issue a ‘remerge’ so the publish job can push the docs to ReadTheDocs.

Add a project to ReadTheDocs

In this task we will add and activate a project to ReadTheDocs. This is necessary to let ReadTheDocs know where to pull your docs to build from.


Remember to add lf-rtd as a maintainer of the project. This is to ensure that LF staff can continue to manage this project even if the project owner stops working on the project. If you would like helpdesk to assist with creating the project for you then open a helpdesk ticket.

  1. Login to ReadTheDocs (LFIT can use the lf-rtd account)

  2. Click “Import a Project” on the dashboard

  3. Click “Import Manually”

  4. Setup Project

    Import Project page

    Import Project page

    1. Give the project a name


      Remember this name to setup the Jenkins jobs.

    2. Provide the Anonymous HTTP clone URL eg.

    3. Repository type: Git

    4. Click Next

  5. Click Admin > Maintainers

  6. Ensure lf-rtd is a maintainer of the project

  7. Setup sub-project

    If this project is not the main documentation project then it needs to be setup as a sub-project of the main documentation project. This will create a subproject link for your project under


    Either the main documentation project’s committers or LF Staff will need to perform this step. If documentation project committers are not available contact the Helpdesk to have LF Staff take care of the subproject configuration.

    1. Goto the main documentation project’s ReadTheDocs admin page

    2. Click Sub-projects

    3. Click Add subproject

    4. Select the child project (the one we created above)

    5. Give it an Alias


      Typically the repo name. Forward slashes are not allowed so convert them to hyphens.


Activate new sub-project:

  1. Select the sub-project

  2. Select Admin > Edit Versions

  3. Locate the version to activate in the “Activate a version” list

  4. Activate it by pressing the “Activate” button on the right hand side of the entry

Intersphinx Linking

This is supplemental documentation for upstream Sphinx docs on intersphinx linking and Sphinx linking in general. Please refer to the upstream docs here:

When working with related projects that generate separate Sphinx documentation that need to be cross referenced, intersphinx linking is the recommended way to link them.

As a refresher, refer to the Sphinx documentation on linking and review the upstream docs for the :doc: and :ref: link types. :any: is a useful helper function to let Sphinx guess if a link is a :doc: or a :ref: link.

In most cases folks use these link references to link to local documentation, we can use these for intersphinx linking to another project’s public docs as well via a namespace and configuration in

The configuration is a dictionary containing a key which we will refer to as a doc namespace and a tuple with a link to the project’s public documentation. This namespace is locally significant and is a free form word so set it to anything, then within the local project use it to reference an external doc.

intersphinx_mapping = {
    'python': ('', None),
} configuration

The lfdocs-conf project already provides common LF docs related intersphinx links for projects using lfdocs-conf.

To add to the intersphinx link dictionary define intersphinx_mapping in the local file, refer to the example above. This overrides the intersphinx_mapping variable. If using lfdocs-conf, we recommend appending to the list instead by setting the following:

intersphinx_mapping['key'] = ('', None)
intersphinx_mapping['netvirt'] = ('', None)

Since lfdocs-conf defines the intersphinx_mapping dictionary, the code above will append to it using a key-value pair. More examples of intersphinx mapping exist in the OpenDaylight

Cross-Reference external docs

Using the namespace we can refer to docs and labels in external project documentation in the same way we can refer to local documentation.

* :doc:`Global JJB <global-jjb:index>`
* :ref:`CI Jobs <global-jjb:lf-global-jjb-jenkins-cfg-merge>`

From the example, we insert the global-jjb docs namespace as deliminated by the colon : symbol inside of link reference to point Sphinx to the global-jjb project docs link.


The above example highlights a bad practice in some LF Docs projects where we were namespacing label definitions using code such as .. _lf-global-jjb-jenkins-cfg-merge. This is redundant and unnecessary as the project is already namespaced by the intersphinx_mapping configuration. When defining labels, define them with locally significant names and use intersphinx_mapping to handle the namespace.