How to publish ExDocs on GitHub Pages
Tags: github, elixir, tutorial
Published: 2022-02-23 20:26:35

---
title: "How to publish ExDocs on GitHub Pages"
published: true
description: 
tags: [github, elixir, tutorial]
//cover_image: https://direct_url_to_image.jpg
---

GitHub Pages allows you to publish static files, but it doesn't allow you to _generate_ these. This is a problem if you want to generate ExDocs for a private package or generate a static website with a web framework like Angular.

The only way to have static files published on GitHub Pages is to put them on the repo, either in `/docs` or in a branch named `gh-pages`. Let's do this using GitHub Actions.

## SSH key

[Generating a new SSH key](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent#generating-a-new-ssh-key) will allow you to push change to your Git repository from a GitHub Action. We'll use this to generate ExDocs and push them whenever there's a push on `master`.

```sh
ssh-keygen -t ed25519 -C "gh-pages"
```

### Deploy key

> A [deploy key](https://docs.github.com/en/developers/overview/managing-deploy-keys#deploy-keys) is an SSH key that grants access to a single repository. GitHub attaches the public part of the key directly to your repository instead of a personal user account, and the private part of the key remains on your server.

Add the public key to the _Deploy keys_ in `/settings/keys`.

![Deploy Key](https://user-images.githubusercontent.com/10495562/155388833-4794ef07-1bd7-4f12-90bf-0020e035e8ea.png)

### Action secrets

> Secrets are environment variables that are **encrypted**. Anyone with
> **collaborator** access to this repository can use these secrets for Actions.

Add the private key to the _Repository secrets_ in `/settings/secrets/actions`.

![Repository Secrets](https://user-images.githubusercontent.com/10495562/155388899-a0886eed-5a8e-4fcd-9c17-ceb6aebebb5a.png)

## GitHub Action

With this setup, your GitHub Actions now have the ability to modify the repository. Depending on weather you want to put the docs in `/docs` or in `gh-pages`, the steps will be very similar.

![Elixir GitHub Action](https://user-images.githubusercontent.com/10495562/155388952-4dbf2817-6b72-4a1f-a5d9-5d6f35929566.png)

Using a GitHub Action, we'll execute these steps:

1. Generate ExDocs in `/doc`
2. Initialize a Git repository in `/doc`
3. Link this new local repo to your repository
4. Force push the whole directory to `gh-pages`

Here's an example of the GitHub Actions file.

```yaml
name: GitHub Pages

on:
  push:
    branches: [master]

jobs:
  build:
    name: Push to gh-pages
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - name: Set up Elixir
        uses: erlef/setup-beam@988e02bfe678367a02564f65ca2e37726dc0268f
        with:
          elixir-version: "1.13.3" # Define the elixir version [required]
          otp-version: "24" # Define the OTP version [required]
      - name: Restore dependencies cache
        uses: actions/cache@v2
        with:
          path: deps
          key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
          restore-keys: ${{ runner.os }}-mix-
      - name: Install dependencies
        run: mix deps.get

      - name: Force push to gh-pages
        run: |
          # Generate docs
          mix docs

          # Setup
          cd doc
          git init --initial-branch gh-pages
          git remote add origin $ORIGIN
          git config user.name "$NAME"
          git config user.email "$EMAIL"
          eval `ssh-agent -s`
          ssh-add - <<< '${{ secrets.GH_PAGES_SSH }}'

          # Push
          git add .
          git commit -m "mix docs"
          git push --set-upstream origin gh-pages -f
```

In this file, you'll have to replace the variables `$NAME`, `$EMAIL` and `$ORIGIN`.

Once it's commited to `master`, the GitHub Pages will be automatically deployed!