Xebia Background Header Wave

To enable CodeQL on GitHub Enterprise Server you need to make sure you have GitHub Actions setup and running, including your own set of self-hosted runners. You can read more about that in my previous post here.

From that point you can get started to enable CodeQL. Of course, you’ll need to have it enabled in your license, and upload that license file to your server as well. Enabling starts at the appliance level, where you need to enable the code scanning and secret scanning features from the management console.


The default workflow that CodeQL will propose links to the github/codeql-action action, of which a static copy is installed with each Enterprise Server update. This organization is hidden by default, but you can navigate to it with the direct link. The issue here is that these action repos (github/dependabot-action and all repos in the actions org) only have the source code linked and updated with each Enterprise Server update. Since the CodeQL bundle is stored as a release asset, it is missing from the appliance. The bundle contains all CodeQL queries, including the security-extended and security-and-quality query types.

Syncing the CodeQL bundle

Normally we’d use the actions-sync tool to update the actions on the appliance with the latest version on github.com. Unfortunately that tool does not sync any release assets. For syncing the release assets, we need to download the latest release of the codeql-action-sync-tool.

After downloading the codeql-action-sync-tool, you need to make sure you have write access to the github organization. By default you do not have it, so you cannot write to the release assets or anything else in this org. That means we need to promote the user that will execute the syncing to an owner of the github org.

To do so, you need to call the ghe-org-admin-promote command line utility from a remote shell on the appliance:

ghe-org-admin-promote <span class="nt">-u</span> USERNAME <span class="nt">-o</span> ORGANIZATION

Now we can call the codeql-action-sync-tool to download the latest version of the CodeQL bundle and upload it to the github/codeql-action repo. This tool will also update the github/codeql-action repo with the latest version of the action code.
You can run it with this command:

codeql-action-sync-tool <span class="nb">sync</span> <span class="nt">--force</span> <span class="se">\</span>
 <span class="nt">--destination-url</span> https://enterprise-server-url.com
 <span class="nt">--destination-token</span> <PAT> <span class="se">\</span>
 <span class="nt">--source-token</span> <PAT> <span class="c"># prevents ratelimiting</span>

Of course, the machine that is running this will need to have access to github.com, as well as the Enterprise Server. The --source-token is optional, but it will prevent you from hitting the rate limit on github.com.

Running CodeQL efficiently

Now that we have the CodeQL bundle on the appliance, we can start using it. The first thing you’ll notice is that the CodeQL bundle is quite large. The Linux zip file alone is 500Mb, which is quite a lot for a GitHub Action. The release asset appropriate for the OS of the runner is downloaded for each run. If you are using ephemeral runners (which you should!), this means that the CodeQL bundle is downloaded for each and every run. Given that this workflow is configured by default to run on every push, pull request as well as on a schedule (once a week), it can take up quite the bandwidth and thus hammer your appliance.

The action follows the normal setup for GitHub Actions to check for the well known folder runner.tool_cache, which is stored in ‘/opt/hostedtoolcache/’. If it can find the bundle in that folder, it will use that. If it cannot find it, it will download the appropriate release asset.

That means that we can prep our runners by copying the CodeQL bundle to this location. This will prevent the bundle from being downloaded for each run. The folder is used by including the CodeQL bundle release version and date: /opt/hostedtoolcache/CodeQL/2.12.1-20230120/x64/codeql/codeql.

Priming that location will significantly lower the download pressure on your appliance, and speed up the execution of the CodeQL workflow.

Rob Bos
Rob has a strong focus on ALM and DevOps, automating manual tasks and helping teams deliver value to the end-user faster, using DevOps techniques. This is applied on anything Rob comes across, whether it’s an application, infrastructure, serverless or training environments. Additionally, Rob focuses on the management of production environments, including dashboarding, usage statistics for product owners and stakeholders, but also as part of the feedback loop to the developers. A lot of focus goes to GitHub and GitHub Actions, improving the security of applications and DevOps pipelines. Rob is a Trainer (Azure + GitHub), a Microsoft MVP and a LinkedIn Learning Instructor.

Get in touch with us to learn more about the subject and related solutions

Explore related posts