Working on the documentation

Qualification documents are built with Sphinx, and their source code is located in the ferrocene/doc folder inside the Ferrocene repository. For example, the source of the Safety Manual is located in ferrocene/doc/safety-manual.

The Ferrocene build system takes care of building and cross-linking the documentation, including downloading all the required dependencies. Building the documents outside of the Ferrocene build system (including building them with the standard Sphinx CLI) is not supported and will likely not work.

This section of the Internal Procedures contains documentation on how to work on the documentation. Quality management procedures are available in the Development Process.

Building documents

You can build a qualification document by passing its path to the Ferrocene build system:

./x doc ferrocene/doc/$name

You can also build multiple documents at the same time by passing all of their paths:

./x doc ferrocene/doc/$foo ferrocene/doc/$bar ferrocene/doc/$baz

If you want to build all the documentation generated with Sphinx (for example if you need to ensure cross-document links work, or you need to test an extension change across all documents) you can run:

./x doc ferrocene/doc

If you want to build all of the available documentation, including the standard library docs and documentation from upstream, you can omit the path:

./x doc

The build system will output the path containing the resulting documents. You can also open the built documents in your browser by passing the --open flag:

./x doc ferrocene/doc/$foo --open

If you are making frequent changes to the contents of a document, the --serve flag will continuously watch for changes in the file system and rebuild content as needed. It also starts a local web server with automatic reloading of the changes in the browser:

./x doc ferrocene/doc/$foo --serve


The --serve flag is only available for documents built with Sphinx, and it will not do anything for other kinds of documentation (like mdBook or rustdoc). It also only supports serving a single Sphinx document: if you attempt to serve more than one at the time it will error out.

When you are working on Sphinx extensions, the --debug-sphinx flag will change the configuration to aid debugging, by running only one builder job at the time and showing exception tracebacks:

./x doc ferrocene/doc/$foo --debug-sphinx


Sphinx features automatic dependency tracking and should rebuild only the files you actually changed. Dependency tracking doesn’t work when the implementation of extensions is changed: in those cases you will want to pass the --fresh flag, which does a fresh build ignoring caches:

./x doc ferrocene/doc/$foo --fresh

Test outcomes

Some of our documents, like the Test results overview page, need to know which tests were executed and ignored to generate parts of the content. We call this information “test outcomes”. While not strictly required to build the docs, not providing them will result in some information being omitted, and warnings being rendered in the generated content mentioning the lack of test outcomes.

Test outcomes consist of a collection of JSON files produced by the build system’s “build metrics” feature. They are usually generated by CI, but it is possible to also generate them locally by setting the build.metrics = true option in config.toml.

Downloading test outcomes from CI

The easiest way to inject test outcomes into the built documentation is to instruct the build system to automatically download the latest available copy of the test outcomes built by CI. People with access to the Ferrocene AWS account can do so by adding this to their config.toml:

ferrocene.test-outcomes = "download-ci"

Generating and using the test outcomes locally

If you are building Ferrocene from source on a single builder machine, or you need to use test outcomes from a local test suite invocation, you can add this to your config.toml:

build.metrics = true
ferrocene.test-outcomes = "local"

Note that there are some limitations to be aware of when doing so:

  • Test outcomes are only persisted when the command finishes, and tasks requiring them will ignore outcomes not persisted to disk. This means that tasks generating test outcomes and tasks consuming test outcomes must be executed in separate build system invocations.

  • Test outcomes are only persisted when the command finishes successfully. Failed build system invocations (for example due to a failing test) will not result in them being persisted.

  • When persisting test outcomes, the build system appends the new test outcomes to the previous one, never overwriting them. If you need fresh test outcomes, remove the build/metrics.json file before invoking the build system.

Injecting external test outcomes

Another way is to fetch the test outcomes from an external source (like a Ferrocene release, or a custom storage solution collecting the test outcomes from different build servers), store all of them in a directory, and point the build system to that directory in config.toml:

ferrocene.test-outcomes = "custom"
ferrocene.test-outcomes-dir = "path/to/outcomes"

An example of this is injecting the test outcomes from a Ferrocene release. Manually download a copy of the test outcomes from the releases download portal (look for a tarball named ferrocene-test-outcomes in the release you care about), extract the tarball in a directory on disk, and add this snippet to config.toml:

ferrocene.test-outcomes = "custom"
ferrocene.test-outcomes-dir = "path/to/extracted/tarball/share/ferrocene/test-outcomes"


When configuring a custom path for the test outcomes, make sure you choose the path actually containing the JSON files. In downloaded tarballs, that is the share/ferrocene/test-outcomes directory inside the tarball.