Skip to content

Make /status list every missing item, including pending checks - #288

Open
upsun-dispatch[bot] wants to merge 1 commit into
mainfrom
upsun-dispatch/issue-280
Open

upsun-dispatch[bot] wants to merge 1 commit into
mainfrom
upsun-dispatch/issue-280

Conversation

@upsun-dispatch

Copy link
Copy Markdown

Summary

The plan assumed /status was only a "TBA" placeholder, but it isn't. The first step (checking what already exists) found that commit b35e425 / #\276 (BERTE-539) already added a working per-pull-request report. It covers approvals, integration builds, Jira fix versions and history, and has 20 tests. So, as the plan said to do in that case, this PR only fills the gaps between that report and the plan's scenarios.

Gaps closed, all in bert_e/workflow/gitwaterflow/commands.py:

  • Builds: the report now lists every integration branch whose build isn't successful, not just the worst one. Each gets a [build](url) link when the git host provides a URL.
  • Builds before integration branches exist: this row used to be left out silently. It now shows as ⏳ "not yet evaluated – will be checked once Bert-E creates integration branches". /status still creates nothing.
  • Bypass options: when a bypass_*_approval option is what makes approvals pass, the row now says so ("author/peer/leader approval bypassed").
  • New wait row: reports the wait option as a blocker when it is set.
  • New queue row: shown when queues are enabled and integration branches exist, as "queued" or ⏳ "not queued yet".
  • Help text: status now reads "Print everything still missing before this pull request can be merged."

Other changes:

  • bert_e/templates/status_report.md: adds the ⏳ "not yet evaluated" state and shows notes on passing rows, so "bypassed" becomes visible (before, a passing row showed only ☀️). A short legend appears only when the report has rows, so the "not available" fallback in init.md is unchanged.
  • bert_e/docs/USER_DOC.md: adds status to the command table and a short section describing the report. It also says it is separate from the web status page.
  • Tests: six new integration tests in bert_e/tests/test_bert_e.py and a new unit test file, bert_e/tests/unit/test_status_report.py, covering each row's logic and how each state renders.

Decisions a reviewer should know about:

  • I did not do the plan's run_checks refactor in gitwaterflow/__init__.py. The existing report already runs its checks one by one without stopping at the first failure, and the plan said to add only what was missing. Leaving the fail-fast merge path alone also avoids the regression risk the plan itself flagged.
  • Other planned files I left alone:
    • exceptions.py: StatusReport already exists and is never de-duplicated.
    • templates/status.md: already exists.
    • templates/help.md: generated from the command registry, so the new help text flows through on its own.
    • README.md: doesn't list commands; the command docs live in USER_DOC.md.
  • Behaviour change: when bypass_build_status is set, the builds row now shows as bypassed even before integration branches exist.
  • Two existing behaviours don't match the plan and are unchanged:
    • If the clone or branch-cascade step fails, the report still falls back to approvals only rather than raising an error.
    • A missing Jira id is still reported under the fix-versions row.

Testing:

  • All 25 TestBertE.test_status_command* tests (old and new) plus test_options_and_commands pass on the mock git host, both with and without --disable-queues.
  • The new unit tests pass, and flake8 is clean on the changed Python files.
  • The full bert_e/tests/unit run has 1 failure and 3 errors, all in the GitHub API tests (test_github_app_auth.py, test_github_build_status.py). They need a mock server on localhost:4010, which wasn't running. I only confirmed on a clean checkout that the test_github_app_auth.py errors happen without my changes; I didn't recheck the test_github_build_status.py failure the same way.
  • The mock git host returns no build URLs, so the build-link format is only checked in the unit test.

Files changed

  • bert_e/docs/USER_DOC.md (modified, +24/-0)
  • bert_e/templates/status_report.md (modified, +3/-1)
  • bert_e/tests/test_bert_e.py (modified, +96/-0)
  • bert_e/tests/unit/test_status_report.py (added, +88/-0)
  • bert_e/workflow/gitwaterflow/commands.py (modified, +84/-30)

Pre-merge review

  • Unconfirmed unit-test failure. The summary says the full bert_e/tests/unit run had 1 failure and 3 errors. Only the test_github_app_auth.py errors were confirmed to also happen on a clean checkout. The test_github_build_status.py failure was not rechecked. That file covers the same build-status area as the new job.project_repo.get_build_url(commit, key) call in _check_builds_status. A reviewer should run it with the mock server on localhost:4010 before merging, to rule out a regression.
  • Extra API calls and one untested path in _check_builds_status. The builds row now calls get_build_url once for every integration branch whose build isn't successful, on top of get_build_status. On long cascades where many builds fail, that is one extra host API call per branch. The plan listed rate limits as a risk. Also, the mock host returns no build URLs, so only the unit test (which mocks project_repo) exercises the link format. Nothing checks that every real git host backend has get_build_url(sha, key) with this signature. If one doesn't, /status will raise AttributeError or TypeError on that host whenever a build is not green.
  • Plan scenarios still not fully met (disclosed in the summary). First, if clone_git_repo or build_branch_cascade fails, _build_status_report still quietly falls back to a report with approvals only. The plan's scenario says unexpected non-template errors should surface rather than be hidden in the report. Second, a missing Jira id is still shown under the fix-versions row instead of its own row. Both are existing behaviours, but a maintainer should decide whether they are acceptable for this issue.

Addresses #280 — implemented according to the plan posted on the issue thread.

Created by Upsun Dispatch™. Requested by @charlesprost.

/status already existed (BERTE-539), but it named only the worst failing
build, hid bypass notes and left out rows it couldn't check yet. It now
lists every failing build, marks unchecked rows as pending, and reports
the wait option and merge-queue state.

Dispatch-Run: 01M3S829EH1E08T79VVGG1Z0EN
Dispatch-Attempt: 1
@upsun-dispatch
upsun-dispatch Bot requested a review from a team as a code owner September 30, 2026 13:45
@upsun-dispatch upsun-dispatch Bot mentioned this pull request Sep 30, 2026

@upsun-dispatch upsun-dispatch Bot left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Warning

Changes suggested — 🟡 1 warning · ⚪ 1 nitpick

🔍 Full review · 5 files reviewed

⚪ Nitpick

  • bert_e/workflow/gitwaterflow/commands.py:66 — bypassed lists every active bypass option, whether or not it was needed. If need_author_approval is false, or required_peer_approvals / required_leader_approvals is 0, but the matching bypass_*_approval is set, the row still says e.g. "author/peer approval bypassed". The bypass changed nothing in that case, so the note wrongly suggests the approvals are satisfied only because of it.
Verification
  • get_build_url(revision, key) exists with this signature on the base, mock, GitHub and Bitbucket hosts, so the new call in _check_builds_status cannot raise TypeError or AttributeError.
  • _check_queue_status runs only after build_branch_cascade, so already_in_queue can read job.git.cascade.dst_branches safely.
  • The template checks pending before pass, so a pending item built with pass=False renders as ⌛ and not as ❗.
  • Help text comes from normalize_whitespace(handler.__doc__), so the two-line status docstring shows as the single sentence the new test expects.

The diff adds six integration tests in bert_e/tests/test_bert_e.py (mock git host) and unit tests in bert_e/tests/unit/test_status_report.py for each row and how each state renders. The build-link format is covered only by the mocked unit test, and no test covers a partial approval bypass.

Review details
  • Commit: deaee51
  • Model: claude-opus-5-5

Review 1 of 10 for this pull request · View the full run

leader_count >= required_leader and
not job.settings.unanimity):
return _StatusItem('Approvals', True)
bypassed = [

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

🟡 Warning — Partial bypasses stay invisible in the report, contrary to the stated feature.

The "approval bypassed" note is only built in the early-return branch, and that branch runs only when the bypasses alone meet every requirement. Take a partial bypass: bypass_peer_approval is set, need_author_approval is true, and the author approved in the UI rather than with approve. author_ok starts out False, so the code skips the early return and falls through to the counting path. That path ends with _StatusItem('Approvals', not details, details=details) with empty details, so the row renders as a plain ☀️. Nothing tells the reader that the peer requirement was met only because of the bypass. The PR says the row now reports when a bypass is what makes approvals pass, but it only does so when all the needed approvals are bypassed.

@codecov

codecov Bot commented Sep 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.33%. Comparing base (cfe0bc2) to head (deaee51).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #288      +/-   ##
==========================================
+ Coverage   90.21%   90.33%   +0.11%     
==========================================
  Files          82       83       +1     
  Lines       11293    11433     +140     
==========================================
+ Hits        10188    10328     +140     
  Misses       1105     1105              
Flag Coverage Δ
integration 87.78% <98.16%> (+0.10%) ⬆️
tests 87.74% <97.24%> (+0.09%) ⬆️
tests-BuildFailedTest 25.54% <8.25%> (-0.18%) ⬇️
tests-QuickTest 32.77% <8.25%> (-0.25%) ⬇️
tests-RepositoryTests 25.22% <8.25%> (-0.18%) ⬇️
tests-TaskQueueTests 49.18% <8.25%> (-0.42%) ⬇️
tests-TestBertE 67.28% <97.24%> (+0.30%) ⬆️
tests-TestQueueing 51.25% <8.25%> (-0.44%) ⬇️
tests-api-mock 14.27% <0.00%> (-0.18%) ⬇️
tests-noqueue 78.50% <91.74%> (+0.12%) ⬆️
tests-noqueue-BuildFailedTest 25.54% <8.25%> (-0.18%) ⬇️
tests-noqueue-QuickTest 32.77% <8.25%> (-0.25%) ⬇️
tests-noqueue-RepositoryTests 25.22% <8.25%> (-0.18%) ⬇️
tests-noqueue-TaskQueueTests 49.18% <8.25%> (-0.42%) ⬇️
tests-noqueue-TestBertE 63.82% <91.74%> (+0.27%) ⬆️
tests-noqueue-TestQueueing 25.24% <8.25%> (-0.18%) ⬇️
tests-server 26.41% <1.89%> (-0.32%) ⬇️
unittests 43.63% <49.36%> (+0.21%) ⬆️
utests 29.48% <49.36%> (+0.38%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

1 participant