Hosting Elixir Docs on GitHub Pages with GitHub Actions

If you're creating a project in Elixir and have been looking for a good way to host your documentation for the world to see, GitHub Pages offers a great solution that's free and fairly simple to set up. This article provides a step-by-step guide on how to integrate it into your GitHub Actions workflow.

Dependencies

First off, we'll want to add :ex_doc to our dependencies. This is the library we'll be using to build our docs.

mix.exs

  defp deps do
    [
      ...
      {:ex_doc, "~> 0.30.5"},
      ...
    ]

Configuration

We'll need to generate a key pair in order to allow our repo to update its documentation branch. To do this, we can run an ssh-keygen.

Note: Remember to change the name of the id_rsa file name so that it does not overwrite an existing key pair. In this example, I used id_rsa_gh_pages as the name

> ssh-keygen

Generating public/private rsa key pair.  
Enter file in which to save the key:  id_rsa_gh_pages  

Next, let's create a Deploy Key on our repo. Copy the output of the public key.

> cat id_rsa_gh_pages.pub
# (copy output)

Navigate to Settings > Deploy keys on the repo and click Add deploy key. Paste the public key in and give it a name (something like DOCS_DEPLOY_PUBKEY will do).

Then, we'll have to add the secret key as a repository secret so that our workflow can access it. Copy the output of the private key. Do not share this key with anyone

> cat id_rsa_gh_pages
# (copy output)

Now, navigate to Settings > Secrets and variables > Actions and click New repository secret. Paste the secret key into the box and name it DOCS_DEPLOY_KEY. We'll access this secret from inside our workflow.

Once we're finished with the public/private rsa keys, we can delete them.

rm id_rsa_gh_pages.pub id_rsa_gh_pages  

GitHub Workflow

This example assumes we're using .tool-versions to manage versions for elixir and erlang. erlef/setup-beam reads the .tool-versions file to install the correct versions before running

I've taken the liberty to add a caveat in for building docs on the elixir-docs branch as well as main. That way, we can test changest to the documentation build without having to merge with main - just push these changes to the elixir-docs branch and submit a PR later.

Once the beam environment is set up, lee-dohm/generate-elixir-docs runs and generates our docs.
peaceiris/actions-gh-pages then publishes our documentation to the gh-pages branch of our project using the DOCS_DEPLOY_KEY we provided as a GitHub Secret earlier.

.github/workflows/main.yml

  ...

  elixir_docs:
    if: ${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/elixir-docs' }}
    name: Generate project documentation
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3.5.3
      - name: Sets up an Erlang/OTP environment
        uses: erlef/setup-beam@v1
        with:
          version-file: .tool-versions
          version-type: strict
      - name: Build docs
        uses: lee-dohm/generate-elixir-docs@v1.0.1
      - name: Publish to Pages
        uses: peaceiris/actions-gh-pages@v3.9.3
        with:
          deploy_key: ${{ secrets.DOCS_DEPLOY_KEY }}
          publish_dir: ./doc
          publish_branch: gh-pages

  ...

Run the workflow and make sure it succeeds. Once it's done, our documentation should be available on the gh-pages branch.

GitHub Pages

Now that our workflow is publishing docs to the gh-pages branch, let's go ahead and configure our repo to host our Pages site...

Navigate to Settings > Pages and select Deploy from a branch under Source. Under Branch, make sure gh-pages is selected and the directory is / (root). Hit Save and it should publish the page - by default, the url will be https://[username].github.io/[project]

Make it accessible

Now comes the fun part. We can include the link to our documentation in our README.md and a link or badge - or use the project's About section to display the link.

About section

Navigate to the project's home page and find the About section (on the right side of the page). Click the gear icon and under the Website section, tick the box next to Use your GitHub Pages website.

Wrapping it up

In this tutorial, we set up our GitHub repo to host Elixir docs for our project. There are tons of extra settings we can use to fine tune our deployed docs - including setting a custom URL for our documentation.

Hopefully, this guide had enough information to get you started. Have a look around at GitHub's documentation for your specific application, and don't be afraid to leave a comment :)