Skip to content

ci: ensure test-results runs on cancellation so auto-merge blocks#24290

Merged
ZheSun88 merged 2 commits into24.10from
fix-test-results-runs-on-cancel-24.10
May 8, 2026
Merged

ci: ensure test-results runs on cancellation so auto-merge blocks#24290
ZheSun88 merged 2 commits into24.10from
fix-test-results-runs-on-cancel-24.10

Conversation

@vaadin-bot
Copy link
Copy Markdown
Collaborator

Summary

Cherry-pick PRs targeting release branches were being merged even when
a matrix it-tests (N, ...) shard had been cancelled (e.g. by the
30-min job timeout when CI hung). Example: #24286
merged at 11:49 UTC two seconds after it-tests (2) was cancelled at
11:48:58, with test-results showing as SKIPPED.

Why this happened

test-results is registered as a required status check on the 24.10
branch protection. The intent is that it acts as the single chokepoint
representing "all matrix it-tests passed" (since the matrix job names
include the dynamic module list and can't be required individually).

The job's gate today is:

test-results:
  ...
  if: ${{ failure() || success() }}
  needs: [unit-tests, it-tests]

GitHub Actions if: semantics on a needs: chain treat
failure() || success() as covering only success and failure — not
cancellation
. So when any matrix shard is cancelled, the
test-results job's gate evaluates to false → SKIPPED.

A skipped required status check
satisfies the requirement in GitHub's evaluation,
so the auto-merge bot proceeds and merges the PR.

The job's existing Set Failure Status step (line 268) is already
written correctly with if: always() && (... .result != 'success')
it just never gets a chance to run because the whole job is skipped
first.

Fix

Change the job-level gate to if: ${{ always() }} so test-results
always runs (success / failure / cancelled / timed out). The existing
Set Failure Status step then explicitly fails the job when any
upstream needs entry is in a non-success state, including
cancelled. The required check turns red instead of grey,
auto-merge correctly blocks on it.

Tiny one-liner; comment added so the next person to touch this gate
understands why always() is required.

Test plan

  • Push a draft PR with an artificially cancelled it-tests shard
    (or wait for the next natural occurrence) and confirm
    test-results runs and reports failure rather than being
    skipped.
  • Confirm the auto-merge bot does not merge a cherry-pick PR
    while test-results is failing.

Follow-up

This change should be cherry-picked to 25.0, 25.1, and main
once verified here. The same one-liner applies on every branch that
carries validation.yml.

🤖 Generated with Claude Code

The test-results job is registered as a required status check on
release branches. With if: ${{ failure() || success() }} the job is
skipped when any matrix entry is cancelled (e.g. when an it-tests
shard hits the 30-min job timeout). GitHub treats a skipped required
check as satisfying the requirement, so the cherry-pick auto-merge
proceeds even though the matrix never completed.

Switch to if: ${{ always() }} so the job actually runs and the
existing Set Failure Status step (already if: always() && needs.*
.result != 'success') turns the check red on cancellation. Auto-merge
correctly blocks on the failed required check from then on.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the +0.0.1 label May 7, 2026
@vaadin-bot
Copy link
Copy Markdown
Collaborator Author

This PR is eligible for auto-merging policy, so it has been approved automatically. If there are pending conditions, auto merge (with 'squash' method) has been enabled for this PR [Message is sent from bot]

@vaadin-bot
Copy link
Copy Markdown
Collaborator Author

This PR is eligible for auto-merging policy, so it has been approved automatically. If there are pending conditions, auto merge (with 'squash' method) has been enabled for this PR[Message is sent from bot]

@ZheSun88 ZheSun88 marked this pull request as ready for review May 7, 2026 13:58
@ZheSun88 ZheSun88 enabled auto-merge (squash) May 7, 2026 13:58
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

Test Results

1 288 files  ±0  1 288 suites  ±0   1h 17m 33s ⏱️ +59s
8 899 tests ±0  8 837 ✅ ±0  62 💤 ±0  0 ❌ ±0 
9 265 runs  +5  9 196 ✅ +5  69 💤 ±0  0 ❌ ±0 

Results for commit deb1fae. ± Comparison against base commit 3eac663.

♻️ This comment has been updated with latest results.

@ZheSun88 ZheSun88 enabled auto-merge (squash) May 8, 2026 09:31
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 8, 2026

@ZheSun88 ZheSun88 merged commit fc3f13b into 24.10 May 8, 2026
26 of 28 checks passed
@ZheSun88 ZheSun88 deleted the fix-test-results-runs-on-cancel-24.10 branch May 8, 2026 09:52
vaadin-bot added a commit that referenced this pull request May 8, 2026
…4290) (CP: 25.0) (#24301)

This PR cherry-picks changes from the original PR #24290 to branch 25.0.
---
#### Original PR description
> ## Summary
> 
> Cherry-pick PRs targeting release branches were being merged even when
> a matrix `it-tests (N, ...)` shard had been cancelled (e.g. by the
> 30-min job timeout when CI hung). Example:
[#24286](#24286)
> merged at 11:49 UTC two seconds after `it-tests (2)` was cancelled at
> 11:48:58, with `test-results` showing as `SKIPPED`.
> 
> ## Why this happened
> 
> `test-results` is registered as a required status check on the 24.10
> branch protection. The intent is that it acts as the single chokepoint
> representing "all matrix it-tests passed" (since the matrix job names
> include the dynamic module list and can't be required individually).
> 
> The job's gate today is:
> 
> ```yaml
> test-results:
>   ...
>   if: ${{ failure() || success() }}
>   needs: [unit-tests, it-tests]
> ```
> 
> GitHub Actions `if:` semantics on a `needs:` chain treat
> `failure() || success()` as covering only success and failure — **not
> cancellation**. So when any matrix shard is cancelled, the
> `test-results` job's gate evaluates to false → SKIPPED.
> 
> A skipped required status check
> [satisfies the requirement in GitHub's
evaluation](https://github.com/orgs/community/discussions/13690),
> so the auto-merge bot proceeds and merges the PR.
> 
> The job's existing `Set Failure Status` step (line 268) is already
> written correctly with `if: always() && (... .result != 'success')` —
> it just never gets a chance to run because the whole job is skipped
> first.
> 
> ## Fix
> 
> Change the job-level gate to `if: ${{ always() }}` so `test-results`
> always runs (success / failure / cancelled / timed out). The existing
> `Set Failure Status` step then explicitly fails the job when any
> upstream needs entry is in a non-success state, including
> `cancelled`. The required check turns **red** instead of grey,
> auto-merge correctly blocks on it.
> 
> Tiny one-liner; comment added so the next person to touch this gate
> understands why `always()` is required.
> 
> ## Test plan
> 
> - [ ] Push a draft PR with an artificially cancelled it-tests shard
>       (or wait for the next natural occurrence) and confirm
>       `test-results` runs and reports failure rather than being
>       skipped.
> - [ ] Confirm the auto-merge bot does *not* merge a cherry-pick PR
>       while `test-results` is failing.
> 
> ## Follow-up
> 
> This change should be cherry-picked to `25.0`, `25.1`, and `main`
> once verified here. The same one-liner applies on every branch that
> carries `validation.yml`.
> 
> 🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Zhe Sun <zhe@vaadin.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Zhe Sun <31067185+ZheSun88@users.noreply.github.com>
vaadin-bot added a commit that referenced this pull request May 8, 2026
…4290) (CP: 24.9) (#24302)

This PR cherry-picks changes from the original PR #24290 to branch 24.9.
---
#### Original PR description
> ## Summary
> 
> Cherry-pick PRs targeting release branches were being merged even when
> a matrix `it-tests (N, ...)` shard had been cancelled (e.g. by the
> 30-min job timeout when CI hung). Example:
[#24286](#24286)
> merged at 11:49 UTC two seconds after `it-tests (2)` was cancelled at
> 11:48:58, with `test-results` showing as `SKIPPED`.
> 
> ## Why this happened
> 
> `test-results` is registered as a required status check on the 24.10
> branch protection. The intent is that it acts as the single chokepoint
> representing "all matrix it-tests passed" (since the matrix job names
> include the dynamic module list and can't be required individually).
> 
> The job's gate today is:
> 
> ```yaml
> test-results:
>   ...
>   if: ${{ failure() || success() }}
>   needs: [unit-tests, it-tests]
> ```
> 
> GitHub Actions `if:` semantics on a `needs:` chain treat
> `failure() || success()` as covering only success and failure — **not
> cancellation**. So when any matrix shard is cancelled, the
> `test-results` job's gate evaluates to false → SKIPPED.
> 
> A skipped required status check
> [satisfies the requirement in GitHub's
evaluation](https://github.com/orgs/community/discussions/13690),
> so the auto-merge bot proceeds and merges the PR.
> 
> The job's existing `Set Failure Status` step (line 268) is already
> written correctly with `if: always() && (... .result != 'success')` —
> it just never gets a chance to run because the whole job is skipped
> first.
> 
> ## Fix
> 
> Change the job-level gate to `if: ${{ always() }}` so `test-results`
> always runs (success / failure / cancelled / timed out). The existing
> `Set Failure Status` step then explicitly fails the job when any
> upstream needs entry is in a non-success state, including
> `cancelled`. The required check turns **red** instead of grey,
> auto-merge correctly blocks on it.
> 
> Tiny one-liner; comment added so the next person to touch this gate
> understands why `always()` is required.
> 
> ## Test plan
> 
> - [ ] Push a draft PR with an artificially cancelled it-tests shard
>       (or wait for the next natural occurrence) and confirm
>       `test-results` runs and reports failure rather than being
>       skipped.
> - [ ] Confirm the auto-merge bot does *not* merge a cherry-pick PR
>       while `test-results` is failing.
> 
> ## Follow-up
> 
> This change should be cherry-picked to `25.0`, `25.1`, and `main`
> once verified here. The same one-liner applies on every branch that
> carries `validation.yml`.
> 
> 🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Zhe Sun <zhe@vaadin.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Zhe Sun <31067185+ZheSun88@users.noreply.github.com>
vaadin-bot added a commit that referenced this pull request May 8, 2026
…4290) (CP: 25.1) (#24300)

This PR cherry-picks changes from the original PR #24290 to branch 25.1.
---
#### Original PR description
> ## Summary
> 
> Cherry-pick PRs targeting release branches were being merged even when
> a matrix `it-tests (N, ...)` shard had been cancelled (e.g. by the
> 30-min job timeout when CI hung). Example:
[#24286](#24286)
> merged at 11:49 UTC two seconds after `it-tests (2)` was cancelled at
> 11:48:58, with `test-results` showing as `SKIPPED`.
> 
> ## Why this happened
> 
> `test-results` is registered as a required status check on the 24.10
> branch protection. The intent is that it acts as the single chokepoint
> representing "all matrix it-tests passed" (since the matrix job names
> include the dynamic module list and can't be required individually).
> 
> The job's gate today is:
> 
> ```yaml
> test-results:
>   ...
>   if: ${{ failure() || success() }}
>   needs: [unit-tests, it-tests]
> ```
> 
> GitHub Actions `if:` semantics on a `needs:` chain treat
> `failure() || success()` as covering only success and failure — **not
> cancellation**. So when any matrix shard is cancelled, the
> `test-results` job's gate evaluates to false → SKIPPED.
> 
> A skipped required status check
> [satisfies the requirement in GitHub's
evaluation](https://github.com/orgs/community/discussions/13690),
> so the auto-merge bot proceeds and merges the PR.
> 
> The job's existing `Set Failure Status` step (line 268) is already
> written correctly with `if: always() && (... .result != 'success')` —
> it just never gets a chance to run because the whole job is skipped
> first.
> 
> ## Fix
> 
> Change the job-level gate to `if: ${{ always() }}` so `test-results`
> always runs (success / failure / cancelled / timed out). The existing
> `Set Failure Status` step then explicitly fails the job when any
> upstream needs entry is in a non-success state, including
> `cancelled`. The required check turns **red** instead of grey,
> auto-merge correctly blocks on it.
> 
> Tiny one-liner; comment added so the next person to touch this gate
> understands why `always()` is required.
> 
> ## Test plan
> 
> - [ ] Push a draft PR with an artificially cancelled it-tests shard
>       (or wait for the next natural occurrence) and confirm
>       `test-results` runs and reports failure rather than being
>       skipped.
> - [ ] Confirm the auto-merge bot does *not* merge a cherry-pick PR
>       while `test-results` is failing.
> 
> ## Follow-up
> 
> This change should be cherry-picked to `25.0`, `25.1`, and `main`
> once verified here. The same one-liner applies on every branch that
> carries `validation.yml`.
> 
> 🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Zhe Sun <zhe@vaadin.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Zhe Sun <31067185+ZheSun88@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants