CI/CD Integration
Pageflare is designed to work in non-interactive environments. This page covers how to integrate it into your CI/CD pipeline.
Key Flags for CI
Section titled “Key Flags for CI”--no-progress
Section titled “--no-progress”Disables the live progress spinners that clutter CI logs:
pageflare dist/ --output dist/ --no-progressAuto-detection: When stdout is not connected to a terminal (i.e., output is piped or redirected), pageflare automatically suppresses spinners. In most CI environments this means you do not need the flag at all — it is provided for cases where auto-detection does not work as expected.
--json
Section titled “--json”Outputs a machine-readable JSON manifest instead of the human-readable summary table. Useful for parsing results, generating reports, or failing the build based on specific criteria:
pageflare dist/ --output dist/ --json > pageflare-report.json--log <LEVEL>
Section titled “--log <LEVEL>”Log messages go to stderr; the JSON/summary output goes to stdout. In CI you typically want warn (the default) or error to keep logs clean:
pageflare dist/ --output dist/ --log errorLicense in CI
Section titled “License in CI”Pro features require a valid license. In CI environments use the PAGEFLARE_LICENSE environment variable — this avoids storing the license token in the filesystem and works across all CI providers.
export PAGEFLARE_LICENSE=your-license-tokenpageflare dist/ --output dist/License resolution order (highest to lowest priority):
PAGEFLARE_LICENSEenvironment variable- License file at
~/.config/pageflare/license.json - Free tier (no license)
Store the token as a secret in your CI provider and inject it as an environment variable — never commit it to source control.
Exit Codes
Section titled “Exit Codes”| Code | Meaning |
|---|---|
0 | Success — all files processed without errors |
1 | One or more files encountered errors during processing |
Use the exit code to fail your pipeline if pageflare reports errors:
pageflare dist/ --output dist/ || exit 1In most CI environments (GitHub Actions, GitLab CI) a non-zero exit code automatically fails the step, so this is the default behavior.
GitHub Actions
Section titled “GitHub Actions”Basic Workflow
Section titled “Basic Workflow”name: Build and Optimize
on: push: branches: [main] pull_request:
jobs: build: runs-on: ubuntu-latest
steps: - uses: actions/checkout@v4
- name: Set up Node.js uses: actions/setup-node@v4 with: node-version: 20
- name: Install dependencies run: npm ci
- name: Build site run: npm run build
- name: Install pageflare run: curl -fsSL https://get.appz.dev/pageflare/install.sh | sh
- name: Optimize site env: PAGEFLARE_LICENSE: ${{ secrets.PAGEFLARE_LICENSE }} run: pageflare dist/ --output dist/ --no-progress
- name: Deploy # Your deployment step here run: echo "Deploy dist/ to your host"With JSON Report
Section titled “With JSON Report” - name: Optimize site env: PAGEFLARE_LICENSE: ${{ secrets.PAGEFLARE_LICENSE }} run: pageflare dist/ --output dist/ --json > pageflare-report.json
- name: Upload optimization report uses: actions/upload-artifact@v4 with: name: pageflare-report path: pageflare-report.jsonCaching the pageflare Binary
Section titled “Caching the pageflare Binary” - name: Cache pageflare uses: actions/cache@v4 with: path: ~/.local/bin/pageflare key: pageflare-${{ runner.os }}-v1
- name: Install pageflare run: | if ! command -v pageflare &> /dev/null; then curl -fsSL https://get.appz.dev/pageflare/install.sh | sh fiGitLab CI
Section titled “GitLab CI”Basic Pipeline
Section titled “Basic Pipeline”stages: - build - optimize - deploy
build: stage: build image: node:20-alpine script: - npm ci - npm run build artifacts: paths: - dist/
optimize: stage: optimize image: alpine:latest dependencies: - build script: - curl -fsSL https://get.appz.dev/pageflare/install.sh | sh - pageflare dist/ --output dist/ --no-progress variables: PAGEFLARE_LICENSE: $PAGEFLARE_LICENSE # Set in CI/CD > Variables artifacts: paths: - dist/
deploy: stage: deploy dependencies: - optimize script: - echo "Deploy dist/ to your host" only: - mainStore PAGEFLARE_LICENSE in Settings > CI/CD > Variables with the “Masked” option enabled to keep it out of job logs.
Docker
Section titled “Docker”Use the official Docker image pageflare/cli to avoid installing the binary altogether. This is useful for CI systems that support container-based steps.
GitHub Actions (container step)
Section titled “GitHub Actions (container step)” - name: Optimize site uses: docker://pageflare/cli:latest with: args: dist/ --in-place --no-progress env: PAGEFLARE_LICENSE: ${{ secrets.PAGEFLARE_LICENSE }}GitLab CI (image)
Section titled “GitLab CI (image)”optimize: stage: optimize image: pageflare/cli:latest dependencies: - build script: - pageflare dist/ --in-place --no-progress variables: PAGEFLARE_LICENSE: $PAGEFLARE_LICENSE artifacts: paths: - dist/Generic Docker
Section titled “Generic Docker”docker run --rm \ -e PAGEFLARE_LICENSE="$PAGEFLARE_LICENSE" \ -v "$(pwd)/dist:/site" \ pageflare/cli /site --in-place --no-progressOther CI Systems
Section titled “Other CI Systems”The pattern is the same regardless of CI provider:
- Build your static site normally
- Set
PAGEFLARE_LICENSEfrom a secret variable - Run
pageflare <input> --output <input> --no-progress - Deploy the output directory
# Generic CI shell scriptset -e
npm run buildcurl -fsSL https://get.appz.dev/pageflare/install.sh | shpageflare dist/ --output dist/ --no-progressParsing JSON Output
Section titled “Parsing JSON Output”The --json flag writes a structured manifest to stdout. Example structure:
{ "summary": { "total": 42, "optimized": 38, "unchanged": 4, "errors": 0, "bytes_before": 390144, "bytes_after": 240640, "elapsed_ms": 1234 }, "files": [ { "path": "index.html", "status": "optimized", "bytes_before": 12800, "bytes_after": 9200 } ]}Use a tool like jq to extract specific values:
pageflare dist/ --output dist/ --json | jq '.summary.errors'# Fail the build if any files erroredpageflare dist/ --output dist/ --json | jq 'if .summary.errors > 0 then error else . end'