name: Run tests on: [push, pull_request] jobs: build: runs-on: ubuntu-latest strategy: matrix: compiler: [gcc, clang] python-ruby-version: - {python: '3.11', ruby: '3.1'} - {python: '3.11', ruby: '3.1', other: 'test-flags-override'} - {python: '3.11', ruby: '3.1', other: 'test-debug'} - {python: '3.11', ruby: '3.1', other: 'linker-bfd'} - {python: '3.11', ruby: '3.1', other: 'linker-gold'} # Test several Python versions with the latest Ruby version - {python: '3.10', ruby: '3.1'} - {python: '3.9', ruby: '3.1'} - {python: '3.8', ruby: '3.1'} - {python: '3.7', ruby: '3.1'} - {python: 'pypy3.7', ruby: '3.1'} # Test several Ruby versions with the latest Python version - {python: '3.11', ruby: '3.0'} - {python: '3.11', ruby: '2.7'} - {python: '3.11', ruby: '2.6'} - {python: '3.11', ruby: '2.5'} exclude: - compiler: clang python-ruby-version: {python: '3.11', ruby: '3.1', other: 'linker-bfd'} - compiler: clang python-ruby-version: {python: '3.11', ruby: '3.1', other: 'linker-gold'} include: - compiler: gcc python-ruby-version: {python: '3.11', ruby: '3.1', other: 'sanitizers'} steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-ruby-version.python }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-ruby-version.python }} - name: Set up Ruby ${{ matrix.python-ruby-version.ruby }} uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.python-ruby-version.ruby }} bundler-cache: true - name: Install dependencies run: | sudo apt-get update -q sudo apt-get install -qy --no-install-recommends \ bison \ flex \ gawk \ gettext \ libaudit-dev \ libcap-dev \ libcap-ng-dev \ libcunit1-dev \ libdbus-glib-1-dev \ libpcre2-dev \ ruby-dev \ swig \ xmlto pip install flake8 - name: Install Clang if: ${{ matrix.compiler == 'clang' }} run: sudo apt-get install -qqy clang - name: Configure the environment run: | DESTDIR=/tmp/destdir echo "PYTHON=python" >> $GITHUB_ENV echo "RUBY=ruby" >> $GITHUB_ENV echo "DESTDIR=$DESTDIR" >> $GITHUB_ENV CC=${{ matrix.compiler }} if [ "${{ matrix.python-ruby-version.other }}" = "linker-bfd" ] ; then CC="$CC -fuse-ld=bfd" elif [ "${{ matrix.python-ruby-version.other }}" = "linker-gold" ] ; then CC="$CC -fuse-ld=gold" fi # https://bugs.ruby-lang.org/issues/18616 # https://github.com/llvm/llvm-project/issues/49958 if [ "${{ matrix.compiler }}" = "clang" ] && [[ "${{ matrix.python-ruby-version.ruby }}" = 3* ]] ; then CC="$CC -fdeclspec" fi echo "CC=$CC" >> $GITHUB_ENV EXPLICIT_MAKE_VARS= if [ "${{ matrix.python-ruby-version.other }}" = "test-flags-override" ] ; then # Test that overriding CFLAGS, LDFLAGS and other variables works fine EXPLICIT_MAKE_VARS="CFLAGS=-I$DESTDIR/usr/include LDFLAGS=-L$DESTDIR/usr/lib LDLIBS= CPPFLAGS=" elif [ "${{ matrix.python-ruby-version.other }}" = "test-debug" ] ; then # Test hat debug build works fine EXPLICIT_MAKE_VARS="DEBUG=1" elif [ "${{ matrix.python-ruby-version.other }}" = "sanitizers" ] ; then sanitizers='-fsanitize=address,undefined' EXPLICIT_MAKE_VARS="CFLAGS='-g -I$DESTDIR/usr/include $sanitizers' LDFLAGS='-L$DESTDIR/usr/lib $sanitizers' LDLIBS= CPPFLAGS= OPT_SUBDIRS=" echo "ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1" >> $GITHUB_ENV echo "UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1" >> $GITHUB_ENV else EXPLICIT_MAKE_VARS= fi echo "EXPLICIT_MAKE_VARS=${EXPLICIT_MAKE_VARS}" >> $GITHUB_ENV # Find files in order of pkgconf to be able to find Python.h # For example with Python 3.5: # * python is located at /opt/hostedtoolcache/Python/3.5.10/x64/bin/python # * sys.prefix is /opt/hostedtoolcache/Python/3.5.10/x64 # * Python.h is located at /opt/hostedtoolcache/Python/3.5.10/x64/include/python3.5m/Python.h # * python-3.5.pc is located at /opt/hostedtoolcache/Python/3.5.10/x64/lib/pkgconfig/python-3.5.pc PYTHON_SYS_PREFIX="$(python -c 'import sys;print(sys.prefix)')" echo "PKG_CONFIG_PATH=${PYTHON_SYS_PREFIX}/lib/pkgconfig" >> $GITHUB_ENV if [[ "${{ matrix.python-ruby-version.python }}" = pypy* ]] ; then # PyPy does not provide a config file for pkg-config # libpypy-c.so is provided in bin/libpypy-c.so for PyPy and bin/libpypy3-c.so for PyPy3 echo "PYINC=-I${PYTHON_SYS_PREFIX}/include" >> $GITHUB_ENV echo "PYLIBS=-L${PYTHON_SYS_PREFIX}/bin -lpypy3-c" >> $GITHUB_ENV fi # Display the final environment file, for debugging purpose cat $GITHUB_ENV - name: Download and install refpolicy headers for sepolgen tests run: | curl --location --retry 10 -o refpolicy.tar.bz2 https://github.com/SELinuxProject/refpolicy/releases/download/RELEASE_2_20220520/refpolicy-2.20220520.tar.bz2 tar -xvjf refpolicy.tar.bz2 sed -e "s,^PREFIX :=.*,PREFIX := $DESTDIR/usr," -i refpolicy/support/Makefile.devel sudo make -C refpolicy install-headers bare sudo mkdir -p /etc/selinux echo 'SELINUXTYPE=refpolicy' | sudo tee /etc/selinux/config echo 'SELINUX_DEVEL_PATH = /usr/share/selinux/refpolicy' | sudo tee /etc/selinux/sepolgen.conf sed -e "s,\"\(/usr/bin/[cs]\),\"$DESTDIR\1," -i python/sepolgen/src/sepolgen/module.py rm -r refpolicy refpolicy.tar.bz2 - name: Display versions run: | echo "::group::Compiler ($CC):" $CC --version echo "::endgroup::" echo "::group::Python ($(which "$PYTHON")):" $PYTHON --version echo "::endgroup::" echo "::group::Ruby ($(which "$RUBY")):" $RUBY --version echo "::endgroup::" - name: Run tests run: | echo "::group::make install" eval make -j$(nproc) install $EXPLICIT_MAKE_VARS -k echo "::endgroup::" echo "::group::make install-pywrap" eval make -j$(nproc) install-pywrap $EXPLICIT_MAKE_VARS -k echo "::endgroup::" echo "::group::make install-rubywrap" eval make -j$(nproc) install-rubywrap $EXPLICIT_MAKE_VARS -k echo "::endgroup::" # Now that everything is installed, run "make all" to build everything which may have not been built echo "::group::make all" eval make -j$(nproc) all $EXPLICIT_MAKE_VARS -k echo "::endgroup::" # Set up environment variables for the tests and show variables (to help debugging issues) echo "::group::Environment variables" . ./scripts/env_use_destdir echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH" echo "PATH=$PATH" echo "PYTHONPATH=$PYTHONPATH" echo "RUBYLIB=$RUBYLIB" echo "::endgroup::" # Run tests echo "::group::make test" eval make test $EXPLICIT_MAKE_VARS echo "::endgroup::" if [ "${{ matrix.python-ruby-version.other }}" != "sanitizers" ] ; then # Test Python and Ruby wrappers echo "::group::Test Python and Ruby wrappers" $PYTHON -c 'import selinux;import selinux.audit2why;import semanage;print(selinux.is_selinux_enabled())' $RUBY -e 'require "selinux";require "semanage";puts Selinux::is_selinux_enabled()' echo "::endgroup::" # Run Python linter, but not on the downloaded refpolicy echo "::group::scripts/run-flake8" ./scripts/run-flake8 echo "::endgroup::" fi echo "::group::Test .gitignore and make clean distclean" # Remove every installed files rm -rf "$DESTDIR" # Test that "git status" looks clean, or print a clear error message git status --short | sed -n 's/^??/error: missing .gitignore entry for/p' | (! grep '^') # Clean up everything and show which file needs to be added to "make clean" eval make clean distclean $EXPLICIT_MAKE_VARS git ls-files --ignored --others --exclude-standard | sed 's/^/error: "make clean distclean" did not remove /' | (! grep '^') echo "::endgroup::"