This is a personal proof-of-concept project. It is not intended for production use. Please refrain from using it.
Skip to content

CI: gate PRs / MRs with Upliftr

Upliftr is AI debugging agents that debug your app, read-only by design. Once an agent confirms a flow, it saves that flow as a plain-English check and re-runs it in CI. Upliftr is designed to be the check that gates a pull request (GitHub) or merge request (GitLab): on every PR/MR an agent drives a real browser, reproduces any regression, root-causes it to the exact backend line, and files a deduped ticket, all without mutating your code, data, or infrastructure. The same engine and the same exit codes back three drop-in surfaces:

  • A GitHub Action (action.yml), PR gating with artifacts and auto-filed issues.
  • A GitLab CI job / component, MR gating on the public Upliftr image, JUnit in the MR widget.
  • The CLI (upliftr run), the underlying gate, usable from any CI system or terminal.

Exit codes (the gate)

The CLI's exit code is the gate. It's the same everywhere:

CodeMeaning
0All cases passed.
1At least one case failed (an assertion didn't hold).
2At least one case is broken (the run couldn't be carried out).
3Spec / config error (bad path, no suites matched, missing API key).

Broken (2) outranks failed (1) outranks ok (0). A non-zero exit fails the job and blocks the PR/MR.

GitHub Action

Add one step. The action runs on the public Upliftr image (Chromium + engine baked in, no install step), runs your suites headless, writes reports, and exits non-zero to gate the PR.

yaml
# .github/workflows/upliftr.yml
name: Upliftr E2E
on: pull_request
jobs:
  e2e:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: upliftrhq/upliftr-action@v1
        with:
          suite: "suites/*.upliftr.yaml"
          file-issues: "github"          # optional; '' to disable
          anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
        env:
          GITHUB_TOKEN: ${{ github.token }}   # only for file-issues: github

Set ANTHROPIC_API_KEY as a repo secret. Inputs: suite, file-issues (default ''), anthropic-api-key (required), out. Ready-to-copy: examples/ci/example-upliftr.yml. The Action is published from a small public repo (upliftrhq/upliftr-action); the full source lives in upliftrhq/upliftr.

GitLab CI

The job runs on the public Upliftr image (Chromium + engine baked in, no install step), writes a JUnit report GitLab shows in the MR widget, and exits non-zero to gate the MR.

yaml
# .gitlab-ci.yml
upliftr:
  image: ghcr.io/upliftrhq/upliftr-api:latest
  variables:
    UPLIFTR_SUITE: "suites/*.upliftr.yaml"
    # FILE_ISSUES: "gitlab"      # optional, needs GITLAB_TOKEN (api scope)
    GITLAB_PROJECT: "$CI_PROJECT_ID"
    GITLAB_URL: "$CI_SERVER_URL"
    GIT_SHA: "$CI_COMMIT_SHA"
    CI_RUN_URL: "$CI_PIPELINE_URL"
  script:
    - ARGS=(); [ -n "${FILE_ISSUES:-}" ] && ARGS=(--file-issues "$FILE_ISSUES")
    - upliftr run "$UPLIFTR_SUITE" "${ARGS[@]}" --out upliftr-artifacts
  artifacts:
    when: always
    paths: ["upliftr-artifacts"]
    reports:
      junit: "upliftr-artifacts/junit.xml"
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

Setup (once): add ANTHROPIC_API_KEY as a masked CI/CD variable, the engine uses your Anthropic key to drive & root-cause the browser. Copy-paste example: examples/ci/.gitlab-ci.yml.

The CLI directly

The same gate, from any CI system or your terminal, see the CLI reference.

bash
ANTHROPIC_API_KEY=sk-ant-... upliftr run "suites/*.upliftr.yaml" \
  --file-issues gitlab \
  --out artifacts
echo "exit: $?"     # 0 / 1 / 2 / 3
  • --file-issues <provider> files failures via GitHub, GitLab, or Jira (needs the matching env, GITHUB_TOKEN/GITHUB_REPO, GITLAB_TOKEN/GITLAB_PROJECT, …). Comma-separate to file to several at once. See Filing issues.
  • --out <dir> writes report.json, junit.xml, and report.html.
  • --headed runs with a visible browser (default is headless, required for CI).

Next: Filing issues · Connecting server logs

Upliftr · AI-native, self-healing E2E testing. Terms · Privacy · Legal Notice