Appearance
Jobs
Trigger a CI pipeline from inside Sulu and have its results land in the launch Sulu creates for you. A Job lives on the Jobs page of a project (/app/jobs).
What is a Job
A Job links a project to a configured CI pipeline — GitHub Actions, GitLab CI, Jenkins, or Bamboo — through a CI connection. You define the workflow target and its default parameters once, then dispatch a run with one click. Every run's results land in the same launch Sulu pre-creates, so you never end up with a duplicate empty launch alongside the real one.
How a run works
When you run a Job, Sulu:
Pre-creates a Launch (state
IN_PROGRESS) and stamps it with aclientUuid.Dispatches your CI workflow, forwarding these environment variables into it:
Variable Meaning SULU_LAUNCH_UUIDThe pre-created launch's id — bind your reporter to this launch SULU_LAUNCH_IDThe numeric launch id SULU_JOB_RUN_IDThis run's id (surface it in your CI run name so Sulu matches the build) SULU_ENV_NAMEThe environment name for the run SULU_TEST_FILTERComma-separated test ids when you ran a subset (empty otherwise) SULU_API_URLThe Sulu API base URL Your reporter uploads results into the launch identified by
SULU_LAUNCH_UUID.You land on the launch and watch results stream in.
Create a job
Creating a Job requires the Member project role or higher (Viewers can't).
Jobs page → + Job. Pick your CI connection, fill in the target (e.g. owner/repo + workflow for GitHub Actions), set the git ref, and add any default parameters. See CI integration for setting up the connection and the personal access token scopes.
Run a job
Jobs page → click the Play button on a Job's row. Sulu pre-creates the launch, dispatches the workflow, and the launch opens so you can follow the run.
You can also run a subset of cases from the Test cases page: select cases → Run → the Job tab (it appears when your selection includes automated cases) → pick the Job. Sulu passes those cases' test ids through as SULU_TEST_FILTER.
Reporting setup
Your CI step needs to send results back to Sulu. The simplest path is the suluctl CLI — a single static binary, nothing to add to your test project.
Environment variables
| Variable | Required | Meaning |
|---|---|---|
SULU_URL | yes | Your Sulu base URL |
SULU_TOKEN | yes | API token (Profile → API keys) |
SULU_PROJECT_ID | yes | Numeric destination project id |
SULU_LAUNCH_NAME | no | Launch display name |
WARNING
Never put the token in a workflow file as a literal. Store it as a GitHub secret or a masked GitLab CI/CD variable and reference it.
The two commands
bash
# One-shot: upload a finished report
suluctl upload --results ./allure-results
# Live streaming: run your tests and stream results as they appear
suluctl watch --results ./allure-results -- <your test command>GitHub Actions
yaml
# .github/workflows/tests.yml
name: tests
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# 1. Run your tests, producing allure-results/ (or JUnit XML)
- run: <your test command> # e.g. ./gradlew test, pytest --alluredir=allure-results
# 2. Install suluctl
- if: always()
run: curl -fsSL https://raw.githubusercontent.com/ellyZz/suluctl/main/install.sh | sh
# 3. Upload results to Sulu
- if: always()
run: suluctl upload --results ./allure-results
env:
SULU_URL: "https://your-sulu.example"
SULU_TOKEN: ${{ secrets.SULU_TOKEN }}
SULU_PROJECT_ID: "42"
SULU_LAUNCH_NAME: "CI · ${{ github.ref_name }}"GitLab CI
yaml
# .gitlab-ci.yml
stages: [test]
test:
stage: test
variables:
SULU_URL: "https://your-sulu.example"
SULU_PROJECT_ID: "42"
SULU_LAUNCH_NAME: "CI · $CI_COMMIT_REF_NAME"
# Add SULU_TOKEN as a masked CI/CD variable: Settings -> CI/CD -> Variables
script:
- <your test command> # produce allure-results/ (or JUnit XML)
- curl -fsSL https://raw.githubusercontent.com/ellyZz/suluctl/main/install.sh | sh
- suluctl upload --results ./allure-results
# tip: move the upload into after_script to also report failed test runsUploading into the Job's launch
When a run is dispatched by a Job, suluctl reads the forwarded SULU_LAUNCH_UUID automatically and uploads into the pre-created launch instead of creating a new one — no extra flags for either upload or watch. A few things to know:
- The Job must target the same project as
SULU_PROJECT_ID. If they differ, Sulu rejects the upload with a403. - The launch keeps the name from the Job, so
SULU_LAUNCH_NAME/--launch-namehas no effect on a Job-triggered run. - For the cleanest results, dispatch the Job without a specific test-case or test-plan selection so the launch is populated entirely from your uploaded report.
See the suluctl page for details.