GitHub Actions
Upload test results from GitHub Actions to Qualflare with qualflare-action or the qf CLI: workflow YAML, the QF_TOKEN secret, inputs and pull request branches.
Last updated
To upload test results from GitHub Actions to Qualflare, add the Qualflare/qualflare-action@v1 step after your tests, or install qf and run qf <identifier> collect <report>, with the access token stored as a repository secret named QF_TOKEN. Qualflare/qualflare-action is a composite action that downloads the right qf binary for the runner and runs the same qf login and qf <identifier> collect steps: it's the CLI, not a separate upload path.
Before you begin
- A project access token with Allow writes off, which you create in Project Settings > Access Tokens Editor+ · project (requires the Editor role or higher in the project). See Access Tokens.
- A report file your test step writes, such as JUnit XML.
- The patterns every CI shares are on CI/CD integration.
Store the token as a secret
- Go to your repository Settings > Secrets and variables > Actions
- Click New repository secret
- Name:
QF_TOKEN - Value: Your Qualflare access token
- Click Add secret
The action takes the secret through its token input, so any secret name works (its README uses QUALFLARE_TOKEN). The manual install reads QF_TOKEN.
Upload with qualflare-action
Add the action after your test step:
- name: Run tests
run: pytest --junitxml=results.xml
- name: Upload results to Qualflare
if: ${{ !cancelled() }} # upload even when tests fail
uses: Qualflare/qualflare-action@v1
with:
token: ${{ secrets.QF_TOKEN }}
project: myapp
results: results.xmlPut if: ${{ !cancelled() }} on the upload step so it runs when your tests
fail. Do not add continue-on-error: true to the test step: it marks the failed
step as passed, so the job and the pull request check turn green even when
tests fail.
Inputs
| Input | Required | Default | Description |
|---|---|---|---|
token | Yes | — | Qualflare project access token (qfp_...). Store it as an encrypted secret, never inline. |
project | Yes | — | A local name for the project, used by qf on the runner. The token decides which project receives the results. Use lowercase letters, digits, - and _, up to 63 characters, starting with a letter or digit, and not a qf command name such as version. |
results | Yes | — | Path or glob to your test result files (e.g. test-results/*.xml). Framework is auto-detected. |
version | No | latest | qualflare-cli version to install, e.g. 0.4.0. A leading v is optional. |
Outputs
None: the action has no outputs: block, so no steps.<id>.outputs.* value (such as a report URL) is there for a later step.
Runner support
Linux and macOS (amd64/arm64) are fully supported. Windows runners are best-effort — if you're on Windows and hit issues, install qf yourself.
What the action runs:
- Install Qualflare CLI (qf) resolves
version(latestby default, through the releases page), downloadsqf_<version>_<os>_<arch>and puts it onPATH. - Upload results to Qualflare runs
qf login <project> <token>, thenqf <project> collect <results>.
What the action doesn't expose
- The action has four inputs. qf still reads its
QF_variables inside it, so setQF_ENVIRONMENT,QF_MILESTONE,QF_BRANCH,QF_COMMIT,QF_UPLOAD_ARTIFACTSorQF_PLATFORMin the job'senv:, as in Branch and commit. - It has no input for the
collectflags that have no variable:--format,--shard,--allow-mixed-runs,--artifacts-dir,--dry-runwith its--output, and the overall--timeout, which stays at its 30s default, short for large uploads with videos or traces. - It passes no
--format, so TestNG, Maestro, XCTest and Espresso XML upload as plainjunit. It runsqf loginwithout--force: on a self-hosted runner that keeps its home directory between jobs, the second run fails withidentifier "myapp" already exists. It passes the token toqf loginas a command-line argument rather than throughQF_TOKEN. resultsis not quoted, so the shell expands globs and splits it on spaces: separate several patterns with a space, and don't use a path that contains one.
Install qf yourself for any case in the last three bullets.
Install qf yourself
Install qf in your own step for Windows, a reused runner, a flag above or a token kept out of the process list:
- name: Upload results to Qualflare
if: ${{ !cancelled() }} # upload even when tests fail
env:
QF_TOKEN: ${{ secrets.QF_TOKEN }}
QF_BRANCH: ${{ github.head_ref || github.ref_name }}
QF_COMMIT: ${{ github.event.pull_request.head.sha || github.sha }}
run: |
# Install qf CLI (ubuntu-latest runners don't ship Homebrew)
VERSION=0.4.0
curl -L "https://github.com/qualflare/qualflare-cli/releases/download/v${VERSION}/qf_${VERSION}_linux_amd64.tar.gz" -o qf.tar.gz
tar -xzf qf.tar.gz && sudo mv qf /usr/local/bin/
# Upload results (qf login reads QF_TOKEN from env)
qf login ci --force
qf ci collect results.xmlOn other runners, download the matching qf_<version>_<os>_<arch> archive (.zip on Windows); for sharded jobs, upload once from a final job with --shard (Sharded runs).
Branch and commit
qf reads GITHUB_REF_NAME and GITHUB_SHA. On pull_request runs those are the <number>/merge branch and a merge commit, so set the pull request's own values at job level, where the action's steps see them too:
jobs:
test:
runs-on: ubuntu-latest
env:
QF_ENVIRONMENT: staging # must exist in the project
QF_BRANCH: ${{ github.head_ref || github.ref_name }}
QF_COMMIT: ${{ github.event.pull_request.head.sha || github.sha }}More on this: Pull request branches.
Version pinning
Qualflare/qualflare-action@v1 tracks the latest v1.x release of the
action itself. The version input is separate — it pins which qualflare-cli
release gets installed underneath, independent of the action's own version.
Pin version explicitly in CI for reproducible builds; leave it on latest
for local experimentation.
Troubleshooting
Error: token cannot be empty: thetokeninput orQF_TOKENis empty in that run. GitHub gives no secrets to workflows run for pull requests from forks.Error: unknown flag: --versionin Install Qualflare CLI (qf): harmless. The action runsqf --version, which qf doesn't have.
More fixes: Troubleshooting on CI/CD integration.
Related
- Guides: CI/CD integration · Setting up CI for an open-source project
- Reference: Upload results with qf collect · Configuration
- CLI/API: Access Tokens
CI/CD integration
Upload test results to Qualflare from GitHub Actions, GitLab CI/CD, Jenkins, Azure Pipelines or any CI with the qf CLI: tokens, variables and branch detection.
GitLab CI/CD
Upload test results from GitLab CI/CD to Qualflare with the qf CLI: a .gitlab-ci.yml job that runs when tests fail, with a masked QF_TOKEN variable.