Appearance
CI/CD: GitHub Actions
Run your test suite in GitHub Actions and upload the results to Sulu with suluctl — no test-framework plugins needed.
This is the same workflow the in-app Set up reporting dialog (Jobs page) generates, prefilled with your backend URL and project id.
Minimal example
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: "<your Sulu base URL>"
SULU_TOKEN: ${{ secrets.SULU_TOKEN }}
SULU_PROJECT_ID: "<your project id>"
SULU_LAUNCH_NAME: "CI · ${{ github.ref_name }}"The if: always() conditions make sure failed test runs are reported too — usually the runs you care about most.
Token storage
Add an API token (Profile → API keys in Sulu) as a repository secret named SULU_TOKEN. Reference it in the workflow as ${{ secrets.SULU_TOKEN }} — never paste the token into the YAML.
Linking the launch back to the run
Include an executor.json file in your results directory; Sulu reads it during import and renders its buildUrl as the launch's external-run link:
yaml
- name: Write executor.json
if: always()
run: |
cat > allure-results/executor.json <<EOF
{
"name": "GitHub Actions",
"type": "github",
"buildName": "${{ github.workflow }} #${{ github.run_number }}",
"buildUrl": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}
EOFRuns dispatched from a Sulu Job get the CI run link automatically — no executor.json needed.
Per-branch launch names
SULU_LAUNCH_NAME is free text — compose it from GitHub's context, e.g. "CI · ${{ github.ref_name }}" for one launch name per branch, or use the PR title from the event payload.
Streaming results live
Swap the separate test + upload steps for suluctl watch to see results appear in Sulu while the suite is still running:
yaml
- run: suluctl watch --results ./allure-results -- <your test command>
env:
SULU_URL: "<your Sulu base URL>"
SULU_TOKEN: ${{ secrets.SULU_TOKEN }}
SULU_PROJECT_ID: "<your project id>"watch always exits with your test command's exit code, so it's safe as the main test step. See Live streaming for what it does.