name: "IGListKit CI"

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - '*'

jobs:
  macOS:
    name: Unit Test macOS
    runs-on: macos-14
    env:
      DEVELOPER_DIR: /Applications/Xcode.app
      PROJECT_NAME: IGListKit.xcodeproj
      SCHEME_NAME: IGListKit-macOS
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Cache RubyGems
        uses: actions/cache@v3
        with:
          path: vendor/bundle
          key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
          restore-keys: |
            ${{ runner.os }}-gems-

      - name: Install ruby gems.
        run: bundle install

      - name: Run unit tests for macOS
        run: |
          set -o pipefail
          xcodebuild build build-for-testing -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "platform=macOS" -configuration Debug CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=YES | bundle exec xcpretty -c
          xcodebuild analyze test-without-building -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "platform=macOS" -configuration Debug CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=YES | bundle exec xcpretty -c

  iOS:
    name: Unit Test iOS
    runs-on: macos-14
    env:
      DEVELOPER_DIR: /Applications/Xcode.app
      PROJECT_NAME: IGListKit.xcodeproj
      SCHEME_NAME: IGListKit
    strategy:
      matrix:
        destination: ["platform=iOS Simulator,name=iPhone 16 Pro Max,OS=18.2"]
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Cache RubyGems
        uses: actions/cache@v3
        with:
          path: vendor/bundle
          key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
          restore-keys: |
            ${{ runner.os }}-gems-

      - name: Install ruby gems.
        run: bundle install

      - name: iOS - ${{ matrix.destination }}
        run: |
          set -o pipefail
          xcodebuild build build-for-testing -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "${{ matrix.destination }}" -configuration Debug CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=YES | bundle exec xcpretty -c
          xcodebuild analyze test-without-building -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "${{ matrix.destination }}" -configuration Debug CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=YES | bundle exec xcpretty -c

      - name: Upload code coverage
        run: bundle exec slather
        env:
          COVERAGE_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          CI_PULL_REQUEST: ${{ github.event.number }}
          GIT_BRANCH: ${{ github.head_ref || github.ref_name }}

  tvOS:
    name: Unit Test tvOS
    runs-on: macos-14
    env:
      DEVELOPER_DIR: /Applications/Xcode.app
      PROJECT_NAME: IGListKit.xcodeproj
      SCHEME_NAME: IGListKit-tvOS
    strategy:
      matrix:
        destination: ["platform=tvOS Simulator,name=Apple TV,OS=18.2"]
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Cache RubyGems
        uses: actions/cache@v3
        with:
          path: vendor/bundle
          key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
          restore-keys: |
            ${{ runner.os }}-gems-

      - name: Install ruby gems.
        run: bundle install

      - name: Run unit tests for tvOS
        run: |
          set -o pipefail
          xcodebuild build build-for-testing -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "${{ matrix.destination }}" -configuration Debug CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=YES | bundle exec xcpretty -c
          xcodebuild analyze test-without-building -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "${{ matrix.destination }}" -configuration Debug CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=YES | bundle exec xcpretty -c

  CocoaPods:
    name: CocoaPods Lint
    runs-on: macos-14
    env:
      DEVELOPER_DIR: /Applications/Xcode.app
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Cache RubyGems
        uses: actions/cache@v3
        with:
          path: vendor/bundle
          key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
          restore-keys: |
            ${{ runner.os }}-gems-

      - name: Install ruby gems.
        run: bundle install

      - name: Run IGListDiffKit podspec lint
        run: bundle exec pod lib lint IGListDiffKit.podspec --allow-warnings

      - name: Run IGListKit podspec lint
        run: bundle exec pod lib lint IGListKit.podspec --allow-warnings "--include-podspecs=IGListDiffKit.podspec"

      - name: Run IGListSwiftKit podspec lint
        run: bundle exec pod lib lint IGListSwiftKit.podspec --allow-warnings "--include-podspecs=*.podspec"

  SPM-layout-generator:
    name: Verify generate_spm_sources_layout.sh is not broken
    runs-on: macos-14
    env:
      DEVELOPER_DIR: /Applications/Xcode.app
      PROJECT_NAME: IGListKit.xcodeproj
      IOS_DESTINATION: "platform=iOS Simulator,name=iPhone 16 Pro Max,OS=18.2"
      SPM_IG_LIST_DIFF_KIT_PUBLIC_HEADERS_PATH: "spm/Sources/IGListDiffKit/include"
      SPM_IG_LIST_DIFF_KIT_SOURCES_PATH: "spm/Sources/IGListDiffKit"
      SPM_IG_LIST_KIT_PUBLIC_HEADERS_PATH: "spm/Sources/IGListKit/include"
      SPM_IG_LIST_KIT_SOURCES_PATH: "spm/Sources/IGListKit"
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Manually clean SPM Sources folder
        run: |
            rm -rf "${{ env.SPM_IG_LIST_DIFF_KIT_PUBLIC_HEADERS_PATH }}/*.*"
            rm -rf "${{ env.SPM_IG_LIST_DIFF_KIT_SOURCES_PATH }}/*.*"
            rm -rf "${{ env.SPM_IG_LIST_KIT_PUBLIC_HEADERS_PATH }}/*.*"
            rm -rf "${{ env.SPM_IG_LIST_KIT_SOURCES_PATH }}/*.*"

      - name: Regenerate SPM layout
        run: sh scripts/generate_spm_sources_layout.sh

      - name: Clean project's ${{ env.PROJECT_NAME }}
        run: |
          rm -rf "${{ env.PROJECT_NAME }}"

      - name: Verify IGListKit can be build using Package.swift which was generated by 'scripts/generate_spm_sources_layout.sh'
        run: xcodebuild -scheme "IGListKit" build -destination "${{ env.IOS_DESTINATION }}" | xcpretty

  SPM-build-from-Package:
    name: Verify SPM build by invoking `xcodebuild` on Package.swift
    runs-on: macos-14
    env:
      DEVELOPER_DIR: /Applications/Xcode.app
      PROJECT_NAME: IGListKit.xcodeproj
      IOS_DESTINATION: "platform=iOS Simulator,name=iPhone 16 Pro Max,OS=18.2"
    strategy:
      matrix:
        schemeName: ["IGListDiffKit",
                      "IGListKit",
                      "IGListSwiftKit"]
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Clean project's ${{ env.PROJECT_NAME }}
        run: |
          rm -rf "${{ env.PROJECT_NAME }}"

      - name: Run ${{ matrix.schemeName}} using Package.swift
        run: xcodebuild -scheme "${{ matrix.schemeName}}" build -destination "${{ env.IOS_DESTINATION }}" | xcpretty

  Carthage-XCFramework:
    name: Verify Carthage build XCFramework
    runs-on: macos-14
    env:
      DEVELOPER_DIR: /Applications/Xcode.app
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Carthage build framework
        run: carthage build --no-skip-current --use-xcframeworks

  Build-Examples:
    name: Build Examples and UI tests.
    runs-on: macos-14
    env:
      DEVELOPER_DIR: /Applications/Xcode.app
      IOS_EXAMPLE_XCODEPROJ: Examples/Examples-iOS/IGListKitExamples.xcodeproj
      TVOS_EXAMPLE_XCODEPROJ: Examples/Examples-tvOS/IGListKitExamples.xcodeproj
      MACOS_EXAMPLE_XCODEPROJ: Examples/Examples-macOS/IGListKitExamples.xcodeproj
      EXAMPLE_SCHEME: IGListKitExamples
    strategy:
      matrix:
        iosDestination: ["platform=iOS Simulator,name=iPhone 16 Pro Max,OS=18.2"]
        tvOSDestination: ["platform=tvOS Simulator,name=Apple TV 4K (3rd generation)"]
        macOSDestination: ["platform=macOS"]
        macCatalystDestination: ["platform=macOS,variant=Mac Catalyst"]
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Cache RubyGems
        uses: actions/cache@v3
        with:
          path: vendor/bundle
          key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
          restore-keys: |
            ${{ runner.os }}-gems-

      - name: Install ruby gems.
        run: bundle install

      - name: Preboot iOS Simulator
        uses: futureware-tech/simulator-action@v2
        with:
          model: 'iPhone 16 Pro Max'
          os_version: '=18.2'

      - name: Build iOS Example - ${{ matrix.iosDestination }}
        run: |
          set -o pipefail
          xcodebuild build build-for-testing -project "${{ env.IOS_EXAMPLE_XCODEPROJ }}" -scheme "${{ env.EXAMPLE_SCHEME }}" -destination "${{ matrix.iosDestination }}" -configuration Debug ONLY_ACTIVE_ARCH=YES CODE_SIGNING_REQUIRED=NO | bundle exec xcpretty -c

      - name: Run iOS Example's UI Tests - ${{ matrix.iosDestination }}
        run: |
          set -o pipefail
          xcodebuild build test -project "${{ env.IOS_EXAMPLE_XCODEPROJ }}" -scheme "${{ env.EXAMPLE_SCHEME }}" -destination "${{ matrix.iosDestination }}" -configuration Debug ONLY_ACTIVE_ARCH=YES CODE_SIGNING_REQUIRED=NO | bundle exec xcpretty -c

      - name: Build tvOS Example - ${{ matrix.tvOSDestination }}
        run: |
          set -o pipefail
          xcodebuild build -project "${{ env.TVOS_EXAMPLE_XCODEPROJ }}" -scheme "${{ env.EXAMPLE_SCHEME }}" -destination "${{ matrix.tvOSDestination }}" -configuration Debug ONLY_ACTIVE_ARCH=YES CODE_SIGNING_REQUIRED=NO | bundle exec xcpretty -c

      - name: Build macOS Example - ${{ matrix.macOSDestination }}
        run: |
          set -o pipefail
          xcodebuild build -project "${{ env.MACOS_EXAMPLE_XCODEPROJ }}" -scheme "${{ env.EXAMPLE_SCHEME }}" -destination "${{ matrix.macOSDestination }}" -configuration Debug ONLY_ACTIVE_ARCH=YES CODE_SIGNING_REQUIRED=NO | bundle exec xcpretty -c

      - name: Build Mac Catalyst Example - ${{ matrix.macCatalystDestination }}
        run: |
          set -o pipefail
          xcodebuild build -project "${{ env.IOS_EXAMPLE_XCODEPROJ }}" -scheme "${{ env.EXAMPLE_SCHEME }}" -destination "${{ matrix.macCatalystDestination }}" -configuration Debug ONLY_ACTIVE_ARCH=YES CODE_SIGNING_REQUIRED=NO | bundle exec xcpretty -c

  Danger:
    name: Run Danger
    if: github.event_name == 'pull_request'
    runs-on: macos-14
    env:
      DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Cache RubyGems
        uses: actions/cache@v3
        with:
          path: vendor/bundle
          key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
          restore-keys: |
            ${{ runner.os }}-gems-

      - name: Install ruby gems.
        run: bundle install

      - name: Run Danger
        run: bundle exec danger --verbose

