Show both the delayed and external-lock stack banners at once#1491
Show both the delayed and external-lock stack banners at once#1491ScottifyShopson wants to merge 1 commit into
Conversation
The stack banners partial rendered the "Continuous Delivery Delayed!" banner and the "Stack has been locked by external system!" banner as an `if`/`elsif`, so whenever continuous delivery was delayed the external deployment-checks banner was suppressed. These convey complementary information: the blue banner explains that CD is paused, while the orange banner is the only one that surfaces the actual lock reason from the external system (via `deployment_checks_message`). Splitting the `elsif` into a separate `if` lets both render when both conditions apply. 🤖 Generated with anthropic/claude-opus-4-8 via pi
There was a problem hiding this comment.
💬 Suggestion: The new test covers the important positive case where delayed CD and failing deployment checks both render. A sibling test for delayed CD with passing deployment checks would harden the opposite side of the contract: the orange external-lock banner should not render just because delayed CD is active.
Suggestion: Add a sibling test that registers a passing fake deployment check while continuous_delivery_delayed? is true, then asserts the blue 'Continuous Delivery Delayed!' banner renders and the orange 'Stack has been locked by external system!' banner has count: 0.
| end | ||
|
|
||
| test "#show renders both the delayed and external-lock banners when both apply" do | ||
| failing_checks = Class.new do |
There was a problem hiding this comment.
💡 Improvement: Consider tightening this regression test so it verifies the specific user-facing reason that motivated the PR. The external deployment-lock reason is surfaced through Shipit.deployment_checks.message(stack) when the checker responds to message. As written, the fake checker only returns false and the assertion only checks the orange banner title, so the test would still pass if the banner appeared but the external-system reason was missing or replaced by a generic message.
Suggestion: Define self.message(_stack) on failing_checks with a distinct sentinel string, then assert that string appears inside the orange banner text after get :show. That keeps the test aligned with the deployment_checks_message contract and the user-visible reason this PR is protecting.
| assert_select '.banner .banner__title', text: 'Continuous Delivery Delayed!' | ||
| assert_select '.banner--orange .banner__title', text: 'Stack has been locked by external system!' | ||
| ensure | ||
| Shipit.deployment_checks = nil |
There was a problem hiding this comment.
🎨 Code Style: The test mutates Shipit.deployment_checks, a module-level global. Resetting it to nil is equivalent today because the attribute has no default, but it could clobber suite-level or setup-provided configuration if that changes later. Restoring the previous value also matches the safer pattern already used for this same global elsewhere in the test suite.
Suggestion: Capture the previous value before assigning failing_checks, then restore that value in the ensure block instead of unconditionally setting Shipit.deployment_checks = nil.
| Shipit.deployment_checks = nil | |
| Shipit.deployment_checks = original_deployment_checks |
What & why
On a stack's page, two banners can apply at the same time:
app/views/shipit/stacks/_banners.html.erbrendered these as anif/elsif, so whenevercontinuous_delivery_delayed?was true the orange banner was suppressed entirely:These banners convey complementary information. The blue banner only says, generically, that "the pre-deploy checks failed", while the orange banner is the only place the actual lock reason from the external system is surfaced (via
deployment_checks_message, e.g. an Infra Central message explaining why deploys are locked). When the blue banner hid the orange one, users lost that reason.This was observed on
shopify/minerva/production, where the stack was both CD-delayed and locked by an external system — only the blue banner showed, hiding the lock reason.What changed
Split the
elsifinto a separateifso the two conditions are evaluated independently and both banners can render when both apply. No change to either banner's content or styling.Current behaviour (the two banners involved)
The orange external-lock banner (the one currently being hidden), which carries the actual lock reason:
The blue continuous-delivery-delayed banner, which currently takes precedence and hides the orange one:
After this change, both render at once when both conditions hold.
Testing
StacksControllerTest#show renders both the delayed and external-lock banners when both apply) that sets up a stack which is simultaneouslycontinuous_delivery_delayed?and failingdeployment_checks, and asserts both banner titles render.pgnative-gem build issue in my environment; relying on CI to run the suite.Notes
scottifyshopson/banner-screenshots-assets) purely so they render here; they are not part of this PR's diff and that branch can be deleted after merge.🤖 Generated with anthropic/claude-opus-4-8 via pi