dotanuki-labs/norris

View on GitHub
.github/workflows/main.yml

Summary

Maintainability
Test Coverage
name: CI

on:
  pull_request:
  push:
    branches:
      - master

concurrency: 
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true


jobs:
  code-quality:
    runs-on: ubuntu-22.04
    timeout-minutes: 10

    steps:
      - name: Project Checkout
        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

      - name: Install asdf
        uses: asdf-vm/actions/setup@v3.0.2

      - name: Install local CLI tooling
        shell: bash
        run: ./scripts/setup-asdf.sh

      - name: Check Kotlin sources
        run: ./scripts/code-style-kotlin.sh all

      - name: Check Bash sources
        run: ./scripts/code-style-bash.sh

      - name: Check typos on code
        uses: crate-ci/typos@v1.22.7

  unit-tests:
    runs-on: ubuntu-22.04
    timeout-minutes: 10
    needs: [code-quality]

    steps:
      - name: Project Checkout
        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

      - name: Setup Android Build
        uses: ./.github/actions/setup-android-build

      - name: Run unit tests
        uses: nick-fields/retry@v3.0.0
        with:
          command: ./gradlew clean test --no-daemon
          timeout_minutes: 8
          max_attempts: 5

      - name: Collect all test results from all modules
        if: always()
        run: ./scripts/aggregate-test-reports.sh build/test-reports

      - name: Archive test results
        if: always()
        uses: actions/upload-artifact@v4.3.3
        with:
          name: unit-tests-reports
          path: build/test-reports

  assemble-apk:
    runs-on: ubuntu-22.04
    timeout-minutes: 25
    needs: [code-quality]

    steps:
      - name: Project Checkout
        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

      - name: Setup Android Build
        uses: ./.github/actions/setup-android-build

      - name: Assemble APKs
        run: ./gradlew app:assembleRelease -PtestMode=true --no-daemon

      - name: Archive Release APK
        if: success()
        uses: actions/upload-artifact@v4.3.3
        with:
          name: release-apk
          path: app/build/outputs/apk/release

      - name: Archive R8 mappings
        if: success()
        uses: actions/upload-artifact@v4.3.3
        with:
          name: release-mappings
          path: app/build/outputs/mapping/release

  functional-tests:
    runs-on: ubuntu-22.04
    timeout-minutes: 25
    needs: [assemble-apk]

    steps:
      - name: Project Checkout
        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

      - name: Install asdf
        uses: asdf-vm/actions/setup@v3.0.2

      - name: Install local CLI tooling
        shell: bash
        run: ./scripts/setup-asdf.sh

      - name: Fetch Instrumentation artefacts
        uses: actions/download-artifact@v4.1.7

      - name: Run E2E tests on mobile.dev clould
        run: ./scripts/maestro.sh release-apk/app-release.apk
        env:
          MOBILE_DEV_CLOUD_TOKEN: ${{ secrets.MOBILE_DEV_CLOUD_TOKEN }}

  instrumentation-tests:
    runs-on: ubuntu-22.04
    needs: [code-quality]
    timeout-minutes: 20
    strategy:
      matrix:
        feature: [ 'facts', 'search' ]

    steps:
      - name: Project Checkout
        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

      - name: Fetch Instrumentation artefacts
        uses: actions/download-artifact@v4.1.7

      - name: Install asdf
        uses: asdf-vm/actions/setup@v3.0.2

      - name: Install local CLI tooling
        run: ./scripts/setup-asdf.sh

      - name: Setup Android Build
        uses: ./.github/actions/setup-android-build

      - name: Run instrumentation tests
        run: ./gradlew features:${{ matrix.feature }}:testDebugWithEmulatorWtf
        env:
          EW_API_TOKEN: ${{ secrets.EMULATOR_WTF_TOKEN }}

      - name: Archive test results
        if: always()
        uses: actions/upload-artifact@v4.3.3
        with:
          name: ${{ matrix.feature }}-instrumentation-tests-reports
          path: features/${{ matrix.feature }}/build/test-results

  security-analysis:
    runs-on: ubuntu-22.04
    timeout-minutes: 25
    needs: assemble-apk

    steps:
      - name: Project Checkout
        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

      - name: Install asdf
        uses: asdf-vm/actions/setup@v3.0.2

      - name: Install local CLI tooling
        run: ./scripts/setup-asdf.sh

      - name: Validate Gradle Wrapper
        uses: gradle/wrapper-validation-action@v3.4.1

      - name: Fetch APK from previous build
        uses: actions/download-artifact@v4.1.7

      - name: Compare APK with baseline
        run: aaw compare -a release-apk/app-release.apk -b .config/norris-watchdog.toml

      - name: Analyse APK with AppSweep
        uses: guardsquare/appsweep-action@main
        with:
          appsweep_api_key: ${{ secrets.APP_SWEEP_TOKEN }}
          commit_hash: ${{ steps.vars.outputs.sha_short }}
          input_file: release-apk/app-release.apk
          mapping_file: release-mappings/mapping.txt

  app-size-analysis:
    runs-on: ubuntu-22.04
    timeout-minutes: 10
    if: github.ref == 'refs/heads/master'
    needs: assemble-apk

    steps:
      - name: Project Checkout
        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

      - name: Fetch Instrumentation artefacts
        uses: actions/download-artifact@v4.1.7

      - name: Upload to EmergeTools
        uses: EmergeTools/emerge-upload-action@v1.1.0
        with:
          artifact_path: release-apk/app-release.apk
          emerge_api_key: ${{ secrets.EMERGETOOLS_API_KEY }}
          build_type: release

  test-results-analysis:
    runs-on: ubuntu-22.04
    timeout-minutes: 25
    needs: [unit-tests, instrumentation-tests, functional-tests]
    steps:
      - name: Project Checkout
        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

      - name: Fetch all artefacts
        uses: actions/download-artifact@v4.1.7

      - name: Copy all test results
        run: mkdir all-reports && mv *-tests-reports/ all-reports

      - name: Report test results
        uses: dorny/test-reporter@v1.9.1
        with:
          name: 'Test Reports'
          reporter: java-junit
          path: all-reports/**/*.xml