xu-cheng/latex-action: compiling LaTeX PDFs in GitHub Actions
:octocat: GitHub Action to compile LaTeX documents
At a glance
- What is it?
- xu-cheng/latex-action is a GitHub Action that compiles one or more LaTeX root files inside a Docker container with TeXLive. It fits repositories that already use GitHub Actions and need reproducible PDF builds, custom packages, fonts, or selectable LaTeX engines, but its container and input configuration add constraints.
- Who is it for?
- Adopt xu-cheng/latex-action when a repository already builds LaTeX documents in GitHub Actions and needs a container-based TeXLive environment. Do not choose it for arbitrary command execution, since the project points that use case to texlive-action.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 100 days ago.
- What is it written in?
- Mainly Shell, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.
Star history
- xu-cheng/latex-action1,425 ★ · +6
| Repository | 2026-10-17 | 2026-11-07 |
|---|---|---|
| xu-cheng/latex-action | 1.4k | 1.4k |
6 Stars in the last 21 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
Why latex-action Fits GitHub-hosted LaTeX Builds
xu-cheng/latex-action solves a narrow CI problem: compiling LaTeX documents into PDFs during a GitHub Actions workflow. It is intended for repositories that contain LaTeX source files and want the build environment packaged as a Docker-based action rather than assembled manually in every workflow. The README describes support for multiple root documents, several TeXLive versions, Alpine and Debian images, additional system packages, custom fonts, and pre- or post-compile scripts.
The action is not a general command runner for every tool that needs TeXLive. Its README explicitly directs users who want arbitrary commands in a TeXLive environment to `texlive-action`. That distinction matters because `latex-action` is centered on document compilation and exposes inputs for compiler selection, root files, working directories, dependencies, and scripts. It is therefore more appropriate for a CI job whose output is a built PDF than for a broader containerized toolchain workflow.
The target user is likely a GitHub repository maintainer who wants a repeatable LaTeX build on `ubuntu-latest` or another GitHub-hosted runner. The action moves the TeXLive environment into Docker, but it does not remove the need for the repository to contain usable LaTeX sources, package dependencies, and any custom files required by the document.
The Docker and TeXLive Build Path
The documented execution model starts with a GitHub Actions step that invokes `xu-cheng/latex-action@v4`. The action runs through a Docker image containing a full TeXLive installation. By default, the image is Alpine based and uses the latest TeXLive version. A workflow can instead request Debian, choose a historic TeXLive release from `2020` through `2026`, or provide a custom Docker image.
Compilation is driven by the `root_file` input. It can name one file, contain several files across multiple lines, or use glob patterns. For a multi-document build, `work_in_root_file_dir` can change into each root file's directory before compilation. This is useful when each document has its own local structure. The action then invokes the configured compiler. When no compiler is supplied, the default is `latexmk`, whose default arguments are `-pdf -file-line-error -halt-on-error -interaction=nonstopmode`.
The engine inputs have an important boundary. `latexmk_use_xelatex` selects XeLaTeX, while `latexmk_use_lualatex` selects LuaLaTeX. The README says these inputs work only with the default `latexmk` compiler. A project that supplies another compiler configuration must handle its own LaTeX engine selection, such as through a `.latexmkrc` file when using `latexmk`.
Installing and Running the First Document Build
The README's example uses `actions/checkout@v6`, followed by the LaTeX action and an artifact upload. This is a complete first workflow for a repository whose root document is `main.tex`. The checkout step gives the action access to the repository files, while the action places the resulting PDF beside the source file.
name: Build LaTeX document
on: [push]
jobs:
build_latex:
runs-on: ubuntu-latest
steps:
- name: Set up Git repository
uses: actions/checkout@v6
- name: Compile LaTeX document
uses: xu-cheng/latex-action@v4
with:
root_file: main.tex
- name: Upload PDF file
uses: actions/upload-artifact@v6
with:
name: PDF
path: main.pdfThe workflow should be placed in the repository's GitHub Actions workflow configuration. The README does not document a separate installation command because the action is consumed through the `uses` entry. After the build, the generated `main.pdf` is available to the upload step. The upload action version shown in the main example is `actions/upload-artifact@v6`.
For XeLaTeX, the action input is added without changing the rest of the workflow:
- uses: xu-cheng/latex-action@v4
with:
root_file: main.tex
latexmk_use_xelatex: trueThis selects XeLaTeX through the default `latexmk` integration. The README does not claim that this changes output naming or adds a new post-processing stage, so the upload path should remain `main.pdf` unless the LaTeX source or compiler settings produce a different filename.
Multiple Documents, Fonts, and System Dependencies
Multi-document support is handled through the `root_file` input rather than by requiring every workflow to contain a separate action step. The documented format accepts a multiline list:
- uses: xu-cheng/latex-action@v4
with:
root_file: |
file1.tex
file2.texBy default, failure of one document stops the build. Setting `continue_on_error: true` allows the action to continue building remaining documents, but the action still reports failure if any document fails. This is useful for a build matrix represented as several root files, although it does not make failed documents successful.
The action can install OS packages through `extra_system_packages`. It uses `apk` on Alpine and `apt-get` on Debian. This input is separate from TeX package management, which is why the README's pre-compile example uses `tlmgr`:
pre_compile: "tlmgr update --self && tlmgr update --all"Custom fonts for `fontspec` are supplied through `extra_fonts`, using `.ttf` or `.otf` paths and glob patterns. For example:
extra_fonts: |
./path/to/custom.ttf
./fonts/*.otfThese inputs address common failures caused by missing OS tools or fonts. They do not remove the need to ensure that the document requests the corresponding packages and that the files are present in the checked-out repository or otherwise available inside the action's environment.
Container Selection and TeXLive Compatibility
The default environment is Alpine with the latest TeXLive, but the action allows a different base or version. This flexibility matters for documents that depend on a specific TeX distribution, although it also makes configuration mistakes easier. The documented version choices are `2020` through `2026`, or `latest`.
- uses: xu-cheng/latex-action@v4
with:
root_file: main.tex
texlive_version: 2024To change the base operating system, set `os` to `debian`:
- uses: xu-cheng/latex-action@v4
with:
root_file: main.tex
os: debianA custom `docker_image` overrides both `texlive_version` and `os`. The README recommends the `latex-docker` images and shows digest pinning as a way to select a fixed image:
- uses: xu-cheng/latex-action@v4
with:
root_file: main.tex
docker_image: ghcr.io/xu-cheng/texlive-alpine@sha256:<hash>The `<hash>` placeholder is part of the README's illustrative form, not a usable digest. A workflow author must supply an actual digest. The README does not document image signing verification, rollback behavior for a failed custom image, or compatibility guarantees for arbitrary Docker images. Those omissions should be considered before replacing the managed image.
Shell Escape, Scripts, and Search Paths
Some LaTeX documents invoke external commands. The action exposes `latexmk_shell_escape`, which defaults to `false`. Enabling it changes the compilation environment by allowing external command execution through `latexmk`:
- uses: xu-cheng/latex-action@v4
with:
root_file: main.tex
latexmk_shell_escape: trueThe README also provides `pre_compile` and `post_compile` for Bash commands around the build. A post-compile command can clean generated files with `latexmk -c`:
post_compile: "latexmk -c"For custom `.sty` or `.cls` files, the README recommends setting `TEXINPUTS`. Its example downloads a custom template and then passes the environment variable to the action:
- name: Download custom template
run: |
curl -OL https://example.com/custom_template.zip
unzip custom_template.zip
- uses: xu-cheng/latex-action@v4
with:
root_file: main.tex
env:
TEXINPUTS: ".:./custom_template//:"The README warns not to use `{{ github.workspace }}` or `$GITHUB_WORKSPACE` in `TEXINPUTS`, because the action runs in a separate Docker container where that workspace reference may not resolve correctly. The documented example uses a path relative to the action's working environment instead.
Operational Limits and the TeXLive Alternative
The main limitation is scope. `latex-action` is designed to compile LaTeX documents, not to provide a general-purpose TeXLive execution environment. A workflow that needs to run package installation commands, arbitrary shell steps, or unrelated TeX tooling may fit `texlive-action` better. The README gives that direct alternative rather than claiming that the two actions have identical purposes.
The second limitation is that configuration is distributed across several inputs with dependencies between them. `docker_image` supersedes `texlive_version` and `os`, and the engine-selection inputs are limited to the default `latexmk` compiler. A custom compiler therefore changes the meaning of the documented engine switches. Multi-document builds also have a deliberate failure model. `continue_on_error` allows later documents to run, but the overall action still fails if any document fails.
The action's maintenance record is positive in a narrow factual sense. The repository is not archived, and its last push was on 2026-07-30. Release history includes `4.1.0` on 2026-04-02 and `v4` on 2025-07-07. The README does not provide a detailed upgrade policy, compatibility matrix between every TeXLive release and every image, or a stated support window, so those details require verification in the repository and workflow logs before adoption. The MIT license permits use and modification under its terms, but license interpretation for a particular deployment should be handled separately from build configuration.
Editorial conclusion
Adopt xu-cheng/latex-action when a repository already builds LaTeX documents in GitHub Actions and needs a container-based TeXLive environment. Do not choose it for arbitrary command execution, since the project points that use case to texlive-action. Verify first that the repository's TeXLive version, base operating system, root-file paths, compiler engine, fonts, and package requirements match the action inputs. The relevant project-specific boundary is that `docker_image` overrides `texlive_version` and `os`, while the XeLaTeX and LuaLaTeX options only apply to the default `latexmk` compiler.
Frequently asked questions
How do I use XeLaTeX or LuaLaTeX with xu-cheng/latex-action?
Set `latexmk_use_xelatex: true` for XeLaTeX or `latexmk_use_lualatex: true` for LuaLaTeX. These inputs work with the default `latexmk` compiler, and a `.latexmkrc` file is the alternative documented by the README.
Where does xu-cheng/latex-action place the compiled PDF?
The README states that the compiled PDF is placed in the same directory as the LaTeX source file. In the documented single-file example, `main.tex` produces `main.pdf`, which can be uploaded as an artifact.
Can xu-cheng/latex-action build multiple LaTeX documents?
Yes. `root_file` accepts glob patterns and a multiline list of root files. By default, a failed document stops the build; `continue_on_error: true` allows remaining documents to be attempted, while the action still reports failure if any document fails.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/xu-cheng-latex-action)Star history chart for your README
[](https://hysenlabs.com/projects/xu-cheng-latex-action)Was this useful?