diff --git a/.github/actions/setup-build/action.yml b/.github/actions/setup-build/action.yml new file mode 100644 index 00000000..867dc53e --- /dev/null +++ b/.github/actions/setup-build/action.yml @@ -0,0 +1,585 @@ +name: setup-build +description: >- + Set up the build environment by installing necessary tools and dependencies. + When necessary, it sets CPATH, LIBRARY_PATH, LD_LIBRARY_PATH, FORMPATH, + DISTNAME and CONFIG_ARGS, and runs autoreconf or extracts a tar.gz archive, + followed by executing ./configure. +inputs: + features: + description: A list of features to enable, separated by spaces. To disable a feature, prefix it with "no". + required: false + default: '' + flint_version: + description: FLINT version to build. + required: false + default: '3.3.1' + +runs: + using: composite + steps: + - name: Initialize setup + id: setup + env: + available_features: >- + form=false tform=false parform=false vorm=false tvorm=false parvorm=false + flint=true ginac=false gmp=true mpfr=true zlib=true zstd=true + mpich=false openmpi=false + bash=false msys2=false debian=false container=false + untar=false autoreconf=false configure=true deploy=false + coverage=false hyperfine=false valgrind=false + build_flint=false + automake=false diffutils=false gcc=true git=false ruby=true wget=false + latex=false latex2html=false + formlib=false color=false forcer=false series=false + # NOTE: Some features and OS image combinations are not implemented. + shell: bash + run: | + ### Initialize setup ### + + # First, parse the input. + + available_features=$(echo "$available_features" | awk '{$1=$1; print}') + + feature_names='' + for entry in $available_features; do + # Get "name=value". + feat_name=$(echo "$entry" | cut -d '=' -f 1) + feat_value=$(echo "$entry" | cut -d '=' -f 2) + feature_names="$feature_names $feat_name" + # Initialize the feature variable. + eval "feat_${feat_name}=${feat_value}" + done + feature_names=$(echo "$feature_names" | awk '{$1=$1; print}') + + input_features=$(echo "${{ inputs.features }}" | awk '{$1=$1; print}') + feature_pattern='^('$(echo "$feature_names" | tr ' ' '|')')$' + no_feature_pattern='^('$(echo "no$feature_names" | sed 's/ /|no/g')')$' + + for feat in $input_features; do + if [[ $feat =~ $feature_pattern ]]; then + eval "feat_${feat}=true" + elif [[ $feat =~ $no_feature_pattern ]]; then + feat=${feat#no} + eval "feat_${feat}=false" + else + echo "Error: unknown feature: $feat" >&2 + exit 1 + fi + done + + # Some features are enabled automatically, + # while others may require extra setup. + + has_scalar=false + has_threaded=false + has_mpi=false + has_bin=false + if $feat_form || $feat_vorm; then + has_scalar=true + fi + if $feat_tform || $feat_tvorm; then + has_threaded=true + fi + if $feat_parform || $feat_parvorm; then + has_mpi=true + fi + if $has_scalar || $has_threaded || $has_mpi; then + has_bin=true + fi + + if ! $has_bin; then + feat_flint=false + feat_ginac=false + feat_gmp=false + feat_mpfr=false + feat_zlib=false + feat_zstd=false + fi + + if $has_mpi && ! $feat_mpich && ! $feat_openmpi; then + # Use OpenMPI by default because MPICH is broken on Ubuntu 24.04. + # See: https://bugs.launchpad.net/ubuntu/+source/mpich/+bug/2072338 + feat_openmpi=true + fi + + # Unfortunately, FLINT packages in many distributions lack a static + # library, as it is not built by default. These packages are also often + # outdated (version < 3.2.0). In such cases, we build FLINT from source. + if $feat_flint; then + if [[ "${{ runner.os }}" == "macOS" ]] && ! $feat_deploy; then + : + else + feat_build_flint=true + fi + fi + + if [ -f /etc/os-release ] && grep -qi '^ID=debian' /etc/os-release; then + feat_debian=true + fi + + if [ -f /.dockerenv ]; then + feat_container=true + fi + + if [ ! -f configure.ac ] && ls form-*.tar.gz 1>/dev/null 2>&1; then + feat_untar=true + fi + + if [ ! -f configure ] && [ -f configure.ac ]; then + feat_autoreconf=true + fi + + if $feat_formlib; then + feat_color=true + feat_forcer=true + feat_series=true + fi + + if $feat_color || $feat_forcer || $feat_series; then + feat_formlib=true + items='' + $feat_color && items="$items-color-1.0.0" + $feat_forcer && items="$items-forcer-1.0.0" + $feat_series && items="$items-series-1.0.0" + echo "formlib_key=formlib$items" >>"$GITHUB_OUTPUT" + echo "formlib_restore_keys=formlib-" >>"$GITHUB_OUTPUT" + echo "FORMPATH=${{ github.workspace }}/formlib" >>"$GITHUB_ENV" + fi + + # Dependencies. + + if $build_feat_flint; then + feat_diffutils=true + feat_gcc=true + feat_mpfr=true + feat_wget=true + fi + + if $feat_formlib; then + feat_wget=true + fi + + if $feat_autoreconf; then + feat_automake=true + feat_git=true + fi + + # Output the features (without "feat_" prefix). + + for feat in $feature_names; do + value=$(eval "echo \$feat_${feat}") + echo " $feat=$value" + echo "$feat=$value" >>"$GITHUB_OUTPUT" + done + + # Construct arguments for the configure script. + + args='--disable-dependency-tracking' + + if $has_scalar; then + args="$args --enable-scalar" + else + args="$args --disable-scalar" + fi + if $has_threaded; then + args="$args --enable-threaded" + else + args="$args --disable-threaded" + fi + if $has_mpi; then + args="$args --enable-parform" + else + args="$args --disable-parform" + fi + + if $feat_vorm || $feat_tvorm || $feat_parvorm; then + args="$args --enable-debug" + fi + + if $feat_coverage; then + args="$args --enable-coverage" + fi + + if $has_bin; then + if $feat_deploy; then + # Avoid compiler optimizations specific to the build host. + args="$args --disable-native" + # Enable static linking whenever possible. + if [[ "${{ runner.os }}" != "macOS" ]]; then + args="$args --enable-static-link" + fi + fi + if [[ "${{ runner.os }}" == "Windows" ]]; then + args="$args --with-api=windows" + else + args="$args --with-api=posix" + fi + else + # This avoids checking optimization flags. + args="$args --disable-native" + fi + + if $feat_gmp; then + args="$args --with-gmp" + else + args="$args --without-gmp" + fi + + if $feat_mpfr; then + args="$args --with-mpfr" + else + args="$args --without-mpfr" + fi + + if $feat_zlib; then + args="$args --with-zlib" + else + args="$args --without-zlib" + fi + + if $feat_zstd; then + args="$args --with-zstd" + else + args="$args --without-zstd" + fi + + if $feat_flint; then + args="$args --with-flint" + else + args="$args --without-flint" + fi + + if $feat_ginac; then + args="$args --with-ginac" + # else + # args="$args --without-ginac" + fi + + echo "config_args=$args" >>"$GITHUB_OUTPUT" + + if ! $feat_configure; then + echo "CONFIG_ARGS=$args" >>"$GITHUB_ENV" + fi + + # Determine DISTNAME if possible. + + if [ -f ./scripts/git-version-gen.sh ] && command -v git >/dev/null 2>&1; then + echo "DISTNAME=form-$(./scripts/git-version-gen.sh -r | sed '2q;d' | sed 's/^v//')" >>"$GITHUB_ENV" + fi + + - name: Install dependencies (Ubuntu) + if: runner.os == 'Linux' && steps.setup.outputs.container == 'false' + uses: awalsh128/cache-apt-pkgs-action@a605dbde2ac49a823c9c87ad58491b51848bf355 # for empty_packages_behavior + with: + # We assume libgmp-dev and zlib1g-dev are always installed. + packages: >- + ${{ steps.setup.outputs.hyperfine == 'true' && 'hyperfine' || '' }} + ${{ steps.setup.outputs.coverage == 'true' && 'lcov' || '' }} + ${{ steps.setup.outputs.ginac == 'true' && 'libginac-dev' || '' }} + ${{ steps.setup.outputs.mpfr == 'true' && 'libmpfr-dev' || '' }} + ${{ steps.setup.outputs.zstd == 'true' && 'libzstd-dev' || '' }} + ${{ steps.setup.outputs.valgrind == 'true' && 'valgrind' || '' }} + version: 1.0 + empty_packages_behavior: ignore + + # awalsh128/cache-apt-pkgs-action does not work for MPI. + # See: https://github.com/awalsh128/cache-apt-pkgs-action/issues/57#issuecomment-1304062077 + - name: Install MPI if necessary + if: >- + runner.os == 'Linux' + && steps.setup.outputs.container == 'false' + && (steps.setup.outputs.mpich == 'true' || steps.setup.outputs.openmpi == 'true') + shell: bash + run: | + ### Install MPI ### + + sudo apt-get update + sudo apt-get install -y -q \ + ${{ steps.setup.outputs.mpich == 'true' && 'libmpich-dev' || '' }} \ + ${{ steps.setup.outputs.openmpi == 'true' && 'libopenmpi-dev' || '' }} + + # Currently, cache-apt-pkgs-action does not work for LaTeX. + # See: https://github.com/awalsh128/cache-apt-pkgs-action/issues/57 + - name: Install LaTeX + if: runner.os == 'Linux' && (steps.setup.outputs.latex == 'true' || steps.setup.outputs.latex2html == 'true') + shell: bash + run: | + ### Install LaTeX ### + + sudo apt-get update + sudo apt-get install -y -q \ + ${{ steps.setup.outputs.latex == 'true' && 'texlive-latex-extra' || '' }} \ + ${{ steps.setup.outputs.latex2html == 'true' && 'latex2html' || '' }} + + # Because we use i386/debian containers, here we do not assume that + # awalsh128/cache-apt-pkgs-action works properly. + # See: https://github.com/actions/cache/issues/675 + - name: Install dependencies (Debian) + if: steps.setup.outputs.debian == 'true' && steps.setup.outputs.container == 'true' + shell: bash + run: | + ### Install dependencies ### + + apt-get update + apt-get install -y -q make \ + ${{ steps.setup.outputs.automake == 'true' && 'automake' || '' }} \ + ${{ steps.setup.outputs.gcc == 'true' && 'g++' || '' }} \ + ${{ steps.setup.outputs.git == 'true' && 'git' || '' }} \ + ${{ steps.setup.outputs.hyperfine == 'true' && 'hyperfine' || '' }} \ + ${{ steps.setup.outputs.coverage == 'true' && 'lcov' || '' }} \ + ${{ steps.setup.outputs.ginac == 'true' && 'libginac-dev' || '' }} \ + ${{ steps.setup.outputs.gmp == 'true' && 'libgmp-dev' || '' }} \ + ${{ steps.setup.outputs.mpfr == 'true' && 'libmpfr-dev' || '' }} \ + ${{ steps.setup.outputs.zstd == 'true' && 'libzstd-dev' || '' }} \ + ${{ steps.setup.outputs.ruby == 'true' && 'ruby' || '' }} \ + ${{ steps.setup.outputs.valgrind == 'true' && 'valgrind' || '' }} \ + ${{ steps.setup.outputs.wget == 'true' && 'wget' || '' }} \ + ${{ steps.setup.outputs.zlib == 'true' && 'zlib1g-dev' || '' }} + + - name: Install dependencies (macOS) + if: >- + runner.os == 'macOS' && ( + steps.setup.outputs.automake == 'true' + || (steps.setup.outputs.flint == 'true' && steps.setup.outputs.build_flint == 'false') + || steps.setup.outputs.hyperfine == 'true' + ) + shell: bash + run: | + ### Install dependencies ### + + brew install \ + ${{ steps.setup.outputs.automake == 'true' && 'automake' || '' }} \ + ${{ (steps.setup.outputs.flint == 'true' && steps.setup.outputs.build_flint == 'false') && 'flint' || '' }} \ + ${{ steps.setup.outputs.hyperfine == 'true' && 'hyperfine' || '' }} + + # --static fails on macOS but we want to statically link + # the brewed gmp. The linker supports neither -Wl,-static nor + # -l:libgmp.a to make partial static links possible. + # As a workaround, we make a library directory with libgmp.a + # but without libgmp.dylib so that the linker has to link libgmp.a. + # The same for other libraries. + # Note that the Homebrew installation path for Apple Silicon (arm64) + # differs from the one on macOS Intel (x86-64). + - name: Set up statically linked libraries (macOS) + if: runner.os == 'macOS' && steps.setup.outputs.deploy == 'true' + shell: bash + run: | + ### Set up statically linked libraries ### + + mkdir static-lib + if [ "${{ runner.arch }}" == "ARM64" ]; then + brew_dir=/opt/homebrew/opt + # Include directories, not located in the usual places, + # must be explicitly appended to the include paths. + CPATH="$brew_dir/gmp/include:$brew_dir/mpfr/include:$brew_dir/zstd/include${CPATH:+":$CPATH"}" + echo "CPATH=$CPATH" >>"$GITHUB_ENV" + else + brew_dir=/usr/local/opt + fi + ln -s "$brew_dir/gmp/lib/libgmp.a" static-lib/libgmp.a + ln -s "$brew_dir/mpfr/lib/libmpfr.a" static-lib/libmpfr.a + ln -s "$brew_dir/zstd/lib/libzstd.a" static-lib/libzstd.a + LIBRARY_PATH="${{ github.workspace }}/static-lib${LIBRARY_PATH:+":$LIBRARY_PATH"}" + echo "LIBRARY_PATH=$LIBRARY_PATH" >>"$GITHUB_ENV" + + - name: Set up Homebrew paths (macOS/arm64) + if: runner.os == 'macOS' && runner.arch == 'ARM64' && steps.setup.outputs.deploy == 'false' + shell: bash + run: | + ### Set up Homebrew paths ### + + brew_dir=/opt/homebrew/opt + CPATH="$brew_dir/flint/include:$brew_dir/gmp/include:$brew_dir/mpfr/include:$brew_dir/zstd/include${CPATH:+":$CPATH"}" + echo "CPATH=$CPATH" >>"$GITHUB_ENV" + LIBRARY_PATH="$brew_dir/flint/lib:$brew_dir/gmp/lib:$brew_dir/mpfr/lib:$brew_dir/zstd/lib${LIBRARY_PATH:+":$LIBRARY_PATH"}" + echo "LIBRARY_PATH=$LIBRARY_PATH" >>"$GITHUB_ENV" + LD_LIBRARY_PATH="$brew_dir/flint/lib:$brew_dir/gmp/lib:$brew_dir/mpfr/lib:$brew_dir/zstd/lib${LD_LIBRARY_PATH:+":$LD_LIBRARY_PATH"}" + echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH" >>"$GITHUB_ENV" + + # NOTE: On MSYS2, autoconf (= autoconf-wrapper) is not listed as + # a dependency of automake (= automake-wrapper). + # Both need to be installed explicitly. + - name: Install dependencies (Windows/x86_64) + if: runner.os == 'Windows' && runner.arch == 'X64' && steps.setup.outputs.msys2 == 'true' + uses: msys2/setup-msys2@v2 + with: + update: true + msystem: mingw64 + install: >- + make + ${{ steps.setup.outputs.automake == 'true' && 'autoconf automake' || '' }} + ${{ steps.setup.outputs.git == 'true' && 'git' || '' }} + ${{ steps.setup.outputs.diffutils == 'true' && 'mingw-w64-x86_64-diffutils' || '' }} + ${{ steps.setup.outputs.gcc == 'true' && 'mingw-w64-x86_64-gcc' || '' }} + ${{ steps.setup.outputs.gmp == 'true' && 'mingw-w64-x86_64-gmp' || '' }} + ${{ steps.setup.outputs.hyperfine == 'true' && 'mingw-w64-x86_64-hyperfine' || '' }} + ${{ steps.setup.outputs.mpfr == 'true' && 'mingw-w64-x86_64-mpfr' || '' }} + ${{ steps.setup.outputs.ruby == 'true' && 'mingw-w64-x86_64-ruby' || '' }} + ${{ steps.setup.outputs.zlib == 'true' && 'mingw-w64-x86_64-zlib' || '' }} + ${{ steps.setup.outputs.zstd == 'true' && 'mingw-w64-x86_64-zstd' || '' }} + + - name: Install dependencies (Windows/arm64) + if: runner.os == 'Windows' && runner.arch == 'ARM64' && steps.setup.outputs.msys2 == 'true' + uses: msys2/setup-msys2@v2 + with: + update: true + msystem: clangarm64 + install: >- + m4 + make + ${{ steps.setup.outputs.automake == 'true' && 'autoconf automake' || '' }} + ${{ steps.setup.outputs.git == 'true' && 'git' || '' }} + ${{ steps.setup.outputs.diffutils == 'true' && 'mingw-w64-clang-aarch64-diffutils' || '' }} + ${{ steps.setup.outputs.gcc == 'true' && 'mingw-w64-clang-aarch64-gcc-compat' || '' }} + ${{ steps.setup.outputs.gmp == 'true' && 'mingw-w64-clang-aarch64-gmp' || '' }} + ${{ steps.setup.outputs.hyperfine == 'true' && 'mingw-w64-clang-aarch64-hyperfine' || '' }} + ${{ steps.setup.outputs.mpfr == 'true' && 'mingw-w64-clang-aarch64-mpfr' || '' }} + ${{ steps.setup.outputs.ruby == 'true' && 'mingw-w64-clang-aarch64-ruby' || '' }} + ${{ steps.setup.outputs.zlib == 'true' && 'mingw-w64-clang-aarch64-zlib' || '' }} + ${{ steps.setup.outputs.zstd == 'true' && 'mingw-w64-clang-aarch64-zstd' || '' }} + + - name: Get cache key for the image + id: cache_key + if: steps.setup.outputs.build_flint == 'true' + shell: ${{ steps.setup.outputs.msys2 == 'true' && 'msys2 {0}' || 'bash' }} + run: | + ### Get cache key for the image ### + + # See: https://github.com/actions/upload-artifact/issues/231 + echo "image_key=$ImageOS-$ImageVersion" >>"$GITHUB_OUTPUT" + + - name: Cache FLINT + id: cache-flint + if: steps.setup.outputs.build_flint == 'true' + uses: actions/cache@v4 + with: + path: lib/flint + # Here, we set a conservative cache key so that the cache is not reused + # when the version or environment changes even slightly. + key: flint-${{ inputs.flint_version }}-${{ runner.os }}-${{ runner.arch }}-${{ steps.cache_key.outputs.image_key }} + + # Note that we always set --enable-static so that release and non-release + # builds can share the same cache. + - name: Build FLINT unless cached + if: steps.setup.outputs.build_flint == 'true' && steps.cache-flint.outputs.cache-hit != 'true' + shell: ${{ steps.setup.outputs.msys2 == 'true' && 'msys2 {0}' || 'bash' }} + run: | + ### Build FLINT ### + + mkdir -p build/flint + cd build/flint + # We use the tarball from GitHub Releases. + # See: https://github.com/flintlib/flint/issues/2311 + wget "https://github.com/flintlib/flint/releases/download/v${{ inputs.flint_version }}/flint-${{ inputs.flint_version }}.tar.gz" + tar -xf "flint-${{ inputs.flint_version }}.tar.gz" + rm "flint-${{ inputs.flint_version }}.tar.gz" + cd "flint-${{ inputs.flint_version }}" + ./configure --prefix="${{ github.workspace }}/lib/flint" --host="$(gcc -dumpmachine)" --enable-static + make -j 4 + make install + + - name: Set FLINT paths + if: steps.setup.outputs.build_flint == 'true' + shell: ${{ steps.setup.outputs.msys2 == 'true' && 'msys2 {0}' || 'bash' }} + run: | + ### Set FLINT paths ### + + CPATH="${{ github.workspace }}/lib/flint/include${CPATH:+":$CPATH"}" + echo "CPATH=$CPATH" >>"$GITHUB_ENV" + LIBRARY_PATH="${{ github.workspace }}/lib/flint/lib${LIBRARY_PATH:+":$LIBRARY_PATH"}" + echo "LIBRARY_PATH=$LIBRARY_PATH" >>"$GITHUB_ENV" + if ${{ steps.setup.outputs.deploy }}; then + if [[ "${{ runner.os }}" == "macOS" ]]; then + # For static linking. + LIBRARY_PATH="${{ github.workspace }}/static-lib:$LIBRARY_PATH" + echo "LIBRARY_PATH=$LIBRARY_PATH" >>"$GITHUB_ENV" + ln -s "${{ github.workspace }}/lib/flint/lib/libflint.a" static-lib/libflint.a + fi + else + if [[ "${{ runner.os }}" != "Windows" ]]; then + LD_LIBRARY_PATH="${{ github.workspace }}/lib/flint/lib${LD_LIBRARY_PATH:+":$LD_LIBRARY_PATH"}" + echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH" >>"$GITHUB_ENV" + else + # MSYS2 ignores modifications to $PATH via standard methods. + # See: https://github.com/msys2/setup-msys2/issues/98 + # As a simple workaround, copy the DLLs to a directory in the PATH. + cp lib/flint/bin/libflint*.dll /mingw64/bin/ + fi + fi + + - name: Cache FORM library + id: cache-formlib + if: steps.setup.outputs.formlib == 'true' + uses: actions/cache@v4 + with: + path: formlib + key: ${{ steps.setup.outputs.formlib_key }} + restore-keys: ${{ steps.setup.outputs.formlib_restore_keys }} + + - name: Install FORM libraries if necessary + if: steps.setup.outputs.formlib == 'true' && steps.cache-formlib.outputs.cache-hit != 'true' + shell: ${{ steps.setup.outputs.msys2 == 'true' && 'msys2 {0}' || 'bash' }} + run: | + ### Install FORM libraries ### + + mkdir -p formlib + if ${{ steps.setup.outputs.color }} && [ ! -f formlib/color-1.0.0 ]; then + rm -rf formlib/color* + wget https://github.com/form-dev/form-packages/archive/refs/tags/v1.0.0.tar.gz -O - | tar -x --gzip + mv form-packages-1.0.0/color/color.h formlib/ + rm -rf form-packages-1.0.0 + touch formlib/color-1.0.0 + fi + if ${{ steps.setup.outputs.forcer }} && [ ! -f formlib/forcer-1.0.0 ]; then + rm -rf formlib/forcer* + wget https://github.com/benruijl/forcer/archive/v1.0.0.tar.gz -O - | tar -x --gzip + mv forcer-1.0.0/forcer.h formlib/ + mv forcer-1.0.0/forcer formlib/ + rm -rf forcer-1.0.0 + touch formlib/forcer-1.0.0 + fi + if ${{ steps.setup.outputs.series }} && [ ! -f formlib/series-1.0.0 ]; then + rm -rf formlib/series* + wget https://github.com/a-maier/series/releases/download/1.0.0/series.h -P formlib + touch formlib/series-1.0.0 + fi + + # Fix dubious ownership in containers for Git operations. + # See: https://github.com/actions/runner/issues/2033#issuecomment-1204205989 + - name: Fix dubious ownership + if: steps.setup.outputs.container == 'true' + shell: bash + run: | + ### Fix dubious ownership + + chown -R $(id -u):$(id -g) $PWD + + - name: Uncompress tarball + if: steps.setup.outputs.untar == 'true' + shell: ${{ steps.setup.outputs.msys2 == 'true' && 'msys2 {0}' || 'bash' }} + run: | + ### Uncompress tarball ### + + echo "DISTNAME=$(basename form-*.tar.gz .tar.gz)" >>"$GITHUB_ENV" + + tar -xf form-*.tar.gz --strip-components 1 + rm *.tar.gz + + - name: Run Autoreconf + if: steps.setup.outputs.autoreconf == 'true' + shell: ${{ steps.setup.outputs.msys2 == 'true' && 'msys2 {0}' || 'bash' }} + run: | + ### Run Autoreconf ### + + autoreconf -i + + - name: Configure + if: steps.setup.outputs.configure == 'true' + shell: ${{ steps.setup.outputs.msys2 == 'true' && 'msys2 {0}' || 'bash' }} + run: | + ### Configure ### + + if ! ./configure ${{ steps.setup.outputs.config_args }}; then + cat config.log >&2 + exit 1 + fi diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 92f85f06..7234647a 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -20,21 +20,20 @@ jobs: with: fetch-depth: 0 # ensures a reachable tag - - name: Determine distname - run: | - echo "distname=form-$(./scripts/git-version-gen.sh -r | sed '2q;d' | sed 's/^v//')" >> $GITHUB_ENV + - name: Set up build + uses: ./.github/actions/setup-build - name: Build tarball distribution run: | - autoreconf -i - ./configure --disable-dependency-tracking --disable-scalar --disable-threaded --disable-native --without-gmp --without-zlib - make distdir=$distname dist-gzip + distname="${{ env.DISTNAME }}" + echo "distname=$distname" >>"$GITHUB_ENV" + make distdir="$distname" dist-gzip - name: Print tarball information run: | - ls -l $distname.tar.gz - file $distname.tar.gz - tar -tf $distname.tar.gz + ls -l "$distname.tar.gz" + file "$distname.tar.gz" + tar -tf "$distname.tar.gz" - name: Upload tarball as artifact uses: actions/upload-artifact@v4 @@ -53,8 +52,6 @@ jobs: defaults: run: shell: ${{ matrix.shell }} {0} - env: - FLINT_VERSION: 3.3.0 strategy: fail-fast: false matrix: @@ -77,123 +74,21 @@ jobs: - {os: windows-2022, shell: msys2, bin: form} - {os: windows-2022, shell: msys2, bin: tform} steps: - - name: Install dependencies (Ubuntu) - if: runner.os == 'Linux' - uses: awalsh128/cache-apt-pkgs-action@v1 - with: - packages: libmpfr-dev libzstd-dev - # We need to handle a bug that may cause cache key conflicts. - # See: https://github.com/awalsh128/cache-apt-pkgs-action/pull/150 - version: ${{ runner.arch }}-1.0 - - - name: Install dependencies (Windows) - if: runner.os == 'Windows' - uses: msys2/setup-msys2@v2 + - name: Checkout repository + uses: actions/checkout@v4 with: - update: true - install: >- - make - mingw-w64-x86_64-gcc - mingw-w64-x86_64-gmp - mingw-w64-x86_64-mpfr - mingw-w64-x86_64-ruby - mingw-w64-x86_64-zlib - - # --static fails on macOS but we want to statically link - # the brewed gmp. The linker supports neither -Wl,-static nor - # -l:libgmp.a to make partial static links possible. - # As a workaround, we make a library directory with libgmp.a - # but without libgmp.dylib so that the linker has to link libgmp.a. - # The same for other libraries. - # Note that the Homebrew installation path for Apple Silicon (arm64) - # differs from the one on macOS Intel (x86-64). - - name: Set up statically linked libraries (macOS) - if: runner.os == 'macOS' - run: | - mkdir static-lib - if [ "$RUNNER_ARCH" == "ARM64" ]; then - brew_dir=/opt/homebrew - # Include directories, not located in the usual places, - # must be explicitly appended to the include paths. - export CPATH="$brew_dir/opt/gmp/include:$brew_dir/opt/mpfr/include:/opt/homebrew/opt/zstd/include${CPATH:+":$CPATH"}" - echo "CPATH=$CPATH" >>"$GITHUB_ENV" - else - brew_dir=/usr/local - fi - ln -s $brew_dir/opt/gmp/lib/libgmp.a static-lib/libgmp.a - ln -s $brew_dir/opt/mpfr/lib/libmpfr.a static-lib/libmpfr.a - ln -s $brew_dir/opt/zstd/lib/libzstd.a static-lib/libzstd.a - export LIBRARY_PATH="$(pwd)/static-lib${LIBRARY_PATH:+":$LIBRARY_PATH"}" - echo "LIBRARY_PATH=$LIBRARY_PATH" >>"$GITHUB_ENV" - - - name: Get cache key - run: | - # See: https://github.com/actions/upload-artifact/issues/231 - echo "ImageOS=$ImageOS" >>"$GITHUB_ENV" - echo "ImageVersion=$ImageVersion" >>"$GITHUB_ENV" - - - name: Cache FLINT - id: cache-flint - uses: actions/cache@v4 - with: - path: lib/flint - # Here, we set a conservative cache key so that the cache is not reused - # when the version or environment changes even slightly. - key: flint-${{ env.FLINT_VERSION }}-${{ runner.os }}-${{ runner.arch }}-${{ env.ImageOS }}-${{ env.ImageVersion }} - - # Unfortunately, the flint packages lack the static library, - # so we need to build it from source. - - name: Build FLINT unless cached - if: steps.cache-flint.outputs.cache-hit != 'true' - run: | - mkdir -p build/flint - cd build/flint - # See: https://github.com/flintlib/flint/issues/2311 - wget https://github.com/flintlib/flint/releases/download/v$FLINT_VERSION/flint-$FLINT_VERSION.tar.gz - tar -xf *.tar.gz - rm *.tar.gz - cd flint-* - ./configure --prefix=$GITHUB_WORKSPACE/lib/flint --enable-static --disable-shared - make -j 4 - # Test temporarily disabled. - # See: https://github.com/flintlib/flint/issues/2058 - # make -j 4 check - make install - - - name: Set FLINT paths - run: | - export CPATH="$(pwd)/lib/flint/include${CPATH:+":$CPATH"}" - echo "CPATH=$CPATH" >>"$GITHUB_ENV" - export LIBRARY_PATH="$(pwd)/lib/flint/lib${LIBRARY_PATH:+":$LIBRARY_PATH"}" - echo "LIBRARY_PATH=$LIBRARY_PATH" >>"$GITHUB_ENV" + sparse-checkout: .github/actions + sparse-checkout-cone-mode: false - name: Download tarball uses: actions/download-artifact@v4 with: name: src - - name: Uncompress tarball - run: | - tar -xf *.tar.gz --strip-components 1 - rm *.tar.gz - - - name: Configure - run: | - opts='--disable-dependency-tracking --disable-scalar --disable-threaded --disable-native --enable-static-link --with-gmp --with-zlib --with-zstd --with-flint' - case ${{ matrix.bin }} in - form) opts="$opts --enable-scalar";; - tform) opts="$opts --enable-threaded";; - esac - if [ "$RUNNER_OS" == "macOS" ]; then - opts="$opts --disable-static-link" - fi - if [ "$RUNNER_OS" == "Windows" ]; then - opts="$opts --with-api=windows" - fi - if ! ./configure $opts; then - cat config.log - exit 1 - fi + - name: Set up build + uses: ./.github/actions/setup-build + with: + features: ${{ matrix.bin }} ${{ matrix.shell }} deploy - name: Build id: build @@ -211,24 +106,24 @@ jobs: continue-on-error: ${{ runner.os == 'Windows' }} run: | binname=${{ matrix.bin }} - if [ "$RUNNER_OS" == "Windows" ]; then + if [ "${{ runner.os }}" == "Windows" ]; then binname=$binname.exe fi - ls -l sources/$binname - file sources/$binname - if [ "$RUNNER_OS" == "macOS" ]; then - otool -L sources/$binname - # Check if brewed libraries are statically linked. - if otool -L sources/$binname | grep -q '/usr/local/opt'; then - echo 'Error: failed to statically link brewed libraries' >&2 + ls -l "sources/$binname" + file "sources/$binname" + if [ "${{ runner.os }}" == "macOS" ]; then + otool -L "sources/$binname" + # Check if brewed/built libraries are statically linked. + if otool -L "sources/$binname" | grep -Eq '/usr/local/opt/|/opt/homebrew/opt/|/form/form/lib/'; then + echo 'Error: unexpected dependency on shared libraries' >&2 exit 1 fi fi - if [ "$RUNNER_OS" == "Windows" ]; then - ldd sources/$binname - # Check if MSYS2 DLLs are not linked. - if ldd sources/$binname | grep -q 'msys'; then - echo 'Error: failed to avoid to link with MSYS2 DLLs' >&2 + if [ "${{ runner.os }}" == "Windows" ]; then + ldd "sources/$binname" + # Check if MSYS2/built DLLs are not linked. + if ldd "sources/$binname" | grep -Eq 'msys|mingw|/form/form/lib/'; then + echo 'Error: unexpected dependency on DLLs' >&2 exit 1 fi fi @@ -249,44 +144,33 @@ jobs: needs: build-src runs-on: ubuntu-latest steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + sparse-checkout: .github/actions + sparse-checkout-cone-mode: false + - name: Download tarball uses: actions/download-artifact@v4 with: name: src - - name: Determine distname - run: | - echo "distname=$(basename *.tar.gz .tar.gz)-manual" >> $GITHUB_ENV - - - name: Uncompress tarball - run: | - tar -xf *.tar.gz --strip-components 1 - rm *.tar.gz - - # Currently, cache-apt-pkgs-action doesn't work for LaTeX. - # https://github.com/awalsh128/cache-apt-pkgs-action/issues/57 - # - name: Install LaTeX2HTML - # uses: awalsh128/cache-apt-pkgs-action@v1 - # with: - # packages: latex2html # shares the same cache with build-doc-html - # version: 1.0 - - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get -y install texlive-latex-extra + - name: Set up build + uses: ./.github/actions/setup-build + with: + features: latex - name: Build PDF file run: | - autoreconf -i - ./configure --disable-dependency-tracking --disable-scalar --disable-threaded --disable-native --without-gmp --without-zlib + distname="${{ env.DISTNAME }}-manual" + echo "distname=$distname" >>"$GITHUB_ENV" make pdf - cp doc/manual/manual.pdf $distname.pdf + mv doc/manual/manual.pdf "$distname.pdf" - name: Print document information run: | - ls -l $distname.pdf - file $distname.pdf + ls -l "$distname.pdf" + file "$distname.pdf" - name: Upload document as artifact uses: actions/upload-artifact@v4 @@ -302,37 +186,26 @@ jobs: needs: build-src runs-on: ubuntu-latest steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + sparse-checkout: .github/actions + sparse-checkout-cone-mode: false + - name: Download tarball uses: actions/download-artifact@v4 with: name: src - - name: Determine distname - run: | - echo "distname=$(basename *.tar.gz .tar.gz)-manual-html" >> $GITHUB_ENV - - - name: Uncompress tarball - run: | - tar -xf *.tar.gz --strip-components 1 - rm *.tar.gz - - # Currently, cache-apt-pkgs-action doesn't work for LaTeX. - # https://github.com/awalsh128/cache-apt-pkgs-action/issues/57 - # - name: Install LaTeX2HTML - # uses: awalsh128/cache-apt-pkgs-action@v1 - # with: - # packages: latex2html # shares the same cache with build-doc-pdf - # version: 1.0 - - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get -y install latex2html + - name: Set up build + uses: ./.github/actions/setup-build + with: + features: latex2html - name: Build HTML files run: | - autoreconf -i - ./configure --disable-dependency-tracking --disable-scalar --disable-threaded --disable-native --without-gmp --without-zlib + distname="${{ env.DISTNAME }}-manual-html" + echo "distname=$distname" >>"$GITHUB_ENV" make -C doc/manual latex2html ( cd doc/manual/manual @@ -340,7 +213,8 @@ jobs: # Print generated files. ls -A -C # Check if there are no unexpected files. - for f in $(ls -A); do + shopt -s nullglob + for f in * .*; do case "$f" in index.html|manual.html|manual.css|img*.svg) ;; @@ -351,14 +225,14 @@ jobs: esac done ) - cp -r doc/manual/manual $distname - tar -c $distname/* | gzip -c -9 > $distname.tar.gz + mv doc/manual/manual "$distname" + tar -c "$distname"/* | gzip -c -9 > "$distname.tar.gz" - name: Print file information run: | - ls -l $distname.tar.gz - file $distname.tar.gz - tar -tf $distname.tar.gz + ls -l "$distname.tar.gz" + file "$distname.tar.gz" + tar -tf "$distname.tar.gz" - name: Upload file as artifact uses: actions/upload-artifact@v4 @@ -384,37 +258,34 @@ jobs: with: path: artifacts - - name: Determine distname - run: | - echo "distname=$(basename artifacts/src/*.tar.gz .tar.gz)" >> $GITHUB_ENV - - name: Print all artifacts run: ls -l -R artifacts - name: Prepare distributions run: | + distname=$(basename artifacts/src/*.tar.gz .tar.gz) mkdir dist - mv artifacts/src/*.tar.gz dist - mv artifacts/doc-html/*.tar.gz dist - mv artifacts/doc-pdf/*.pdf dist + mv artifacts/src/*.tar.gz dist/ + mv artifacts/doc-html/*.tar.gz dist/ + mv artifacts/doc-pdf/*.pdf dist/ make_tar_gz() { - if ls artifacts/$2 >/dev/null 2>&1; then + if compgen -G "artifacts/$2" >/dev/null; then pkgname=$distname-$1 - mkdir $pkgname - mv artifacts/$2 $pkgname - chmod +x $pkgname/*form* - tar -c $pkgname/* | gzip -c -9 >dist/$pkgname.tar.gz - rm -rf $pkgname + mkdir "$pkgname" + mv artifacts/$2 "$pkgname"/ + chmod +x "$pkgname"/*form* + tar -c "$pkgname"/* | gzip -c -9 >"dist/$pkgname.tar.gz" + rm -rf "$pkgname" fi } make_zip() { - if ls artifacts/$2 >/dev/null 2>&1; then + if compgen -G "artifacts/$2" >/dev/null; then pkgname=$distname-$1 - mkdir $pkgname - mv artifacts/$2 $pkgname - chmod +x $pkgname/*form* - zip -9 dist/$pkgname.zip $pkgname/* - rm -rf $pkgname + mkdir "$pkgname" + mv artifacts/$2 "$pkgname"/ + chmod +x "$pkgname"/*form* + zip -9 "dist/$pkgname.zip" "$pkgname"/* + rm -rf "$pkgname" fi } make_tar_gz x86_64-linux '*-ubuntu-24.04/*form' @@ -423,13 +294,23 @@ jobs: make_tar_gz arm64-osx '*-macos-14/*form' make_zip x86_64-windows '*-windows-2022/*form.exe' - - name: Summarize files for distribution + - name: Summarize the distributions run: | - echo "Number of files: $(ls -1 dist | wc -l)" >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '| File Name | Size (bytes) |' >> $GITHUB_STEP_SUMMARY - echo '| --- | ---: |' >> $GITHUB_STEP_SUMMARY - ls -l dist | tail -n +2 | awk '{ printf "| %s | %s |\n", $9, $5 }' >> $GITHUB_STEP_SUMMARY + expected_count=8 + actual_count=$(find dist -type f | wc -l) + + { + echo "Number of files: $actual_count" + echo + echo '| File Name | Size (bytes) |' + echo '| --- | ---: |' + find dist -type f -printf "| %f | %s |\n" + } >>"$GITHUB_STEP_SUMMARY" + + if [[ $actual_count -ne $expected_count ]]; then + echo "Error: expected $expected_count files, but found $actual_count." >&2 + exit 1 + fi # Upload the distributions as an artifact, regardless of whether # the commit has a versioning tag. This makes checking and debugging easy. @@ -451,7 +332,7 @@ jobs: # a versioning tag. - name: Publish distributions if: startsWith(github.ref, 'refs/tags/v') - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 with: files: | dist/*.tar.gz diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b67ed099..37048a39 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -37,67 +37,19 @@ jobs: with: fetch-depth: 0 # ensures a reachable tag - - name: Install dependencies - uses: awalsh128/cache-apt-pkgs-action@v1 + - name: Set up build + uses: ./.github/actions/setup-build with: - packages: libflint-dev libmpfr-dev libzstd-dev - # We need to handle a bug that may cause cache key conflicts. - # See: https://github.com/awalsh128/cache-apt-pkgs-action/pull/150 - version: ${{ runner.arch }}-1.0 - - - name: Configure - run: | - opts='--disable-dependency-tracking' - case ${{ matrix.bin }} in - form|vorm) opts="$opts --enable-scalar --disable-threaded --disable-parform";; - tform|tvorm) opts="$opts --disable-scalar --enable-threaded --disable-parform";; - esac - case ${{ matrix.bin }} in - vorm|tvorm|parvorm) opts="$opts --enable-debug";; - esac - case "${{ matrix.flint }}" in - no) opts="$opts --without-flint";; - *) opts="$opts --with-flint";; - esac - opts="$opts --with-gmp --with-zlib --with-zstd" - autoreconf -i - ./configure $opts + features: >- + ${{ matrix.bin }} + ${{ matrix.flint == 'no' && 'noflint' || '' }} + ${{ matrix.test == 'extra' && 'formlib' || '' }} - name: Build run: make -C sources -j 4 ${{ matrix.bin }} - - name: Cache library - id: cache-formlib - if: contains(fromJson('["extra"]'), matrix.test) - uses: actions/cache@v4 - with: - path: formlib - key: formlib-${{ matrix.test }}-v2 - - - name: Install library if necessary - if: steps.cache-formlib.outputs.cache-hit != 'true' - run: | - mkdir -p formlib - case ${{ matrix.test }} in - extra) - # forcer library for the forcer test in extra - wget https://github.com/benruijl/forcer/archive/v1.0.0.tar.gz -O - | tar -x --gzip - mv forcer-1.0.0/forcer.h formlib - mv forcer-1.0.0/forcer formlib - rm -rf forcer-1.0.0 - # color library for the color test in extra - wget https://github.com/form-dev/form-packages/archive/refs/tags/v1.0.0.tar.gz -O - | tar -x --gzip - mv form-packages-1.0.0/color/color.h formlib - rm -rf form-packages-1.0.0 - # series library for test in extra - wget https://github.com/a-maier/series/releases/download/1.0.0/series.h -P formlib - ;; - esac - - name: Test run: ./check/check.rb ./sources/${{ matrix.bin }} --stat ${{ matrix.nthreads && format('-w{0}', matrix.nthreads) || '' }} ${{ matrix.timeout && format('--timeout {0}', matrix.timeout) || '' }} ${{ matrix.test != 'default' && format('-C {0}', matrix.test) || '' }} - env: - FORMPATH: ${{ github.workspace }}/formlib check-parform: name: Test (${{ matrix.test }}) for ${{ matrix.bin }}${{ matrix.nthreads && format(' -w{0}', matrix.nthreads) || '' }}${{ matrix.flint && format(' (flint - {0})', matrix.flint) || '' }} @@ -113,71 +65,19 @@ jobs: with: fetch-depth: 0 # ensures a reachable tag - - name: Install dependencies - uses: awalsh128/cache-apt-pkgs-action@v1 + - name: Set up build + uses: ./.github/actions/setup-build with: - packages: libflint-dev libmpfr-dev libzstd-dev - # We need to handle a bug that may cause cache key conflicts. - # See: https://github.com/awalsh128/cache-apt-pkgs-action/pull/150 - version: ${{ runner.arch }}-1.0 - - - name: Install MPI - run: | - sudo apt update - sudo apt install -y -q libopenmpi-dev - - - name: Configure - run: | - opts='--disable-dependency-tracking' - case ${{ matrix.bin }} in - parform|parvorm) opts="$opts --disable-scalar --disable-threaded --enable-parform";; - esac - case ${{ matrix.bin }} in - vorm|tvorm|parvorm) opts="$opts --enable-debug";; - esac - case "${{ matrix.flint }}" in - no) opts="$opts --without-flint";; - *) opts="$opts --with-flint";; - esac - opts="$opts --with-gmp --with-zlib --with-zstd" - autoreconf -i - ./configure $opts + features: >- + ${{ matrix.bin }} + ${{ matrix.flint == 'no' && 'noflint' || '' }} + ${{ matrix.test == 'extra' && 'formlib' || '' }} - name: Build run: make -C sources -j 4 ${{ matrix.bin }} - - name: Cache library - id: cache-formlib - if: contains(fromJson('["extra"]'), matrix.test) - uses: actions/cache@v4 - with: - path: formlib - key: formlib-${{ matrix.test }}-v2 - - - name: Install library if necessary - if: steps.cache-formlib.outputs.cache-hit != 'true' - run: | - mkdir -p formlib - case ${{ matrix.test }} in - extra) - # forcer library for the forcer test in extra - wget https://github.com/benruijl/forcer/archive/v1.0.0.tar.gz -O - | tar -x --gzip - mv forcer-1.0.0/forcer.h formlib - mv forcer-1.0.0/forcer formlib - rm -rf forcer-1.0.0 - # color library for the color test in extra - wget https://github.com/form-dev/form-packages/archive/refs/tags/v1.0.0.tar.gz -O - | tar -x --gzip - mv form-packages-1.0.0/color/color.h formlib - rm -rf form-packages-1.0.0 - # series library for test in extra - wget https://github.com/a-maier/series/releases/download/1.0.0/series.h -P formlib - ;; - esac - - name: Test run: ./check/check.rb ./sources/${{ matrix.bin }} --stat ${{ matrix.nthreads && format('-w{0}', matrix.nthreads) || '' }} ${{ matrix.timeout && format('--timeout {0}', matrix.timeout) || '' }} ${{ matrix.test != 'default' && format('-C {0}', matrix.test) || '' }} - env: - FORMPATH: ${{ github.workspace }}/formlib # Check memory errors (e.g., uninitialized values and memory leaks) # thoroughly by using Valgrind on Linux. To maximize the use of concurrent @@ -224,63 +124,20 @@ jobs: with: fetch-depth: 0 # ensures a reachable tag - - name: Install dependencies - uses: awalsh128/cache-apt-pkgs-action@v1 + - name: Set up build + uses: ./.github/actions/setup-build with: - packages: libflint-dev libmpfr-dev libzstd-dev valgrind - # We need to handle a bug that may cause cache key conflicts. - # See: https://github.com/awalsh128/cache-apt-pkgs-action/pull/150 - version: ${{ runner.arch }}-1.0 - - - name: Configure - run: | - opts='--disable-dependency-tracking' - case ${{ matrix.bin }} in - vorm) opts="$opts --enable-scalar --disable-threaded --disable-parform";; - tvorm) opts="$opts --disable-scalar --enable-threaded --disable-parform";; - esac - case ${{ matrix.bin }} in - vorm|tvorm|parvorm) opts="$opts --enable-debug";; - esac - opts="$opts --with-gmp --with-zlib --with-zstd" - autoreconf -i - ./configure $opts + features: >- + ${{ matrix.bin }} + ${{ matrix.flint == 'no' && 'noflint' || '' }} + ${{ matrix.test == 'extra' && 'formlib' || '' }} + valgrind - name: Build run: make -C sources -j 4 ${{ matrix.bin }} - - name: Cache library - id: cache-formlib - if: contains(fromJson('["extra"]'), matrix.test) - uses: actions/cache@v4 - with: - path: formlib - key: formlib-${{ matrix.test }}-v2 - - - name: Install library if necessary - if: steps.cache-formlib.outputs.cache-hit != 'true' - run: | - mkdir -p formlib - case ${{ matrix.test }} in - extra) - # forcer library for the forcer test in extra - wget https://github.com/benruijl/forcer/archive/v1.0.0.tar.gz -O - | tar -x --gzip - mv forcer-1.0.0/forcer.h formlib - mv forcer-1.0.0/forcer formlib - rm -rf forcer-1.0.0 - # color library for the color test in extra - wget https://github.com/form-dev/form-packages/archive/refs/tags/v1.0.0.tar.gz -O - | tar -x --gzip - mv form-packages-1.0.0/color/color.h formlib - rm -rf form-packages-1.0.0 - # series library for test in extra - wget https://github.com/a-maier/series/releases/download/1.0.0/series.h -P formlib - ;; - esac - - name: Test run: ./check/check.rb valgrind ./sources/${{ matrix.bin }} --stat -g ${{ matrix.group }} --retries 5 ${{ matrix.nthreads && format('-w{0}', matrix.nthreads) || '' }} ${{ matrix.test != 'default' && format('-C {0}', matrix.test) || '' }} - env: - FORMPATH: ${{ github.workspace }}/formlib # Generate LCOV coverage data to be posted to coveralls.io. Note that # we measure code coverage only for tests checked with Valgrind. @@ -310,69 +167,25 @@ jobs: with: fetch-depth: 0 # ensures a reachable tag - - name: Install dependencies - uses: awalsh128/cache-apt-pkgs-action@v1 + - name: Set up build + uses: ./.github/actions/setup-build with: - packages: lcov libflint-dev libmpfr-dev libzstd-dev - # We need to handle a bug that may cause cache key conflicts. - # See: https://github.com/awalsh128/cache-apt-pkgs-action/pull/150 - version: ${{ runner.arch }}-1.0 - - - name: Configure - run: | - opts='--disable-dependency-tracking' - case ${{ matrix.bin }} in - vorm) opts="$opts --enable-scalar --disable-threaded --disable-parform";; - tvorm) opts="$opts --disable-scalar --enable-threaded --disable-parform";; - esac - case "${{ matrix.flint }}" in - no) opts="$opts --without-flint";; - *) opts="$opts --with-flint";; - esac - opts="$opts --enable-debug --enable-coverage --with-gmp --with-zlib --with-zstd" - autoreconf -i - ./configure $opts + features: >- + ${{ matrix.bin }} + ${{ matrix.flint == 'no' && 'noflint' || '' }} + ${{ matrix.test == 'extra' && 'formlib' || '' }} + coverage - name: Build run: make -C sources -j 4 ${{ matrix.bin }} - - name: Cache library - id: cache-formlib - if: contains(fromJson('["extra"]'), matrix.test) - uses: actions/cache@v4 - with: - path: formlib - key: formlib-${{ matrix.test }}-v2 - - - name: Install library if necessary - if: steps.cache-formlib.outputs.cache-hit != 'true' - run: | - mkdir -p formlib - case ${{ matrix.test }} in - extra) - # forcer library for the forcer test in extra - wget https://github.com/benruijl/forcer/archive/v1.0.0.tar.gz -O - | tar -x --gzip - mv forcer-1.0.0/forcer.h formlib - mv forcer-1.0.0/forcer formlib - rm -rf forcer-1.0.0 - # color library for the color test in extra - wget https://github.com/form-dev/form-packages/archive/refs/tags/v1.0.0.tar.gz -O - | tar -x --gzip - mv form-packages-1.0.0/color/color.h formlib - rm -rf form-packages-1.0.0 - # series library for test in extra - wget https://github.com/a-maier/series/releases/download/1.0.0/series.h -P formlib - ;; - esac - - name: Test run: ./check/check.rb ./sources/${{ matrix.bin }} --stat --timeout ${{ matrix.timeout && format('{0}', matrix.timeout) || '30' }} ${{ matrix.nthreads && format('-w{0}', matrix.nthreads) || '' }} ${{ matrix.test != 'default' && format('-C {0}', matrix.test) || '' }} --fake-valgrind - env: - FORMPATH: ${{ github.workspace }}/formlib - name: Generate LCOV coverage data run: | lcov -d . -c -o coverage.lcov - lcov -r coverage.lcov */usr/include/* -o coverage.lcov + lcov -r coverage.lcov '*/usr/include/*' '*/extern/*'${{ matrix.flint != 'no' && ' ''*/lib/*''' || '' }} -o coverage.lcov - name: Coveralls Parallel uses: coverallsapp/github-action@v2 @@ -409,26 +222,10 @@ jobs: - name: Checkout repository uses: actions/checkout@v1 - - name: Install dependencies - run: | - apt-get update - apt-get -y install automake build-essential git libgmp-dev libmpfr-dev libzstd-dev ruby zlib1g-dev - - # Fix dubious ownership for Git operations. - # See https://github.com/actions/runner/issues/2033#issuecomment-1204205989 - - name: Set ownership - run: chown -R $(id -u):$(id -g) $PWD - - - name: Configure - run: | - opts='--disable-dependency-tracking' - case ${{ matrix.bin }} in - form) opts="$opts --enable-scalar --disable-threaded --disable-parform";; - tform) opts="$opts --disable-scalar --enable-threaded --disable-parform";; - esac - opts="$opts --disable-debug --with-gmp --with-zlib --with-zstd --without-flint" - autoreconf -i - ./configure $opts + - name: Set up build + uses: ./.github/actions/setup-build + with: + features: ${{ matrix.bin }} noflint # actions/cache@v4 doesn't work - name: Build run: make -C sources -j 4 ${{ matrix.bin }}