Skip to content
ERP Preflight

CI integration

Use the erp-preflight CLI as a quality gate in CI pipelines: --fail-on semantics, exit codes, GitHub Actions and GitLab CI examples.

Content reviewed September 26, 2026

Prerequisites

  • An organization API key, stored as a secret CI variable. Keys created in the web app carry the default scopes, which cover uploading, running analyses, reading findings and exporting reports.
  • The id of an existing project — create it once in the web app, or with a key that has projects:write.
  • Node.js 18 or newer on the runner and the CLI package directory in your repository, because the CLI is not published to the public npm registry. The examples below assume it is committed as tools/erp-preflight-cli; it has no dependencies, so no install step is needed.
  • ERP_PREFLIGHT_API_URL and ERP_PREFLIGHT_API_KEY set as environment variables of the job; login is not needed in CI.

How --fail-on works

--fail-on takes a comma-separated list of severities: BLOCKER, CRITICAL, MAJOR, MEDIUM, MINOR, LOW, INFO (case does not matter). The gate fails when at least one finding has one of the listed severities. The list is not a threshold: --fail-on CRITICAL does not fail on BLOCKER findings. Name every severity that should break the build, for example --fail-on BLOCKER,CRITICAL.

  • The gate is evaluated by analyze … --wait and by findings. Without --wait, analyze returns right after queueing and evaluates no gate.
  • A run that ends FAILED or CANCELLED exits with code 1, with or without --fail-on. A PARTIAL run is gated on the findings it produced.
  • To gate a run that was started elsewhere, use findings --analysis <analysisId> --fail-on BLOCKER,CRITICAL.

Exit codes: 0 gate passed, 3 gate failed, 1 error (including a failed run or a --wait timeout), 2 usage or authentication problem (including a missing scope).

GitHub Actions

Store the key as the repository secret ERP_PREFLIGHT_API_KEY and the project id as the variable ERP_PREFLIGHT_PROJECT_ID:

name: sap-preflight
on:
  pull_request:
jobs:
  preflight:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - name: Clean Core quality gate
        env:
          ERP_PREFLIGHT_API_URL: https://api.example.com
          ERP_PREFLIGHT_API_KEY: ${{ secrets.ERP_PREFLIGHT_API_KEY }}
          PROJECT_ID: ${{ vars.ERP_PREFLIGHT_PROJECT_ID }}
        run: |
          node tools/erp-preflight-cli/bin/erp-preflight.js analyze clean-core ./src \
            --project "$PROJECT_ID" --wait --timeout 900 \
            --fail-on BLOCKER,CRITICAL --json > preflight-result.json
      - name: Keep the result
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: preflight-result
          path: preflight-result.json

The step uploads the matching files under ./src to the project, runs Clean Core Object Guard and fails the job when a BLOCKER or CRITICAL finding exists. With --json the result is written before the gate is evaluated, so the artifact is kept even when the job fails.

GitLab CI

Define ERP_PREFLIGHT_API_URL, ERP_PREFLIGHT_API_KEY (masked) and ERP_PREFLIGHT_PROJECT_ID as CI/CD variables of the project:

sap-preflight:
  image: node:20
  stage: test
  script:
    - node tools/erp-preflight-cli/bin/erp-preflight.js analyze clean-core ./src --project "$ERP_PREFLIGHT_PROJECT_ID" --wait --timeout 900 --fail-on BLOCKER,CRITICAL --json > preflight-result.json
  artifacts:
    when: always
    paths:
      - preflight-result.json

The job fails with exit code 3 when the gate fails and with 1 or 2 on errors; GitLab marks the pipeline as failed in every case.

Tips

  • To gate files that are already in the project, run analyze <projectId> --engines <engine> --files <fileId,...> --wait --fail-on BLOCKER,CRITICAL instead of uploading again.
  • To attach a report to the pipeline, take analysisId from the --json output and run report export <projectId> <analysisId> --format PDF --out preflight.pdf.
  • Give every pipeline its own key with an expiry date, and revoke it when the pipeline is retired.
  • Raise --timeout for large uploads; a --wait timeout ends with exit code 1.
CI integration — ERP Preflight Docs