# Copyright 2021 Google Inc. All Rights Reserved. # # Distributed under MIT license. # See file LICENSE for detail or copy at https://opensource.org/licenses/MIT # Workflow for building and running tests under Ubuntu name: Build/Test on: push: branches: - master pull_request: types: [opened, reopened, labeled, unlabeled, synchronize] permissions: contents: read concurrency: group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: build_test: name: Build and test ${{ matrix.name }} runs-on: ${{ matrix.os || 'ubuntu-latest' }} defaults: run: shell: bash strategy: fail-fast: false matrix: include: - name: cmake:gcc build_system: cmake c_compiler: gcc cxx_compiler: g++ - name: cmake:gcc-old build_system: cmake c_compiler: gcc cxx_compiler: g++ os: ubuntu-22.04 - name: cmake:clang build_system: cmake c_compiler: clang cxx_compiler: clang - name: cmake:clang-old build_system: cmake c_compiler: clang cxx_compiler: clang os: ubuntu-22.04 - name: cmake:package build_system: cmake cmake_args: -DBROTLI_BUILD_FOR_PACKAGE=ON - name: cmake:static build_system: cmake cmake_args: -DBUILD_SHARED_LIBS=OFF - name: cmake:clang:asan build_system: cmake sanitizer: address c_compiler: clang cxx_compiler: clang++ - name: cmake:clang:tsan build_system: cmake sanitizer: thread c_compiler: clang cxx_compiler: clang++ - name: cmake:clang:ubsan build_system: cmake sanitizer: undefined c_compiler: clang cxx_compiler: clang++ c_flags: -fno-sanitize-recover=undefined,integer - name: cmake:qemu-arm-neon-gcc build_system: cmake c_compiler: arm-linux-gnueabihf-gcc cxx_compiler: arm-linux-gnueabihf-g++ c_flags: -march=armv7-a -mfloat-abi=hard -mfpu=neon extra_apt_pkgs: gcc-arm-linux-gnueabihf libc6-dev-armhf-cross qemu-user - name: cmake-osx:clang build_system: cmake c_compiler: clang cxx_compiler: clang++ os: macos-latest - name: cmake-osx:gcc build_system: cmake c_compiler: gcc cxx_compiler: g++ os: macos-latest - name: cmake-ios:clang build_system: cmake c_compiler: clang cxx_compiler: clang++ os: macos-latest skip_tests: true # TODO(eustas): run tests in a simulator cmake_args: >- -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 - name: cmake-win64:msvc-rel build_system: cmake cmake_config: Release os: windows-latest - name: cmake-win64:msvc-dbg build_system: cmake cmake_config: Debug os: windows-latest - name: fuzz:clang build_system: fuzz c_compiler: clang cxx_compiler: clang++ - name: python3.10:clang build_system: python python_version: "3.10" c_compiler: clang cxx_compiler: clang++ - name: python3.14:clang build_system: python python_version: "3.14" c_compiler: clang cxx_compiler: clang++ - name: python3.14t:clang build_system: python python_version: "3.14t" c_compiler: clang cxx_compiler: clang++ - name: python3.14-win build_system: python python_version: "3.14" os: windows-latest - name: maven build_system: maven - name: bazel:root build_system: bazel bazel_project: . - name: bazel:go build_system: bazel bazel_project: go - name: bazel:java build_system: bazel bazel_project: java - name: bazel:research build_system: bazel bazel_project: research - name: bazel-osx:root build_system: bazel bazel_project: . os: macos-latest - name: bazel-osx:go build_system: bazel bazel_project: go os: macos-latest - name: bazel-osx:java build_system: bazel bazel_project: java os: macos-latest - name: bazel-osx:research build_system: bazel bazel_project: research os: macos-latest - name: bazel-win:root build_system: bazel bazel_project: . os: windows-latest # TODO(eustas): restore when go is fixed #- name: bazel-win:go # build_system: bazel # bazel_project: go # os: windows-latest # TODO(eustas): restore when kotlin is fixed #- name: bazel-win:java # build_system: bazel # bazel_project: java # os: windows-latest - name: bazel-win:research build_system: bazel bazel_project: research os: windows-latest env: CC: ${{ matrix.c_compiler || 'gcc' }} CXX: ${{ matrix.cxx_compiler || 'gcc' }} steps: - name: Harden Runner uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - name: Install extra deps @ Ubuntu if: ${{ runner.os == 'Linux' }} # Already installed: bazel, clang{13-15}, cmake, gcc{9.5-13.1}, java{8,11,17,21}, maven, python{3.10} run: | EXTRA_PACKAGES="${{ matrix.extra_apt_pkgs || '' }}" sudo apt update sudo apt install -y ${EXTRA_PACKAGES} - name: Checkout the source uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: submodules: false fetch-depth: 1 persist-credentials: false - name: Configure / Build / Test with CMake if: ${{ matrix.build_system == 'cmake' }} run: | export ASAN_OPTIONS=detect_leaks=0 declare -a CMAKE_OPTIONS=(${{ matrix.cmake_args || '' }}) CMAKE_OPTIONS+=("-DCMAKE_VERBOSE_MAKEFILE=ON") [ ! -z '${{ matrix.c_compiler || '' }}' ] && CMAKE_OPTIONS+=(-DCMAKE_C_COMPILER='${{ matrix.c_compiler }}') [ ! -z '${{ matrix.cxx_compiler || '' }}' ] && CMAKE_OPTIONS+=(-DCMAKE_CXX_COMPILER='${{ matrix.cxx_compiler }}') [ ! -z '${{ matrix.sanitizer || '' }}' ] && CMAKE_OPTIONS+=(-DENABLE_SANITIZER='${{ matrix.sanitizer }}') declare -a CMAKE_BUILD_OPTIONS=() [ ! -z '${{ matrix.cmake_config || '' }}' ] && CMAKE_BUILD_OPTIONS+=(--config '${{ matrix.cmake_config }}') declare -a CMAKE_TEST_OPTIONS=() [ ! -z '${{ matrix.cmake_config || '' }}' ] && CMAKE_TEST_OPTIONS+=(-C '${{ matrix.cmake_config }}') cmake -B out . ${CMAKE_OPTIONS[*]} -DCMAKE_C_FLAGS='${{ matrix.c_flags || '' }}' cmake --build out ${CMAKE_BUILD_OPTIONS[*]} cd out [ ! -z '${{ matrix.skip_tests || '' }}' ] || ctest ${CMAKE_TEST_OPTIONS[*]} cd .. - name: Quick Fuzz if: ${{ matrix.build_system == 'fuzz' }} run: | mkdir ${RUNNER_TEMP}/decode_corpora unzip java/org/brotli/integration/fuzz_data.zip -d ${RUNNER_TEMP}/decode_corpora cd ${GITHUB_WORKSPACE}/c/fuzz bazelisk build --config=asan-libfuzzer :decode_fuzzer for f in `ls ${RUNNER_TEMP}/decode_corpora` do echo "Testing $f" ./bazel-bin/decode_fuzzer_bin ${RUNNER_TEMP}/decode_corpora/$f done - name: Build with Bazel if: ${{ matrix.build_system == 'bazel' }} run: | cd ${GITHUB_WORKSPACE}/${{ matrix.bazel_project }} bazelisk build -c opt ...:all --java_runtime_version=remotejdk_21 - name: Fix symlinks for Bazel (Windows) if: ${{ matrix.build_system == 'bazel' && runner.os == 'Windows' && matrix.bazel_project == 'java' }} shell: python run: | import fnmatch import os import os.path from shutil import copyfile os.chdir('${{ matrix.bazel_project }}') print('Searching for manifests in ' + os.getcwd()) matches = [] for root, dirnames, filenames in os.walk('bazel-bin\\org\\brotli'): for filename in fnmatch.filter(filenames, '*.runfiles_manifest'): matches.append(os.path.join(root, filename)) for match in matches: print('Scanning manifest ' + match) runfiles = match[:-len('_manifest')] with open(match) as manifest: for entry in manifest: entry = entry.strip() if not entry.startswith("_main"): continue if entry.startswith("_main/external"): continue (alias, space, link) = entry.partition(' ') if alias.endswith('.jar') or alias.endswith('.exe'): continue link = link.replace('/', '\\') alias = alias.replace('/', '\\') dst = os.path.join(runfiles, alias) if not os.path.exists(dst): print(link + ' -> ' + dst) parent = os.path.dirname(dst) if not os.path.exists(parent): os.makedirs(parent) copyfile(link, dst) print('Finished resolving symlinks') - name: Test with Bazel if: ${{ matrix.build_system == 'bazel' }} run: | cd ${GITHUB_WORKSPACE}/${{ matrix.bazel_project }} bazelisk query "tests(...)" --output=label > ${RUNNER_TEMP}/tests.lst [ -s ${RUNNER_TEMP}/tests.lst ] && bazelisk test -c opt ...:all --java_runtime_version=remotejdk_21 bazelisk clean - name: Build / Test with Maven if: ${{ matrix.build_system == 'maven' }} run: | export MAVEN_OPTS=-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn cd java/org/brotli mvn -B install # TODO(eustas): nuke maven build? # cd integration # mvn -B verify - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 if: ${{ matrix.build_system == 'python' }} with: python-version: ${{ matrix.python_version }} # TODO(eustas): use modern setuptools (split out testing) - name: Build / Test with Python if: ${{ matrix.build_system == 'python' }} run: | python -VV pip install "setuptools>=70.0.0" pytest python setup.py build_ext --inplace pytest ./python/tests build_test_dotnet: name: Build and test with .NET runs-on: ubuntu-latest steps: - name: Checkout the source uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: submodules: false fetch-depth: 1 persist-credentials: false - name: Build / Test run: | cd csharp dotnet build brotlidec.csproj --configuration Release dotnet test brotlidec.Tests.csproj