Skip to main content

Run tests in GitHub Actions

Use GitHub Actions to start a Qodex run whenever a pull request opens or code lands on main. The workflow below runs a smoke set against staging for pull requests and against production after merge.

Before you start

You need:
  • A Qodex project with runnable scenarios.
  • A project API key from Settings > Platform > API keys.
  • Permission to add GitHub repository secrets.

Add GitHub secrets and variables

In GitHub, open Settings > Secrets and variables > Actions.
  • Add secret QODEX_API_KEY with your qk_... key.
  • Add variable QODEX_PROJECT with your Qodex project slug.

Add the workflow

Save this file at .github/workflows/qodex.yml.
name: Qodex

on:
  pull_request:
    branches: [main]
  push:
    branches: [main]

jobs:
  qodex:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    steps:
      - name: Trigger Qodex run
        id: trigger
        env:
          QODEX_PROJECT: ${{ vars.QODEX_PROJECT }}
          QODEX_API_KEY: ${{ secrets.QODEX_API_KEY }}
        run: |
          ENV_NAME=staging
          if [ "${{ github.event_name }}" = "push" ]; then ENV_NAME=prod; fi

          RESPONSE=$(curl -fsS -X POST \
            "https://agents.qodex.ai/api/projects/${QODEX_PROJECT}/webhooks/trigger" \
            -H "Authorization: Bearer ${QODEX_API_KEY}" \
            -H "Content-Type: application/json" \
            -d "{\"environment\":\"${ENV_NAME}\",\"tags\":[\"smoke\"]}")

          RUN_ID=$(echo "$RESPONSE" | jq -r .testRunId)
          if [ -z "$RUN_ID" ] || [ "$RUN_ID" = "null" ]; then
            echo "Failed to start run. Response: $RESPONSE"
            exit 1
          fi

          echo "run_id=${RUN_ID}" >> "$GITHUB_OUTPUT"
          echo "Started Qodex run ${RUN_ID}"

      - name: Wait for Qodex
        env:
          QODEX_PROJECT: ${{ vars.QODEX_PROJECT }}
          QODEX_API_KEY: ${{ secrets.QODEX_API_KEY }}
          RUN_ID: ${{ steps.trigger.outputs.run_id }}
        run: |
          DEADLINE=$(( $(date +%s) + 1500 ))
          while [ "$(date +%s)" -lt "$DEADLINE" ]; do
            STATUS=$(curl -fsS \
              "https://agents.qodex.ai/api/projects/${QODEX_PROJECT}/test-runs/${RUN_ID}" \
              -H "Authorization: Bearer ${QODEX_API_KEY}" | jq -r .status)
            echo "status=$STATUS"
            case "$STATUS" in
              completed) exit 0 ;;
              failed) exit 1 ;;
              *) sleep 10 ;;
            esac
          done
          echo "Timed out waiting for Qodex run ${RUN_ID}"
          exit 1

Make it required

In GitHub branch protection for main, add the Qodex workflow as a required status check. Pull requests will not merge until the Qodex job passes.

Common adjustments

  • Change tags from smoke to critical for a smaller gate.
  • Remove tags to run the full active suite.
  • Use a schedule webhook if the workflow should trigger one preconfigured policy.
  • Use separate API keys for staging and production if you want independent rotation.

Run tests via webhook

Generic shell recipe