> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tester.army/llms.txt
> Use this file to discover all available pages before exploring further.

# Any CI or Custom Deployment

> Trigger TesterArmy from any CI or deployment system - Jenkins, Buildkite, CircleCI, GitHub Actions, or a shell script - with a signed group webhook.

Trigger TesterArmy after any CI system or deployment platform finishes deploying your application. This works with GitHub Actions, Jenkins, Buildkite, CircleCI, shell scripts, and other systems that can send an HTTP request.

For GitLab, use the focused [GitLab CI recipe](/integrations/gitlab-ci).

## How it works

1. Create and manually verify a [test group](/run/groups).
2. Enable a signed webhook for the group.
3. After deployment, your pipeline sends the saved environment ID or deployed URL to the webhook.
4. TesterArmy queues every enabled test in the group and returns the run IDs.
5. Full results appear in the TesterArmy dashboard.

The target URL must be reachable from the public internet. "Custom deployment" does not mean a private TesterArmy runner or access to private-network URLs.

## 1. Enable a signed group webhook

1. Open your project → **Tests** tab.
2. Pick the group in the **Test library** rail, then open the **Webhook**
   menu in the **Run tests** row under the group name.
3. Switch the webhook **On**.
4. Copy the URL - the secret is shown once.

The URL looks like:

```
https://tester.army/api/v1/groups/webhook/{id}/{secret}
```

The secret is part of the URL, so store the entire value as a masked CI secret. See [Signed Group Webhook Reference](/run/group-webhooks) for payload fields, mobile overrides, responses, and limits.

## 2. Choose the run target

Use a saved environment for stable staging or QA deployments:

```json theme={"theme":"vesper"}
{
  "commitSha": "abc123",
  "projectEnvironmentId": "00000000-0000-0000-0000-000000000000"
}
```

Use `targetUrl` for temporary deployments and review applications:

```json theme={"theme":"vesper"}
{
  "commitSha": "abc123",
  "targetUrl": "https://preview.example.com",
  "environment": "preview"
}
```

`projectEnvironmentId` selects a saved URL and its credential overrides. `environment` only labels the result as `production`, `staging`, or `preview`; it does not select a saved environment.

## 3. Call the webhook after deployment

### GitHub Actions

```yaml theme={"theme":"vesper"}
- name: Run TesterArmy tests
  run: |
    curl -X POST "${{ secrets.TESTERARMY_WEBHOOK_URL }}" \
      -H "Content-Type: application/json" \
      -d "{\"commitSha\":\"${{ github.sha }}\",\"targetUrl\":\"${{ steps.deploy.outputs.url }}\",\"environment\":\"preview\"}"
```

### Any shell

```bash theme={"theme":"vesper"}
curl -X POST "$TESTERARMY_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{"commitSha":"'"$COMMIT_SHA"'","targetUrl":"'"$DEPLOY_URL"'","environment":"staging"}'
```

Use `curl --fail-with-body` when an authentication, validation, or usage-limit response should fail the CI job. A successful response means TesterArmy accepted the runs; it does not mean the tests have already passed.

## Results

* **TesterArmy dashboard:** Always contains the run status, test outcome, steps, screenshots, video, and issues.
* **GitHub Check Run:** Created on a best-effort basis only when `commitSha` belongs to the repository connected through the native GitHub integration.
* **GitHub PR comment:** Not created by the signed webhook because it does not accept a PR number.
* **GitLab status or merge request comment:** Not supported by this trigger.
* **JUnit XML / TestRail:** Available through `GET /api/v1/batches/{batchId}/junit` and the dashboard's **Download JUnit report** action. See [Export to TestRail](/integrations/testrail).

For a walkthrough focused on a staging environment, see [Testing Staging Environment](/guides/testing-staging).

## When to use the API instead

Use `POST /api/v1/groups/{groupId}/runs` with an API key when you need richer response metadata, result polling, or GitHub PR context. Unlike the signed webhook, the API-key endpoint accepts `prNumber` for best-effort GitHub PR reporting when the project has an active GitHub connection.

For change-specific exploration, use `POST /api/v1/projects/{projectId}/pull-request-runs`. Without a native GitHub connection, planning uses the PR metadata supplied by the caller and cannot read repository diffs or post provider-native results.

## Troubleshooting

### No check run on the PR

1. **Missing `commitSha`** - the tests run, but no commit check can be created.
2. **Commit not in the connected repository** - TesterArmy cannot attach the check to an unrelated SHA.
3. **GitHub App not connected** - connect the repository through [GitHub](/integrations/github).
4. **Permissions** - the GitHub App needs **Checks: Read & Write**.

### `401 Unauthorized`

The webhook ID or secret is wrong. The plaintext secret cannot be recovered, but you can use **Regenerate URL** in the group's webhook menu on the **Tests** tab and replace the URL in your CI secret manager. The previous URL stops working immediately.

### `403 Forbidden`

The webhook is disabled. Open the group's webhook menu on the **Tests** tab and switch it back **On**.

### Tests run against the wrong URL

Tests use `targetUrl` from the payload if provided, otherwise the URL configured in your project settings. Check both.

### Target URL is rejected

TesterArmy blocks localhost, private IP ranges, and internal hostnames. Deploy the application to a publicly reachable URL or expose it through an appropriate secure tunnel.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.