Skip to content

feat: Adds retry functionality to handle transient build failures with configurable parameters.#1422

Closed
morwn wants to merge 1 commit intodocker:masterfrom
morwn:master
Closed

feat: Adds retry functionality to handle transient build failures with configurable parameters.#1422
morwn wants to merge 1 commit intodocker:masterfrom
morwn:master

Conversation

@morwn
Copy link
Copy Markdown

@morwn morwn commented Oct 28, 2025

Description

Add retry mechanism with configurable maximum attempts, wait time, and timeout

New input parameters:

  • max-attempts (default: 1) - Maximum number of build attempts
  • retry-wait-seconds (default: 0) - Delay between retry attempts
  • timeout-minutes (default: 0) - Timeout per attempt (0 = no timeout)

Implementation:

  • Wraps build execution in retry loop with comprehensive logging
  • Adds timeout support per attempt using Promise.race()
  • Fully backward compatible (default values maintain current behavior)
  • Adds 2 test cases

…timeout

New input parameters:
- max-attempts (default: 1) - Maximum number of build attempts
- retry-wait-seconds (default: 0) - Delay between retry attempts
- timeout-minutes (default: 0) - Timeout per attempt (0 = no timeout)

Implementation:
- Wraps build execution in retry loop with comprehensive logging
- Adds timeout support per attempt using Promise.race()
- Fully backward compatible (default values maintain current behavior)
- Adds 2 test cases

Signed-off-by: Mor Weinberger <test@example.com>
@crazy-max
Copy link
Copy Markdown
Member

Thanks for taking the time to implement this. We're declining it because it changes responsibility boundaries in this action; retry/failure policy should be handled upstream rather than in the GitHub Action wrapper. Closing.

@crazy-max crazy-max closed this Mar 2, 2026
@morwn
Copy link
Copy Markdown
Author

morwn commented Mar 2, 2026

Thanks for the explanation. However, "handle it upstream" has no clean implementation path. GitHub Actions provides no native mechanism to retry a uses: step - only run steps can be wrapped by retry actions like nick-fields/retry. The only alternatives are duplicating the entire job or bypassing build-push-action entirely with raw docker buildx build + docker push shell commands.

Transient failures (registry timeouts, BuildKit connectivity issues) are a real and frequent pain point for users of this action specifically. Keeping retry logic here allows it to be scoped correctly to the build attempt itself, without duplicating setup overhead.

The retry logic can't be moved upstream without either significant workflow complexity or losing the abstraction this action provides.

@crazy-max
Copy link
Copy Markdown
Member

crazy-max commented Mar 3, 2026

Thanks for the follow-up.

You're correct that GitHub Actions does not currently provide a clean native retry for uses: steps (something they wanted to implement some time ago iirc), and I understand the pain from transient connectivity failures.

We're still going to keep this PR closed because adding retry policy inside build-push-action would move this action from "build invocation" into workflow orchestration/failure policy, which we intentionally keep outside this repository. That boundary is important for predictability and long-term maintenance.

We agree the upstream options are imperfect today, but we prefer that tradeoff over embedding retry semantics in this wrapper.

magyargergo added a commit to abhigyanpatwari/GitNexus that referenced this pull request Apr 24, 2026
…ened shell

Wraps docker/build-push-action with a local composite action that retries
once on failure (upstream keeps retry out of the action per
docker/build-push-action#1422). Adds ignore-error=true on cache-to so GHA
cache export flakes don't fail an otherwise successful push.

- Emit `::notice::` in the resolve step when attempt 2 recovers from a
  first-attempt failure, so silent retries are grep-able in run logs and
  trending registry/cache flakes stay visible.
- Bind `retry-wait-seconds` via `env:` in the backoff step to match the
  env-binding convention used elsewhere in docker.yml (TAG_INPUT, DIGEST,
  TAGS) — no direct expression interpolation inside shell bodies.

Preserves existing contract end-to-end: SHA pin, provenance=max, sbom=true,
dual-registry push, `steps.build.outputs.digest` wiring to Cosign and the
build-provenance attestations.
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.

2 participants