diff options
Diffstat (limited to '.github/workflows/ci.yml')
-rw-r--r-- | .github/workflows/ci.yml | 456 |
1 files changed, 456 insertions, 0 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..074da62 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,456 @@ +name: CI + +on: + push: + branches-ignore: + - coverity_scan + pull_request: + +env: + PANIC_ACTION: "gdb -batch -x raddb/panic.gdb %e %p 1>&0 2>&0" + ALT_OPENSSL: "3.0.2" + CI: 1 + GH_ACTIONS: 1 + DEBIAN_FRONTEND: noninteractive + APT_OPTS: "-y --no-install-recommends" + LDAP_TEST_SERVER: 127.0.0.1 + LDAP_TEST_SERVER_PORT: 3890 +# +# Update between running in a container (GitHub runner and +# self-hosted runner), or directly on the VM (currently GitHub +# runner only, as our runners don't get root access). Remember to +# comment/uncomment other sections below as well. +# +# Container: + USE_DOCKER: 1 + SQL_MYSQL_TEST_SERVER: mariadb + SQL_POSTGRESQL_TEST_SERVER: postgres +# Hosted: +# USE_DOCKER: 0 +# SQL_MYSQL_TEST_SERVER: 127.0.0.1 +# SQL_POSTGRESQL_TEST_SERVER: 127.0.0.1 + +jobs: + ci: + + runs-on: ${{ matrix.os.runs_on }} + +# Comment out when not using containers: + container: + image: ${{ matrix.os.docker }} + + strategy: + fail-fast: false + matrix: + os: +# +# runs_on - where GitHub will spin up the runner, either +# "self-hosted", or the name of a GitHub VM image. +# code - the name/version of the OS (for step evaluations below) +# docker - the docker image name, if containers are being used +# name - used in the job name only +# +# Self-hosted runner (must set USE_DOCKER=1 above): + - { runs_on: "${{ github.repository_owner == 'FreeRADIUS' && 'self-hosted' || 'ubuntu-20.04' }}", code: "ubuntu2004", docker: "ubuntu:20.04", name: "${{ github.repository_owner == 'FreeRADIUS' && 'self' || 'gh' }}-ubuntu20" } +# GitHub runner (may set USE_DOCKER=0 or 1 above): +# - { runs_on: "ubuntu-20.04", code: "ubuntu2004", docker: "ubuntu:20.04", name: "gh20-ubuntu20" } + + env: + - { CC: gcc, DO_BUILD: yes, LIBS_OPTIONAL: no, LIBS_ALT: no, REPRODUCIBLE: no, BUILD_CFLAGS: "-DWITH_EVAL_DEBUG", NAME: linux-gcc-lean } + - { CC: gcc, DO_BUILD: yes, LIBS_OPTIONAL: yes, LIBS_ALT: no, REPRODUCIBLE: no, BUILD_CFLAGS: "-DWITH_EVAL_DEBUG", NAME: linux-gcc } + - { CC: gcc, DO_BUILD: yes, LIBS_OPTIONAL: yes, LIBS_ALT: no, REPRODUCIBLE: yes, BUILD_CFLAGS: "-DWITH_EVAL_DEBUG", NAME: linux-gcc-reproducible } + - { CC: gcc, DO_BUILD: yes, LIBS_OPTIONAL: yes, LIBS_ALT: no, REPRODUCIBLE: no, BUILD_CFLAGS: "-DWITH_EVAL_DEBUG -O2 -g3", NAME: linux-gcc-O2-g3 } + - { CC: clang, DO_BUILD: yes, LIBS_OPTIONAL: no, LIBS_ALT: no, REPRODUCIBLE: no, BUILD_CFLAGS: "-DWITH_EVAL_DEBUG", NAME: linux-clang-lean } + - { CC: clang, DO_BUILD: yes, LIBS_OPTIONAL: yes, LIBS_ALT: no, REPRODUCIBLE: no, BUILD_CFLAGS: "-DWITH_EVAL_DEBUG", NAME: linux-clang } + - { CC: clang, DO_BUILD: yes, LIBS_OPTIONAL: yes, LIBS_ALT: yes, REPRODUCIBLE: no, BUILD_CFLAGS: "-DWITH_EVAL_DEBUG", NAME: linux-clang-altlibs } + - { CC: clang, DO_BUILD: yes, LIBS_OPTIONAL: yes, LIBS_ALT: no, REPRODUCIBLE: yes, BUILD_CFLAGS: "-DWITH_EVAL_DEBUG", NAME: linux-clang-reproducible } + - { CC: clang, DO_BUILD: yes, LIBS_OPTIONAL: yes, LIBS_ALT: no, REPRODUCIBLE: no, BUILD_CFLAGS: "-DWITH_EVAL_DEBUG -O2 -g3", NAME: linux-clang-O2-g3 } + + env: ${{ matrix.env }} + + # Test names are used in the branch protection rules in GitHub + # If you change the names here, or add additional matrix entries, you + # must also amend the branch protection fules. + name: "v3.2.x-${{ matrix.os.name }}-${{ matrix.env.NAME }}" + + # The standard GitHub environment contains PostgreSQL and + # MySQL already. However when running on hosted GitHub runners + # we need to run separate database containers to provide these. +# +# Comment out the "services" section when USE_DOCKER=0 +# + services: + mariadb: + image: mariadb + env: + MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: yes + ports: + - 3306:3306 + options: --health-cmd="mysqladmin ping" --health-interval 10s --health-timeout 5s --health-retries 10 + + postgres: + image: postgres + env: + POSTGRES_HOST_AUTH_METHOD: trust + ports: + - 5432:5432 + options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 + + steps: + + - name: Self-hosted runner container fixes + if: ${{ env.USE_DOCKER == 1 }} + run: | + ln -fs /usr/bin/env /usr/local/bin/sudo + + - name: Package manager performance improvements + run: | + sudo sh -c 'echo force-unsafe-io > /etc/dpkg/dpkg.cfg.d/02speedup' + if command -v mandb >/dev/null; then + echo 'man-db man-db/auto-update boolean false' | sudo debconf-set-selections + sudo dpkg-reconfigure man-db + fi + + - name: Freshen APT repo metadata + run: | + sudo apt-get update + + - name: Install common build dependencies + run: | + sudo apt-get install ${APT_OPTS} \ + autoconf \ + build-essential \ + debhelper \ + devscripts \ + dh-make \ + fakeroot \ + firebird-dev \ + freetds-dev \ + gawk \ + git \ + gnupg \ + libcap-dev \ + libcollectdclient-dev \ + libcurl4-openssl-dev \ + libgdbm-dev \ + libhiredis-dev \ + libidn11-dev \ + libiodbc2 \ + libiodbc2-dev \ + libjson-c-dev \ + libkqueue-dev \ + libkrb5-dev \ + libldap2-dev \ + libmemcached-dev \ + libmysqlclient-dev \ + libnl-3-dev \ + libnl-genl-3-dev \ + libpam0g-dev \ + libpcap-dev \ + libpcre3-dev \ + libperl-dev \ + libpq-dev \ + libreadline-dev \ + libruby \ + libsnmp-dev \ + libsqlite3-dev \ + libssl-dev \ + libtalloc-dev \ + libunbound-dev \ + libwbclient-dev \ + libykclient-dev \ + libyubikey-dev \ + lintian \ + pbuilder \ + python-dev \ + python3-dev \ + ruby-dev \ + snmp \ + software-properties-common \ + quilt + + - name: Install LLVM 10 for 18.04 + if: ${{ matrix.os.code == 'ubuntu1804' && matrix.env.CC == 'clang' }} + run: | + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add + sudo apt-add-repository "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main" + sudo apt-get install ${APT_OPTS} clang-10 llvm-10 gdb + sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-10 60 && sudo update-alternatives --set clang /usr/bin/clang-10 + sudo update-alternatives --install /usr/bin/llvm-symbolizer llvm-symbolizer /usr/bin/llvm-symbolizer-10 60 && sudo update-alternatives --set llvm-symbolizer /usr/bin/llvm-symbolizer-10 + + - name: Install LLVM 10 for 20.04 + if: ${{ matrix.os.code == 'ubuntu2004' && matrix.env.CC == 'clang' }} + run: | + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add + sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-10 main" + sudo apt-get install ${APT_OPTS} clang-10 llvm-10 gdb + sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-10 60 && sudo update-alternatives --set clang /usr/bin/clang-10 + sudo update-alternatives --install /usr/bin/llvm-symbolizer llvm-symbolizer /usr/bin/llvm-symbolizer-10 60 && sudo update-alternatives --set llvm-symbolizer /usr/bin/llvm-symbolizer-10 + + - name: Install GCC + if: ${{ matrix.env.CC == 'gcc' }} + run: | + sudo apt-get install ${APT_OPTS} gcc gdb + + # + # Build using some alternative libraries + # + # MIT Kerberos -> HEIMDAL Kerberos + # OpenSSL 1.0 -> OpenSSL 3.0 + # + - name: 'Fetch OpenSSL 3.0 SHA' + id: opensslshasum + if: ${{ matrix.env.LIBS_ALT == 'yes' }} + run: | + wget -qO- http://www.openssl.org/source/openssl-$ALT_OPENSSL.tar.gz.sha256 | sed -ne 's/^\s\+/::set-output name=shasum::/p' + + - name: 'Restore OpenSSL 3.0 from the cache' + if: ${{ matrix.env.LIBS_ALT == 'yes' }} + uses: actions/cache@v2 + id: openssl-cache + with: + path: /opt/openssl/ + key: openssl3-${{ steps.opensslshasum.outputs.shasum }} + + - name: 'Build OpenSSL 3.0 (if cache stale)' + if: ${{ matrix.env.LIBS_ALT == 'yes' && steps.openssl-cache.outputs.cache-hit != 'true' }} + run: | + cd ~ + wget https://www.openssl.org/source/openssl-$ALT_OPENSSL.tar.gz + tar xzf openssl-$ALT_OPENSSL.tar.gz + cd openssl-$ALT_OPENSSL + ./Configure --prefix=/opt/openssl --openssldir=. + make -j `nproc` + make install + + - name: Use alternative libraries + if: ${{ matrix.env.LIBS_ALT == 'yes' }} + run: | + echo /opt/openssl/lib64 | sudo tee /etc/ld.so.conf.d/openssl3.conf >/dev/null + sudo ldconfig + sudo apt-get install ${APT_OPTS} heimdal-dev + + - name: Show versions + run: | + $CC --version + make --version + krb5-config --all || : + [ -d /opt/openssl ] && export PATH=/opt/openssl/bin:$PATH + openssl version + + - uses: actions/checkout@v2 + + - name: Build eapol_test + run: | + if [ -d /opt/openssl ]; then + # Used by scripts/ci/eapol_test-build.sh + export PATH=/opt/openssl/bin:$PATH + export EAPOL_TEST_CFLAGS="-I/opt/openssl/include" + export EAPOL_TEST_LDFLAGS="-L/opt/openssl/lib64" + fi + ./scripts/ci/eapol_test-build.sh + + - name: Build FreeRADIUS + run: | + export PATH=$(echo "$PATH" | sed -e 's#:/home/linuxbrew/[^:]\+##g') + if [ -d /opt/openssl ]; then + export PATH=/opt/openssl/bin:$PATH + CONFIG_OPENSSL="--with-openssl-lib-dir=/opt/openssl/lib64 --with-openssl-include-dir=/opt/openssl/include" + fi + CFLAGS="${BUILD_CFLAGS}" ./configure -C --enable-developer --enable-werror --prefix=$HOME/freeradius --with-threads=$LIBS_OPTIONAL --with-udpfromto=$LIBS_OPTIONAL --with-openssl=$LIBS_OPTIONAL --with-pcre=$LIBS_OPTIONAL --enable-reproducible-builds=${REPRODUCIBLE} $CONFIG_OPENSSL + make -j $(($(nproc) + 1)) + + - name: clang scan + run: | + make -j $(($(nproc) + 1)) scan && [ "$(find build/plist/ -name *.html)" = '' ] + if: ${{ matrix.env.CC == 'clang' }} + + - name: "Clang Static Analyzer: Store assets on failure" + uses: actions/upload-artifact@v2 + with: + name: clang-scan.tgz + path: build/plist/**/*.html + if: ${{ matrix.env.CC == 'clang' && failure() }} + + - name: Install test requisites + run: | + # Temporarily replace ucf (for config merge) with cp since it's + # terribly slow! + sudo mv /usr/bin/ucf /usr/bin/ucf.disabled + sudo sh -c 'echo "#!/bin/sh" > /usr/bin/ucf' + sudo sh -c 'echo "shift && cp -v \$@" >> /usr/bin/ucf' + sudo chmod +x /usr/bin/ucf + + sudo apt-get install ${APT_OPTS} \ + apparmor-utils \ + ldap-utils \ + slapd + + sudo mv -f /usr/bin/ucf.disabled /usr/bin/ucf + + - name: Database dependencies (GitHub runner) + if: ${{ env.USE_DOCKER != 1 }} + run: | + export PG_VER=$(cd /etc/postgresql ; ls | head ) + sudo sh -c "echo host all all 127.0.0.1/32 trust > /etc/postgresql/$PG_VER/main/pg_hba.conf" + sudo sh -c "echo local all all trust >> /etc/postgresql/$PG_VER/main/pg_hba.conf" + + sudo systemctl stop slapd + sudo aa-complain /usr/sbin/slapd + + sudo systemctl start mysql postgresql + + sudo mysql -h 127.0.0.1 -uroot -proot -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '';" + + - name: Database dependencies (containers) + if: ${{ env.USE_DOCKER == 1 }} + run: | + sudo apt-get install ${APT_OPTS} \ + mariadb-client \ + postgresql-client + + slapd + + - name: Setup test databases + run: | + for i in \ + postgresql-setup.sh \ + mysql-setup.sh \ + ldap-setup.sh \ + ldap2-setup.sh; do + + script="./scripts/ci/$i" + echo "Calling $i" + $script + done + + - name: Configure test database access (containers) + if: ${{ env.USE_DOCKER == 1 }} + run: | + mysql -h mariadb -uroot -e "CREATE USER 'radius'@'%' IDENTIFIED BY 'radpass';" + mysql -u root -h mariadb -e "GRANT ALL ON radius.* TO 'radius'; FLUSH PRIVILEGES;" + + - name: Run tests + run: | + [ -d /opt/openssl ] && export PATH=/opt/openssl/bin:$PATH + + openssl dhparam -out ./raddb/certs/dh -2 128 || \ + openssl dhparam -out ./raddb/certs/dh -2 512 || \ + true + + make ci-test + + - name: Show debug logs on failure + if: ${{ failure() }} + run: | + cat src/tests/radius.log || : + + # + # If the CI has failed and the branch is ci-debug then start a tmate + # session. SSH rendezvous point is emited continuously in the job output. + # + - name: "Debug: Start tmate" + uses: mxschmitt/action-tmate@v3 + with: + limit-access-to-actor: true + if: ${{ github.ref == 'refs/heads/ci-debug' && failure() }} + +########################################################################################## +# FREERADIUS CORE DEVELOPERS ONLY +########################################################################################## +# +# Direct push access to the main freeradius-server repo has been disabled in an attempt +# to keep CI passing reliably. +# +# The code below will automatically push to the main repository if a commit passes CI in +# your fork on a branch that exists in the main repository. +# +# The code below will only run if PERSONAL_ACCESS_TOKEN is defined in the repository +# secrets for your fork of the freeradius-server repo. +# +# If the above CI checks pass then we auto-merge into the same branch in the +# main FR repo (only on push) if the PERSONAL_ACCESS_TOKEN secret is defined, i.e. when +# the actor claims to be a FreeRADIUS developer with push access. +# +# Personal access tokens can be generated via the GitHub website: +# +# - Click on the Profile menu (top right) +# > Settings +# > Developer settings +# > Personal access tokens +# > Generate New Token +# - Next, add the following settings and scopes: +# Note: FreeRADIUS CI Push +# public_repo (checked) +# +# This will allow any git operations using this PERSONAL_ACCESS_TOKEN to commit code to any +# public repository you have access to. +# +# As this PERSONAL_ACCESS_TOKEN will only ever be accessible from GitHub actions when they are +# running from your fork of the FreeRADIUS repo, this shouldn't be a security issue. +# +# After generating your PERSONAL_ACCESS_TOKEN you will need to add it as a secret to your +# repository. +# +# - Copy your new token +# - Click on the Profile menu (top right) +# > Your repositories +# - Search for freeradius-server +# > Click freeradius-server +# - Click settings in the tabs on the left +# - Click secrets in the menu items on the left +# - Click New repository secret +# - Name: PERSONAL_ACCESS_TOKEN +# Value: <value you copied> +# - Click Add secret + # + # Needed because secrets are not available for evaluation in if conditions + # at the job level, so we evaluate the existence of the PERSONAL_ACCESS_TOKEN secret + # within a step and export the result instead. We also extract the short + # branch name here because it's convenient to do so. + # + merge-preflight: + needs: + - ci + if: ( github.event_name == 'push' ) && ( github.repository_owner != 'FreeRADIUS' ) && ( github.ref == 'refs/heads/master' || github.ref == 'refs/heads/v3.2.x' ) + name: "Merge preflight" + runs-on: ubuntu-latest + steps: + - name: "Report whether PERSONAL_ACCESS_TOKEN secret exists" + id: merge-preflight + run: | + [ -z "$PERSONAL_ACCESS_TOKEN" ] || echo "::set-output name=PERSONAL_ACCESS_TOKEN_EXISTS::1" + env: + PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + outputs: + PERSONAL_ACCESS_TOKEN_EXISTS: ${{ steps.merge-preflight.outputs.PERSONAL_ACCESS_TOKEN_EXISTS }} + + merge-upstream: + needs: + - ci + - merge-preflight + if: needs.merge-preflight.outputs.PERSONAL_ACCESS_TOKEN_EXISTS == '1' + runs-on: ubuntu-latest + name: "Merge into upstream" + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + lfs: false + persist-credentials: false + # Note: This also opportunistically updates the developer's branch with commits from + # the main repository. + # This update may fail if the developer has pushed additional commits since the + # workflow started. This is normal, and we ignore the failure. + - name: "Merge into upstream dev branch and update local branch" + run: | + BRANCH=${GITHUB_REF#refs/heads/} + git remote add upstream https://$USERNAME:$REPO_KEY@github.com/FreeRADIUS/freeradius-server.git + git fetch --no-recurse-submodules upstream +refs/heads/*:refs/remotes/upstream/* +refs/tags/*:refs/tags/upstream/* + git checkout --progress --force -B upstream-branch "refs/remotes/upstream/$BRANCH" + git merge "$BRANCH" --ff-only + git push upstream "upstream-branch:$BRANCH" + git push origin "$BRANCH" || true + env: + USERNAME: ${{ github.actor }} + REPO_KEY: ${{ secrets.PERSONAL_ACCESS_TOKEN }} |