From d2c5d81051f57e6cd70131541dac29e9e41e5f3f Mon Sep 17 00:00:00 2001 From: Josh Black Date: Wed, 7 Oct 2026 12:27:04 -0500 Subject: [PATCH 1/6] ci: add integration-result workflow for managing labels --- .github/workflows/integration-result.yml | 68 ++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 .github/workflows/integration-result.yml diff --git a/.github/workflows/integration-result.yml b/.github/workflows/integration-result.yml new file mode 100644 index 00000000000..4b00d4518c9 --- /dev/null +++ b/.github/workflows/integration-result.yml @@ -0,0 +1,68 @@ +name: integration-result + +on: + status: + +jobs: + label: + if: ${{ startsWith(github.event.context, 'github-ui') }} + runs-on: ubuntu-latest + steps: + - name: Get status check results + id: integration + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + SHA: ${{ github.event.sha }} + shell: bash + run: | + statuses=$(gh api --paginate --slurp \ + "repos/$GH_REPO/commits/$SHA/status?per_page=100") + + passing=$(jq ' + [.[].statuses[] | select(.context | startswith("github-ui"))] + | length > 0 and all(.[]; .state == "success") + ' <<< "$statuses") + + echo "passing=$passing" >> "$GITHUB_OUTPUT" + - name: Add passing integration label + if: ${{ steps.integration.outputs.passing == 'true' } + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + LABELS=$(gh pr -R "$GH_REPO" view ${{ github.event.pull_request.number }} --json labels | jq -r '.labels | map(.name) | join(",")') + HAS_PASSING_LABEL=$(echo "$LABELS" | grep -c "integration-tests: passing") + HAS_FAILING_LABEL=$(echo "$LABELS" | grep -c "integration-tests: failing") + + if [ "$HAS_PASSING_LABEL" -eq 0 ]; then + echo "Adding 'integration-tests: passing' label" + gh pr -R "$GH_REPO" edit "$PR_NUMBER" --add-label "integration-tests: passing" + fi + + if [ "$HAS_FAILING_LABEL" -gt 0 ]; then + echo "Removing 'integration-tests: failing' label" + gh pr -R "$GH_REPO" edit "$PR_NUMBER" --remove-label "integration-tests: failing" + fi + run: + - name: Add failing integration label + if: ${{ steps.integration.outputs.passing != 'true' } + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + LABELS=$(gh pr -R "$GH_REPO" view ${{ github.event.pull_request.number }} --json labels | jq -r '.labels | map(.name) | join(",")') + HAS_PASSING_LABEL=$(echo "$LABELS" | grep -c "integration-tests: passing") + HAS_FAILING_LABEL=$(echo "$LABELS" | grep -c "integration-tests: failing") + + if [ "$HAS_FAILING_LABEL" -eq 0 ]; then + echo "Adding 'integration-tests: failing' label" + gh pr -R "$GH_REPO" edit "$PR_NUMBER" --add-label "integration-tests: failing" + fi + + if [ "$HAS_PASSING_LABEL" -gt 0 ]; then + echo "Removing 'integration-tests: passing' label" + gh pr -R "$GH_REPO" edit "$PR_NUMBER" --remove-label "integration-tests: passing" + fi From 090c2fc392b14fc33b38a33a9836a1c763dea50a Mon Sep 17 00:00:00 2001 From: Josh Black Date: Wed, 7 Oct 2026 12:29:54 -0500 Subject: [PATCH 2/6] ci: only run workflow on final status check states --- .github/workflows/integration-result.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration-result.yml b/.github/workflows/integration-result.yml index 4b00d4518c9..66c311b6cf6 100644 --- a/.github/workflows/integration-result.yml +++ b/.github/workflows/integration-result.yml @@ -5,7 +5,9 @@ on: jobs: label: - if: ${{ startsWith(github.event.context, 'github-ui') }} + if: >- + startsWith(github.event.context, 'github-ui') && + contains(fromJSON('["success", "failure", "error"]'), github.event.state) runs-on: ubuntu-latest steps: - name: Get status check results From b7c3b2d1e2ba2368f23a404902c09aadb69e436b Mon Sep 17 00:00:00 2001 From: Josh Black Date: Wed, 7 Oct 2026 12:34:22 -0500 Subject: [PATCH 3/6] fix(ci): ignore manually overridden integration statuses Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8179c399-5285-4340-bdfc-d0d00ada417f --- .github/workflows/integration-result.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/integration-result.yml b/.github/workflows/integration-result.yml index 66c311b6cf6..cde0793e99f 100644 --- a/.github/workflows/integration-result.yml +++ b/.github/workflows/integration-result.yml @@ -7,7 +7,9 @@ jobs: label: if: >- startsWith(github.event.context, 'github-ui') && - contains(fromJSON('["success", "failure", "error"]'), github.event.state) + contains(fromJSON('["success", "failure", "error"]'), github.event.state) && + github.event.description != 'Skipped' && + github.event.description != 'Manual override' runs-on: ubuntu-latest steps: - name: Get status check results @@ -28,7 +30,7 @@ jobs: echo "passing=$passing" >> "$GITHUB_OUTPUT" - name: Add passing integration label - if: ${{ steps.integration.outputs.passing == 'true' } + if: ${{ steps.integration.outputs.passing == 'true' }} env: GH_TOKEN: ${{ github.token }} GH_REPO: ${{ github.repository }} @@ -47,10 +49,9 @@ jobs: echo "Removing 'integration-tests: failing' label" gh pr -R "$GH_REPO" edit "$PR_NUMBER" --remove-label "integration-tests: failing" fi - run: - name: Add failing integration label - if: ${{ steps.integration.outputs.passing != 'true' } - env: + if: ${{ steps.integration.outputs.passing != 'true' }} + env: GH_TOKEN: ${{ github.token }} GH_REPO: ${{ github.repository }} PR_NUMBER: ${{ github.event.pull_request.number }} From 9eb1e479e7408c947ebbdd5ddd3f3128efbd3c7b Mon Sep 17 00:00:00 2001 From: Josh Black Date: Wed, 7 Oct 2026 12:44:22 -0500 Subject: [PATCH 4/6] fix(ci): resolve integration status pull request Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8179c399-5285-4340-bdfc-d0d00ada417f --- .github/workflows/integration-result.yml | 88 +++++++++++++++--------- 1 file changed, 57 insertions(+), 31 deletions(-) diff --git a/.github/workflows/integration-result.yml b/.github/workflows/integration-result.yml index cde0793e99f..8f5ae6c33e5 100644 --- a/.github/workflows/integration-result.yml +++ b/.github/workflows/integration-result.yml @@ -11,9 +11,35 @@ jobs: github.event.description != 'Skipped' && github.event.description != 'Manual override' runs-on: ubuntu-latest + permissions: + statuses: read + pull-requests: write steps: + - name: Find pull request for status commit + id: pull-request + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + SHA: ${{ github.event.sha }} + shell: bash + run: | + pull_requests=$(gh api --paginate --slurp \ + "repos/$GH_REPO/commits/$SHA/pulls?per_page=100") + + number=$(jq -r --arg sha "$SHA" ' + [ .[][] | select(.state == "open" and .head.sha == $sha) | .number ] + | unique + | if length > 1 then + error("Multiple open pull requests match the status commit") + else + .[0] // empty + end + ' <<< "$pull_requests") + + echo "number=$number" >> "$GITHUB_OUTPUT" - name: Get status check results id: integration + if: ${{ steps.pull-request.outputs.number != '' }} env: GH_TOKEN: ${{ github.token }} GH_REPO: ${{ github.repository }} @@ -28,44 +54,44 @@ jobs: | length > 0 and all(.[]; .state == "success") ' <<< "$statuses") + failing=$(jq ' + [.[].statuses[] | select(.context | startswith("github-ui"))] + | any(.[]; .state == "failure" or .state == "error") + ' <<< "$statuses") + echo "passing=$passing" >> "$GITHUB_OUTPUT" - - name: Add passing integration label - if: ${{ steps.integration.outputs.passing == 'true' }} + echo "failing=$failing" >> "$GITHUB_OUTPUT" + - name: Update integration labels + if: ${{ steps.integration.outputs.passing == 'true' || steps.integration.outputs.failing == 'true' }} env: GH_TOKEN: ${{ github.token }} GH_REPO: ${{ github.repository }} - PR_NUMBER: ${{ github.event.pull_request.number }} + SHA: ${{ github.event.sha }} + PR_NUMBER: ${{ steps.pull-request.outputs.number }} + PASSING: ${{ steps.integration.outputs.passing }} + shell: bash run: | - LABELS=$(gh pr -R "$GH_REPO" view ${{ github.event.pull_request.number }} --json labels | jq -r '.labels | map(.name) | join(",")') - HAS_PASSING_LABEL=$(echo "$LABELS" | grep -c "integration-tests: passing") - HAS_FAILING_LABEL=$(echo "$LABELS" | grep -c "integration-tests: failing") - - if [ "$HAS_PASSING_LABEL" -eq 0 ]; then - echo "Adding 'integration-tests: passing' label" - gh pr -R "$GH_REPO" edit "$PR_NUMBER" --add-label "integration-tests: passing" + if [ "$PASSING" = "true" ]; then + ADD_LABEL="integration-tests: passing" + REMOVE_LABEL="integration-tests: failing" + else + ADD_LABEL="integration-tests: failing" + REMOVE_LABEL="integration-tests: passing" fi - if [ "$HAS_FAILING_LABEL" -gt 0 ]; then - echo "Removing 'integration-tests: failing' label" - gh pr -R "$GH_REPO" edit "$PR_NUMBER" --remove-label "integration-tests: failing" - fi - - name: Add failing integration label - if: ${{ steps.integration.outputs.passing != 'true' }} - env: - GH_TOKEN: ${{ github.token }} - GH_REPO: ${{ github.repository }} - PR_NUMBER: ${{ github.event.pull_request.number }} - run: | - LABELS=$(gh pr -R "$GH_REPO" view ${{ github.event.pull_request.number }} --json labels | jq -r '.labels | map(.name) | join(",")') - HAS_PASSING_LABEL=$(echo "$LABELS" | grep -c "integration-tests: passing") - HAS_FAILING_LABEL=$(echo "$LABELS" | grep -c "integration-tests: failing") + pull_request=$(gh pr view -R "$GH_REPO" "$PR_NUMBER" \ + --json labels,headRefOid,state) - if [ "$HAS_FAILING_LABEL" -eq 0 ]; then - echo "Adding 'integration-tests: failing' label" - gh pr -R "$GH_REPO" edit "$PR_NUMBER" --add-label "integration-tests: failing" - fi + eligible=$(jq --arg sha "$SHA" ' + .state == "OPEN" and .headRefOid == $sha and + all(.labels[]; .name != "integration-tests: skipped manually") + ' <<< "$pull_request") - if [ "$HAS_PASSING_LABEL" -gt 0 ]; then - echo "Removing 'integration-tests: passing' label" - gh pr -R "$GH_REPO" edit "$PR_NUMBER" --remove-label "integration-tests: passing" + if [ "$eligible" != "true" ]; then + echo "Skipping PR #$PR_NUMBER: closed, outdated commit, or manually skipped" + exit 0 fi + + gh pr edit -R "$GH_REPO" "$PR_NUMBER" \ + --add-label "$ADD_LABEL" \ + --remove-label "$REMOVE_LABEL" From 822921086b9c28b318f60d93c09f505ffba7e206 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Nov 2026 16:48:43 +0000 Subject: [PATCH 5/6] fix(ci): skip labels for bypassed integration checks Co-authored-by: joshblack <3901764+joshblack@users.noreply.github.com> --- .github/workflows/integration-result.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration-result.yml b/.github/workflows/integration-result.yml index 8f5ae6c33e5..7c9f1ae42ec 100644 --- a/.github/workflows/integration-result.yml +++ b/.github/workflows/integration-result.yml @@ -59,10 +59,18 @@ jobs: | any(.[]; .state == "failure" or .state == "error") ' <<< "$statuses") + skipped=$(jq ' + [.[].statuses[] + | select(.context | startswith("github-ui")) + | select(.description == "Skipped" or .description == "Manual override")] + | length > 0 + ' <<< "$statuses") + echo "passing=$passing" >> "$GITHUB_OUTPUT" echo "failing=$failing" >> "$GITHUB_OUTPUT" + echo "skipped=$skipped" >> "$GITHUB_OUTPUT" - name: Update integration labels - if: ${{ steps.integration.outputs.passing == 'true' || steps.integration.outputs.failing == 'true' }} + if: ${{ (steps.integration.outputs.passing == 'true' || steps.integration.outputs.failing == 'true') && steps.integration.outputs.skipped != 'true' }} env: GH_TOKEN: ${{ github.token }} GH_REPO: ${{ github.repository }} From edf613f461ed60250816623e165f321d7ecd2dc8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 12 Nov 2026 22:04:28 +0000 Subject: [PATCH 6/6] ci: remove comment-based integration label updates Co-authored-by: joshblack <3901764+joshblack@users.noreply.github.com> --- .../check-for-integration-result-comment.yml | 75 ------------------- 1 file changed, 75 deletions(-) delete mode 100644 .github/workflows/check-for-integration-result-comment.yml diff --git a/.github/workflows/check-for-integration-result-comment.yml b/.github/workflows/check-for-integration-result-comment.yml deleted file mode 100644 index 9cbc18195a6..00000000000 --- a/.github/workflows/check-for-integration-result-comment.yml +++ /dev/null @@ -1,75 +0,0 @@ -name: Check for integration result comment - -on: - issue_comment: - types: [created, edited] - -jobs: - # note: this workflow always passes, it does not fail when integration tests are failing - check-for-integration-result-comment: - if: github.event.issue.pull_request - runs-on: ubuntu-latest - steps: - - name: Get integration result comment - uses: actions/github-script@5c56fde4671bc2d3592fb0f2c5b5bab9ddae03b1 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const INTEGRATION_LABEL_NAMES = { - // synced with https://github.com/primer/react/labels?q=integration-tests - skipped: 'integration-tests: skipped manually', - recommended: 'integration-tests: recommended', - failing: 'integration-tests: failing', - passing: 'integration-tests: passing' - }; - - const issue = { - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo - }; - - const { data: currentLabels } = await github.rest.issues.listLabelsOnIssue(issue); - const existingIntegrationLabels = currentLabels - .map(label => label.name) - .filter(label => label.startsWith('integration-tests:')); - - if (existingIntegrationLabels.includes(INTEGRATION_LABEL_NAMES.skipped)) return; - - const result = await github.rest.issues.listComments(issue); - const integrationComments = result.data.filter( - comment => - comment.user.login == 'primer-integration[bot]' && - (comment.body.includes('