Skip to content

ci: always report LAVA results; even on failure - #594

Open
Christopher Obbard (obbardc) wants to merge 5 commits into
qualcomm-linux:mainfrom
obbardc:wip/obbardc/ci-lava-report-results-on-failure
Open

ci: always report LAVA results; even on failure#594
Christopher Obbard (obbardc) wants to merge 5 commits into
qualcomm-linux:mainfrom
obbardc:wip/obbardc/ci-lava-report-results-on-failure

Conversation

@obbardc

@obbardc Christopher Obbard (obbardc) commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Currently the LAVA results are not published (to workflow summary or PR comments) if a LAVA job fails. Fix it so the results are always published.

See these sample workflow runs to see broken behaviour:

build.yml:

test-on-pr.yml:

Effect on other callers

lava-test.yml has more callers than just the PR path and external reporting (report_test_results_externally) is left at its true default for build.yml, build-on-push.yml and via linux.yml, linux-qcom-next.yml and linux-arduino.yml. It is off for build-debian.yml, linux-next.yml and linux-mainline.yml.

Because publish-test-results previously skipped whenever any board's submit job failed, partial LAVA failures in those runs reported nothing at all. They will now publish: expect "Test Results" check runs on the daily build.yml and qcom-next/arduino kernel runs and on pushes to main and, since comment_mode is always, comments on the associated, already-merged PRs. That is the intended effect of the fix, but it is a visible increase in CI noise beyond the PR path, so the first failure should not come as a surprise.

The PR path itself does not gain a duplicate: test-on-pr.yml now passes report_test_results_externally: false, because the inner job has no way to know the PR head SHA under workflow_run and was attaching its check run to the default-branch tip. test-on-pr.yml's own publish job does the external reporting with the correct commit.

Testing

The test-on-pr.yml half cannot be exercised before merge: workflow_run always runs the default-branch copy of the workflow file. The lava-test.yml half can: every scheduled caller permits workflow_dispatch from any branch of the main repo, so dispatching build.yml from this branch exercises the new guard, including the partial-failure path if a board is currently flaky.

@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown

Test Results

  7 files  ±0   21 suites  ±0   15m 19s ⏱️ ±0s
 21 tests ±0   21 ✅ ±0  0 💤 ±0  0 ❌ ±0 
184 runs  ±0  184 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit 4c5331c. ± Comparison against base commit 0257878.

♻️ This comment has been updated with latest results.

@github-actions

Copy link
Copy Markdown

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Ensures LAVA results remain visible when test submission jobs fail.

Changes:

  • Runs result-publishing jobs after failures, excluding skipped or cancelled runs.
  • Adds the triggering build workflow link to PR comments.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
.github/workflows/test-on-pr.yml Publishes failed test results and links the originating build run.
.github/workflows/lava-test.yml Publishes available LAVA artifacts despite submission failures.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@lool Loïc Minier (lool) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loïc asked Claude to review this PR and here's what it found.

Overall: the fix looks correct. Four things worth raising before merge, one of which is a concrete suggestion to fold in.

The fix itself is right

The root cause diagnosis is accurate. A job with needs: and no if: carries an implicit success(), so a single failing submit-job matrix leg skipped publish-test-results entirely — discarding the results of every board that did run, from both the check run/PR comment and the job summary. fail-fast: false on the matrix meant the other legs ran to completion and then had their results thrown away.

!cancelled() is the right primitive (unlike always(), it still honours cancellation), and the second clause is meaningful rather than defensive padding in both files:

  • lava-test.yml: submit-job genuinely reaches skipped via if: needs.prepare-job-list.outputs.has_jobs == 'true' — either no LAVA template matched the board filters, or prepare-job-list failed (empty output → '' == 'true' → false).
  • test-on-pr.yml: test is reported skipped when retrieve-build-url is skipped (build conclusion ≠ success) or fails. Both mean "nothing to report", which matches the comment.

The inline comments explain why rather than restating the expression.

1. The total-failure case now posts a near-empty comment

Worth deciding whether you care. When no board produces results, nothing in the chain objects:

  • actions/download-artifact in pattern: mode succeeds silently on zero matches (it filters the artifact list and logs only at debug level, then reports success) — unlike name: or ID mode, which throw.
  • EnricoMi/publish-unit-test-result-action v2.24.0 defaults to action_fail: false and action_fail_on_inconclusive: false.

So on total failure the job now runs green and posts a PR comment containing just the heading plus the new "Triggered by build workflow run" line, with no job bullets, alongside a contentless "Test Results" check run. Previously it skipped silently. Arguably still an improvement — the "Triggered by" link at least gets you to the failed run — but if you want it to read as a failure rather than as an empty success, either emit an explicit "no test jobs produced results" line when the find loop finds nothing, or set action_fail_on_inconclusive: true.

2. Concrete suggestion: report_test_results_externally: false on the test: call in test-on-pr.yml

This is the one worth actually changing. test-on-pr.yml calls lava-test.yml without report_test_results_externally, so it defaults to true — meaning lava-test.yml's own publish-test-results job also does check_run: true and comment_mode: always, in addition to test-on-pr.yml's publish job.

The inner one has no commit: / event_file: / event_name: overrides, so under workflow_run it attaches its check run to github.sha, which for that trigger is the default branch tip, not the PR head. test-on-pr.yml's own publish job is the one that gets this right (commit: ${{ github.event.workflow_run.head_sha }}, event_file, event_name).

That mis-targeting is pre-existing and already happens on the happy path, so it's not a regression — but this PR makes it fire on the failure path too, which is where a stray red check on main would be most noticeable. Passing report_test_results_externally: false on that call would leave the inner job's job-summary table intact while letting test-on-pr.yml own all external reporting.

3. Blast radius is wider than the description suggests

lava-test.yml has more callers than the PR body implies. With external reporting left at its true default: build.yml, build-on-push.yml, test-on-pr.yml, and — via linux.ymllinux-qcom-next.yml and linux-arduino.yml. (Off for build-debian.yml, linux-next.yml, linux-mainline.yml.)

So partial LAVA failures in the daily qcom-next and arduino kernel builds, the daily build.yml run, and pushes to main will now all start producing red "Test Results" check runs, and comment_mode: always will comment on the associated (already-merged) PRs where previously the job just skipped. That's presumably the intended behaviour — it's the whole point — but it's a visible change in CI noise on main beyond the PR path, and worth a sentence in the commit message or PR body so nobody is surprised by the first red check.

4. The "can't be tested before merge" claim is only half true

The description says this is difficult to test because workflow_run-triggered workflows always run the default-branch copy of the file. That's correct for test-on-pr.yml — no way around it.

It doesn't hold for the lava-test.yml half, though. Every scheduled caller (build.yml, build-debian.yml, linux-*.yml) explicitly permits workflow_dispatch from any branch of the main repo, with comments to that effect: "manual runs are allowed from any branch of the main repository so that changes to the workflows can be tested before they are merged." A manual dispatch of build.yml from this branch would exercise the new guard for real, including the partial-failure path if a board is currently flaky. Given that's the change with the widest reach, it seems worth doing rather than merging on inspection.

Minor

  • The third commit (69be2d44, the build-run link in the PR comment) is a genuinely useful addition but isn't mentioned in the PR title or body — worth a line so it doesn't look like drive-by scope creep. A link to the test run might be at least as useful as the build run, since that's where the failure will be.
  • All three commits are well scoped with why-focused messages and Signed-off-by: trailers.

Adjacent, not this PR: the mirror-image footgun in linux.yml

While tracing the callers, two jobs in linux.yml stood out — an explicit if: on a job with needs: that doesn't check status:

debos-linux-deb:
  if: ${{ !inputs.skip_image_build }}
  needs: build-linux-deb

test-linux-deb:
  if: ${{ !inputs.skip_lava_tests }}
  needs: debos-linux-deb

Because an explicit if: replaces the implicit success(), these should run even when their dependency fails — so test-linux-deb would submit LAVA jobs with an empty url after a failed debos build. That's the exact inverse of the bug this PR fixes. Worth confirming against a real failed run rather than taking this at face value; if it holds, && success() on both (or needs.<job>.result == 'success') would be a good follow-up issue. Out of scope here.

@lool Loïc Minier (lool) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I asked both copilot and claude for a review of this PR; copilot found nothing, but claude had interesting things to say

Looking at the claude review, I think the report_test_results_externally (point 2) would be good to change before landing, otherwise we'll continue attaching test run info to the wrong commits. The rest can be improved later, it was also already there.

The `publish-test-results` job only depends on `submit-job`, so GitHub
skips the job whenever any board's submit job fails (e.g. LAVA
submission error, job timeout, job failure, etc). The results of the
boards which did run are then lost; neither the check run nor the job
summary listing the LAVA jobs is produced for any caller of this
workflow.

Guard the job with `!cancelled()` instead so it runs on failure and
keep skipping it when `submit-job` did not run at all, e.g. when no
test jobs match the board filters.

Now that the summary is written even when every board failed to submit,
say so explicitly when there are no job details to list: an empty list
otherwise reads as if there had been nothing to test.

Signed-off-by: Christopher Obbard <chris.obbard@oss.qualcomm.com>
The `publish-test-results` job only depends on `test`, so GitHub skips
it whenever the lava-test workflow it calls fails, e.g. because one
board's test job failed. The comment listing the LAVA job links is then
never added to the pull request; the results of the boards which did
run are not published either.

Guard the job with `!cancelled()` instead so it runs on failure and
keep skipping it when the test workflow itself did not run (e.g. the
build URL could not be retrieved), as there is nothing to report in
that case.

As the comment is now posted even when every board failed to submit,
say so when there are no job links to list, rather than commenting a
bare heading which reads as if the tests had passed.

Signed-off-by: Christopher Obbard <chris.obbard@oss.qualcomm.com>
The comment lists the individual LAVA jobs, but nothing points back at
the "Build on PR" run whose image they tested. Add a link to it above
the job list, taken from the `html_url` of the `workflow_run` payload
which triggered this workflow.

Signed-off-by: Christopher Obbard <chris.obbard@oss.qualcomm.com>
The `test` job calls lava-test.yml without setting
`report_test_results_externally`, which defaults to true, so that
the workflow's own `publish-test-results` job creates a check run and
comments on the pull request as well.

It has no way to know which commit is being tested: under
`workflow_run`, `github.sha` is the tip of the default branch, not the
pull request head, so its check run is attached to the wrong commit.
The `publish-test-results` job in this workflow gets this right as it
passes `commit`, `event_file` and `event_name` explicitly.

Set `report_test_results_externally: false` on the call so this
workflow owns all external reporting; the job summary written by
lava-test.yml is unaffected.

Signed-off-by: Christopher Obbard <chris.obbard@oss.qualcomm.com>
A job with `needs:` and no `if:` gets an implicit `success()`, but an
explicit `if:` replaces it rather than adding to it. Four jobs which
carry a condition of their own therefore run whatever their dependency
did: `test` in build.yml, `test-debian` in build-debian.yml and
`debos-linux-deb` and `test-linux-deb` in linux.yml. Once the build
they need fails, the image URL they pass on is empty and LAVA jobs are
submitted against nothing, which is the exact inverse of the missing
results this branch otherwise fixes.

Check the result of the dependency in the condition. Comparing it
against 'success' rather than calling `success()` also covers the case
where the dependency was skipped, e.g. when build-linux-deb is guarded
out because the workflow runs from a fork.

Signed-off-by: Christopher Obbard <chris.obbard@oss.qualcomm.com>
@obbardc
Christopher Obbard (obbardc) force-pushed the wip/obbardc/ci-lava-report-results-on-failure branch from 69be2d4 to 4c5331c Compare August 27, 2026 22:40
@github-actions

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants