> For the complete documentation index, see [llms.txt](https://docs.algenta.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.algenta.ai/guides/ci-cd.md).

# Use Algenta in CI/CD

Algenta is built to run unattended. Every `de` CLI command is a thin, faithful wrapper over the same `/v1` HTTP surface the SDKs use, it authenticates with one API key read from the environment, and it sets a non-zero exit code whenever the engine returns an error. That makes it a clean fit for a CI/CD job: store your key as a secret, run a decision, simulation, or repository triage, ask for machine-readable JSON, and let the exit code gate the pipeline.

This guide shows how to authenticate in CI, run the core verbs, capture JSON for gating, and wire a pass/fail check into both a GitHub Actions workflow and a generic shell script.

{% hint style="info" %}
The CLI invents no behavior of its own — anything below works identically from the Python or TypeScript SDK, or from raw `curl`. See the [CLI reference](/sdks/cli.md) for the full command surface.
{% endhint %}

## Before you start

You need:

* An Algenta API key. Mint one in the dashboard or with `de keys create "CI key"` — see [Authentication](/getting-started/authentication.md).
* The CLI available on the runner. Install the SDK package, which ships the CLI, or run it as a module from the repository root.

```bash
pip install algenta-sdk
```

## Authenticate from a CI secret

The CLI reads the key from the environment first. Set `ALGENTA_API_KEY` and the CLI picks it up with no interactive login and no on-disk config — exactly what an ephemeral CI runner wants. The legacy name `DE_API_KEY` is also accepted.

Store the key as an encrypted CI secret (never commit it), then export it into the job environment. For a self-hosted or air-gapped engine, also point the CLI at your own origin with `ALGENTA_BASE_URL` (aliases: `DE_BASE_URL`, `ALGENTA_API_URL`); otherwise the CLI targets the managed cloud at `https://api.algenta.ai`.

```bash
export ALGENTA_API_KEY="$CI_SECRET_ALGENTA_KEY"
# Self-hosted only — pin the engine origin so nothing phones home to the cloud:
export ALGENTA_BASE_URL="https://algenta.internal.example.com"
```

The CLI sends the key on every request as `Authorization: Bearer <key>`. Verify it works before doing real work — `de account me` calls `GET /v1/me` and exits non-zero if the key is missing, invalid, expired, or revoked:

```bash
de account me --format json
```

**Expected result:** the command prints a JSON object describing your org and plan (`org_id`, `org_name`, `plan`) and exits `0`. If the key is bad, it prints `❌ Error 401: ...` to stderr and exits `1`, failing the step immediately.

{% hint style="warning" %}
Mask the key in logs. Most CI systems redact registered secrets automatically, but never `echo` the key or pass it on a command line — keep it in `ALGENTA_API_KEY` only.
{% endhint %}

## Run a decision, simulation, or repository triage

Each task type maps to one verb. All of them take a request JSON file checked into your repo (or generated by an earlier step) and accept `--format json` for machine-readable output.

{% tabs %}
{% tab title="Simulation" %}

```bash
de simulate examples/scenario.json --format json > result.json
```

Calls `POST /v1/simulate`. The `200` body carries the decision envelope: a populated `recommended_action`, a `confidence` between 0 and 1, a `metrics` summary, `percentiles`, and a `result_hash` for reproducibility. See [Simulate a scenario](/guides/simulate.md).
{% endtab %}

{% tab title="Decision" %}

```bash
de decision score request.json --format json > result.json
```

Scores one simulation request (`POST /v1/simulate` via the decision surface). Use `de decision compare scenarios.json` to rank named scenarios, or `de recommend compare.json --format` for a recommendation. See [Run a decision](/guides/run-a-decision.md).
{% endtab %}

{% tab title="Repository triage" %}

```bash
de repositories triage "$REPO_ID" triage-request.json --format json > triage.json
```

Calls `POST /v1/repositories/<id>/triage` and returns a bounded workspace evidence bundle. To assess a candidate patch instead, use `de repositories simulate <id> request.json`. See [Triage a repository](/guides/repository-intelligence.md).
{% endtab %}
{% endtabs %}

Every one of these commands exits `0` on an HTTP `200` and exits `1` on any error status (the error is printed to stderr as `❌ Error <status>: ...`). That is the contract your pipeline gates on.

## Get machine-readable JSON for gating

Pass `--format json` to any command that produces output (the default is a human-readable table). The CLI then prints the raw response body as JSON to stdout, which you can redirect to a file and parse with `jq` to make a gating decision on a specific field — for example a confidence threshold or a repository change-risk score.

```bash
de simulate examples/scenario.json --format json > result.json

confidence=$(jq -r '.confidence' result.json)
echo "confidence=$confidence"

# Fail the pipeline if confidence is below 0.8
awk -v c="$confidence" 'BEGIN { exit (c >= 0.8 ? 0 : 1) }' \
  || { echo "Decision confidence too low: $confidence"; exit 1; }
```

{% hint style="info" %}
There are two layers of gating. The CLI exit code already fails on transport, auth, and validation errors. The `jq`/`awk` step adds a business gate on the result content (a threshold on a field you choose).
{% endhint %}

## Gate a GitHub Actions pipeline

This workflow installs the CLI, verifies the key, runs a simulation, and gates on both the exit code and a confidence threshold. `ALGENTA_API_KEY` comes from a repository or environment secret of the same name.

```yaml
name: algenta-decision-gate
on:
  pull_request:
jobs:
  decide:
    runs-on: ubuntu-latest
    env:
      ALGENTA_API_KEY: ${{ secrets.ALGENTA_API_KEY }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      - name: Install Algenta CLI
        run: pip install algenta-sdk
      - name: Verify credentials
        run: de account me --format json
      - name: Run decision
        run: de simulate examples/scenario.json --format json > result.json
      - name: Gate on confidence
        run: |
          confidence=$(jq -r '.confidence' result.json)
          echo "confidence=$confidence"
          awk -v c="$confidence" 'BEGIN { exit (c >= 0.8 ? 0 : 1) }'
```

**Expected result:** the job succeeds (green check) when the simulation returns HTTP `200` and `confidence` is at least `0.8`. If the key is rejected, the request fails, or confidence falls short, the corresponding step exits non-zero and the check goes red, blocking the merge.

## Gate a generic shell pipeline

The same pattern works in any CI system (GitLab CI, Jenkins, CircleCI, a plain shell script). Set the key as an environment variable from your secret store and rely on exit codes.

```bash
#!/usr/bin/env bash
set -euo pipefail

export ALGENTA_API_KEY="$CI_SECRET_ALGENTA_KEY"

# 1. Fail fast if the credential is bad.
de account me --format json > /dev/null

# 2. Run the task. A non-200 from the engine exits non-zero here and
#    `set -e` aborts the script.
de repositories triage "$REPO_ID" triage-request.json --format json > triage.json

# 3. Optional business gate on the response content.
risk=$(jq -r '.top_change_risk_files[0].risk_score // 0' triage.json)
echo "highest change-risk score: $risk"
```

{% hint style="success" %}
Because the CLI exits non-zero on every engine error, `set -e` (or any CI runner's default "fail on non-zero exit") is enough to stop the pipeline on auth, validation, rate-limit, and server errors — no extra error handling required.
{% endhint %}

## Automated fix-PRs (related capability)

If your goal is to have an agent open a fix pull request automatically when CI fails, that workflow is delivered as a separate distribution — the **codna** GitHub App and Action — built on this same Algenta repository-intelligence surface. It is a distinct product, not a `de` flag. From the engine side you would reach the same machinery with `de repositories triage`, `de repositories simulate`, and `de repositories apply`. See [Triage a repository](/guides/repository-intelligence.md) for the underlying capability.

## Next steps

* [Python SDK](/sdks/python.md) — drive the same decisions and triage from a CI script in Python instead of the CLI.
* [Triage a repository](/guides/repository-intelligence.md) — the full repository-intelligence flow the fix-PR automation is built on.
* [CLI reference](/sdks/cli.md) — every `de` subcommand, flag, and the endpoint it calls.
* [Authentication](/getting-started/authentication.md) — mint, scope, and revoke the API key you store as a CI secret.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.algenta.ai/guides/ci-cd.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
