Export Automation
Export Automation
Section titled “Export Automation”Export Confluence pages to PDF (or DOCX) from a CI/CD pipeline, parse the machine-readable report, and upload the result as a build artifact — no hosted service, no polling, and no data leaving your runner.
Automation is the CLI itself. There is no hosted export job to submit or poll: a single
atlcli wiki export … --format pdf --report jsoncall does the whole job on the runner and reports its result as one JSON document on stdout with a deterministic exit code.
On this page
Section titled “On this page”- Prerequisites
- How it works
- GitHub Actions
- GitLab CI
- Parsing the report
- Troubleshooting
- Related topics
Prerequisites
Section titled “Prerequisites”- An Atlassian API token stored as a CI/CD secret.
- The Confluence base URL and (for Cloud) the account email.
- View permission on the page(s) to export.
No ~/.atlcli/config.json is needed: the jobs below use
profile-free auth via environment variables.
How it works
Section titled “How it works”The export command:
- Fetches the page (or the whole tree/space) with token auth.
- Compiles a tagged, font-embedded PDF in-process (no browser).
- Writes the file atomically (nothing partial on failure).
- Prints an
atlcli.export-report/1JSON document on stdout and exits with a documented code.
GitHub Actions
Section titled “GitHub Actions”name: Export handbook PDFon: workflow_dispatch:jobs: export: runs-on: ubuntu-latest steps: - name: Install atlcli run: curl -fsSL https://atlcli.sh/install.sh | bash - name: Export to PDF env: ATLCLI_BASE_URL: ${{ vars.CONFLUENCE_BASE_URL }} ATLCLI_EMAIL: ${{ vars.CONFLUENCE_EMAIL }} ATLCLI_API_TOKEN: ${{ secrets.CONFLUENCE_TOKEN }} run: | atlcli wiki export "${{ github.event.inputs.page || '12345678' }}" \ --format pdf --scope tree --label-exclude internal \ --out-dir dist --report json --strict | tee report.json - name: Summarize run: | jq -r '"Exported \(.outputs[0]) — \(.outputDetails[0].pageCount) pages, \(.warnings | length) warnings"' report.json - name: Fail on an incomplete export run: | # `complete` is emitted for --format pdf and --format docx alike, so # this gate is identical whichever format the job produces. [ "$(jq -r '.complete' report.json)" = "true" ] || { echo "Export incomplete:" >&2; jq '.notesByCode' report.json >&2; exit 1; } - uses: actions/upload-artifact@v4 with: name: handbook-pdf path: dist/*.pdfGitLab CI
Section titled “GitLab CI”export_pdf: image: ubuntu:24.04 variables: ATLCLI_BASE_URL: "$CONFLUENCE_BASE_URL" ATLCLI_EMAIL: "$CONFLUENCE_EMAIL" # ATLCLI_API_TOKEN is a protected/masked CI variable before_script: - apt-get update && apt-get install -y curl jq ca-certificates unzip - curl -fsSL https://atlcli.sh/install.sh | bash - export PATH="$HOME/.local/bin:$PATH" script: - atlcli wiki export "$PAGE_ID" --format pdf --out-dir dist --report json --strict | tee report.json - jq -r '.outputs[0]' report.json artifacts: paths: - dist/*.pdf when: on_successParsing the report
Section titled “Parsing the report”The report is a stable, versioned projection. Useful jq queries:
# The produced file path(s)jq -r '.outputs[]' report.json
# Per-artifact metrics (pages, embedded images, skipped assets)jq '.outputDetails[0]' report.json
# Fail the build on any warning yourself (equivalent to --strict)test "$(jq '.warnings | length' report.json)" -eq 0
# List every issue with its severity and phasejq -r '.issues[] | "\(.severity)\t\(.phase)\t\(.code)"' report.json
# Informational notes (timings, label filters, macros that rendered fine) are# reported but never fail the build — they are not in `.warnings`jq -r '.issues[] | select(.severity == "info") | .code' report.json
# Gate on ONE condition by code — the same code whichever format you exportjq -e '(.notesByCode["image-missing-alt"] // 0) == 0' report.jsonseverity is one of error, warning or info, and --strict trips on the first two
only — see Note severity and --strict.
If you are upgrading from a release where every note was reported as a warning, expect
jq '.warnings | length' to drop and a previously-always-2 --engine ts --strict job to
start passing.
Exit codes let the pipeline branch without parsing at all: 0 success, 2 warnings under
--strict, 3 auth, 4 remote/API (e.g. page not found), 5 compile failure. See the
full table.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Likely cause | Fix |
|---|---|---|
Exit 3, auth-error issue |
Bad or missing ATLCLI_API_TOKEN, or Cloud without ATLCLI_EMAIL |
Check the secret; Cloud needs the email, Data Center needs --auth-type bearer (no email) |
Exit 1, “must use HTTPS” |
Plain-HTTP --base-url |
Use HTTPS, or add --allow-http for Data Center |
Exit 4, page not found |
Wrong page id, or no view permission for the token’s user | Verify the id and the token account’s permissions |
Exit 1, “already exists” |
Output file exists | Use --out-dir for a fresh name, or --force to overwrite |
Related topics
Section titled “Related topics”- DOCX and PDF Export — full command reference
- CI/CD Documentation — publishing docs into Confluence from CI
- Authentication — tokens and profiles