DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

epassaro
epassaro

Posted on

Build a LaTeX document by opening an issue (or pull request)

I heard about Tectonic for the first time during the PackagingCon 2021 and immediately I knew that's the kind of stuff I want to deploy on GitHub Actions.

LaTeX is a high-quality typesetting system, and it's the de facto standard for the communication and publication of scientific documents. Installing a full LaTeX system takes up a considerable amount time and space on your hard drive.

Also, the reproducibility of these documents is not trivial. That's where Tectonic comes in:

Tectonic is a modernized, complete, self-contained TeX/LaTeX engine, powered by XeTeX and TeXLive. (...) Tectonic automatically downloads support files so you don’t have to install a full LaTeX system in order to start using it. If you start using a new LaTeX package, Tectonic just pulls down the files it needs and continues processing. The underyling β€œbundle” technology allows for completely reproducible document compiles.

But... Why not just use Overleaf? Personally, I think the Git version control system fits perfectly when it comes to collaborative writing.

The workflow

This time, I wrote two different workflows: one to build from pull requests and other to build from issues.

I'm going to focus on the second one, because the other is very similar and easier to follow.

First, I created an issue template to submit LaTeX code:

Image description

Then, the workflow runs as you can see in the trigger section. Notice the job requires the [Build] label on the issue title.

name: issues

on:
  issues:
      types: [opened, edited]

env:
  REPO_URL: https://github.com/${{ github.repository_owner }}/${{ github.event.repository.name }}

jobs:
  build:
    if: startsWith(github.event.issue.title, '[Build]')
    runs-on: ubuntu-latest
Enter fullscreen mode Exit fullscreen mode

The latest version of Tectonic is installed. dos2unix is required because the text from issue the body uses CRLF.

    steps:
      - uses: actions/checkout@v2

      - name: Install dependencies
        run: |
          sudo apt-get install dos2unix

          LAST_TAG=$(curl -s https://api.github.com/repos/tectonic-typesetting/tectonic/releases/latest | jq -r .tag_name)
          VERSION="${LAST_TAG##tectonic@}"

          wget -q https://github.com/tectonic-typesetting/tectonic/releases/latest/download/tectonic-$VERSION-x86_64-unknown-linux-gnu.tar.gz
          tar -zxf tectonic-$VERSION-x86_64-unknown-linux-gnu.tar.gz -C /usr/local/bin

Enter fullscreen mode Exit fullscreen mode

The code from the body is extracted with a sed command and built with Tectonic. The result is uploaded as an artifact.

      - name: Extract code
        run: |
          echo $ISSUE_BODY | dos2unix -c mac > issue_body.txt
          sed -n '/%%build/, /%%dliub/{ /%%build/! { /%%dliub/! p } }' issue_body.txt > build/main.tex
        env:
          ISSUE_BODY: ${{ github.event.issue.body }}

      - name: Build PDF
        run: tectonic -X compile build/main.tex

      - uses: actions/upload-artifact@v2
        with:
          name: main
          path: build/main.pdf
Enter fullscreen mode Exit fullscreen mode

Finally, the github-actions bot post the result of the workflow run as a comment in the corresponding issue.

Image description

Successive runs will update this comment, not creating new ones.

      - name: Find comment
        uses: peter-evans/find-comment@v1
        id: fc
        with:
          issue-number: ${{ github.event.issue.number }}
          comment-author: 'github-actions[bot]'
        if: always()

      - name: Post comment (success)
        uses: peter-evans/create-or-update-comment@v1
        with:
          issue-number: ${{ github.event.issue.number }}
          comment-id: ${{ steps.fc.outputs.comment-id }}
          edit-mode: replace
          body: |
            Hi, @${{ github.event.sender.login }}! :wave: <br>
            The workflow run has **succeeded**. [**Click here**](${{ env.LOG_URL }}) to download your results.
        env:
          LOG_URL: ${{ env.REPO_URL }}/actions/runs/${{ github.run_id }}?check_suite_focus=true

      - name: Post comment (failure)
        uses: peter-evans/create-or-update-comment@v1
        with:
          issue-number: ${{ github.event.issue.number }}
          comment-id: ${{ steps.fc.outputs.comment-id }}
          edit-mode: replace
          body: |
            Sorry, @${{ github.event.sender.login }}! :disappointed: <br>
            The workflow run has **failed**. [**Click here**](${{ env.LOG_URL }}) to see the build log.
        env:
          LOG_URL: ${{ env.REPO_URL }}/actions/runs/${{ github.run_id }}?check_suite_focus=true
        if: failure()
Enter fullscreen mode Exit fullscreen mode

Future improvements

Currently, you need to download them and extract the ZIP file in order to see your results. This happens because workflows does not have access to the artifact ID while the job is running, and GitHub does not allow uploading unzipped archives.

An alternative is pushing the PDF to a specific branch or folder, but populating the repository with binary files is not a good idea.

Get the code

GitHub logo epassaro / texbuilder

Build and preview LaTeX documents with GitHub Actions

texbuilder

Build and preview LaTeX documents with GitHub Actions

Usage

  • Open a Build request and submit your LaTeX code.
  • Fork this repository, apply your changes to build/main.tex and open a pull request.

Top comments (0)

Another day as a dev

Stop by this week's meme thread!