Resume-md: Manage your resume with GitHub and Markdown
Tags: githubhack23, github, career, programming
Published: 2023-05-15 17:10:11

## What I built 

This project allows you to write and maintain your resume in markdown. GitHub Actions is used to generate stylized PDF and HTML files based on `resume.md` and `style.css`. The stylized files are found as outputs in the `Releases` section, the HTML file is also deployed as a static website using GitHub Pages.

**Category Submission:** DIY Deployments

**Link:**{% embed https://github.com/siph/resume-md %}

## About 

I have seen other projects that provided some of the same features but I wanted something that automatically deployed via GitHub Pages. Unfortunately those projects were not licensed so I didn't feel comfortable forking them. Instead I decided to build my own solution from scratch and used the opportunity to make heavy use of nix throughout the process.

### Nix

If you don't know about nix, I wrote ~~some propaganda~~ an [article](https://dev.to/siph/hi-there-have-you-heard-the-good-news-about-our-lord-and-savior-nix-o16) introducing some features that nix offers.

`Resume-md` uses nix for both dependency management and as a build system. The build process just consists of running a `pandoc` command to make the html file and a `wkhtmltopdf` command to build the pdf file. This nix derivation just runs those commands and moves the resulting files so that they're accessible in the nix store via `/nix/store/${resume-md}/resumes/`.

```nix
{
packages = {

  default = stdenv.mkDerivation {

    name = "resume_md";
    src = ./.;

    buildInputs = [
      pandoc
      wkhtmltopdf-bin
    ];

    buildPhase = ''

      pandoc resume.md \
      -t html -f markdown \
      -c style.css --self-contained \
      -o resume.html

      wkhtmltopdf --enable-local-file-access \
      resume.html \
      resume.pdf

    '';

    installPhase = ''

      mkdir -p $out/resume
      cp resume.* $out/resume/

    '';

  };
};
}
```

Using nix flakes to manage the dependencies means that each dependency is pinned to a specific commit which results in an extremely reproducible build process. You can run this build process locally to build the files which get placed into the nix store and symlinked to `./result`.


### GitHub Actions

The GitHub Actions marketplace is incredibly expansive and includes multiple options for including nix in your Actions. This makes it trivial to leverage all the powerful nix stuff already in place.

```yaml
jobs:
  generate:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - uses: cachix/install-nix-action@v19
      with:
        github_access_token: ${{ secrets.GITHUB_TOKEN }}
    - name: Build Resume
      run: |
        mkdir out
        nix build
        cp result/resume/resume.html out/${{ github.actor}}_resume.html
        cp result/resume/resume.pdf out/${{ github.actor}}_resume.pdf
        cp result/resume/resume.md out/${{ github.actor}}_resume.md
    - name: Store Artifacts
      uses: actions/upload-artifact@v3
      with:
        name: resume
        path: out/
```

Look at how simple this Action is as a result of the nix integration. It just tells nix to build the default package and copies/renames the files to prepend the GitHub username to the build artifacts.


### GitHub Pages

This build process already outputs an html file so it makes perfect sense to deploy it as a static website using GitHub Pages.

```yaml
jobs:
  publish:
    runs-on: ubuntu-latest
    needs: generate
    steps:
    - uses: actions/checkout@v3
    - name: Retrieve Artifacts
      uses: actions/download-artifact@v3
      with:
        name: resume
        path: out/

    - name: Stage
      run: |
        mkdir public
        cp out/${{ github.actor }}_resume.html public/index.html
    - name: Deploy
      uses: peaceiris/actions-gh-pages@v3
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: ./public
```

This also uses the `hub` cli tool, available in any Actions environment, to build a release for the user to download the html, pdf, and original md files. This generates a time-stamp for the release title and adds the resume files, all without needing to manually make and push tags.

```yaml
    - name: Set Tag
      id: current-datetime
      run: echo "CURRENT_DATETIME=$(date +'%Y-%m-%d-%H_%M_%S%z')" >> "$GITHUB_OUTPUT"
    - name: Build Release
      shell: bash
      run: |
        hub release create ${{ steps.current-datetime.outputs.CURRENT_DATETIME }} \
        -m ${{ steps.current-datetime.outputs.CURRENT_DATETIME }} \
        -a out/${{ github.actor }}_resume.html \
        -a out/${{ github.actor }}_resume.md \
        -a out/${{ github.actor }}_resume.pdf
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

### Conclusion

GitHub Actions is an awesome automation platform and combined with nix provides and incredible toolkit to build powerful, reproducible and streamlined pipelines.