current commit
261106.3 · Bump macos CI version (#9355)
name: CI

on:
  # If we run CI on all branches then we end up doing duplicate work for
  # branches which are also PRs.
  push:
    branches:
      - main
      - kripken/*
  pull_request:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:

  lint:
    name: lint
    if: ${{ github.event_name == 'pull_request' }}
    # Use Ubuntu 26.04 to get clang-21 (not present in 24.04)
    runs-on: ubuntu-26.04
    env:
      # Keep this in sync with clang-format-diff.sh
      LLVM_VERSION: 21
    steps:
    - uses: actions/setup-python@v5
      with:
        python-version: '3.x'
    - uses: actions/checkout@v4
      with:
        submodules: true
        fetch-depth: 0
    - name: install tools
      run: |
        pip3 install -r requirements-dev.txt
        sudo apt install lsb-release wget software-properties-common gnupg
        sudo apt-get install clang-${LLVM_VERSION} clang-format-${LLVM_VERSION} clang-tidy-${LLVM_VERSION}
    - run: ruff check
    - run: ./scripts/clang-format-diff.sh
    - name: clang-tidy
      run: |
        # clang-tidy requires compile_commands.json generated by cmake
        cmake . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
        ./scripts/clang-tidy-diff.sh

  build:
    name: build
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        # Test on the oldest support Ubuntu version in addition to `latest`.
        # Build using the oldest support macOS version.  For emsdk this is
        # currently macos-13, but unfortunately that doesn't exist in github
        # actions so we settle for macos-15.
        os: [ubuntu-22.04, ubuntu-latest, macos-15, windows-latest, windows-11-arm]
    steps:
    - uses: actions/setup-python@v5
      with:
        python-version: '3.x'
    - uses: actions/checkout@v4
      with:
        submodules: true

    - name: install Python dev dependencies
      run: pip3 install -r requirements-dev.txt

    - name: gen-s-parser
      run: ./scripts/gen-s-parser.py | diff src/gen-s-parser.inc -
      if: startsWith(matrix.os, 'ubuntu')

    - name: install ninja (linux)
      run: sudo apt-get install ninja-build
      if: startsWith(matrix.os, 'ubuntu')

    - name: install ninja (macos)
      run: brew install ninja
      if: startsWith(matrix.os, 'macos')

    - name: install ninja (win)
      run: choco install ninja
      if: startsWith(matrix.os, 'windows')

    - name: install v8
      run: |
        npm install jsvu -g
        jsvu --os=default --engines=v8

    - name: mkdir
      run: mkdir -p out

    - name: cmake (linux)
      run: cmake -S . -B out -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=out/install
      if: startsWith(matrix.os, 'ubuntu')

    - name: cmake (macos)
      run: cmake -S . -B out -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=out/install '-DCMAKE_OSX_ARCHITECTURES=x86_64;arm64'
      if: startsWith(matrix.os, 'macos')

    - name: cmake (win)
      # -G "Visual Studio 15 2017"
      run: cmake -S . -B out -DCMAKE_INSTALL_PREFIX=out/install
      if: startsWith(matrix.os, 'windows')

    - name: build
      run: cmake --build out --config Release -v

    - name: install
      run: cmake --install out --config Release

    - name: strip
      run: find out/install/ -type f -perm -u=x -exec strip -x {} +
      if: ${{ !startsWith(matrix.os, 'windows') }}

    - name: Upload artifacts
      uses: actions/upload-artifact@v4
      with:
        name: build-${{ matrix.os }}
        path: out/install

    - name: test binaryen-lit
      run: python out/bin/binaryen-lit -vv test/lit/parse-error.wast

    - name: test
      run: python check.py --binaryen-bin=out/bin

  build-clang:
    name: clang (LTO)
    runs-on: ubuntu-latest
    steps:
    - uses: actions/setup-python@v5
      with:
        python-version: '3.x'
    - uses: actions/checkout@v4
      with:
        submodules: true
    - name: install ninja
      run: sudo apt-get install ninja-build
    - name: install v8
      run: |
        npm install jsvu -g
        jsvu --os=default --engines=v8
    - name: install Python dev dependencies
      run: pip3 install -r requirements-dev.txt
    - name: cmake
      run: |
        mkdir -p out
        cmake -S . -B out -G Ninja -DCMAKE_INSTALL_PREFIX=out/install -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DBYN_ENABLE_LTO=ON
    - name: build
      run: cmake --build out -v
    - name: test binaryen-lit
      run: python out/bin/binaryen-lit -vv test/lit/parse-error.wast
    - name: test
      run: python check.py --binaryen-bin=out/bin

  # Copied and modified from build-clang
  build-fuzztest:
    name: clang with fuzztest
    runs-on: ubuntu-latest
    steps:
    - uses: actions/setup-python@v5
      with:
        python-version: '3.x'
    - uses: actions/checkout@v4
      with:
        submodules: true
    - name: install ninja
      run: sudo apt-get install ninja-build
    - name: install v8
      run: |
        npm install jsvu -g
        jsvu --os=default --engines=v8
    - name: install Python dev dependencies
      run: pip3 install -r requirements-dev.txt
    - name: cmake
      run: |
        mkdir -p out
        cmake -S . -B out -G Ninja -DCMAKE_INSTALL_PREFIX=out/install -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DBUILD_FUZZTEST=ON
    - name: build
      run: cmake --build out -v
    - name: test
      run: python check.py --binaryen-bin=out/bin

  # TODO(sbc): Find a way to reduce the duplicate between these sanitizer jobs
  build-asan:
    name: asan
    runs-on: ubuntu-latest
    env:
      ASAN_OPTIONS: "symbolize=1"
      COMPILER_FLAGS: "-fsanitize=address"
      CC: "clang-18"
      CXX: "clang++-18"
    steps:
    - uses: actions/setup-python@v5
      with:
        python-version: '3.x'
    - uses: actions/checkout@v4
      with:
        submodules: true
    - name: install ninja
      run: sudo apt-get install ninja-build
    - name: install v8
      run: |
        npm install jsvu -g
        jsvu --os=default --engines=v8
    - name: install Python dev dependencies
      run: pip3 install -r requirements-dev.txt
    - name: cmake
      run: |
        mkdir -p out
        cmake -S . -B out -G Ninja -DCMAKE_INSTALL_PREFIX=out/install -DCMAKE_C_COMPILER=clang-18 -DCMAKE_CXX_COMPILER=clang++-18 -DCMAKE_C_FLAGS="$COMPILER_FLAGS" -DCMAKE_CXX_FLAGS="$COMPILER_FLAGS"
    - name: build
      run: cmake --build out
    - name: test
      run: python check.py --binaryen-bin=out/bin

  # Run tests on Alpine Linux, which we use to make our release builds.
  # Note: Alpine uses musl libc.
  # Keep in sync with create_release.yml. The only difference is that here we
  # do not have the "archive" and "upload tarball" jobs.
  build-alpine:
    name: alpine
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, ubuntu-24.04-arm]
    steps:
    - uses: actions/setup-python@v5
      with:
        python-version: '3.x'
    - uses: actions/checkout@v4
      with:
        submodules: true

    - name: start docker
      run: |
        if [[ "${{ matrix.docker_platform }}" == "ubuntu-24.04-arm" ]]; then
          platform="--platform=linux/arm64"
        fi
        docker run -w /src -dit $platform --name alpine -v $PWD:/src node:lts-alpine
        echo 'docker exec alpine "$@";' > ./alpine.sh
        chmod +x ./alpine.sh

    - name: install packages
      run: |
        ./alpine.sh apk update
        ./alpine.sh apk add build-base cmake git python3 py3-pip clang ninja util-linux

    - name: avoid d8 tests (jsvu is not compatible with alpine)
      run: |
        ./alpine.sh rm -Rf test/lit/d8

    - name: install python dev dependencies
      run: ./alpine.sh pip3 install --break-system-packages -r requirements-dev.txt

    - name: cmake
      # Build with an 8MB stack size, as otherwise Alpine/musl's default stack
      # size for pthreads is tiny,
      # https://github.com/WebAssembly/binaryen/issues/8594
      run: |
        ./alpine.sh cmake . -G Ninja -DCMAKE_CXX_FLAGS="-static" -DCMAKE_C_FLAGS="-static" -DCMAKE_EXE_LINKER_FLAGS="-Wl,-z,stack-size=8388608" -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DBUILD_MIMALLOC=ON -DCMAKE_INSTALL_PREFIX=install

    - name: build
      run: |
        ./alpine.sh ninja install

    - name: test
      run: ./alpine.sh python3 ./check.py

  # Duplicates build-asan.  Please keep in sync
  build-ubsan:
    name: ubsan
    runs-on: ubuntu-latest
    env:
      COMPILER_FLAGS: "-fsanitize=undefined -fno-sanitize-recover=all"
      CC: "clang"
      CXX: "clang++"
    steps:
    - uses: actions/setup-python@v5
      with:
        python-version: '3.x'
    - uses: actions/checkout@v4
      with:
        submodules: true
    - name: install ninja
      run: sudo apt-get install ninja-build
    - name: install v8
      run: |
        npm install jsvu -g
        jsvu --os=default --engines=v8
    - name: install Python dev dependencies
      run: pip3 install -r requirements-dev.txt
    - name: cmake
      run: |
        mkdir -p out
        cmake -S . -B out -G Ninja -DCMAKE_INSTALL_PREFIX=out/install -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_FLAGS="$COMPILER_FLAGS" -DCMAKE_CXX_FLAGS="$COMPILER_FLAGS -fsanitize-blacklist=$PWD/ubsan.blacklist"
    - name: build
      run: cmake --build out
    - name: test
      run: python check.py --binaryen-bin=out/bin

  # Duplicates build-asan.  Please keep in sync
  build-tsan:
    name: tsan
    runs-on: ubuntu-latest
    env:
      COMPILER_FLAGS: "-fsanitize=thread"
      LINKER_FLAGS: "-fsanitize=thread"
      CC: "clang-18"
      CXX: "clang++-18"
    steps:
    - uses: actions/setup-python@v5
      with:
        python-version: '3.x'
    - uses: actions/checkout@v4
      with:
        submodules: true
    - name: install ninja
      run: sudo apt-get install ninja-build
    - name: install v8
      run: |
        npm install jsvu -g
        jsvu --os=default --engines=v8
    - name: install Python dev dependencies
      run: pip3 install -r requirements-dev.txt
    - name: cmake
      run: |
        mkdir -p out
        cmake -S . -B out -G Ninja -DCMAKE_INSTALL_PREFIX=out/install -DCMAKE_C_COMPILER=clang-18 -DCMAKE_CXX_COMPILER=clang++-18 -DCMAKE_C_FLAGS="$COMPILER_FLAGS" -DCMAKE_CXX_FLAGS="$COMPILER_FLAGS" -DCMAKE_EXE_LINKER_FLAGS="$LINKER_FLAGS"
    - name: build
      run: cmake --build out
    - name: test
      run: python check.py --binaryen-bin=out/bin

  # Duplicates build-asan.  Please keep in sync
  coverage:
    name: coverage
    if: ${{ github.event_name == 'pull_request' }}
    runs-on: ubuntu-26.04
    env:
      COMPILER_FLAGS: "-fprofile-instr-generate -fcoverage-mapping -fcoverage-mcdc"
      LLVM_VERSION: 21
    steps:
    - uses: actions/setup-python@v5
      with:
        python-version: '3.x'
    - uses: actions/checkout@v4
      with:
        submodules: true
        fetch-depth: 0
    - name: install tools
      run: sudo apt-get install ninja-build clang-${LLVM_VERSION} llvm-${LLVM_VERSION}
    - name: install v8
      run: |
        npm install jsvu -g
        jsvu --os=default --engines=v8
    - name: install Python dev dependencies
      run: pip3 install -r requirements-dev.txt
    - name: cmake
      run: |
        mkdir -p out
        cmake -S . -B out -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=out/install -DCMAKE_C_COMPILER=clang-${LLVM_VERSION} -DCMAKE_CXX_COMPILER=clang++-${LLVM_VERSION} -DCMAKE_C_FLAGS="$COMPILER_FLAGS" -DCMAKE_CXX_FLAGS="$COMPILER_FLAGS"
    - name: build
      run: cmake --build out
    - name: coverage-diff
      run: |
        MERGE_BASE=$(git merge-base "origin/$GITHUB_BASE_REF" HEAD)
        ./scripts/experimental/coverage-diff.py --base "$MERGE_BASE" -B out --lit test/lit --gtest -a --github-annotations
        ./scripts/experimental/coverage-diff.py --base "$MERGE_BASE" -B out -a --markdown >> "$GITHUB_STEP_SUMMARY"

  # Build the .js outputs using emcc
  build-emscripten:
    name: emscripten
    runs-on: ubuntu-latest
    env:
      # Set this environment variable to test a specific Emscripten branch.
      # Format: https://github.com/<fork>/emscripten/tree/<refspec>
      EMSCRIPTEN_REPO: ""
    steps:
    - uses: actions/setup-python@v5
      with:
        python-version: '3.x'
    - uses: actions/checkout@v4
      with:
        submodules: true
    - name: install ninja
      run: sudo apt-get install ninja-build
    - name: emsdk install
      uses: emscripten-core/setup-emsdk@v15
      with:
        version: tot
    - name: override emscripten repository
      if: ${{ env.EMSCRIPTEN_REPO != '' }}
      run: |
        $EMSDK/emsdk install emscripten-main-64bit \
          --override-repository emscripten-main-64bit@$EMSCRIPTEN_REPO
        $EMSDK/emsdk activate emscripten-main-64bit
    - name: update path
      run:  echo "PATH=$PATH:$EMSDK" >> $GITHUB_ENV
    - name: emcc-tests
      run: |
        source $EMSDK/emsdk_env.sh
        ./scripts/emcc-tests.sh

  # Windows + gcc needs work before the tests will run, so just test the compile
  build-mingw:
    name: mingw
    runs-on: windows-latest
    steps:
    - uses: actions/setup-python@v5
      with:
        python-version: '3.x'
    - uses: actions/checkout@v4
      with:
        submodules: true
    - name: cmake
      run: |
        mkdir -p out
        cmake -S . -B out -G "MSYS Makefiles"
    - name: build
      run: cmake --build out --parallel 4

  # Ensures we can build in no-asserts mode (just building).
  build-noasserts:
    name: noasserts
    runs-on: ubuntu-latest
    steps:
    - uses: actions/setup-python@v5
      with:
        python-version: '3.x'
    - uses: actions/checkout@v4
      with:
        submodules: true
    - name: install ninja
      run: sudo apt-get install ninja-build
    - name: cmake
      run: |
        mkdir -p out
        cmake -S . -B out -G Ninja -DCMAKE_INSTALL_PREFIX=out/install -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -DBYN_ENABLE_ASSERTIONS=OFF
    - name: build
      run: cmake --build out -v