CodeQL code scanning
Run GitHub CodeQL code scanning on RunsOn Fleet or Flex self-hosted runners, with default setup or advanced setup.
GitHub CodeQL code scanning can run on RunsOn runners instead of GitHub-hosted runners. GitHub offers two setups, and they select a runner differently:
| Setup | How the runner is chosen | Fleet | Flex |
|---|---|---|---|
| Default setup | One runner label in the repository or organization security settings | Yes | No |
| Advanced setup | The runs-on: label of a CodeQL workflow you commit | Yes | Yes |
Code scanning must be available on the repository: it is free for public repositories, and private or internal repositories need GitHub Code Security ↗.
Default setup on Fleet#
A Fleet runner scale set is registered with a single compound label, such as:
runs-on/fleet=codeql-x64/env=productionThe fleet name and environment must match a fleet in your Fleet configuration. GitHub creates the CodeQL jobs, so there is no workflow YAML to change.
Select the fleet as the runner for default setup:
- Open the repository’s Settings → Advanced Security, or go directly to
https://github.com/<ORG>/<REPO>/settings/security_analysis. - In the CodeQL analysis row, select Set up → Default. If default setup is already enabled, open the row’s menu, select View CodeQL configuration, then Edit.
- Under Runner type, select Labeled runner.
- Enter the full Fleet label in Runner label.
- Enable or save the configuration.
You can also set the runner with the REST API:
gh api -X PATCH repos/<ORG>/<REPO>/code-scanning/default-setup \ -f state=configured \ -f runner_type=labeled \ -f runner_label='runs-on/fleet=codeql-x64/env=production'To use the same runner across many repositories, set the label in an organization security configuration ↗.
GitHub only accepts the label if a runner with that label is available to the repository. A fleet’s scale set satisfies this check even when no runner is running, as long as the fleet’s runner group allows the repository. For a public repository, the runner group must also allow public repositories.
Sizing the fleet#
Default setup starts one job per detected language, in parallel, so a repository with four languages needs four runners at once. GitHub recommends ↗ at least 8 GB of RAM for codebases under 100,000 lines of code, and more for larger ones.
Default setup builds some compiled languages, such as Go, with autobuild, so the runner needs their toolchains. Use a -full image such as ubuntu24-full-x64, which is compatible with the GitHub-hosted runner image.
Default setup is not available on Flex#
Flex cannot be the runner for default setup. GitHub checks that a runner with the label is already registered when you save the setting, and Flex registers a just-in-time runner only when a job arrives. GitHub rejects the label with:
Code scanning default setup can only be enabled if a runner with the specified label is assigned to this repository.Use advanced setup on Flex instead.
Advanced setup#
Advanced setup works on Flex and Fleet. Commit a CodeQL workflow and pick the runner with runs-on::
name: CodeQL
on: push: branches: [main] pull_request: branches: [main] schedule: - cron: "30 4 * * 1"
permissions: actions: read contents: read security-events: write
jobs: analyze: name: Analyze (${{ matrix.language }}) runs-on: runs-on=${{ github.run_id }}/runner=4cpu-linux-x64 strategy: fail-fast: false matrix: include: - language: javascript-typescript build-mode: none - language: python build-mode: none - language: go build-mode: autobuild steps: - uses: actions/checkout@v5 - uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} - uses: github/codeql-action/analyze@v4 with: category: "/language:${{ matrix.language }}"On Fleet, only the runs-on: line changes:
runs-on: runs-on/fleet=codeql-x64/env=productionGitHub does not process advanced setup results while default setup is enabled on the repository. The analyze step fails with:
CodeQL analyses from advanced configurations cannot be processed when the default setup is enabledDisable default setup before you add the workflow. New repositories can have default setup enabled on GitHub-hosted runners automatically, when the organization applies a security configuration such as GitHub recommended.
Troubleshooting#
- Jobs stay queued. Check that the label matches the fleet exactly and that the fleet’s runner group allows the repository. Jobs that were queued before you changed runner group access are not picked up afterwards: cancel and re-run them.
- No scan after changing the runner. Changing only the runner through the API does not start an analysis. Push to the default branch, or wait for the weekly scheduled scan.
Code scanning default setup can only be enabled if a runner with the specified label is assigned to this repository. The label has a typo, the runner group does not allow the repository, or the label targets Flex.