TestNeo
TestNeo Docs CI/CD · External signals
Integrations · DevOps

CI/CD Runs & External Signals

Baby-step guide to wire your pipeline to TestNeo, see Recent Runs with a full Report, and optionally post External CI signals (build / security / foreign smoke) so Release Readiness can show “also ran” — without confusing the two.

Quick start (anyone can do this):
  1. Open /web/ci → Integration → Generate an API key.
  2. Update your repo: add the workflow from Integration (Setup A) so Recent Runs + Report appear.
  3. Optional — Update other jobs (CodeQL, build, Jenkins): add the copy-paste POST (Setup B) for External signals.
  4. Refresh /web/ci — Runs at the top, External signals below. Not the same rows.
Confusion killer: A job id like CI_8614… under Recent Runs is not the same row as External CI signals below it. They are two data pipes on one page. Runs = TestNeo executed your suite. External = another system finished and told TestNeo via HTTP.
Pipe A — Recent Runs GHA/Jenkins → TestNeo API (trigger) → agent runs NLP tests → results → CI_… + Report Pipe B — External CI signals GHA/Jenkins/CodeQL finishes ITS job → POST /release-readiness/ci-evidence → receipt on /web/ci

Problem we solve

  • Teams already run builds, security scans, and tests in GitHub Actions / Jenkins — but the ship story is scattered across tabs.
  • You need one place that shows: “Did TestNeo run our suite?” and “Did other checks also finish?”
  • Release owners want a simple Also ran in CI line next to Release Readiness — without turning TestNeo into a log warehouse.

What TestNeo does: execute your NLP/API tests from CI (Runs + Report), accept small receipts from any pipeline (External signals), and optionally soft-weight those receipts into the release gate.

Read this first: two pipes

Recent Runs (CI_…)External CI signals
Who runs? TestNeo agent / cloud runner Jenkins, GHA, CodeQL, Snyk, your script — their runner
What runs? Your TestNeo tests (tags / folder) Whatever their job is (image build, security scan, foreign smoke)
How it hits TestNeo Trigger job → download tests → upload results One POST /release-readiness/ci-evidence with API key
What you see Pass/fail counts + Report link Status, kind, summary, optional console URL / counts
Agent online? Needed if jobs run on a self-hosted agent Not required — receipt only
Connected to each other? No automatic link today. Same page for comparison; optional later correlate by sha.

Where in the product

PlaceURLUse for
CI/CD · Runs + External signals /web/ci or /web/projects/<id>/ci Setup keys, see jobs, post/view receipts
Job Report /web/ci/report/CI_… Per-test detail for a TestNeo run
Release Readiness /web/release-readiness “Also ran in CI” + optional Soft-weight external CI
Analytics /web/analytics Trends over time (not a substitute for Report)

Setup A — Recent Runs (TestNeo executes your suite)

Goal: push to GitHub → see a row like CI_8614… with 10✓ / 0✗ and a Report button.

1

Open CI/CD in the app

Go to app.testneo.ai/web/ci → select your project → open the Integration tab.

2

Generate an API key

Click Generate API Key, name it (e.g. GitHub Actions), copy the tn_… value once. Store it as a GitHub Actions secret named TESTNEO_API_KEY.

3

Add secrets / variables

In your CI platform (GitHub → Settings → Secrets and variables):

NameExample
TESTNEO_API_KEYtn_… from step 2
TESTNEO_PROJECT_IDYour project number (e.g. 8)
TESTNEO_SERVERhttps://app.testneo.ai (or your self-hosted API base)
4

Update your repo with the workflow

On the same Integration tab, pick GitHub Actions (or Jenkins / GitLab) and copy the generated workflow into .github/workflows/testneo.yml (or your Jenkinsfile). Tag tests in TestNeo with @smoke / @regression so the workflow can select them.

5

Push, then refresh Recent Runs

Push to the branch that triggers the workflow. Refresh CI/CD → Runs. You should see Job ID, Status, Tests (✓ / ✗), Branch, Duration, and Report.

When is this data collected? When the TestNeo CI job finishes uploading results — not when you only open the CI page. If the agent is offline and the job needs a local agent, the run stays queued.

Setup B — External CI signals (receipt only)

Goal: after CodeQL / image build / foreign Jenkins smoke finishes, TestNeo shows a row under External CI signals and on Release Readiness Also ran in CI.

No tech-stack limit. Anything that can POST JSON with a Bearer API key works: GitHub Actions, Jenkins, GitLab, Azure DevOps, CodeQL, Snyk, Sonar, Trivy, or a shell script.

1

Reuse the same API key

Use TESTNEO_API_KEY from Setup A (or generate another key on Integration). Auth header: Authorization: Bearer tn_… (not X-API-Key for this endpoint).

2

Update the external job — add a last step

Example — after CodeQL (or any job) in GitHub Actions:

- name: Tell TestNeo about this check
  if: always()
  env:
    TESTNEO_API_KEY: ${{ secrets.TESTNEO_API_KEY }}
    TESTNEO_SERVER: ${{ vars.TESTNEO_SERVER }}
  run: |
    STATUS=pass
    [ "${{ job.status }}" = "failure" ] && STATUS=fail
    curl -fsS -X POST "$TESTNEO_SERVER/api/web/v1/release-readiness/ci-evidence" \
      -H "Authorization: Bearer $TESTNEO_API_KEY" \
      -H "Content-Type: application/json" \
      -d "{
        \"project_id\": ${{ vars.TESTNEO_PROJECT_ID }},
        \"provider\": \"github_actions\",
        \"kind\": \"security\",
        \"status\": \"$STATUS\",
        \"external_ref\": \"actions/runs/${{ github.run_id }}\",
        \"environment_name\": \"Staging\",
        \"sha\": \"${{ github.sha }}\",
        \"summary\": \"CodeQL finished with status $STATUS\",
        \"details_url\": \"${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\",
        \"payload\": { \"source\": \"codeql\" }
      }"
3

Confirm in the UI

Open /web/ci → scroll to External CI signals (under Recent Runs), or open Release Readiness → Also ran in CI. Demo without a pipeline: click Record signal on the CI page.

When is this data collected? Only when something POSTs the receipt (or you Record signal). If Jenkins ran for an hour but never called TestNeo, nothing appears under External signals.

Evidence field reference

FieldRequired?What to put
project_idYesTestNeo project number
providerYesgithub_actions, jenkins, gitlab, …
kindYesbuild, smoke, security, e2e, …
statusYespass / fail / warn / skipped
external_refYesTheir job id, e.g. actions/runs/902
environment_nameNoQA, Staging, …
summaryNoOne human line (“CodeQL: 2 medium findings”)
shaNoCommit hash (shown short in UI)
details_urlNoLink to their console (makes Open CI console work)
payloadNoSmall extras: passed/failed/total — not full logs

Tip: If TestNeo already ran the suite, use Recent Runs → Report. Do not also Record signal for the same suite unless you intentionally want a duplicate billboard.

How to read /web/ci

  1. Recent Runs (top) — TestNeo jobs. Click Report for per-test detail.
  2. “How to read this page” — short reminder of the two pipes.
  3. External CI signals (bottom) — receipts. Click a row for detail; Open CI console only if details_url is a real external URL.

Filter Failed on Runs to focus on broken TestNeo jobs. External fails/warns show as status badges in the signals table.

How to read a Report

From Recent Runs → Report opens /web/ci/report/CI_….

  • Use this for which tests passed/failed, duration, and triage of a TestNeo execution.
  • For trends across many days, use Analytics — not the External signals panel.
  • External signal detail will never replace Report unless that foreign system posted rich payload counts (still no TestNeo step video).

Not observability

External signals are a release billboard, not Datadog / logs / APM.

We storeWe do not scrape
Status, kind, summary, optional counts, console linkFull job logs, traces, metrics streams

Deep analysis stays in CodeQL / Jenkins / your observability tool via details_url. TestNeo answers: “did that check also finish for this ship?”

Optional soft gate

By default, external receipts are display-first — they do not change confidence.

  • Open Release Readiness → select a bundle → check Soft-weight external CI → Evaluate gate.
  • Critical fails (e.g. smoke/security/e2e fail) can demote PASS; security warn can demote to WARN.
  • Full gate policies (BLOCK PRs, min confidence): see Release Intelligence · CI/CD Gate.

FAQ & troubleshooting

SymptomWhat to check
Recent Runs emptyIntegration key + workflow pushed? Job triggered? Agent online if using self-hosted runner?
External signals emptyDid the pipeline POST? Auth Bearer tn_…? Correct project_id? Try Record signal once.
403 Not authenticatedUse Authorization: Bearer, not X-API-Key, for this endpoint.
No Open CI consoleSet details_url to a real GitHub/Jenkins URL (not an in-app /web/… link).
Is CI_… linked to External?No — different tables. Correlate manually by commit SHA if needed.
Agent Online = 0OK for External signals. Only matters for agent-backed Recent Runs.