Skip to content

feat(dashboard): Add "Redeploy without cache" for cache-related build failures - #7187

Open
huzan-kazi wants to merge 4 commits into
developfrom
fix/dashboard-redeploy-without-cache
Open

feat(dashboard): Add "Redeploy without cache" for cache-related build failures#7187
huzan-kazi wants to merge 4 commits into
developfrom
fix/dashboard-redeploy-without-cache

Conversation

@huzan-kazi

@huzan-kazi huzan-kazi commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • The Release Pipeline detail page in the dashboard had no way to retry a build that failed due to a stale Docker build cache, short of going into Desk and using the existing "Redeploy (No Cache)" button on the Deploy Candidate Build.
  • Exposes DeployCandidateBuild.redeploy(no_cache=True) (the same method the Desk button already uses) through press.api.bench.redeploy, and adds a "Redeploy Without Cache" button on the pipeline page.
  • The button only appears when the failure is actually fixable by a no-cache rebuild — a new is_cache_related_failure() check is exposed via DeployCandidateBuild.get_doc() as an is_cache_failure dashboard field, and the button is gated on that.

Detecting a cache-related failure

no_cache maps directly to Docker's --no-cache flag, which only affects BuildKit's layer cache — it does not clear --mount=type=cache volumes, which are a separate, persistent, builder-host-level cache shared across every build (none of the mounts in press/docker/Dockerfile set an id=). So detection intentionally does not match on --mount=type=cache being present in the output — that's boilerplate on nearly every "apps" stage RUN instruction and fires on any failure in that stage, cache-related or not (verified against a real "missing import" build failure that isn't a cache issue at all). Instead it matches specific, unambiguous signatures for failures a --no-cache rebuild actually resolves:

  • failed to compute cache key (BuildKit's own layer-cache-key resolution)
  • Incorrect integrity when fetching from the cache (yarn)
  • Could not get lock /var/cache/apt/archives/lock (apt)

Boundary input handling

no_cache is typed as bool but is forwarded through three whitelisted entry points (press.api.bench.redeploy, DeployCandidateBuild.redeploy, and the module-level redeploy). A false-like string value (e.g. no_cache="false") is truthy under Python's native bool(), so it could silently flip a request for a cached rebuild into an uncached one by the time it reaches the persisted build's no_cache field and the agent's if self.no_cache: --no-cache check. Each boundary now coerces with bool(sbool(no_cache)), the same pattern already used elsewhere in press/api/bench.py (format_config_value).

Note on scope

This reuses the existing standalone-rebuild redeploy flow rather than threading no_cache through the Release Pipeline workflow engine, to keep the change small. The resulting build is a fresh Deploy Candidate Build (visible under Desk / "Older Deploys") rather than a new tracked Release Pipeline entry — consistent with how the existing (non-cache) "Redeploy" action already behaves outside the pipeline view.

Test plan

  • Trigger a deploy that fails with a genuine cache-related error (e.g. failed to compute cache key: ..., a yarn "Incorrect integrity when fetching from the cache" error, or an apt lock error) and confirm the "Redeploy Without Cache" button appears on the pipeline detail page.
  • Confirm the button does not appear for failures unrelated to cache (e.g. a plain missing-import/broken-build error, even if it happened inside a --mount=type=cache step).
  • Click the button, confirm the dialog, and verify a new Deploy Candidate Build is created with no_cache=1 and the browser navigates to it.
  • Call press.api.bench.redeploy with no_cache="false" (string) and confirm the resulting build is not built with --no-cache.

🤖 Generated with Claude Code

… failures

The Release Pipeline detail page had no way to retry a build that failed
due to a stale Docker build cache (BuildKit cache-key mismatch or a
`--mount=type=cache` step) short of going to Desk and using the existing
"Redeploy (No Cache)" button on the underlying Deploy Candidate Build.

Exposes that same DeployCandidateBuild.redeploy(no_cache=True) method
through press.api.bench.redeploy, and adds a "Redeploy Without Cache"
button on the pipeline page that only appears when the active build's
failure output actually looks cache-related, via a new
is_cache_related_failure() check reused by DeployCandidateBuild.get_doc()
to compute an is_cache_failure dashboard field.

Deliberately reuses the existing standalone-rebuild redeploy flow rather
than threading no_cache through the Release Pipeline workflow engine, to
keep the change small; the resulting build is a fresh Deploy Candidate
Build (visible under Desk / "Older Deploys") rather than a new tracked
Release Pipeline entry.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Reviews (4): Last reviewed commit: "fix(deploy-candidate-build): Coerce no_c..." | Re-trigger Greptile

Comment thread press/api/bench.py Outdated
@codecov-commenter

codecov-commenter commented Aug 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 50.00000% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.27%. Comparing base (9a39716) to head (13f11e1).
⚠️ Report is 5 commits behind head on develop.

Files with missing lines Patch % Lines
...e/deploy_candidate_build/deploy_candidate_build.py 50.00% 5 Missing ⚠️
press/api/bench.py 50.00% 1 Missing ⚠️

❌ Your patch status has failed because the patch coverage (50.00%) is below the target coverage (75.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #7187      +/-   ##
===========================================
+ Coverage    59.23%   59.27%   +0.04%     
===========================================
  Files         1009     1009              
  Lines        91940    92051     +111     
  Branches      1228     1228              
===========================================
+ Hits         54457    54562     +105     
- Misses       37460    37466       +6     
  Partials        23       23              
Flag Coverage Δ
dashboard 87.18% <ø> (ø)

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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mergify

mergify Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

huzan-kazi and others added 3 commits August 12, 2026 10:17
…ild.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
… false positives

`--mount=type=cache` is boilerplate on nearly every "apps" stage RUN
instruction in the generated Dockerfile, so its mere presence in a
build's output doesn't mean the failure was actually caused by the
cache — e.g. a genuinely broken import path (RollupError: Could not
resolve "posthog.js") was being flagged as cache-related purely
because it failed inside that same RUN step.

Replaces it with specific, unambiguous cache failure signatures:
yarn's "Incorrect integrity when fetching from the cache" and apt's
"Could not get lock /var/cache/apt/archives/lock", alongside the
existing BuildKit "failed to compute cache key". This keeps the
"Redeploy Without Cache" button from showing up on failures that a
no-cache rebuild wouldn't actually fix.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…elisted boundary

no_cache was typed as bool but forwarded as-is through three whitelisted
entry points (press.api.bench.redeploy, DeployCandidateBuild.redeploy,
and the module-level redeploy). A false-like string value (e.g.
no_cache="false") is truthy under Python's native bool(), so it could
silently flip a request for a cached rebuild into an uncached one by
the time it reaches the persisted build's no_cache field and the
agent's `if self.no_cache: --no-cache` check.

Applies the same bool(sbool(...)) coercion already used elsewhere in
this file (format_config_value) at each boundary, so the value is a
real bool before it's forwarded or persisted, regardless of how it
was serialized on the way in.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@Aradhya-Tripathi Aradhya-Tripathi 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.

LGTM

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