DEV Community

Yawar Amin
Yawar Amin

Posted on • Edited on

Publish ReasonML API docs automatically

API docs are a much-needed and often missing piece of the documentation story of every good library. For BuckleScript/ReasonML libraries, the information on how to generate them has been a bit obscure. Fortunately, it's now possible to set up an automatic API doc pipeline with fairly low effort.

In this post I will show how to:

  • Set up a separate git branch in your repo for documentation
  • Write some basic API docs in the source code
  • Add Azure Pipelines CI/CD pipeline files to the repo that describe how to build and publish API docs
  • Navigate the Azure Pipelines developer portal and finalize the pipeline setup

Set up git branch

The first thing to do is to set up a new orphan branch to hold the actual documentation files. We will use GitHub Pages to host the docs and serve them from the repo. Start from a clean repo state and create the branch:

$ git checkout --orphan gh-pages
Enter fullscreen mode Exit fullscreen mode

Now delete all project files except the .gitignore, and add this index.html file to the project root. Once added, edit the file and replace ./Yawaramin__Prometo/Yawaramin__Prometo with ./YourProject/YourProject, where YourProject is your project name.

Commit this file to the branch and push it:

$ git add .
$ git commit -m"Add index"
$ git push -u origin gh-pages
Enter fullscreen mode Exit fullscreen mode

Now checkout your main branch and get ready to write some API docs.

Write some API docs

This is a very basic overview of how to write doc comments. See the OCamldoc link above for more.

Say you have a standard ReasonML project structure with source files under src/, e.g. src/YourProject.re. Let's write some API docs:

[@text {|YourProject - a nice project.|}];

/** [coolFunction(x)] is [x + 1]. */
let coolFunction = x => x + 1;
Enter fullscreen mode Exit fullscreen mode

The [@text ...]; block (the semicolon is important) at the top of the file becomes the overall module's doc comment. We need to use this special [@text ...] attribute because of a bug in Reason that doesn't understand the normal doc comment, /** ... */, at the module level.

However as shown next, Reason works OK for doc comments that are attached to specific items in the module, like the coolFunction function.

Note that this bug only affects Reason syntax; if you're writing source code in OCaml syntax, then the regular doc comment (** ... *) will work anywhere in a module.

Quick tip: it's important to not start each line with * as the doc generator doesn't strip out the leading asterisk. Ensure that multi-line comments look something like this:

/** This
    is a
    multi-line
    comment. */
Enter fullscreen mode Exit fullscreen mode

Next, install the bsdoc package as a development dependency:

$ npm install -D bsdoc # or yarn etc.
Enter fullscreen mode Exit fullscreen mode

Commit and push these changes.

Add Azure Pipelines capability to the repo

This involves adding several files to the repo and customizing them for your project. They are:

azure-pipelines.yml

This goes in the project root. You can copy over this file and customize to your needs. Specifically:

  • L1: you may want to customize the build name
  • L6: set the name of the branch that should trigger the build
  • L13: this doesn't need to change; just a note that you specifically want to use a MacOS VM to run the main build because the bsdoc binary is only published for MacOS now. In the future if it's available for Linux you may use a Linux VM.
  • L26: set the same branch name as in L6

.ci/

Copy over the entire .ci/ directory and its contents to your repo. The needed changes are:

  • .ci/build-docs.yml:
    • L2: change the Yawaramin__Prometo to YourProject (remember, assuming YourProject is the name of your project, see above)

Special note: the way this works is, the bsdoc tool generates docs and puts them in the project's docs/ directory. It's important that this directory be free of any other files. But many projects put documentation in docs/, so this can be a problem. If this is the case for you, add a step to this file, before the npx bsdoc build ... step, to delete the existing docs directory, so the bsdoc command's output is not mixed up with any other files.

  • .ci/publish-api-docs.yml:
    • L3: change the repo URL to your repo
    • L9: change Yawaramin__Prometo to YourProject
    • L31: change the repo URL to your repo
    • L32: change the name of the docs publisher bot
  • .ci/utils/cache.yml:
    • L2: change the value of the cache_key parameter to your project lockfile name. I'm using pnpm so mine is pnpm-lock.yaml, but you will likely have package-lock.json or yarn.lock. This is important for caching to work properly. This pipeline will cache all build artifacts so it never needs to download and rebuild dependencies over and over again. Builds should take a couple of minutes, max.

Now commit and push all of the above.

Allow the pipeline to update and push docs

Now you will want to grant the pipeline permission to push generated docs to your repo's gh-pages branch which you created earlier. You can do this by generating a deploy key and telling GitHub about it.

First, generate an SSH key:

$ ssh-keygen -t rsa -b 4096 -C "your@email"
Enter fullscreen mode Exit fullscreen mode

When prompted for a location, enter /Users/YourName/.ssh/deploy_key (or the equivalent absolute path for your operating system). Note, it's important that deploy_key be exactly the name used. Press Enter both times when prompted for a passphrase and wait for the key to be generated (should take a second). Copy the contents of /Users/YourName/.ssh/deploy_key.pub to the clipboard.

Now go to https://github.com/YourName/YourProject/settings/keys/new and set the title 'docs', and for the key value, paste in the contents you copied above.

Check the 'Allow write access' checkbox and click 'Add key'.

Set up Azure Pipelines

Now, you are ready to tell Azure Pipelines about the project, so it can start running builds on every push. Do the following:

Go to https://dev.azure.com/ and log in with your GitHub account.

Click the '+ New project' button (blue, top-right corner) and enter your project name and description (this will probably be the same as in the GitHub repo). Select visibility 'Public' and click 'Create'.

In the new project, go to your 'Library' page's 'Secure files' section: https://dev.azure.com/YourName/YourProject/_library?itemType=SecureFiles

Click the '+ Secure file' button and choose the SSH private key you created earlier, called deploy_key. Ensure in the 'Pipeline permissions' section of this file that the 'Authorize for use in all pipelines' setting is turned on.

Now, go to the 'Pipelines' page in the left panel, and click 'Create Pipeline'. Choose GitHub for the 'Where is your code?' question, and select your repository. It should find and show your repo's azure-pipelines.yml file. Click the 'Run' button (top-right corner) to create and run it for the first time.

If all goes well, the pipeline runs and publishes the generated API docs to your repo's gh-pages branch, which is then served by GitHub under https://YourName.github.io/YourProject. If everything looks good, add that URL prominently to the repo's URL/README, and you now have automatic API docs! See this repo for an example of this setup and the generated documentation.

Of course, it may not be as simple as that, especially if I've forgotten something in the steps above. Any feedback about that is appreciated!

Top comments (2)

Collapse
 
rjmurtagh profile image
Rob Murtagh

Great stuff Yawar! Do you have any examples of what this documentation looks like? It'd be great if you could link out to a real world example...

Collapse
 
yawaramin profile image
Yawar Amin

Thanks Rob. I've updated the post with an example. See second-last para.