name: CI on: push: branches: - master pull_request: # This allows a subsequently queued workflow run to interrupt previous runs concurrency: group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}' cancel-in-progress: true jobs: setup: name: Prepare workflow data runs-on: ubuntu-latest timeout-minutes: 2 outputs: config-path: ${{ steps.load-config.outputs.config-path }} device-list: ${{ steps.load-config.outputs.device-list }} magisk-key: ${{ steps.cache-keys.outputs.magisk-key }} img-key-prefix: ${{ steps.cache-keys.outputs.img-key-prefix }} img-hit: ${{ steps.get-img-cache.outputs.cache-matched-key }} tox-key-prefix: ${{ steps.cache-keys.outputs.tox-key-prefix }} tox-hit: ${{ steps.get-tox-cache.outputs.cache-matched-key }} steps: - uses: actions/checkout@v3 with: submodules: true - uses: awalsh128/cache-apt-pkgs-action@v1 with: packages: python3-strictyaml - name: Loading test config id: load-config shell: python run: | import json import os import sys sys.path.append(os.environ['GITHUB_WORKSPACE']) import tests.config config_data = tests.config.load_config() devices = [d.data for d in config_data['device']] with open(os.environ['GITHUB_OUTPUT'], 'a') as f: f.write(f'config-path={tests.config.CONFIG_PATH}\n') f.write(f"device-list={json.dumps(devices)}\n") - name: Generating cache keys id: cache-keys run: | { echo "tox-key-prefix=tox-${{ hashFiles('tox.ini') }}-"; \ echo "img-key-prefix=img-${{ hashFiles(steps.load-config.outputs.config-path) }}-"; \ echo "magisk-key=magisk-${{ hashFiles(steps.load-config.outputs.config-path) }}"; } >> $GITHUB_OUTPUT - name: Checking for cached tox environments id: get-tox-cache uses: actions/cache/restore@v3 with: key: ${{ steps.cache-keys.outputs.tox-key-prefix }} lookup-only: true path: | .tox/ ~/.cache/pip - name: Checking for cached device images id: get-img-cache uses: actions/cache/restore@v3 with: key: ${{ steps.cache-keys.outputs.img-key-prefix }} lookup-only: true path: | tests/files/${{ fromJSON(steps.load-config.outputs.device-list)[0] }}-sparse.tar - name: Checking for cached magisk apk id: get-magisk-cache uses: actions/cache/restore@v3 with: key: ${{ steps.cache-keys.outputs.magisk-key }} lookup-only: true path: tests/files/magisk - name: Preloading Magisk cache if: ${{ ! steps.get-magisk-cache.outputs.cache-hit }} uses: ./.github/actions/preload-magisk-cache with: cache-key: ${{ steps.cache-keys.outputs.magisk-key }} preload-img: name: Preload device images runs-on: ubuntu-latest needs: setup timeout-minutes: 5 # Assume that preloading always succesfully cached all images before. # If for some reason only some got cached, on the first run, the cache will not be preloaded # which will result in some being downloaded multiple times when running the tests. if: ${{ ! needs.setup.outputs.img-hit }} strategy: matrix: device: ${{ fromJSON(needs.setup.outputs.device-list) }} steps: - uses: actions/checkout@v3 with: submodules: true - name: Preloading image cache uses: ./.github/actions/preload-img-cache with: cache-key-prefix: ${{ needs.setup.outputs.img-key-prefix }} device: ${{ matrix.device }} preload-tox: name: Preload tox environments runs-on: ubuntu-latest needs: setup timeout-minutes: 5 # Assume that preloading always succesfully cached all tox environments before. # If for some reason only some got cached, on the first run, the cache will not be preloaded # which will result in some being downloaded multiple times when running the tests. if: ${{ ! needs.setup.outputs.tox-hit }} strategy: matrix: python: [py39, py310, py311] steps: - uses: actions/checkout@v3 - name: Preloading tox cache uses: ./.github/actions/preload-tox-cache with: cache-key-prefix: ${{ needs.setup.outputs.tox-key-prefix }} python-version: ${{ matrix.python }} - name: Generating tox environment run: tox -e ${{ matrix.python }} --notest tests: name: Run test for ${{ matrix.device }} with ${{ matrix.python }} runs-on: ubuntu-latest needs: [setup, preload-img, preload-tox] timeout-minutes: 10 # Continue on skipped but not on failures or cancels if: ${{ always() && ! failure() && ! cancelled() }} strategy: matrix: device: ${{ fromJSON(needs.setup.outputs.device-list) }} python: [py39, py310, py311] steps: - uses: actions/checkout@v3 with: submodules: true - name: Restoring Magisk cache uses: ./.github/actions/preload-magisk-cache with: cache-key: ${{ needs.setup.outputs.magisk-key }} - name: Restoring image cache uses: ./.github/actions/preload-img-cache with: cache-key-prefix: ${{ needs.setup.outputs.img-key-prefix }} device: ${{ matrix.device }} - name: Restoring tox cache uses: ./.github/actions/preload-tox-cache with: cache-key-prefix: ${{ needs.setup.outputs.tox-key-prefix }} python-version: ${{ matrix.python }} # Finally run tests - name: Run test for ${{ matrix.device }} with ${{ matrix.python }} run: tox -e ${{ matrix.python }} -- --stripped -d ${{ matrix.device }}