| # Copyright (C) 2025 The Android Open Source Project | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| name: Perfetto CI | |
| on: | |
| # 1. postsubmit | |
| push: | |
| branches: | |
| - main | |
| # 2. presubmit | |
| pull_request: | |
| types: [opened, synchronize] | |
| branches: | |
| - main | |
| - dev/**/* | |
| permissions: | |
| pull-requests: write # Required for UI build PR comment | |
| # If a new commit is pushed, cancel previous jobs for the same PR / branch. | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.head_ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| analyze: | |
| # Unlike other workflows, this runs on the Github ubuntu-latest pool. | |
| # This is deliberate: (1) this workflow doesn't need anything special from | |
| # our 'sandbox' docker container, and GitHub's pool is just faster. | |
| # (2) when our CI autoscaler ramps down, it can take a long time until we | |
| # have some capacity to run this. In turn, delaying analyze.yml further | |
| # delays in scaling-up because we didn't queue the child jobs. | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| outputs: | |
| TRIVIAL_CHANGE: ${{ steps.trivial.outputs.TRIVIAL_CHANGE }} | |
| UI_ONLY_CHANGE: ${{ steps.ui_only.outputs.UI_ONLY_CHANGE }} | |
| BIGTRACE_CHANGE: ${{ steps.bigtrace.outputs.BIGTRACE_CHANGE }} | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 1 | |
| # Fetch the upstream branch as well, so we can diff and see the list of | |
| # changed files. | |
| - name: Fetch upstream branch | |
| if: ${{ github.base_ref != '' }} | |
| shell: bash | |
| run: git fetch origin ${{ github.base_ref }} --depth=1 | |
| - name: Check if the change is trivial (docs/infra only) | |
| id: trivial | |
| shell: bash | |
| run: | | |
| # In postsubmit (cron) github.base_ref is "" | |
| if [ -z "${{ github.base_ref }}" ] || git diff --name-only origin/${{ github.base_ref }} HEAD | egrep -qv '^(docs|infra|tools|test/data|[.]github)/'; then | |
| echo "TRIVIAL_CHANGE=0" | tee -a $GITHUB_OUTPUT | |
| else | |
| echo "TRIVIAL_CHANGE=1" | tee -a $GITHUB_OUTPUT | |
| fi | |
| - name: Check if the change is UI only (skip linux/android tests) | |
| id: ui_only | |
| shell: bash | |
| run: | | |
| # In postsubmit (cron) github.base_ref is "" | |
| if [ -z "${{ github.base_ref }}" ] || git diff --name-only origin/${{ github.base_ref }} HEAD | egrep -qv '^(ui|test/data/ui-screenshots)/'; then | |
| echo "UI_ONLY_CHANGE=0" | tee -a $GITHUB_OUTPUT | |
| else | |
| echo "UI_ONLY_CHANGE=1" | tee -a $GITHUB_OUTPUT | |
| fi | |
| - name: Check if bigtrace files changed | |
| id: bigtrace | |
| shell: bash | |
| run: | | |
| # In postsubmit (cron) github.base_ref is "" | |
| if [ -n "${{ github.base_ref }}" ] && git diff --name-only origin/${{ github.base_ref }} HEAD | egrep -q '^ui/src/bigtrace/'; then | |
| echo "BIGTRACE_CHANGE=1" | tee -a $GITHUB_OUTPUT | |
| else | |
| echo "BIGTRACE_CHANGE=0" | tee -a $GITHUB_OUTPUT | |
| fi | |
| linux: | |
| needs: analyze | |
| if: | |
| needs.analyze.outputs.UI_ONLY_CHANGE == '0' && | |
| needs.analyze.outputs.TRIVIAL_CHANGE == '0' | |
| uses: ./.github/workflows/linux-tests.yml | |
| android: | |
| needs: analyze | |
| if: | |
| needs.analyze.outputs.UI_ONLY_CHANGE == '0' && | |
| needs.analyze.outputs.TRIVIAL_CHANGE == '0' | |
| uses: ./.github/workflows/android-tests.yml | |
| ui: | |
| needs: analyze | |
| if: needs.analyze.outputs.TRIVIAL_CHANGE == '0' | |
| uses: ./.github/workflows/ui-tests.yml | |
| bazel: | |
| needs: analyze | |
| if: | |
| needs.analyze.outputs.UI_ONLY_CHANGE == '0' && | |
| needs.analyze.outputs.TRIVIAL_CHANGE == '0' | |
| uses: ./.github/workflows/bazel-tests.yml | |
| fuzzer: | |
| needs: analyze | |
| if: | |
| needs.analyze.outputs.UI_ONLY_CHANGE == '0' && | |
| needs.analyze.outputs.TRIVIAL_CHANGE == '0' | |
| uses: ./.github/workflows/fuzzer-tests.yml | |
| bigtrace: | |
| needs: analyze | |
| if: needs.analyze.outputs.BIGTRACE_CHANGE == '1' | |
| uses: ./.github/workflows/bigtrace-tests.yml | |
| repo-checks: | |
| needs: analyze | |
| uses: ./.github/workflows/repo-checks.yml | |
| rust-sdk: | |
| needs: analyze | |
| if: | |
| needs.analyze.outputs.UI_ONLY_CHANGE == '0' && | |
| needs.analyze.outputs.TRIVIAL_CHANGE == '0' | |
| uses: ./.github/workflows/rust-sdk-tests.yml | |
| # This final step joins the results of the nested workflows and succeeds if | |
| # all the non-skipped workflows have suceeded. This job is used by the | |
| # "require CI to pass" GitHub ruleset. | |
| ensure-ci-is-green: | |
| needs: | |
| - analyze | |
| - linux | |
| - android | |
| - ui | |
| - bazel | |
| - fuzzer | |
| - bigtrace | |
| - repo-checks | |
| - rust-sdk | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Ensure all non-skipped jobs have suceeded | |
| shell: bash | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| failed=0 | |
| cancelled=0 | |
| # Possible values: success, failure, cancelled, skipped | |
| # Treat unknown values as failures to be defensive. | |
| check() { | |
| job="$1" | |
| result="$2" | |
| if [ "$result" = "success" ] || [ "$result" = "skipped" ]; then | |
| : | |
| elif [ "$result" = "cancelled" ]; then | |
| echo "::notice::$job was cancelled" | |
| cancelled=1 | |
| else | |
| echo "::error::$job failed with result: $result" | |
| failed=1 | |
| fi | |
| } | |
| warn() { | |
| job="$1" | |
| result="$2" | |
| if [ "$result" = "success" ] || [ "$result" = "skipped" ]; then | |
| : | |
| elif [ "$result" = "cancelled" ]; then | |
| echo "::warning::$job was cancelled" | |
| else | |
| echo "::warning::$job failed with result: $result" | |
| fi | |
| } | |
| check linux ${{ needs.linux.result }} | |
| check android ${{ needs.android.result }} | |
| check ui ${{ needs.ui.result }} | |
| check bazel ${{ needs.bazel.result }} | |
| check fuzzer ${{ needs.fuzzer.result }} | |
| check repo-checks ${{ needs.repo-checks.result }} | |
| warn bigtrace ${{ needs.bigtrace.result }} | |
| warn rust-sdk ${{ needs.rust-sdk.result }} | |
| if [ "$failed" -eq 1 ]; then | |
| exit 1 | |
| fi | |
| if [ "$cancelled" -eq 1 ]; then | |
| echo "Some jobs were cancelled. Marking this check as cancelled." | |
| gh run cancel ${{ github.run_id }} --repo ${{ github.repository }} | |
| # Wait for the cancellation to take effect | |
| while true; do sleep 60; done | |
| fi |