Skip to content

CI integration

Trigger your test workflows from Sulu and have the results land in the same Launch you created — no manual wiring on the test framework side.

What you get

  • Launch a configured GitHub Actions or GitLab CI workflow from inside Sulu.
  • Test results uploaded by suluctl (or any import-API client) land in the same Sulu Launch that Sulu pre-created (no duplicate launches).
  • See live status from the Sulu Launches page; click through to the GH / GL run UI for full logs.

Set up

1. Create a Personal Access Token

GitHub — Settings → Developer settings → Personal access tokens.

  • Classic: scopes workflow (+ repo if private)
  • Fine-grained: Actions: Read+Write, Contents: Read

GitLab — User Settings → Access Tokens.

  • Scopes: api, read_repository

2. Add a CI connection in Sulu

Project Settings → Integrations → CI Connections → + New connection.

Paste the PAT and click Test connection before saving. Sulu queries /user to validate scopes; you'll see your username on success.

3. Prepare your workflow

Your workflow file must accept workflow_dispatch with Sulu's reserved inputs. Sulu's job dialog has a built-in validator that fetches your YAML and tells you exactly what's missing, with a copy-paste snippet.

Minimum block:

yaml
on:
  workflow_dispatch:
    inputs:
      SULU_LAUNCH_ID:    { required: false, type: string }
      SULU_LAUNCH_UUID:  { required: false, type: string }
      SULU_JOB_RUN_ID:   { required: false, type: string }
      SULU_API_URL:      { required: false, type: string }
      SULU_ENV_NAME:     { required: false, type: string }
      SULU_TEST_FILTER:  { required: false, type: string }

# Recommended: surface SULU_JOB_RUN_ID in the run name so Sulu can match runs accurately
run-name: 'tests / SULU_JOB_RUN_ID=${{ inputs.SULU_JOB_RUN_ID }}'

jobs:
  tests:
    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 — SULU_LAUNCH_UUID routes them into the pre-created Launch
      - if: always()
        run: suluctl upload --results ./allure-results
        env:
          SULU_URL: ${{ inputs.SULU_API_URL }}
          SULU_TOKEN: ${{ secrets.SULU_TOKEN }}
          SULU_PROJECT_ID: "<your project id>"
          SULU_LAUNCH_UUID: ${{ inputs.SULU_LAUNCH_UUID }}

4. Create a job in Sulu

Jobs page → + New job. Pick your CI connection, fill repo (e.g. owner/repo), pick the workflow from the dropdown, set git ref.

5. Run

Jobs page → click the Play button. Sulu pre-creates a Launch, dispatches your workflow, and you'll see results stream in as your tests run.

You can also run a subset of test cases from the Test Cases page: select cases → Run → Auto mode → pick the job.

Token scopes — full table

ProviderToken typeRequired scopes
GitHubClassic PATworkflow + repo (if private)
GitHubFine-grained PATActions: Read+Write, Contents: Read
GitLabPersonal Access Tokenapi, read_repository

How results reach the pre-created Launch

Sulu forwards the pre-created launch's id to your workflow as the SULU_LAUNCH_UUID input. suluctl (both upload and watch) auto-detects SULU_LAUNCH_UUID from the environment and uploads into that launch instead of creating a new one — no extra flags needed. The upload must target the same project as the Job; the launch keeps the Job's name. See the suluctl page for details.

For runs not triggered from Sulu (plain pushes/PRs), the same upload step simply creates a fresh launch — see GitHub Actions and GitLab CI for the standalone setup.

Troubleshooting

SymptomLikely cause
Test connection returns 401 Bad credentialsPAT expired or wrong token type
Test connection returns 200 but Run returns 404Repository path wrong (e.g. typo in owner/repo)
Test connection passes, workflow picker loads, but Run fails with 403 Resource not accessible by personal access tokenPAT has read scopes but lacks workflow (classic) / Actions: Read and write (fine-grained). Reading workflows only needs repo / Actions:Read; dispatching needs the write scope. Regenerate the token with the right scope and re-paste it.
Run returns 422 Validation failedWorkflow missing workflow_dispatch: — fix per the validator snippet in the job dialog
Upload fails with 403 mentioning another projectThe Job targets a different project than SULU_PROJECT_ID — they must match
Two Launches per run (one empty + one real)The upload step didn't receive SULU_LAUNCH_UUID (input not passed into the step's env), so results went to a fresh launch

Sulu Test Management System