# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# build under various Alpine Linux versions with clang and gcc

# info: Alpine 3.9 has clang-5, cmake-3.13.0 and gcc-8, which nicely
#   matches our minimal build requirements

name: 'Weekly CI - Alpine Linux'

on:
  schedule: [cron: '10 4 * * 3'] # run weekly Wednesday 04:10 UTC
  workflow_dispatch:

jobs:
  job-alpine-cmake:
    strategy:
      fail-fast: false
#     matrix: { container: ['alpine:3.12','alpine:3.18','alpine:edge','i386/alpine:edge'] }
      matrix: { container: ['alpine:3.9','alpine:3.10','alpine:3.11','alpine:3.12','alpine:3.13','alpine:3.14','alpine:3.15','alpine:3.16','alpine:3.17','alpine:3.18','alpine:edge','i386/alpine:edge'] }
    name: ${{ format('container {0}', matrix.container) }}
    runs-on: ubuntu-latest
    container: ${{ matrix.container }}
    env: { UPX_CMAKE_CONFIG_FLAGS: '-DCMAKE_VERBOSE_MAKEFILE=ON' }
    steps:
      - name: ${{ format('Install packages {0}', matrix.container) }}
        run: |
          apk update && apk upgrade && apk add clang cmake g++ git make
          case ${{ matrix.container }} in
            # clang-dev is needed on older Alpine versions for clang headers like <emmintrin.h>
            *:3.[0-9]|*:3.10|*:3.11) apk add clang-dev ;;
          esac
      - name: ${{ format('Check out UPX {0} source code', github.ref_name) }}
        run: |
          git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx
          git -C upx submodule update --init
          x="$(apk list -I "$(apk info -Wq "$(which clang)")")"; echo "clang_package=${x%% *}" >> $GITHUB_ENV
          x="$(apk list -I "$(apk info -Wq "$(which gcc)")")"; echo "gcc_package=${x%% *}" >> $GITHUB_ENV
          N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-weekly-ci-alpine-${{ matrix.container }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
          echo "artifact_name=$N" >> $GITHUB_ENV

      # build with C++17
      - name: ${{ format('Build clang Release with {0}', env.clang_package) }}
        run: 'make -C upx UPX_XTARGET=clang-static CC="clang -static" CXX="clang++ -static"'
      - name: ${{ format('Build clang Debug with {0}', env.clang_package) }}
        run: 'make -C upx UPX_XTARGET=clang-static CC="clang -static" CXX="clang++ -static" xtarget/debug'
      - name: ${{ format('Build gcc Release with {0}', env.gcc_package) }}
        run: 'make -C upx UPX_XTARGET=gcc-static   CC="gcc -static"   CXX="g++ -static"'
      - name: ${{ format('Build gcc Debug with {0}', env.gcc_package) }}
        run: 'make -C upx UPX_XTARGET=gcc-static   CC="gcc -static"   CXX="g++ -static" xtarget/debug'

      # build with C++20 on alpine:edge
      - name: ${{ format('Build clang C++20 Release with {0}', env.clang_package) }}
        if: ${{ contains(matrix.container, ':edge') }}
        run: |
          export UPX_CMAKE_CONFIG_FLAGS='-DUPX_CONFIG_DISABLE_CXX_STANDARD=ON -DCMAKE_VERBOSE_MAKEFILE=ON'
          make -C upx UPX_XTARGET=clang-cxx20-static CC="clang -static" CXX="clang++ -std=gnu++20 -static"
      - name: ${{ format('Build clang C++20 Debug with {0}', env.clang_package) }}
        if: ${{ contains(matrix.container, ':edge') }}
        run: |
          export UPX_CMAKE_CONFIG_FLAGS='-DUPX_CONFIG_DISABLE_CXX_STANDARD=ON -DCMAKE_VERBOSE_MAKEFILE=ON'
          make -C upx UPX_XTARGET=clang-cxx20-static CC="clang -static" CXX="clang++ -std=gnu++20 -static" xtarget/debug
      - name: ${{ format('Build gcc C++20 Release with {0}', env.gcc_package) }}
        if: ${{ contains(matrix.container, ':edge') }}
        run: |
          export UPX_CMAKE_CONFIG_FLAGS='-DUPX_CONFIG_DISABLE_CXX_STANDARD=ON -DCMAKE_VERBOSE_MAKEFILE=ON'
          make -C upx UPX_XTARGET=gcc-cxx20-static   CC="gcc -static"   CXX="g++ -std=gnu++20 -static"
      - name: ${{ format('Build gcc C++20 Debug with {0}', env.gcc_package) }}
        if: ${{ contains(matrix.container, ':edge') }}
        run: |
          export UPX_CMAKE_CONFIG_FLAGS='-DUPX_CONFIG_DISABLE_CXX_STANDARD=ON -DCMAKE_VERBOSE_MAKEFILE=ON'
          make -C upx UPX_XTARGET=gcc-cxx20-static   CC="gcc -static"   CXX="g++ -std=gnu++20 -static" xtarget/debug

      # build with C++23 on alpine:edge
      - name: ${{ format('Build clang C++23 Release with {0}', env.clang_package) }}
        if: ${{ contains(matrix.container, ':edge') }}
        run: |
          export UPX_CMAKE_CONFIG_FLAGS='-DUPX_CONFIG_DISABLE_CXX_STANDARD=ON -DCMAKE_VERBOSE_MAKEFILE=ON'
          make -C upx UPX_XTARGET=clang-cxx23-static CC="clang -static" CXX="clang++ -std=gnu++23 -static"
      - name: ${{ format('Build clang C++23 Debug with {0}', env.clang_package) }}
        if: ${{ contains(matrix.container, ':edge') }}
        run: |
          export UPX_CMAKE_CONFIG_FLAGS='-DUPX_CONFIG_DISABLE_CXX_STANDARD=ON -DCMAKE_VERBOSE_MAKEFILE=ON'
          make -C upx UPX_XTARGET=clang-cxx23-static CC="clang -static" CXX="clang++ -std=gnu++23 -static" xtarget/debug
      - name: ${{ format('Build gcc C++23 Release with {0}', env.gcc_package) }}
        if: ${{ contains(matrix.container, ':edge') }}
        run: |
          export UPX_CMAKE_CONFIG_FLAGS='-DUPX_CONFIG_DISABLE_CXX_STANDARD=ON -DCMAKE_VERBOSE_MAKEFILE=ON'
          make -C upx UPX_XTARGET=gcc-cxx23-static   CC="gcc -static"   CXX="g++ -std=gnu++23 -static"
      - name: ${{ format('Build gcc C++23 Debug with {0}', env.gcc_package) }}
        if: ${{ contains(matrix.container, ':edge') }}
        run: |
          export UPX_CMAKE_CONFIG_FLAGS='-DUPX_CONFIG_DISABLE_CXX_STANDARD=ON -DCMAKE_VERBOSE_MAKEFILE=ON'
          make -C upx UPX_XTARGET=gcc-cxx23-static   CC="gcc -static"   CXX="g++ -std=gnu++23 -static" xtarget/debug

      - { name: 'Strip release binaries', run: 'strip -p --strip-unneeded upx/build/*/*/release/upx' }
      - name: ${{ format('Upload artifact {0}', env.artifact_name) }}
        if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: missing nodejs on host
        uses: actions/upload-artifact@v3
        with:
          name: ${{ env.artifact_name }}
          path: 'upx*/build/*/*/*/upx'
      - { name: 'Run basic tests clang Release', run: 'make -C upx/build/xtarget/clang-static/release test' }
      - { name: 'Run basic tests clang Debug',   run: 'make -C upx/build/xtarget/clang-static/debug test' }
      - { name: 'Run basic tests gcc Release',   run: 'make -C upx/build/xtarget/gcc-static/release test' }
      - { name: 'Run basic tests gcc Debug',     run: 'make -C upx/build/xtarget/gcc-static/debug test' }
