name: CI

on:
  pull_request:
  push:
    tags:
      - "**"
    branches:
      - main
  schedule:
    - cron: "0 0 * * *"

jobs:
  generate-config:
    runs-on: ubuntu-24.04
    permissions: write-all
    outputs:
      BIRTH_GITHUB_TARGETS: ${{ steps.generate-config.outputs.BIRTH_GITHUB_TARGETS }}
      BIRTH_CMAKE_BUILD_TYPES: ${{ steps.generate-config.outputs.BIRTH_CMAKE_BUILD_TYPES }}
      BIRTH_MACOS_IMAGE: ${{ steps.generate-config.outputs.BIRTH_LINUX_IMAGE }}
      BIRTH_LINUX_IMAGE: ${{ steps.generate-config.outputs.BIRTH_LINUX_IMAGE }}
      BIRTH_WINDOWS_IMAGE: ${{ steps.generate-config.outputs.BIRTH_WINDOWS_IMAGE }}
      RELEASE_TAG_NAME: ${{ steps.generate-tag.outputs.RELEASE_TAG_NAME }}  # Define job output here
    steps:
      - name: Check out repository
        uses: actions/checkout@v4
      - name: Generate config
        id: generate-config
        uses: birth-software/github-config@v3
      - name: Create tag
        if: github.ref == 'refs/heads/main'
        shell: bash
        id: generate-tag
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          set -eux
          git config --global user.name "github-actions"
          git config --global user.email "github-actions@github.com"
          TAG="dev"
          gh release delete $TAG --yes || true
          git tag -d $TAG || true
          git push origin --delete $TAG || true
          git fetch --tags
          git tag -l
          git tag $TAG
          git push origin $TAG
          echo "RELEASE_TAG_NAME=$TAG" >> $GITHUB_OUTPUT
  build_and_test:
    needs: generate-config
    permissions: write-all
    strategy:
      fail-fast: false
      matrix:
        os: ${{ fromJSON(needs.generate-config.outputs.BIRTH_GITHUB_TARGETS) }}
        CMAKE_BUILD_TYPE: ${{ fromJSON(needs.generate-config.outputs.BIRTH_CMAKE_BUILD_TYPES) }}
    runs-on: ${{ matrix.os }}
    env:
      BIRTH_LINUX_IMAGE: ${{ needs.generate-config.outputs.BIRTH_LINUX_IMAGE }}
      BIRTH_MACOS_IMAGE: ${{ needs.generate-config.outputs.BIRTH_MACOS_IMAGE }}
      BIRTH_WINDOWS_IMAGE: ${{ needs.generate-config.outputs.BIRTH_WINDOWS_IMAGE }}
      RELEASE_TAG_NAME: ${{ needs.generate-config.outputs.RELEASE_TAG_NAME }}
    steps:
      - name: Maximize build space
        if: matrix.os == env.BIRTH_LINUX_IMAGE
        uses: AdityaGarg8/remove-unwanted-software@v4.1
        with:
          remove-android: 'true'
          remove-dotnet: 'true'
          remove-haskell: 'true'
          remove-codeql: 'true'
          remove-docker-images: 'true'
          remove-large-packages: 'true'
          remove-cached-tools: 'true'
          remove-swapfile: 'true'
      - uses: actions/checkout@v4
      - uses: birth-software/github-setup@v3
      - name: Fetch LLVM
        id: fetch_llvm
        run: ./fetch-llvm.sh
        shell: bash
        env:
          CMAKE_BUILD_TYPE: ${{matrix.CMAKE_BUILD_TYPE}}
      - name: Build
        id: build
        run: ./project.sh
        shell: bash
        env:
          CMAKE_BUILD_TYPE: ${{matrix.CMAKE_BUILD_TYPE}}
          CMAKE_PREFIX_PATH: ${{steps.fetch_llvm.outputs.CMAKE_PREFIX_PATH}}
          BB_IS_CI: true
      - name: Test
        run: ./project.sh test all
        shell: bash
        env:
          CMAKE_BUILD_TYPE: ${{matrix.CMAKE_BUILD_TYPE}}
          CMAKE_PREFIX_PATH: ${{steps.fetch_llvm.outputs.CMAKE_PREFIX_PATH}}
          BB_IS_CI: true
      - name: Package
        id: package
        if: ${{ always() && steps.build.outcome == 'success' }}
        run: ./package.sh
        shell: bash
        env:
          CMAKE_BUILD_TYPE: ${{matrix.CMAKE_BUILD_TYPE}}
          BB_IS_CI: true
      - name: Upload artifact
        if: ${{ always() && steps.package.outcome == 'success' }}
        uses: actions/upload-artifact@v4
        with:
          name: ${{env.BLOAT_BUSTER_RELEASE_NAME_BASE}}
          if-no-files-found: 'error'
          path: ${{env.BLOAT_BUSTER_RELEASE_PATH_BASE}}.7z*
      - name: Release - Attempt 1
        id: release_attempt_1
        uses: softprops/action-gh-release@v2
        if: github.ref == 'refs/heads/main'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          name: "Development build"
          tag_name: ${{ env.RELEASE_TAG_NAME }}
          fail_on_unmatched_files: true
          make_latest: true
          files: |
            ${{ env.BLOAT_BUSTER_RELEASE_PATH_BASE }}.7z
            ${{ env.BLOAT_BUSTER_RELEASE_PATH_BASE }}.7z.b2sum
        continue-on-error: true
      - name: Release - Attempt 2
        id: release_attempt_2
        if: ${{ steps.release_attempt_1.outcome == 'failure' && github.ref == 'refs/heads/main' }}
        uses: softprops/action-gh-release@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          name: "Development build"
          tag_name: ${{ env.RELEASE_TAG_NAME }}
          fail_on_unmatched_files: true
          make_latest: true
          files: |
            ${{ env.BLOAT_BUSTER_RELEASE_PATH_BASE }}.7z
            ${{ env.BLOAT_BUSTER_RELEASE_PATH_BASE }}.7z.b2sum
        continue-on-error: true
      - name: Release - Attempt 3
        if: ${{ steps.release_attempt_2.outcome == 'failure' && github.ref == 'refs/heads/main' }}
        uses: softprops/action-gh-release@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          name: "Development build"
          tag_name: ${{ env.RELEASE_TAG_NAME }}
          fail_on_unmatched_files: true
          make_latest: true
          files: |
            ${{ env.BLOAT_BUSTER_RELEASE_PATH_BASE }}.7z
            ${{ env.BLOAT_BUSTER_RELEASE_PATH_BASE }}.7z.b2sum