Christopher Doyle

LATEX GitHub Workflow with Release Tagging

Feb 21, 2024

Create a GitHub workflow for compiling LATEX to PDF including version tagging on the commit and inside the PDF, and asset release. See christopherdoyle:LaTeXTemplate for a basic working example. The end result is:

  1. User merges PR into main.
  2. Workflow pushes a new commit bumping the verison.
  3. Workflow pushes a tag and release containing a compiled PDF, which includes the new version on the title page.

The Code

Here is the YAML workflow:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
name: Build LaTeX document

on:
  pull_request:
    types: [closed]
    branches: [main]

jobs:
  build_latex:
    runs-on: ubuntu-latest

    permissions:
      contents: write

    steps:

      - name: Set up Git repository
        uses: actions/checkout@v4
        with:
          ref: ${{ github.ref_name }}
          fetch-depth: '0'

      - name: Get next version
        id: get_next_version
        uses: thenativeweb/get-next-version@main
        with:
          prefix: 'v'

      - name: Show the next version
        run: |
          echo ${{ steps.get_next_version.outputs.version }}
          echo ${{ steps.get_next_version.outputs.hasNextVersion }}

      - name: Update version.tex, tag, commit, push
        if: steps.get_next_version.outputs.hasNextVersion == 'true'
        env:
          NEW_VERSION: ${{ steps.get_next_version.outputs.version }}
        shell: bash
        run: |
          old_version=$(git describe --tags --abbrev=0)
          sed -i "s/$old_version/$NEW_VERSION/" version.tex
          git config user.name "$(git log -n 1 --pretty=format:%an)"
          git config user.email "$(git log -n 1 --pretty=format:%ae)"
          git add version.tex
          git commit -m "Bump version $old_version->${{ steps.get_next_version.outputs.version }}"
          git push

      - name: Compile LaTeX document
        uses: xu-cheng/latex-action@3.1.0
        if: steps.get_next_version.outputs.hasNextVersion == 'true'
        with:
          root_file: main.tex

      - name: Create Release
        id: create_release
        uses: softprops/action-gh-release@v1
        if: steps.get_next_version.outputs.hasNextVersion == 'true'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          name: Release ${{ steps.get_next_version.outputs.version }}
          tag_name: ${{ steps.get_next_version.outputs.version }}
          draft: false
          prerelease: false
          files: main.pdf

How it work

We use the get next version action to interpret commit messages into major-minor-patch version bumps. This is detailed on the linked page, but for example a commit message like “fix: typos” will lead to a patch bump, say from 1.2.5 to 1.2.6.

To store the version inside the compiled document, we touch a small file called version.tex which is being \input to the main LATEX document. We need to have at least one tag already in git history for this to work, because we are reading the old version from the tag history (not from version.tex directly). So when setting up the workflow, you need to push a tag first.

main.tex looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
\newcommand{\Version}{}

\makeatletter
\renewcommand{\maketitle}{%
    %...
    \Version{}
    %...
}
\makeatother

\input{version.tex}

\begin{document}
\maketitle
\end{document}

and the contents of version.tex is like:

\renewcommand\Version{v1.2.5}

We use a custom \maketitle to add \Version to the title page. \Version could be defined and sed directly in main.tex, but it is safer to have a minimal separate file for this.

After sed-ing the version, the changes are committed with the prior commit’s author meta, and pushed to the main branch. So after this runs we have an extra commit:

The first commit is you merging a PR; the second commit is from the workflow. The new commit is not tagged yet. First we build the PDF with latex-action, then use action-gh-release to push a tagged release that contains the PDF.

Bonus: distribution to NextCloud (/Dropbox/etc.)

If you want to give your supervisor the latest version without adding them to your repository, you could use something like NextCloud WebDAV to push to a hosted NextCloud instance:

      - name: Upload Release Asset to NextCloud
        if: env.DO_BUMP_RELEASE == 'true'
        run: 'curl -u ${{ secrets.NEXTCLOUD_USERNAME }}:${{ secrets.NEXTCLOUD_PASSWORD }} -T ./main.pdf ${{ secrets.NEXTCLOUD_URL }}'

This requires you to set the secrets in your repository’s secrets and variables page.


← Back to all articles