name: Build

on:
  push: {}
  pull_request: {}
  release:
    types:
      - created

permissions: {}
jobs:
  linting:
    permissions:
      contents: read #  to fetch code (actions/checkout)

    name: Code Linting
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Checkwhite
        run: util/checkwhite -n
        working-directory: crawl-ref/source
      - name: Unbrace
        run: util/unbrace -n
        working-directory: crawl-ref/source

  build_source:
    permissions:
      contents: write #  for release creation (svenstaro/upload-release-action)

    name: Source Packages ${{ matrix.arch }}
    runs-on: ubuntu-latest
    if: github.event.release.tag_name != null
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0 # all history
          submodules: true
      - name: Fix tags for release # work around https://github.com/actions/checkout/issues/882
        run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* # will break on a lightweight tag
      - name: Build source packages
        run: make -j$(nproc) package-source
        working-directory: crawl-ref/source
      - name: Add build to release
        uses: svenstaro/upload-release-action@v2
        with:
          repo_token: ${{ secrets.GITHUB_TOKEN }}
          tag: ${{ github.ref }}
          file: stone_soup-${{ github.ref_name }}*
          file_glob: true

  build_linux:
    permissions:
      contents: read #  to fetch code (actions/checkout)

    name: Linux ${{ matrix.compiler }} ${{ matrix.build_opts }} ${{ matrix.debug }} ${{ matrix.build_all }} tag_upgrade=${{ matrix.tag_upgrade }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        compiler:
          - gcc
          - clang
        build_opts:
          - ""
          - WEBTILES=1
          - WEBTILES=1 USE_DGAMELAUNCH=1
          - TILES=1
        debug:
          - ""
          - FULLDEBUG=1
        tag_upgrade:
          - false
        build_all:
          - ""
        exclude:
          - compiler: gcc
            build_opts: WEBTILES=1 USE_DGAMELAUNCH=1
            debug: FULLDEBUG=1
          # Limit Clang jobs:
          # 1. Only build fulldebug
          - compiler: clang
            debug: ""
          # 2. Skip webtiles builds (all webtiles servers use GCC)
          - compiler: clang
            build_opts: WEBTILES=1 USE_DGAMELAUNCH=1
          - compiler: clang
            build_opts: WEBTILES=1
        include:
          # Jobs for tag_upgrade=true.
          - compiler: gcc
            build_opts: ""
            debug: FULLDEBUG=1
            tag_upgrade: true
            build_all: ""
          - compiler: gcc
            build_opts: WEBTILES=1 USE_DGAMELAUNCH=1
            debug: FULLDEBUG=1
            tag_upgrade: true
            build_all: ""
          - compiler: gcc
            build_opts: TILES=1
            debug: FULLDEBUG=1
            tag_upgrade: true
            build_all: ""
          - compiler: gcc
            build_opts: TILES=1
            debug: ""
            tag_upgrade: false
            build_all: BUILD_ALL=1
          - compiler: clang
            build_opts: TILES=1
            debug: ""
            tag_upgrade: false
            build_all: BUILD_ALL=1
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0 # all history
          submodules: true
      - name: Fix tags for release # work around https://github.com/actions/checkout/issues/882
        if: github.event.release.tag_name != null
        run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* # will break on a lightweight tag
      - name: Set up Python 3.8
        uses: actions/setup-python@v4
        with:
          python-version: 3.8
      - name: Install requirements.txt
        run: |
            python -m pip install --upgrade pip
            pip install -r webserver/requirements/dev.py3.txt # use this until we have a repo-wide requirements.txt
        working-directory: crawl-ref/source
      - name: Install dependencies
        run: ./deps.py --compiler ${{ matrix.compiler }} --build-opts "${{ matrix.build_opts }}" --debug-opts "${{ matrix.debug }}"
        working-directory: .github/workflows
      - name: Setup ccache
        uses: hendrikmuhs/ccache-action@v1.2
        with:
          key: linux-${{ matrix.compiler }}-${{ matrix.tag_upgrade }}-${{ matrix.build_opts }}-${{ matrix.debug }}-${{ matrix.build_all }}
          restore-keys: |
            linux-${{ matrix.compiler }}-${{ matrix.tag_upgrade }}-${{ matrix.build_opts }}-${{ matrix.debug }}-${{ matrix.build_all }}
            linux-${{ matrix.compiler }}-${{ matrix.tag_upgrade }}-${{ matrix.build_opts }}-${{ matrix.debug }}
            linux-${{ matrix.compiler }}-${{ matrix.tag_upgrade }}-${{ matrix.build_opts }}
            linux-${{ matrix.compiler }}-${{ matrix.tag_upgrade }}
            linux-${{ matrix.compiler }}
      - name: "Setup ccache: prepend path"
        run: "echo /usr/lib/ccache >> $GITHUB_PATH"
      - name: "Setup ccache: update symlinks"
        run: "/usr/sbin/update-ccache-symlinks"
      - name: Run tag upgrade scripts
        if: matrix.tag_upgrade == true
        run: |
          if ! grep -q '#define TAG_MAJOR_VERSION 34' tag-version.h ; then
            echo "::error ::CI job for TAG_MAJOR_VERSION testing needs to be updated for new major tag"
            exit 1
          fi
          sed -i'' -e 's/^#define TAG_MAJOR_VERSION 34$/#define TAG_MAJOR_VERSION 35/' tag-version.h
          util/tag-major-upgrade -t 35
          util/tag-35-upgrade.py
        working-directory: crawl-ref/source
      - run: make -j$(nproc) ${{ matrix.build_opts }} ${{ matrix.debug }} ${{ matrix.build_all }}
        working-directory: crawl-ref/source
      # Only run `make test` with TAG_MAJOR_VERSION 34 (it fails with 35).
      - if: matrix.debug == 'FULLDEBUG=1' && (matrix.build_opts == '' || matrix.build_opts == 'WEBTILES=1') && matrix.tag_upgrade == false
        run: make -j$(nproc) ${{ matrix.build_opts }} ${{ matrix.debug }} ${{ matrix.build_all }} test
        working-directory: crawl-ref/source
        env:
          TERM: dumb

  build_appimage:
    permissions:
      contents: write #  for release creation (svenstaro/upload-release-action)

    name: Linux AppImage ${{ matrix.build_type }}
    runs-on: ubuntu-latest
    if: github.event.release.tag_name != null
    strategy:
      matrix:
        build_type:
          - console
          - tiles
        build_opts:
          - LINUXDEPLOY=/tmp/linuxdeploy-x86_64.AppImage
          - TILES=1 LINUXDEPLOY=/tmp/linuxdeploy-x86_64.AppImage
        exclude:
          - build_type: console
            build_opts: TILES=1 LINUXDEPLOY=/tmp/linuxdeploy-x86_64.AppImage
          - build_type: tiles
            build_opts: LINUXDEPLOY=/tmp/linuxdeploy-x86_64.AppImage
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0 # all history
          submodules: false
      - name: Fix tags for release # work around https://github.com/actions/checkout/issues/882
        run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* # will break on a lightweight tag
      - name: Install dependencies
        run: ./deps.py --build-opts "${{ matrix.build_opts }}" --appimage
        working-directory: .github/workflows
      - name: Setup ccache
        uses: hendrikmuhs/ccache-action@v1.2
        with:
          key: appimage-${{ matrix.build_type }}
          restore-keys: |
            appimage-${{ matrix.build_type }}
            appimage
      - name: "Setup ccache: prepend path"
        run: "echo /usr/lib/ccache >> $GITHUB_PATH"
      - name: "Setup ccache: update symlinks"
        run: "/usr/sbin/update-ccache-symlinks"
      - run: make -j$(nproc) ${{ matrix.build_opts }} appimage
        working-directory: crawl-ref/source
      - name: Add build to release
        uses: svenstaro/upload-release-action@v2
        with:
          repo_token: ${{ secrets.GITHUB_TOKEN }}
          tag: ${{ github.ref }}
          file: crawl-ref/source/stone_soup-latest-linux-${{ matrix.build_type }}.x86_64.AppImage
          asset_name: dcss-$tag-linux-${{ matrix.build_type }}.x86_64.AppImage

  build_debian:
    permissions:
      contents: write #  for release creation (svenstaro/upload-release-action)

    name: Debian Packages ${{ matrix.arch }}
    runs-on: ubuntu-latest
    if: github.event.release.tag_name != null
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0 # all history
          submodules: false
      - name: Fix tags for release # work around https://github.com/actions/checkout/issues/882
        run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* # will break on a lightweight tag
      - name: Install dependencies
        run: ./deps.py --build-opts TILES=1 --debian-packages
        working-directory: .github/workflows
      - run: sudo cp crawl-ref/docs/develop/release/pbuilderrc /etc/pbuilderrc
      - name: Create i386 chroot directory
        run: sudo DEBFULLNAME=Crawl\ bot DEBEMAIL=bot@crawl.develz.org OS=debian DIST=oldstable ARCH=i386 cowbuilder --create --basepath /var/cache/pbuilder/oldstable-i386.cow
      - name: Create amd64 chroot directory
        run: sudo DEBFULLNAME=Crawl\ bot DEBEMAIL=bot@crawl.develz.org OS=debian DIST=oldstable ARCH=amd64 cowbuilder --create --basepath /var/cache/pbuilder/oldstable-amd64.cow
      - name: Build source packages
        run: make -j$(nproc) package-source
        working-directory: crawl-ref/source
      - run: mkdir -p crawl-deb
      - run: mv stone_soup-${{ github.ref_name }}-nodeps.tar.xz crawl-deb/crawl_${{ github.ref_name }}.orig.tar.xz
      - run: tar Jxf crawl_${{ github.ref_name }}.orig.tar.xz
        working-directory: crawl-deb
      - run: mv stone_soup-${{ github.ref_name }} crawl-${{ github.ref_name }}
        working-directory: crawl-deb
      - run: mv source/debian .
        working-directory: crawl-deb/crawl-${{ github.ref_name }}
      - name: Update changelog if needed
        run: .github/workflows/debian_changelog.py crawl-deb/crawl-${{ github.ref_name }}/debian/changelog ${{ github.ref_name }}
      - name: Build the i386 packages
        run: sudo DEBFULLNAME=Crawl\ bot DEBEMAIL=bot@crawl.develz.org OS=debian DIST=oldstable ARCH=i386 pdebuild
        working-directory: crawl-deb/crawl-${{ github.ref_name }}
      - name: Build the amd64 packages
        run: sudo DEBFULLNAME=Crawl\ bot DEBEMAIL=bot@crawl.develz.org OS=debian DIST=oldstable ARCH=amd64 pdebuild
        working-directory: crawl-deb/crawl-${{ github.ref_name }}
      - name: Join the release files
        run: tar Jcvf "${GITHUB_WORKSPACE}/debian.tar.xz" crawl*
        working-directory: /var/cache/pbuilder/result
      - name: Add build to release
        uses: svenstaro/upload-release-action@v2
        with:
          repo_token: ${{ secrets.GITHUB_TOKEN }}
          tag: ${{ github.ref }}
          file: debian.tar.xz
          asset_name: dcss-$tag-debian-all.tar.xz

  build_macos:
    permissions:
      contents: write #  for release creation (svenstaro/upload-release-action)

    name: macOS ${{ matrix.build_type }}
    runs-on: macos-latest
    strategy:
      matrix:
        build_type:
          # `tiles` and `console` can be used as build types to build a
          # non-universal (x86_64, unless there are ever arm runners) binary
          - tiles-universal
          - console-universal
        build_opts:
          - ""
          - TILES=y
        exclude:
          - build_type: tiles
            build_opts: ""
          - build_type: console
            build_opts: TILES=y
          - build_type: tiles-universal
            build_opts: ""
          - build_type: console-universal
            build_opts: TILES=y
    steps:
      - name: Set up Homebrew
        id: set-up-homebrew
        uses: Homebrew/actions/setup-homebrew@master
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0 # all history
      - name: Fix tags for release # work around https://github.com/actions/checkout/issues/882
        if: github.event.release.tag_name != null
        run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* # will break on a lightweight tag
      - name: Checkout submodules
        shell: bash
        run: |
          auth_header="$(git config --local --get http.https://github.com/.extraheader)"
          git submodule sync --recursive
          git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
      # Some extremely messy interactions between default runner setup and what
      # brew may or may not do here. Many closed issues around this, here's one
      # where a github actions contributor more or less says they won't fix it:
      # https://github.com/actions/runner-images/issues/9471. The issues comes
      # and goes depending on runner image versions. I believe I originally
      # found the workaround step below somewhere in:
      #   https://github.com/actions/setup-python/issues/577
      # We have the problem because libpng has python as a dep.
      # * Scenario 1: libpng forces brew to install python in `/usr/local/bin`.
      #   Then we need to clear out the pre-provided symlinks or brew will fail.
      #   Further steps use newly installed python.
      # * Scenario 2: libpng is up-to-date in the current runner. For this case,
      #   clearing out the links is safe because the runner's default path
      #   should still include
      #   `/Library/Frameworks/Python.framework/Versions/Current/bin/python`
      #   (with a lower priority than `/usr/local/bin`) and pre-installed
      #   python remains available.
      # * For both scenarios, we should install pyyaml via pip, not brew, so
      #   that it is installed for the correct python version. Installing it
      #   via `brew` doesn't work right in scenario 2.
      - name: Python install bug workaround
        run: |
          find /usr/local/bin -type l -exec sh -c 'readlink -f "$1" \
          | grep -q ^/Library/Frameworks/Python.framework/Versions/' _ {} \; -exec rm -v {} \;
      # this isn't needed with current GHA MacOS images
      #- name: Install Dependencies
      #  run: |
      #    brew install pkg-config libpng
      # To fix an error running new version of pip3 in virtualised environments.
      # > You may restore the old behavior of pip by passing
      # > the '--break-system-packages' flag to pip, or by adding
      # > 'break-system-packages = true' to your pip.conf file. The latter
      # > will permanently disable this error.
      # > If you disable this error, we STRONGLY recommend that you additionally
      # > pass the '--user' flag to pip, or set 'user = true' in your pip.conf
      # > file. Failure to do this can result in a broken Homebrew installation.
      # https://peps.python.org/pep-0668/
      - name: Install pyyaml
        run: pip3 install pyyaml --break-system-packages --user
      - name: diagnostic
        run: |
          echo $PATH
          which python
      - name: Setup ccache
        uses: hendrikmuhs/ccache-action@v1.2
        with:
          key: macos-clang-${{ matrix.build_type }}
          restore-keys: |
            macos-clang-${{ matrix.build_type }}
            macos-clang
      - name: "Setup ccache: prepend path"
        run: "echo $(brew --prefix)/opt/ccache/libexec >> $GITHUB_PATH"
      - run: make -j$(sysctl -n hw.ncpu) mac-app-${{ matrix.build_type }} ${{matrix.build_opts }}
        working-directory: crawl-ref/source
      - name: Add build to release
        if: github.event.release.tag_name != null
        uses: svenstaro/upload-release-action@v2
        with:
          repo_token: ${{ secrets.GITHUB_TOKEN }}
          tag: ${{ github.ref }}
          file: crawl-ref/source/mac-app-zips/latest.zip
          asset_name: dcss-$tag-macos-${{ matrix.build_type}}.zip

  build_mingw64_crosscompile:
    permissions:
      contents: write #  for release creation (svenstaro/upload-release-action)

    name: mingw64 ${{ matrix.build_type }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        build_type:
          - tiles
          - console
          - installer
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0 # all history
      - name: Fix tags for release # work around https://github.com/actions/checkout/issues/882
        if: github.event.release.tag_name != null
        run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* # will break on a lightweight tag
      - name: Checkout submodules (for crosscompile)
        shell: bash
        run: |
          auth_header="$(git config --local --get http.https://github.com/.extraheader)"
          git submodule sync --recursive
          git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
      - name: Set up Python 3.8
        uses: actions/setup-python@v4
        with:
          python-version: 3.8
      - name: Install requirements.txt
        run: |
            python -m pip install --upgrade pip
            pip install -r webserver/requirements/dev.py3.txt # use this until we have a repo-wide requirements.txt
        working-directory: crawl-ref/source
      - name: Install dependencies
        run: ./deps.py --crosscompile
        working-directory: .github/workflows
      - name: Setup ccache
        uses: hendrikmuhs/ccache-action@v1.2
        with:
          key: key2-mingw64-${{ matrix.build_type }}
          restore-keys: |
            key2-mingw64-${{ matrix.build_type }}
            key2-mingw64
      - name: "Setup ccache: prepend path"
        run: "echo /usr/lib/ccache >> $GITHUB_PATH"
      - name: "Setup ccache: update symlinks"
        run: "/usr/sbin/update-ccache-symlinks"
      - run: make -j$(nproc) CROSSHOST=i686-w64-mingw32 package-windows-${{ matrix.build_type }}
        working-directory: crawl-ref/source
      # The zip & installer targets create different sorts of names, so we need
      # a little shell script magic here.
      - name: Determine release file names
        if: github.event.release.tag_name != null
        id: release-names
        run: |
          if [[ ${{ matrix.build_type }} != installer ]] ; then
            source='crawl-ref/source/stone_soup-latest-${{ matrix.build_type}}-win32.zip'
            dest='dcss-$tag-win32-${{ matrix.build_type}}.zip'
          else
            source='crawl-ref/source/stone_soup-latest-win32-installer.exe'
            dest='dcss-$tag-win32-installer.exe'
          fi
          echo "source=${source}" >> $GITHUB_OUTPUT
          echo "dest=${dest}" >> $GITHUB_OUTPUT
      - name: Add build to release
        if: github.event.release.tag_name != null
        uses: svenstaro/upload-release-action@v2
        with:
          repo_token: ${{ secrets.GITHUB_TOKEN }}
          tag: ${{ github.ref }}
          file: ${{ steps.release-names.outputs.source }}
          asset_name: ${{ steps.release-names.outputs.dest }}

  codecov_catch2:
    permissions:
      contents: read #  to fetch code (actions/checkout)

    name: Catch2 (GCC/Linux) + Codecov
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0 # all history
      - name: Set up Python 3.8
        uses: actions/setup-python@v4
        with:
          python-version: 3.8
      - name: Install requirements.txt
        run: |
            python -m pip install --upgrade pip
            pip install -r webserver/requirements/dev.py3.txt # use this until we have a repo-wide requirements.txt
        working-directory: crawl-ref/source
      - name: Install dependencies
        run: ./deps.py --coverage
        working-directory: .github/workflows
      - name: Setup ccache
        uses: hendrikmuhs/ccache-action@v1.2
        with:
          key: catch2
          restore-keys: |
            catch2
      - name: "Setup ccache: prepend path"
        run: "echo /usr/lib/ccache >> $GITHUB_PATH"
      - name: "Setup ccache: update symlinks"
        run: "/usr/sbin/update-ccache-symlinks"
      - run: make -j$(nproc) catch2-tests
        working-directory: crawl-ref/source
      - name: Generate LCOV data
        working-directory: crawl-ref/source
        run: >
          lcov
          --capture
          --directory .
          --output-file ../../coverage.info
          --ignore-errors source
          --rc lcov_branch_coverage=1
      - name: Send coverage data to Codecov
        uses: codecov/codecov-action@v3
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          files: ./coverage.info
          flags: catch2
          fail_ci_if_error: false

  webserver:
    permissions:
      contents: read #  to fetch code (actions/checkout)

    runs-on: ubuntu-20.04 # TODO: go back to ubuntu-latest
    strategy:
      matrix:
        # oldest non-eol security release + current bugfix version
        #   https://devguide.python.org/versions/
        # TODO: 3.12 is currently broken because of requirements.txt brittleness
        python-version: [3.8, 3.11]
    steps:
    - uses: actions/checkout@v3
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v4
      with:
        python-version: ${{ matrix.python-version }}
    - name: Install dependencies (py3)
      working-directory: crawl-ref/source/webserver
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements/dev.py3.txt
    - name: Lint (flake8)
      working-directory: crawl-ref/source/webserver
      run: make lint
    - name: Unit Tests (pytest)
      working-directory: crawl-ref/source/webserver
      run: pytest
    - name: Unit Tests (unittest)
      working-directory: crawl-ref/source/webserver
      run: python -m unittest webtiles.userdb

  build_headers:
    permissions:
      contents: read #  to fetch code (actions/checkout)

    name: Build headers ${{ matrix.compiler }} ${{ matrix.build_opts }} ${{ matrix.debug }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        compiler:
          - gcc
          - clang
        build_opts:
          - ""
          - WEBTILES=1
          - TILES=1
        debug:
          - ""
          - FULLDEBUG=1
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0 # all history
      - name: Set up Python 3.8
        uses: actions/setup-python@v4
        with:
          python-version: 3.8
      - name: Install requirements.txt
        run: |
            python -m pip install --upgrade pip
            pip install -r webserver/requirements/dev.py3.txt # use this until we have a repo-wide requirements.txt
        working-directory: crawl-ref/source
      - name: Install dependencies
        run: ./deps.py --compiler ${{ matrix.compiler }} --build-opts "${{ matrix.build_opts }}" --debug-opts "${{ matrix.debug }}"
        working-directory: .github/workflows
      - name: Setup ccache
        uses: hendrikmuhs/ccache-action@v1.2
        with:
          key: build-headers-${{ matrix.compiler }}-${{ matrix.build_opts }}-${{ matrix.debug }}
          restore-keys: |
            build-headers-${{ matrix.compiler }}-${{ matrix.build_opts }}-${{ matrix.debug }}
            build-headers-${{ matrix.compiler }}-${{ matrix.build_opts }}
            build-headers-${{ matrix.compiler }}
            build-headers
      - name: "Setup ccache: prepend path"
        run: "echo /usr/lib/ccache >> $GITHUB_PATH"
      - name: "Setup ccache: update symlinks"
        run: "/usr/sbin/update-ccache-symlinks"
      - run: make -j$(nproc) header-build-tests
        working-directory: crawl-ref/source

  build_android:
    name: Android
    runs-on: ubuntu-latest
    strategy:
      matrix:
        build_opts:
          - ANDROID=1
    env:
      NDK_CCACHE: ccache
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0 # all history
          submodules: true
      - name: Fix tags for release # work around https://github.com/actions/checkout/issues/882
        if: github.event.release.tag_name != null
        run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* # will break on a lightweight tag
      - name: Install dependencies
        run: ./deps.py --build-opts "${{ matrix.build_opts }}"
        working-directory: .github/workflows
      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3
        with:
          gradle-version: 8.7 # compatible with Android Gradle plugin 8.5
      - name: Setup ccache
        uses: hendrikmuhs/ccache-action@v1.2
        with:
          key: android
          restore-keys: |
            android
      - name: "Setup ccache: extra configuration"
        run: "ccache --set-config compiler_check=content"
      - name: "Setup ccache: prepend path"
        run: "echo /usr/lib/ccache >> $GITHUB_PATH"
      - name: "Setup ccache: update symlinks"
        run: "/usr/sbin/update-ccache-symlinks"
      - name: Prepare Android build
        run: make -j$(nproc) ${{ matrix.build_opts }} android
        working-directory: crawl-ref/source
      - name: Build with Gradle
        run: gradle :app:assembleBuildTest
        working-directory: crawl-ref/source/android-project

  notify_irc:
    name: "Notify #crawl-dev of build failure"
    needs:
      - linting
      - build_linux
      - build_macos
      - build_mingw64_crosscompile
      - codecov_catch2
      - webserver
    if: failure() && github.event_name == 'push'
    runs-on: ubuntu-latest
    steps:
      - name: Build message
        id: message
        run: |
          ref="${{ github.ref }}"
          branch="${ref##refs/heads/}"
          sha="${{ github.sha }}"
          short_sha="${sha:0:8}"

          # https://modern.ircdocs.horse/formatting.html
          bold=$(printf '\x02')
          col=$(printf '\x03')
          red="04"
          magenta="06"
          yellow="08"
          url="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
          message="${bold}${col}${red}Build failed${col}${bold} for ${col}${yellow}${branch}${col} @ $short_sha ${col}${magenta}${url}"

          echo "message=${message}" >> $GITHUB_OUTPUT
      - uses: rectalogic/notify-irc@v1
        with:
          server: irc.libera.chat
          channel: ${{ secrets.IRC_CHANNEL }}
          nickname: dcss-ci
          message: ${{ steps.message.outputs.message }}
