Skip to content

dnsdist: Handle custom load-balancing policies from YAML #2413

dnsdist: Handle custom load-balancing policies from YAML

dnsdist: Handle custom load-balancing policies from YAML #2413

name: "CodeQL and clang-tidy"
on:
push:
pull_request:
schedule:
- cron: '0 22 * * 2'
permissions: # least privileges, see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions
contents: read
# clang-tidy fun:
# We need to invoke clang-tidy from the correct directory, the one the product was compiled in, so that we get the correct include paths.
# This means the root for the auth, pdns/recursordist for the rec and pdns/dnsdistdist for dnsdist
# It is important that files that are used by more than one product are processed by all the products using them
# because they might have difference compilation flags.
# We have to use our own clang-tidy-diff.py because the line-filter flag only supports file names, not paths.
# Finally the GH annotations that we generate from clang-tidy.py, have to be relative to the path in the git repository, so we need to
# follow symlinks.
# How does that work? We use git diff to get the list of diffs, and git-filter.py to get the right folder depending on the product.
# Then we call clang-tidy-diff.py, which invokes clang-tidy on the correct file, deducing the line numbers from the diff, and
# merging the results for all processed files to a YAML file. Finally clang-tidy.py converts the YAML output to GitHub annotations
# (GitHub only supports 10 of these per job, the rest are not displayed) and to GitHub markdown step summary (which has no such limits).
jobs:
analyze:
name: Analyze
if: ${{ !github.event.schedule || vars.SCHEDULED_CODEQL_ANALYSIS }}
runs-on: ubuntu-22.04
permissions:
actions: read # for github/codeql-action/init to get workflow details
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/analyze to upload SARIF results
strategy:
fail-fast: false
matrix:
# Override automatic language detection by changing the below list
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
language: ['cpp']
product: ['auth', 'rec', 'dnsdist']
# Learn more...
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
env:
COMPILER: gcc
UNIT_TESTS: yes
FUZZING_TARGETS: yes
COVERAGE: no
OPTIMIZATIONS: no
# for clang-tidy only, not compilation
CLANG_VERSION: '14'
REPO_HOME: ${{ github.workspace }}
DECAF_SUPPORT: no
outputs:
clang-tidy-annotations-auth: ${{ steps.clang-tidy-annotations-auth.outputs.failed }}
clang-tidy-annotations-dnsdist: ${{ steps.clang-tidy-annotations-dnsdist.outputs.failed }}
clang-tidy-annotations-rec: ${{ steps.clang-tidy-annotations-rec.outputs.failed }}
steps:
- uses: PowerDNS/pdns/set-ubuntu-mirror@meta
- name: Checkout repository
uses: actions/checkout@v4
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2
- uses: actions/setup-python@v5
with:
python-version: '3.11'
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: +security-and-quality
# TODO: go through +security-and-quality (400 alerts) once, then see if we can upgrade to it
# 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.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# 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.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
- name: Update repository metadata
run: |
sudo apt-get update
- name: Install python invoke and needed libs
run: |
sudo apt-get -qq -y --no-install-recommends install python3 python3-pip python3-invoke python3-git python3-unidiff ccache
- name: Install clang-tidy tools
run: |
inv install-clang-tidy-tools
- name: Install dependencies for auth
if: matrix.product == 'auth'
run: |
inv install-auth-build-deps
- name: Autoreconf auth
if: matrix.product == 'auth'
run: |
inv ci-autoconf
- name: Configure auth
if: matrix.product == 'auth'
run: |
inv ci-auth-configure
- name: Build auth
if: matrix.product == 'auth'
run: |
inv ci-auth-make-bear
- run: ln -s .clang-tidy.full .clang-tidy
if: matrix.product == 'auth'
- name: Run clang-tidy for auth
if: matrix.product == 'auth'
run: git diff --no-prefix -U0 HEAD^..HEAD | /usr/bin/python3 .github/scripts/git-filter.py --product auth | /usr/bin/python3 .github/scripts/clang-tidy-diff.py -clang-tidy-binary /usr/bin/clang-tidy-${CLANG_VERSION} -extra-arg=-ferror-limit=0 -p0 -export-fixes clang-tidy-auth.yml
- name: Print clang-tidy fixes YAML for auth
if: matrix.product == 'auth'
shell: bash
run: |
if [ -f clang-tidy-auth.yml ]; then
cat clang-tidy-auth.yml
fi
- name: Result annotations for auth
if: matrix.product == 'auth'
id: clang-tidy-annotations-auth
shell: bash
run: |
if [ -f clang-tidy-auth.yml ]; then
set +e
/usr/bin/python3 .github/scripts/clang-tidy.py --fixes-file clang-tidy-auth.yml
echo "failed=$?" >> $GITHUB_OUTPUT
fi
- name: Install dependencies for dnsdist
if: matrix.product == 'dnsdist'
run: |
inv install-dnsdist-build-deps --skipXDP
- name: Autoreconf dnsdist
if: matrix.product == 'dnsdist'
working-directory: ./pdns/dnsdistdist/
run: |
inv ci-autoconf
- run: inv ci-install-rust ${{ env.REPO_HOME }}
if: matrix.product == 'dnsdist'
working-directory: ./pdns/dnsdistdist/
- run: inv ci-build-and-install-quiche ${{ env.REPO_HOME }}
if: matrix.product == 'dnsdist'
working-directory: ./pdns/dnsdistdist/
- name: Configure dnsdist
if: matrix.product == 'dnsdist'
working-directory: ./pdns/dnsdistdist/
run: |
inv ci-dnsdist-configure full
- name: Build dnsdist
if: matrix.product == 'dnsdist'
working-directory: ./pdns/dnsdistdist/
run: |
inv ci-dnsdist-make-bear
- run: ln -s ../../.clang-tidy.full .clang-tidy
if: matrix.product == 'dnsdist'
working-directory: ./pdns/dnsdistdist/
- name: Run clang-tidy for dnsdist
if: matrix.product == 'dnsdist'
working-directory: ./pdns/dnsdistdist/
run: git diff --no-prefix -U0 HEAD^..HEAD | /usr/bin/python3 ../../.github/scripts/git-filter.py --product dnsdist | /usr/bin/python3 ../../.github/scripts/clang-tidy-diff.py -clang-tidy-binary /usr/bin/clang-tidy-${CLANG_VERSION} -extra-arg=-ferror-limit=0 -p0 -export-fixes clang-tidy-dnsdist.yml
- name: Print clang-tidy fixes YAML for dnsdist
if: matrix.product == 'dnsdist'
working-directory: ./pdns/dnsdistdist/
shell: bash
run: |
if [ -f clang-tidy-dnsdist.yml ]; then
cat clang-tidy-dnsdist.yml
fi
- name: Result annotations for dnsdist
if: matrix.product == 'dnsdist'
id: clang-tidy-annotations-dnsdist
working-directory: ./pdns/dnsdistdist/
shell: bash
run: |
if [ -f clang-tidy-dnsdist.yml ]; then
set +e
/usr/bin/python3 ../../.github/scripts/clang-tidy.py --fixes-file clang-tidy-dnsdist.yml
echo "failed=$?" >> $GITHUB_OUTPUT
fi
- name: Install dependencies for rec
if: matrix.product == 'rec'
run: |
inv install-rec-build-deps
- run: inv ci-install-rust ${{ env.REPO_HOME }}
if: matrix.product == 'rec'
working-directory: ./pdns/recursordist/
- name: Autoreconf rec
if: matrix.product == 'rec'
working-directory: ./pdns/recursordist/
run: |
inv ci-autoconf
- name: Configure rec
if: matrix.product == 'rec'
working-directory: ./pdns/recursordist/
run: |
inv ci-rec-configure full
- name: Build rec
if: matrix.product == 'rec'
working-directory: ./pdns/recursordist/
run: |
CONCURRENCY=4 inv ci-rec-make-bear
- run: ln -s ../../.clang-tidy.full .clang-tidy
if: matrix.product == 'rec'
working-directory: ./pdns/recursordist/
- name: Run clang-tidy for rec
if: matrix.product == 'rec'
working-directory: ./pdns/recursordist/
run: git diff --no-prefix -U0 HEAD^..HEAD | /usr/bin/python3 ../../.github/scripts/git-filter.py --product rec | /usr/bin/python3 ../../.github/scripts/clang-tidy-diff.py -clang-tidy-binary /usr/bin/clang-tidy-${CLANG_VERSION} -extra-arg=-ferror-limit=0 -p0 -export-fixes clang-tidy-rec.yml
- name: Print clang-tidy fixes YAML for rec
if: matrix.product == 'rec'
working-directory: ./pdns/recursordist/
shell: bash
run: |
if [ -f clang-tidy-rec.yml ]; then
cat clang-tidy-rec.yml
fi
- name: Result annotations for rec
if: matrix.product == 'rec'
id: clang-tidy-annotations-rec
working-directory: ./pdns/recursordist/
shell: bash
run: |
if [ -f clang-tidy-rec.yml ]; then
set +e
/usr/bin/python3 ../../.github/scripts/clang-tidy.py --fixes-file clang-tidy-rec.yml
echo "failed=$?" >> $GITHUB_OUTPUT
fi
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
check-clang-tidy:
needs: analyze
runs-on: ubuntu-22.04
name: Check whether clang-tidy succeeded
steps:
- run: |
if [ "x${{ needs.analyze.outputs.clang-tidy-annotations-auth }}" != "x" -a "${{ needs.analyze.outputs.clang-tidy-annotations-auth }}" != "0" ]; then
echo "::error::Auth clang-tidy failed"
exit 1
fi
if [ "x${{ needs.analyze.outputs.clang-tidy-annotations-dnsdist }}" != "x" -a "${{ needs.analyze.outputs.clang-tidy-annotations-dnsdist }}" != "0" ]; then
echo "::error::DNSdist clang-tidy failed"
exit 1
fi
if [ "x${{needs.analyze.outputs.clang-tidy-annotations-rec }}" != "x" -a "${{needs.analyze.outputs.clang-tidy-annotations-rec }}" != "0" ]; then
echo "::error::Rec clang-tidy failed"
exit 1
fi
check-for-binaries:
runs-on: ubuntu-22.04
name: Force failure in case there are binaries present in a pull request
if: ${{ github.event_name == 'pull_request' }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 2
- run: if [[ "$(file -i --dereference $(git diff --name-only HEAD^..HEAD -- . :^fuzzing/corpus) | grep binary | grep -v 'image/' | grep -v 'inode/x-empty' | grep -v 'inode/directory' | tee /dev/stderr)" != "" ]]; then exit 1; fi