Guide

PDF/A validation in CI

Creating a build gate that fails on a non-conformant document.

Run gopdfrab verify as a build step, which a non-conformant document fails. There is only one binary to install and no extra wiring.

The steps

  1. Install the gopdfrab CLI: Install the single static binary with go install, or download a release build. No further provisioning is required on the runner.
  2. Run verify over the documents: Point gopdfrab verify at a file or a directory. Directories are walked recursively, so one invocation covers a whole output folder.
  3. Let the exit code fail the job: The CLI exits 0 when every file conforms, 1 when at least one does not, and 2 on a usage or I/O error.
  4. Emit a machine-readable report: Add --json to get one object per file, so the job can annotate a pull request or archive the report as a build artifact instead of only printing to the log.

GitHub Actions

.github/workflows/pdfa.yml
name: pdfa

on: [push, pull_request]

jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-go@v5
        with:
          go-version: stable

      - name: Install gopdfrab
        run: go install github.com/voidrab/gopdfrab/cmd/gopdfrab@latest

      # Exits 1 when any document under docs/ is non-conformant, which
      # fails the job. Exit 2 means the tool itself could not run.
      - name: Verify PDF/A-1b
        run: gopdfrab verify docs/

GitLab CI

The same idea with the report kept as an artifact, so a failure is inspectable after the job finishes.

.gitlab-ci.yml
pdfa:
  image: golang:1
  script:
    - go install github.com/voidrab/gopdfrab/cmd/gopdfrab@latest
    - gopdfrab verify --json docs/ | tee pdfa-report.json
  artifacts:
    when: always
    paths:
      - pdfa-report.json

Exit codes

0Conformant — every file passed.
1Non-conformant — at least one file failed.
2Error — usage, open, or I/O failure.
verify-pdfa.sh
#!/usr/bin/env bash
# Fail the build when any PDF under docs/ is not PDF/A-1b conformant.
set -euo pipefail

if gopdfrab verify docs/; then
  echo "all documents are conformant"
else
  status=$?
  if [ "$status" -eq 1 ]; then
    echo "::error::one or more documents are not PDF/A-1b conformant"
  else
    echo "::error::gopdfrab failed to run"
  fi
  exit "$status"
fi

Machine-readable output

--json emits one object per file, which is useful when the job should annotate a pull request, for example.

bash
# verify --json emits an array of {path, error?, result?}
gopdfrab verify --json docs/ | jq -r '.[] | select(.result.valid == false) | .path'

The full shape is documented under JSON output, and the flags under the verify subcommand.

Validating in the service instead

A CI gate catches documents you commit. It does not catch documents your users upload. For that, call the library in-process with Verify, or run it in a function at the edge, covered in serverless and edge.

Frequently asked

How do I fail a CI build when a PDF is not PDF/A?

Run `gopdfrab verify <dir>` as a build step. It exits 1 if any file is non-conformant, which fails the step in GitHub Actions, GitLab CI, Jenkins or a plain shell script with no extra wiring.

Is it fast enough to run on every commit?

Yes, the entire conformance corpus takes less than a second to verify in one process, and the startup time is negligible.

Can I check only some rules?

Yes. --profile selects pdfa1b (the default, veraPDF-aligned), legacy1b (the stricter Isartor-derived profile), or pdf (generic ISO 32000 object-model checks only). From the library you can add or remove individual checks.

How do I handle documents that are known to be non-conformant?

Only verify the directory that must conform, rather than the entire repository.