From ae648d5b0fc971fbebfb98c5c68d7e2d1ba656f2 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Fri, 7 Nov 2025 15:58:15 +0100 Subject: [PATCH 1/2] chore(ci): Require `ready-to-merge` label to run all checks --- .github/workflows/e2e-v2.yml | 13 ++++-- .github/workflows/ready-to-merge-workflow.yml | 41 +++++++++++++++++++ .github/workflows/sample-application-expo.yml | 10 ++++- .github/workflows/sample-application.yml | 12 ++++-- 4 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/ready-to-merge-workflow.yml diff --git a/.github/workflows/e2e-v2.yml b/.github/workflows/e2e-v2.yml index 74b450cc16..cd89448d11 100644 --- a/.github/workflows/e2e-v2.yml +++ b/.github/workflows/e2e-v2.yml @@ -7,6 +7,7 @@ on: - v5 - release/** pull_request: + types: [opened, synchronize, reopened, labeled] concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -24,9 +25,15 @@ jobs: auth_token_check: uses: ./.github/workflows/skip-ci-noauth.yml secrets: inherit + ready-to-merge-gate: + name: Ready-to-merge gate + uses: ./.github/workflows/ready-to-merge-workflow.yml + with: + is-pr: ${{ github.event_name == 'pull_request' }} + labels: ${{ toJson(github.event.pull_request.labels) }} metrics: runs-on: ${{ matrix.runs-on }} - needs: [diff_check, auth_token_check] + needs: [ready-to-merge-gate,diff_check, auth_token_check] if: ${{ needs.diff_check.outputs.skip_ci != 'true' && needs.auth_token_check.outputs.skip_ci != 'true' && !startsWith(github.ref, 'refs/heads/release/') }} env: SENTRY_DISABLE_AUTO_UPLOAD: 'true' @@ -158,7 +165,7 @@ jobs: react-native-build: name: Build RN ${{ matrix.rn-version }} ${{ matrix.rn-architecture }} ${{ matrix.engine }} ${{ matrix.platform }} ${{ matrix.build-type }} ${{ matrix.ios-use-frameworks }} runs-on: ${{ matrix.runs-on }} - needs: [diff_check, auth_token_check] + needs: [ready-to-merge-gate,diff_check, auth_token_check] if: ${{ needs.diff_check.outputs.skip_ci != 'true' && needs.auth_token_check.outputs.skip_ci != 'true' && !startsWith(github.ref, 'refs/heads/release/') }} env: RN_VERSION: ${{ matrix.rn-version }} @@ -294,7 +301,7 @@ jobs: name: Test RN ${{ matrix.rn-version }} ${{ matrix.rn-architecture }} ${{ matrix.engine }} ${{ matrix.platform }} ${{ matrix.build-type }} ${{ matrix.ios-use-frameworks }} - needs: [react-native-build, diff_check] + needs: [ready-to-merge-gate, react-native-build, diff_check] if: ${{ needs.diff_check.outputs.skip_ci != 'true' }} runs-on: ${{ matrix.runs-on }} diff --git a/.github/workflows/ready-to-merge-workflow.yml b/.github/workflows/ready-to-merge-workflow.yml new file mode 100644 index 0000000000..402593eb85 --- /dev/null +++ b/.github/workflows/ready-to-merge-workflow.yml @@ -0,0 +1,41 @@ +name: Ready to Merge Workflow +on: + workflow_call: + inputs: + labels: + description: The GitHub event's labels + required: true + type: string + is-pr: + description: Whether the workflow is running on a PR + required: true + type: boolean + +jobs: + ready-to-merge-gate: + name: 'Missing "ready-to-merge" label' + runs-on: ubuntu-latest + steps: + - name: Check for exact 'ready-to-merge' label + if: ${{ inputs.is-pr }} + id: check-label + run: | + # Use jq to check for exact label match (avoids substring matching issues with contains()) + if echo '${{ inputs.labels }}' | jq -e '.[] | select(.name == "ready-to-merge")' > /dev/null; then + echo "label_found=true" >> $GITHUB_OUTPUT + else + echo "label_found=false" >> $GITHUB_OUTPUT + fi + # Since Github also accepts `skipped` results for Required Workflows, we need + # to fail the job to ensure that the downstream jobs don't just skip. + - name: Fail until the 'ready-to-merge' label is present + if: ${{ inputs.is-pr && steps.check-label.outputs.label_found == 'false' }} + run: | + echo "Add the 'ready-to-merge' label to run CI." + exit 1 + - name: Gate passed + if: ${{ inputs.is-pr && steps.check-label.outputs.label_found == 'true' }} + run: echo "Label present. Proceeding with CI." + - name: Gate passed + if: ${{ !inputs.is-pr }} + run: echo "Not a PR. Proceeding with CI." diff --git a/.github/workflows/sample-application-expo.yml b/.github/workflows/sample-application-expo.yml index 6d1008e5f6..7209bbeae2 100644 --- a/.github/workflows/sample-application-expo.yml +++ b/.github/workflows/sample-application-expo.yml @@ -6,6 +6,7 @@ on: - main - v5 pull_request: + types: [opened, synchronize, reopened, labeled] concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -18,11 +19,16 @@ env: jobs: diff_check: uses: ./.github/workflows/skip-ci.yml - + ready-to-merge-gate: + name: Ready-to-merge gate + uses: ./.github/workflows/ready-to-merge-workflow.yml + with: + is-pr: ${{ github.event_name == 'pull_request' }} + labels: ${{ toJson(github.event.pull_request.labels) }} build: name: Build ${{ matrix.platform }} ${{ matrix.build-type }} ${{ matrix.ios-use-frameworks}} runs-on: ${{ matrix.runs-on }} - needs: [diff_check] + needs: [ready-to-merge-gate, diff_check] if: ${{ needs.diff_check.outputs.skip_ci != 'true' }} env: SENTRY_DISABLE_AUTO_UPLOAD: 'true' diff --git a/.github/workflows/sample-application.yml b/.github/workflows/sample-application.yml index 8aa441da17..24933074f1 100644 --- a/.github/workflows/sample-application.yml +++ b/.github/workflows/sample-application.yml @@ -6,6 +6,7 @@ on: - main - v5 pull_request: + types: [opened, synchronize, reopened, labeled] concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -25,11 +26,16 @@ env: jobs: diff_check: uses: ./.github/workflows/skip-ci.yml - + ready-to-merge-gate: + name: Ready-to-merge gate + uses: ./.github/workflows/ready-to-merge-workflow.yml + with: + is-pr: ${{ github.event_name == 'pull_request' }} + labels: ${{ toJson(github.event.pull_request.labels) }} build: name: Build ${{ matrix.rn-architecture }} ${{ matrix.platform }} ${{ matrix.build-type }} ${{ matrix.ios-use-frameworks}} runs-on: ${{ matrix.runs-on }} - needs: [diff_check] + needs: [ready-to-merge-gate, diff_check] if: ${{ needs.diff_check.outputs.skip_ci != 'true' }} env: SENTRY_DISABLE_AUTO_UPLOAD: 'true' @@ -215,7 +221,7 @@ jobs: test: name: Test ${{ matrix.platform }} ${{ matrix.build-type }} REV2 runs-on: ${{ matrix.runs-on }} - needs: [diff_check, build] + needs: [ready-to-merge-gate, diff_check, build] if: ${{ needs.diff_check.outputs.skip_ci != 'true' }} strategy: # we want that the matrix keeps running, default is to cancel them if it fails. From 6fd56e71d7ad46054b2175dad5f2fa3d4b97dd33 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Mon, 10 Nov 2025 09:50:07 +0100 Subject: [PATCH 2/2] Add doc and update condition --- .github/workflows/e2e-v2.yml | 18 +++++++------ .github/workflows/native-tests.yml | 11 +++++++- .github/workflows/sample-application-expo.yml | 9 ++++--- .github/workflows/sample-application.yml | 11 +++++--- CI.md | 25 +++++++++++++++++++ 5 files changed, 58 insertions(+), 16 deletions(-) create mode 100644 CI.md diff --git a/.github/workflows/e2e-v2.yml b/.github/workflows/e2e-v2.yml index cd89448d11..bc92f2ef30 100644 --- a/.github/workflows/e2e-v2.yml +++ b/.github/workflows/e2e-v2.yml @@ -20,20 +20,22 @@ env: IOS_VERSION: '18.1' jobs: - diff_check: - uses: ./.github/workflows/skip-ci.yml - auth_token_check: - uses: ./.github/workflows/skip-ci-noauth.yml - secrets: inherit ready-to-merge-gate: name: Ready-to-merge gate uses: ./.github/workflows/ready-to-merge-workflow.yml with: is-pr: ${{ github.event_name == 'pull_request' }} labels: ${{ toJson(github.event.pull_request.labels) }} + + diff_check: + needs: [ready-to-merge-gate] + uses: ./.github/workflows/skip-ci.yml + auth_token_check: + uses: ./.github/workflows/skip-ci-noauth.yml + secrets: inherit metrics: runs-on: ${{ matrix.runs-on }} - needs: [ready-to-merge-gate,diff_check, auth_token_check] + needs: [diff_check, auth_token_check] if: ${{ needs.diff_check.outputs.skip_ci != 'true' && needs.auth_token_check.outputs.skip_ci != 'true' && !startsWith(github.ref, 'refs/heads/release/') }} env: SENTRY_DISABLE_AUTO_UPLOAD: 'true' @@ -165,7 +167,7 @@ jobs: react-native-build: name: Build RN ${{ matrix.rn-version }} ${{ matrix.rn-architecture }} ${{ matrix.engine }} ${{ matrix.platform }} ${{ matrix.build-type }} ${{ matrix.ios-use-frameworks }} runs-on: ${{ matrix.runs-on }} - needs: [ready-to-merge-gate,diff_check, auth_token_check] + needs: [diff_check, auth_token_check] if: ${{ needs.diff_check.outputs.skip_ci != 'true' && needs.auth_token_check.outputs.skip_ci != 'true' && !startsWith(github.ref, 'refs/heads/release/') }} env: RN_VERSION: ${{ matrix.rn-version }} @@ -301,7 +303,7 @@ jobs: name: Test RN ${{ matrix.rn-version }} ${{ matrix.rn-architecture }} ${{ matrix.engine }} ${{ matrix.platform }} ${{ matrix.build-type }} ${{ matrix.ios-use-frameworks }} - needs: [ready-to-merge-gate, react-native-build, diff_check] + needs: [react-native-build, diff_check] if: ${{ needs.diff_check.outputs.skip_ci != 'true' }} runs-on: ${{ matrix.runs-on }} diff --git a/.github/workflows/native-tests.yml b/.github/workflows/native-tests.yml index 2b8a087574..bf4eddfba7 100644 --- a/.github/workflows/native-tests.yml +++ b/.github/workflows/native-tests.yml @@ -7,13 +7,22 @@ on: - v5 - release/** pull_request: - + types: [opened, synchronize, reopened, labeled] + concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} jobs: + ready-to-merge-gate: + name: Ready-to-merge gate + uses: ./.github/workflows/ready-to-merge-workflow.yml + with: + is-pr: ${{ github.event_name == 'pull_request' }} + labels: ${{ toJson(github.event.pull_request.labels) }} + diff_check: + needs: [ready-to-merge-gate] uses: ./.github/workflows/skip-ci.yml test-ios: diff --git a/.github/workflows/sample-application-expo.yml b/.github/workflows/sample-application-expo.yml index 7209bbeae2..9b7c17f94d 100644 --- a/.github/workflows/sample-application-expo.yml +++ b/.github/workflows/sample-application-expo.yml @@ -17,18 +17,21 @@ env: RN_SENTRY_POD_NAME: RNSentry jobs: - diff_check: - uses: ./.github/workflows/skip-ci.yml ready-to-merge-gate: name: Ready-to-merge gate uses: ./.github/workflows/ready-to-merge-workflow.yml with: is-pr: ${{ github.event_name == 'pull_request' }} labels: ${{ toJson(github.event.pull_request.labels) }} + + diff_check: + needs: [ready-to-merge-gate] + uses: ./.github/workflows/skip-ci.yml + build: name: Build ${{ matrix.platform }} ${{ matrix.build-type }} ${{ matrix.ios-use-frameworks}} runs-on: ${{ matrix.runs-on }} - needs: [ready-to-merge-gate, diff_check] + needs: [diff_check] if: ${{ needs.diff_check.outputs.skip_ci != 'true' }} env: SENTRY_DISABLE_AUTO_UPLOAD: 'true' diff --git a/.github/workflows/sample-application.yml b/.github/workflows/sample-application.yml index 24933074f1..94a25d4579 100644 --- a/.github/workflows/sample-application.yml +++ b/.github/workflows/sample-application.yml @@ -24,18 +24,21 @@ env: ANDROID_API_LEVEL: '30' jobs: - diff_check: - uses: ./.github/workflows/skip-ci.yml ready-to-merge-gate: name: Ready-to-merge gate uses: ./.github/workflows/ready-to-merge-workflow.yml with: is-pr: ${{ github.event_name == 'pull_request' }} labels: ${{ toJson(github.event.pull_request.labels) }} + + diff_check: + needs: [ready-to-merge-gate] + uses: ./.github/workflows/skip-ci.yml + build: name: Build ${{ matrix.rn-architecture }} ${{ matrix.platform }} ${{ matrix.build-type }} ${{ matrix.ios-use-frameworks}} runs-on: ${{ matrix.runs-on }} - needs: [ready-to-merge-gate, diff_check] + needs: [diff_check] if: ${{ needs.diff_check.outputs.skip_ci != 'true' }} env: SENTRY_DISABLE_AUTO_UPLOAD: 'true' @@ -221,7 +224,7 @@ jobs: test: name: Test ${{ matrix.platform }} ${{ matrix.build-type }} REV2 runs-on: ${{ matrix.runs-on }} - needs: [ready-to-merge-gate, diff_check, build] + needs: [diff_check, build] if: ${{ needs.diff_check.outputs.skip_ci != 'true' }} strategy: # we want that the matrix keeps running, default is to cancel them if it fails. diff --git a/CI.md b/CI.md new file mode 100644 index 0000000000..09ee96b7c8 --- /dev/null +++ b/CI.md @@ -0,0 +1,25 @@ +# CI inner working + +## `ready-to-merge` label + +CI checks are great, but macOS runners are limited on every provider, because of this, we need to be smarter on how we run jobs. +To avoid running many jobs on every PR's commit, we have decided to only run a subset of tests regularily and run the full suite only when the PR has the label `ready-to-merge`. + +### How to use the gate + +Add this job at the start the workflow and then add `need: ready-to-merge-gate` to jobs that you want to be skipped. + +``` +ready-to-merge-gate: + name: Ready-to-merge gate + uses: ./.github/workflows/ready-to-merge-workflow.yml + with: + is-pr: ${{ github.event_name == 'pull_request' }} + labels: ${{ toJson(github.event.pull_request.labels) }} +``` + +This job will: + +- Pass if the event is not a PR +- Fail if the event is a PR and is missing the `ready-to-merge` label +- Pass if the event is a PR and is has the `ready-to-merge` label