name: PR Tests on: pull_request_target: types: - synchronize - labeled concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} cancel-in-progress: true jobs: gatekeeper: runs-on: ubuntu-latest outputs: scope: ${{ steps.check-scope.outputs.scope }} is_trusted: ${{ steps.check-scope.outputs.is_trusted }} steps: - name: check-scope id: check-scope uses: actions/github-script@v8 with: github-token: ${{ secrets.TFLM_BOT_REPO_TOKEN }} script: | const { data: permission } = await github.rest.repos.getCollaboratorPermissionLevel({ owner: context.repo.owner, repo: context.repo.repo, username: context.payload.pull_request.user.login }); const trustedRoles = ['admin', 'maintain', 'write', 'triage']; const isTrusted = trustedRoles.includes(permission.permission); core.setOutput('is_trusted', isTrusted ? 'true' : 'false'); const labels = context.payload.pull_request.labels.map(l => l.name); let scope = "none"; if (labels.includes('ci:full')) { scope = "all"; } else if (labels.includes('ci:ready')) { scope = "basic"; } else if (isTrusted) { // Maintainers and bots have 'basic' scope by default on every push scope = "basic"; } if (context.payload.action === 'labeled') { const labelName = context.payload.label.name; if (labelName !== 'ci:ready' && labelName !== 'ci:full') { scope = "none"; } } core.setOutput('scope', scope); approval-gate: needs: gatekeeper if: needs.gatekeeper.outputs.scope != 'none' runs-on: ubuntu-latest # If untrusted, use integration-test. Otherwise, use empty string (no gate). environment: ${{ needs.gatekeeper.outputs.is_trusted == 'false' && 'integration-test' || '' }} steps: - name: Authorize run: echo "CI Authorized." call-check-tflite-files: needs: [gatekeeper, approval-gate] if: needs.gatekeeper.outputs.scope != 'none' permissions: contents: read pull-requests: read uses: ./.github/workflows/check_tflite_files.yml with: trigger-sha: ${{ github.event.pull_request.head.sha }} pr-number: ${{ github.event.pull_request.number }} pr-body: ${{ github.event.pull_request.body }} call-core: needs: [gatekeeper, approval-gate] if: needs.gatekeeper.outputs.scope != 'none' uses: ./.github/workflows/suite_core.yml with: trigger-sha: ${{ github.event.pull_request.head.sha }} secrets: tflm-bot-token: ${{ secrets.TFLM_BOT_PACKAGE_READ_TOKEN }} call-windows: needs: [gatekeeper, approval-gate] if: needs.gatekeeper.outputs.scope != 'none' uses: ./.github/workflows/test_windows.yml with: trigger-sha: ${{ github.event.pull_request.head.sha }} call-cortex-m: needs: [gatekeeper, approval-gate] if: needs.gatekeeper.outputs.scope != 'none' uses: ./.github/workflows/suite_cortex_m.yml with: trigger-sha: ${{ github.event.pull_request.head.sha }} scope: ${{ needs.gatekeeper.outputs.scope }} secrets: tflm-bot-token: ${{ secrets.TFLM_BOT_PACKAGE_READ_TOKEN }} call-xtensa: needs: [gatekeeper, approval-gate] if: needs.gatekeeper.outputs.scope != 'none' uses: ./.github/workflows/suite_xtensa.yml with: trigger-sha: ${{ github.event.pull_request.head.sha }} scope: ${{ needs.gatekeeper.outputs.scope }} secrets: tflm-bot-token: ${{ secrets.TFLM_BOT_PACKAGE_READ_TOKEN }} call-hexagon: needs: [gatekeeper, approval-gate] if: needs.gatekeeper.outputs.scope != 'none' uses: ./.github/workflows/suite_hexagon.yml with: trigger-sha: ${{ github.event.pull_request.head.sha }} secrets: tflm-bot-token: ${{ secrets.TFLM_BOT_PACKAGE_READ_TOKEN }} call-riscv: needs: [gatekeeper, approval-gate] if: needs.gatekeeper.outputs.scope == 'all' uses: ./.github/workflows/suite_riscv.yml with: trigger-sha: ${{ github.event.pull_request.head.sha }} secrets: tflm-bot-token: ${{ secrets.TFLM_BOT_PACKAGE_READ_TOKEN }} tests-passed: needs: [gatekeeper, approval-gate, call-check-tflite-files, call-core, call-windows, call-cortex-m, call-xtensa, call-hexagon, call-riscv] if: always() runs-on: ubuntu-latest steps: - run: | # If skipped, result is 'skipped' or 'success' depending on logic? # needs.*.result contains 'skipped' if job didn't run. # We fail if any result is 'failure' or 'cancelled'. if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" || "${{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then echo "One or more dependent jobs failed." exit 1 fi # If gatekeeper said none, everything skipped. That's success (nothing failed). exit 0