CodeQL is the analysis engine used by developers to automate security checks, and by security researchers to perform variant analysis.

In CodeQL, code is treated like data. Security vulnerabilities, bugs, and other errors are modeled as queries that can be executed against databases extracted from code. You can run the standard CodeQL queries, written by GitHub researchers and community contributors, or write your own to use in custom analyses. Queries that find potential bugs highlight the result directly in the source file.

-CodeQL doc

Dependabot takes the effort out of maintaining your dependencies. You can use it to ensure that your repository automatically keeps up with the latest releases of the packages and applications it depends on.

-Dependabot Doc


After setting up CodeQL, it creates a new workflow inside .github/workflows. The default setup is to run static code analysis whenever a PR/push is made against the master branch. The problem was that two workflows executed each code push.

Screenshot of Git Actions showing two workflows. One by blogthedata tests and the other by CodeQL.

It made more sense for CodeQL to be the last step in my existing CI workflow instead of having to rebuild the container twice. I joined the two workflows.

name: Blogthedata Tests
      - main
    - cron: '0 3 * * 0-6'
    runs-on: ubuntu-latest
      actions: read
      contents: read
      security-events: write

      fail-fast: false
        language: [ 'javascript', 'python' ]
        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
        # Learn more about CodeQL language support at

      SECRET_KEY: ${{secrets.SECRET_KEY}}
      FROM_EMAIL: ${{secrets.FROM_EMAIL}}
      POSTGRES_PASS: $${{secrets.POSTGRES_PASS}}
      GIT_TOKEN: ${{secrets.GIT_TOKEN}}
      DEBUG: ${{secrets.DEBUG}}
      MODE: ${{secrets.MODE}}
    - uses: actions/checkout@v2
    - name: Setup Python 3.9.7
      uses: actions/setup-python@v2
        python-version: 3.9.7
    - name: Install dependencies
      run: |
        pip install --upgrade pip
        pip install wheel
        pip install -r django_project/requirements/requirements.txt
    - name: Lint with Flake8
      run: |
        flake8 django_project
    - name: Coverage report
      run: |
        coverage run -m unittest discover django_project 
        coverage report -m --skip-empty --skip-covered
    - name: Run unit tests
      run: |
        python3 -m unittest discover django_project

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v2
        languages: ${{ matrix.language }}
        # If you wish to specify custom queries, you can do so here or in a config file.
        # By default, queries listed here will override any specified in a config file.
        # Prefix the list here with "+" to use these queries and those in the config file.
        # Details on CodeQL's query packs refer to :
        # queries: security-extended,security-and-quality

    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
    # If this step fails, then you should remove it and run the build manually (see below)
    #- name: Autobuild
    #  uses: github/codeql-action/autobuild@v2

    # ℹī¸ Command-line programs to run using the OS shell.
    # 📚 See

    #   If the Autobuild fails above, remove it and uncomment the following three lines. 
    #   modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.

    # - run: |
    #   echo "Run, Build Application using script"
    #   ./location_of_script_within_repo/

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v2

The new code starts on line 58. I commented out lines 72 and 73 because Python and JavaScript do not compile. CodeQL adds a few minutes to build time, including unit test coverage, linting, passing unit tests, and a security scan.


To add Dependabot, I created a dependabot.yml file inside the .github folder.


├── dependabot.yml

└── workflows

    └── django-test.yaml


# .github/dependabot.yml
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:

version: 2
  # Maintain dependencies for GitHub Actions
  - package-ecosystem: "" # See documentation for possible values
    directory: "/" # Location of package manifests
      interval: "daily"

  # Maintain dependencies for pip package manager
  - package-ecosystem: "pip"
    directory: "/config/requirements.txt"
      interval: "daily"

I changed line 18 to point it to my requirements.txt file. Dependabot creates PRs for the issues it finds. I have four open Dependabot branches that I'll tackle in this issue. The code changes Dependabot suggests often bump the module version number in the requirements.txt. Since unit tests pass, I'll merge them and roll back if things go sideways.

Screenshot of Dependabot PR. Code change from Pillow8.3.2 to 9.0.1 


I lint, assess code coverage, run unit tests, and security scan my code + dependencies with two short YAML files. It takes 7-8 minutes for the CI workflow to finish, and dependabot creates PRs to fix vulnerabilities. My next step is to fix the issues that were found. Add CodeQL and Dependabot to your repo today!


Back to Home
John Solly Profile Picture
John Solly Profile Picture

John Solly

Hi, I'm John, a Software Engineer with a decade of experience building, deploying, and maintaining cloud-native geospatial solutions. I currently serve as a senior software engineer at New Light Technologies (NLT), where I work on a variety of infrastructure and application development projects.

Throughout my career, I've built applications on platforms like Esri and Mapbox while also leveraging open-source GIS technologies such as OpenLayers, GeoServer, and GDAL. This blog is where I share useful articles with the GeoDev community. Check out my portfolio to see my latest work!