name: CI

on: [ push, pull_request ]

env:
  # Enable format attributes in ncurses headers
  # Enable fortified memory/string handling
  CPPFLAGS: -DGCC_PRINTF -DGCC_SCANF -D_FORTIFY_SOURCE=2

jobs:
  build-ubuntu-latest-minimal-gcc:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v6
    - name: Install Dependencies
      run: |
        sudo apt-get update -q
        sudo apt-get install --no-install-recommends libncursesw5-dev
    - name: Bootstrap
      run: ./autogen.sh
    - name: Configure
      run: ./configure --enable-werror --enable-affinity --disable-unicode --disable-sensors || (cat config.log; exit 1)
    - name: Enable compatibility modes
      run: |
        sed -i 's/#define HAVE_FSTATAT 1/#undef HAVE_FSTATAT/g' config.h
        sed -i 's/#define HAVE_OPENAT 1/#undef HAVE_OPENAT/g' config.h
        sed -i 's/#define HAVE_READLINKAT 1/#undef HAVE_READLINKAT/g' config.h
    - name: Build
      run: make -k
    - name: Distcheck
      run: make distcheck DISTCHECK_CONFIGURE_FLAGS="--enable-werror --enable-affinity --disable-unicode --disable-sensors"

  build-ubuntu-latest-minimal-clang:
    runs-on: ubuntu-latest
    env:
      CC: clang-22
    steps:
    - uses: actions/checkout@v6
    - name: install clang repo
      run: |
        ubuntu_codename=`LC_ALL=C sed 's/^ *UBUNTU_CODENAME *= *\([a-z]*\).*$/\1/p; d' /etc/os-release`
        wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key 2>/dev/null | sudo apt-key add -
        sudo add-apt-repository "deb http://apt.llvm.org/${ubuntu_codename}/ llvm-toolchain-${ubuntu_codename}-22 main" -y
    - name: Install Dependencies
      run: |
        sudo apt-get update -q
        sudo apt-get install --no-install-recommends clang-22 libncursesw5-dev
    - name: Bootstrap
      run: ./autogen.sh
    - name: Configure
      run: ./configure --enable-werror --enable-affinity --disable-unicode --disable-sensors || ( cat config.log; exit 1; )
    - name: Build
      run: make -k
    - name: Distcheck
      run: make distcheck DISTCHECK_CONFIGURE_FLAGS="--enable-werror --enable-affinity --disable-unicode --disable-sensors"

  build-ubuntu-latest-full-featured-gcc:
    runs-on: ubuntu-latest
    # Enable LTO, might trigger additional warnings on advanced inlining
    env:
      CFLAGS: -O3 -g -flto
      LDFLAGS: -O3 -g -flto -Wl,--as-needed
    steps:
    - uses: actions/checkout@v6
    - name: Install Dependencies
      run: |
        sudo apt-get update -q
        sudo apt-get install --no-install-recommends libncursesw5-dev libhwloc-dev libnl-3-dev libnl-genl-3-dev libsensors-dev libcap-dev libiberty-dev libunwind-dev
    - name: Bootstrap
      run: ./autogen.sh
    - name: Configure
      run: ./configure --enable-werror --enable-openvz --enable-vserver --enable-ancient-vserver --enable-unicode --enable-hwloc --enable-delayacct --enable-sensors --enable-capabilities --enable-backtrace --enable-demangling || ( cat config.log; exit 1; )
    - name: Build
      run: make -k
    - name: Distcheck
      run: make distcheck DISTCHECK_CONFIGURE_FLAGS='--enable-werror --enable-openvz --enable-vserver --enable-ancient-vserver --enable-unicode --enable-hwloc --enable-delayacct --enable-sensors --enable-capabilities --enable-backtrace --enable-demangling'

  build-ubuntu-latest-full-featured-clang:
    runs-on: ubuntu-latest
    env:
      CC: clang-22
    steps:
    - uses: actions/checkout@v6
    - name: install clang repo
      run: |
        ubuntu_codename=`LC_ALL=C sed 's/^ *UBUNTU_CODENAME *= *\([a-z]*\).*$/\1/p; d' /etc/os-release`
        wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key 2>/dev/null | sudo apt-key add -
        sudo add-apt-repository "deb http://apt.llvm.org/${ubuntu_codename}/ llvm-toolchain-${ubuntu_codename}-22 main" -y
    - name: Install Dependencies
      run: |
        sudo apt-get update -q
        sudo apt-get install --no-install-recommends clang-22 libncursesw5-dev libhwloc-dev libnl-3-dev libnl-genl-3-dev libsensors-dev libcap-dev libiberty-dev libunwind-dev
    - name: Bootstrap
      run: ./autogen.sh
    - name: Configure
      run: ./configure --enable-werror --enable-openvz --enable-vserver --enable-ancient-vserver --enable-unicode --enable-hwloc --enable-delayacct --enable-sensors --enable-capabilities --enable-backtrace --enable-demangling || ( cat config.log; exit 1; )
    - name: Build
      run: make -k
    - name: Distcheck
      run: make distcheck DISTCHECK_CONFIGURE_FLAGS='--enable-werror --enable-openvz --enable-vserver --enable-ancient-vserver --enable-unicode --enable-hwloc --enable-delayacct --enable-sensors --enable-capabilities --enable-backtrace --enable-demangling'

  build-ubuntu-latest-gcc-static:
    runs-on: ubuntu-latest
    # Enable LTO, might trigger additional warnings on advanced inlining
    env:
      CFLAGS: -O3 -g -flto
      LDFLAGS: -O3 -g -flto
    steps:
    - uses: actions/checkout@v6
    - name: Install Dependencies
      run: |
        sudo apt-get update -q
        sudo apt-get install --no-install-recommends libncursesw5-dev libtinfo-dev libgpm-dev libsensors-dev libcap-dev
    - name: Bootstrap
      run: ./autogen.sh
    - name: Configure
      run: ./configure --enable-static --enable-werror --enable-openvz --enable-vserver --enable-ancient-vserver --enable-unicode --disable-hwloc --disable-delayacct --enable-sensors --enable-capabilities || ( cat config.log; exit 1; )
    - name: Build
      run: make -k
    - name: Distcheck
      run: make distcheck DISTCHECK_CONFIGURE_FLAGS='--enable-static --enable-werror --enable-openvz --enable-vserver --enable-ancient-vserver --enable-unicode --disable-hwloc --disable-delayacct --enable-sensors --enable-capabilities'

  build-ubuntu-latest-pcp:
    # we want PCP v5.2.3+
    runs-on: ubuntu-22.04
    steps:
    - uses: actions/checkout@v6
    - name: Install Dependencies
      run: |
        sudo apt-get update -q
        sudo apt-get install --no-install-recommends libpcp3-dev libncursesw5-dev libtinfo-dev libgpm-dev
    - name: Bootstrap
      run: ./autogen.sh
    - name: Configure
      run: ./configure --enable-werror --enable-pcp --enable-unicode || ( cat config.log; exit 1; )
    - name: Build
      run: make -k

  build-unsupported-latest-gcc:
    # build as if we were on an unsupported platform
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v6
    - name: Install Dependencies
      run: |
        sudo apt-get update -q
        sudo apt-get install --no-install-recommends libncursesw5-dev libtinfo-dev libgpm-dev
    - name: Bootstrap
      run: ./autogen.sh
    - name: Configure
      run: ./configure --host=`uname -m`-none --enable-werror --enable-unicode || ( cat config.log; exit 1; )
    - name: Build
      run: make -k

  build-ubuntu-latest-clang-analyzer:
    runs-on: ubuntu-latest
    env:
      CC: clang-22
    steps:
    - uses: actions/checkout@v6
    - name: install clang repo
      run: |
        ubuntu_codename=`LC_ALL=C sed 's/^ *UBUNTU_CODENAME *= *\([a-z]*\).*$/\1/p; d' /etc/os-release`
        wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key 2>/dev/null | sudo apt-key add -
        sudo add-apt-repository "deb http://apt.llvm.org/${ubuntu_codename}/ llvm-toolchain-${ubuntu_codename}-22 main" -y
    - name: Install Dependencies
      run: |
        sudo apt-get update -q
        sudo apt-get install --no-install-recommends clang-22 clang-tools-22 libncursesw5-dev libnl-3-dev libnl-genl-3-dev libsensors-dev libcap-dev libiberty-dev libunwind-dev
    - name: Bootstrap
      run: ./autogen.sh
    - name: Configure
      run: scan-build-22 -analyze-headers --status-bugs ./configure --enable-debug --enable-werror --enable-openvz --enable-vserver --enable-ancient-vserver --enable-unicode --enable-delayacct --enable-sensors --enable-capabilities --enable-backtrace --enable-demangling || ( cat config.log; exit 1; )
    - name: Build
      run: scan-build-22 -analyze-headers --status-bugs make -j"$(nproc)"

  build-ubuntu-latest-clang-sanitizer:
    runs-on: ubuntu-latest
    env:
      CC: clang-22
      CFLAGS: '-O1 -g -ftrivial-auto-var-init=pattern -fsanitize=address -fsanitize-address-use-after-scope -fsanitize-address-use-after-return=always -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=nullability -fsanitize=implicit-conversion -fsanitize=integer -fsanitize=float-divide-by-zero -fsanitize=local-bounds'
      LDFLAGS: '-ftrivial-auto-var-init=pattern -fsanitize=address -fsanitize-address-use-after-scope -fsanitize-address-use-after-return=always -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=nullability -fsanitize=implicit-conversion -fsanitize=integer -fsanitize=float-divide-by-zero -fsanitize=local-bounds'
      ASAN_OPTIONS: strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1
      UBSAN_OPTIONS: print_stacktrace=1:print_summary=1:halt_on_error=1
      TERM: xterm-color
      HTOPRC: .github/workflows/htoprc
    steps:
    - uses: actions/checkout@v6
    - name: install clang repo
      run: |
        ubuntu_codename=`LC_ALL=C sed 's/^ *UBUNTU_CODENAME *= *\([a-z]*\).*$/\1/p; d' /etc/os-release`
        wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key 2>/dev/null | sudo apt-key add -
        sudo add-apt-repository "deb http://apt.llvm.org/${ubuntu_codename}/ llvm-toolchain-${ubuntu_codename}-22 main" -y
    - name: Install LLVM Toolchain
      run: |
        sudo apt-get update -q
        sudo apt-get install --no-install-recommends clang-22 libclang-rt-22-dev llvm-22
    - name: Install Dependencies
      run: sudo apt-get install --no-install-recommends libncursesw5-dev libhwloc-dev libnl-3-dev libnl-genl-3-dev libsensors-dev libcap-dev libiberty-dev libunwind-dev
    - name: Bootstrap
      run: ./autogen.sh
    - name: Configure
      run: ./configure --enable-werror --enable-openvz --enable-vserver --enable-ancient-vserver --enable-unicode --enable-hwloc --enable-delayacct --enable-sensors --enable-capabilities --enable-backtrace --enable-demangling || ( cat config.log; exit 1; )
    - name: Build
      run: make -k
    - name: Run sanitized htop (1)
      run: ./htop -h
    - name: Run sanitized htop (2)
      run: ./htop -n 5
    - name: Run sanitized htop (3)
      run: ./htop -n 5 -t
    - name: Run sanitized htop (4)
      run: ./htop -d 1 -n 50

  build-macos-latest-clang:
    runs-on: macOS-latest
    env:
      CC: clang
    steps:
    - uses: actions/checkout@v6
    - name: Install Dependencies
      run: brew install automake pkg-config
    - name: Bootstrap
      run: ./autogen.sh
    - name: Configure
      run: ./configure --enable-werror || ( cat config.log; exit 1; )
    - name: Build
      run: make -k
    - name: Distcheck
      run: make distcheck DISTCHECK_CONFIGURE_FLAGS="--enable-werror"

  build-macos-latest-pcp:
    runs-on: macOS-latest
    env:
      CC: clang
      CFLAGS: -O3 -g -flto
      LDFLAGS: -O3 -g -flto
    steps:
    - uses: actions/checkout@v6
    - name: Install Dependencies
      run: |
        pcp_version=7.0.3-1
        brew install automake pkg-config
        curl -f -L -O https://github.com/performancecopilot/pcp/releases/download/$(echo ${pcp_version} | sed 's/-.*$//')/pcp-${pcp_version}.dmg
        hdiutil attach pcp-${pcp_version}.dmg
        sudo installer -verbose -pkg /Volumes/pcp-${pcp_version}/pcp-${pcp_version}.pkg -target /
    - name: Bootstrap
      run: ./autogen.sh
    - name: Configure
      run: ./configure --enable-werror --enable-pcp --enable-unicode || ( cat config.log; exit 1; )
    - name: Build
      run: make -k

  build-dragonflybsd-latest-gcc:
      runs-on: ubuntu-22.04
      timeout-minutes: 20
      steps:
        - uses: actions/checkout@v6
          with:
            submodules: recursive
        - name: Compile
          uses: vmactions/dragonflybsd-vm@v1
          with:
            release: '6.4.2'
            usesh: true
            prepare: |
              pkg install -y gmake autoconf automake ncurses git
              git config --global --add safe.directory /home/runner/work/htop/htop
            run: |
              set -e
              export LDFLAGS="-L/usr/local/lib"
              export CFLAGS="-I/usr/local/include"
              ./autogen.sh
              ./configure --enable-unicode --enable-werror
              gmake -k

  build-freebsd-latest-clang:
      runs-on: ubuntu-22.04
      timeout-minutes: 20
      steps:
        - uses: actions/checkout@v6
          with:
            submodules: recursive
        - name: Compile
          uses: vmactions/freebsd-vm@v1
          with:
            release: '15.0'
            usesh: true
            prepare: |
              pkg install -y gmake autoconf automake pkgconf git libunwind gnulibiberty
              git config --global --add safe.directory /home/runner/work/htop/htop
            run: |
              set -e
              ./autogen.sh
              ./configure --enable-unicode --enable-werror --enable-backtrace --enable-demangling
              gmake -k

  build-netbsd-latest-gcc:
      runs-on: ubuntu-22.04
      timeout-minutes: 20
      steps:
        - uses: actions/checkout@v6
          with:
            submodules: recursive
        - name: Compile
          uses: vmactions/netbsd-vm@v1
          with:
            release: '10.1'
            usesh: true
            prepare: |
              PATH="/usr/pkg/sbin:/usr/pkg/bin:$PATH"
              PKG_PATH="https://ftp.netbsd.org/pub/pkgsrc/packages/NetBSD/amd64/10.1/All/"
              export PATH PKG_PATH
              /usr/sbin/pkg_add pkgin
              pkgin -y install autoconf automake libtool ncurses pkg-config gmake git
              git config --global --add safe.directory /home/runner/work/htop/htop
            run: |
              set -e
              ./autogen.sh
              ./configure --enable-unicode --enable-werror
              gmake -k

  build-openbsd-latest-clang:
      runs-on: ubuntu-22.04
      timeout-minutes: 20
      steps:
        - uses: actions/checkout@v6
          with:
            submodules: recursive
        - name: Compile
          uses: vmactions/openbsd-vm@v1
          with:
            release: '7.8'
            usesh: true
            prepare: |
              pkg_add gmake git
              git config --global --add safe.directory /home/runner/work/htop/htop
            run: |
              set -e
              autoconf_version_full=$(pkg_info -Q autoconf |
                LC_ALL=C sed 's/^autoconf-\([0-9]*\.[0-9]*\)\(p[.0-9]*\)\{0,1\}$/\1\2/p; d' |
                LC_ALL=C sort -n -r -t . -k 1,1 -k 2,2 |
                sed '1 q')
              automake_version_full=$(pkg_info -Q automake |
                LC_ALL=C sed 's/^automake-\([0-9]*\.[0-9]*\)\(\.[0-9]*\)\{0,1\}\(p[0-9]*\)\{0,1\}$/\1\2\3/p; d' |
                LC_ALL=C sort -n -r -t . -k 1,1 -k 2,2 -k 3,3 |
                sed '1 q')
              pkg_add -v autoconf-${autoconf_version_full} automake-${automake_version_full}
              export AUTOCONF_VERSION=$(echo ${autoconf_version_full} |
                LC_ALL=C sed 's/^\([0-9]*\.[0-9]*\).*$/\1/')
              # Must not include the third version field in $AUTOMAKE_VERSION
              export AUTOMAKE_VERSION=$(echo ${automake_version_full} |
                LC_ALL=C sed 's/^\([0-9]*\.[0-9]*\).*$/\1/')
              ./autogen.sh
              ./configure --enable-unicode --enable-werror
              gmake -k

  build-solaris-latest-gcc:
      runs-on: ubuntu-22.04
      timeout-minutes: 20
      steps:
        - uses: actions/checkout@v6
          with:
            submodules: recursive
        - name: Compile
          uses: vmactions/solaris-vm@v1
          with:
            release: '11.4'
            usesh: true
            prepare: |
              pkg install gnu-make autoconf automake ncurses git gcc
              git config --global --add safe.directory /home/runner/work/htop/htop
            run: |
              set -e
              ./autogen.sh
              ./configure --enable-unicode --enable-werror
              gmake -k

  lint-whitespace:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - name: check-whitespaces
        run: git diff-tree --check $(git hash-object -t tree /dev/null) HEAD

  lint-pcp-config:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - name: check-pcp-style
        run: ./check-pcp-style.sh
