Skip to content

ROSAENG-61040 | refactor: remove github.com/dustin/go-humanize#3414

Open
markirish wants to merge 1 commit into
openshift:masterfrom
markirish:ROSAENG-61040-remove-dustin-go-humanize
Open

ROSAENG-61040 | refactor: remove github.com/dustin/go-humanize#3414
markirish wants to merge 1 commit into
openshift:masterfrom
markirish:ROSAENG-61040-remove-dustin-go-humanize

Conversation

@markirish

@markirish markirish commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

PR Summary

Replace humanize.Bytes with a ~15-line readableBytes helper using SI units (base 1000) matching the original behavior.

Detailed Description of the Issue

Our ROSA CLI project currently imports several third-party libraries that are only utilized in a single file (e.g., exclusively within a test file or for a single validation function). Relying on entire external dependencies for isolated use cases unnecessarily increases our security attack surface, complicates dependency management, and bloats the project.

This PR is part of that initiative to remove github.com/dustin/go-humanize

Related Issues and PRs

Type of Change

  • feat - adds a new user-facing capability.
  • fix - resolves an incorrect behavior or bug.
  • docs - updates documentation only.
  • style - formatting or naming changes with no logic impact.
  • refactor - code restructuring with no behavior change.
  • test - adds or updates tests only.
  • chore - maintenance work (tooling, housekeeping, non-product code).
  • build - changes build system, packaging, or dependencies for build output.
  • ci - changes CI pipelines, jobs, or automation workflows.
  • perf - improves performance without changing intended behavior.

Previous Behavior

Behavior After This Change

How to Test (Step-by-Step)

Preconditions

Test Steps

  1. run make test

Expected Results

All tests pass

Proof of the Fix

Tests pass

Breaking Changes

  • No breaking changes
  • Yes, this PR introduces a breaking change (describe impact and migration plan below)

Developer Verification Checklist

  • Commit subject/title follows [JIRA-TICKET] | [TYPE]: <MESSAGE>.
  • PR description clearly explains both what changed and why.
  • Relevant Jira/GitHub issues and related PRs are linked.
  • make install-hooks has been run in this clone.
  • Tests were added/updated where appropriate.
  • I manually tested the change.
  • make test passes.
  • make lint passes.
  • make rosa passes.
  • Documentation or repo-local agent guidance was added/updated where appropriate.
  • Any risk, limitation, or follow-up work is documented.

Summary by CodeRabbit

Summary

  • Bug Fixes

    • Standardized download progress and completion to show consistent human-readable byte sizes.
    • Improved non-2xx download failure messages with clearer multi-line details, including HTTP status code and the requested URL.
    • Refined timeout error formatting for clearer troubleshooting.
  • Tests

    • Added automated test coverage for byte-size formatting across unit boundaries, rounding cases, and large values.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 7bacfd58-0818-426c-a9bb-ffebc84d24b4

📥 Commits

Reviewing files that changed from the base of the PR and between 3a5eeb6 and afbda87.

⛔ Files ignored due to path filters (16)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/dustin/go-humanize/.travis.yml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/LICENSE is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/README.markdown is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/big.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/bigbytes.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/bytes.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/comma.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/commaf.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/ftoa.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/humanize.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/number.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/ordinals.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/si.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/times.go is excluded by !vendor/**, !**/vendor/**
  • vendor/modules.txt is excluded by !vendor/**, !**/vendor/**
📒 Files selected for processing (3)
  • go.mod
  • pkg/helper/download/download.go
  • pkg/helper/download/readable_bytes_test.go
💤 Files with no reviewable changes (1)
  • go.mod
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/helper/download/readable_bytes_test.go

📝 Walkthrough

Walkthrough

The download helper removes go-humanize, adds an internal readableBytes formatter using math, and uses it for completion progress output. New parameterized tests cover byte units, rounding, boundaries, and maximum values. HTTP status and timeout error construction are reformatted while preserving their existing categories and message content.

Suggested reviewers: braetroutman, dustman9000, amandahla


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 2 warnings)

Check name Status Explanation Resolution
No-Sensitive-Data-In-Logs ❌ Error Error messages now embed the raw request URL in multiple user-visible paths, which can leak tokens, query params, or internal hostnames. Redact URLs before emitting errors/logs (e.g., strip query/userinfo or replace with a sanitized host/path placeholder).
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Test Structure And Quality ⚠️ Warning readable_bytes_test.go uses bare Expect(...).To(Equal(...)) with no failure message, violating the required assertion-message quality check. Add a meaningful message to the assertion (e.g. include the input and expected output) or a helper that reports which case failed.
✅ Passed checks (12 passed)
Check name Status Explanation
Title check ✅ Passed The title is specific, concise, and accurately summarizes the dependency removal change.
Description check ✅ Passed The description mostly follows the template and includes summary, issue context, related issue, testing, proof, and checklist items.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed The new Ginkgo titles are static strings with no generated names, dates, UUIDs, or other dynamic data.
Microshift Test Compatibility ✅ Passed The new Ginkgo test is a pure unit test for readableBytes and uses no cluster/OpenShift APIs or MicroShift-unsupported assumptions.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The added Ginkgo tests are local unit tests using math/httptest only; they make no cluster, node, or HA assumptions, so SNO-specific guarding is unnecessary.
Topology-Aware Scheduling Compatibility ✅ Passed Only download helper, tests, and dependency cleanup changed; no deployment manifests, controllers, or scheduling constraints were added or modified.
Ote Binary Stdout Contract ✅ Passed The PR only changes a library helper and a Describe-only test; no main/init/TestMain/BeforeSuite code adds stdout writes.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The new Ginkgo test is a pure unit test for readableBytes; it contains no IP literals, host building, or external network access.
No-Weak-Crypto ✅ Passed The PR only changes download progress formatting and tests; no MD5/SHA1/DES/RC4/3DES/Blowfish, ECB, custom crypto, or secret comparisons appear.
Container-Privileges ✅ Passed PR diff only updates dependency removal/download code; no added container/K8s manifests or privileged settings were present in the changed files.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@openshift-ci

openshift-ci Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: markirish
Once this PR has been reviewed and has the lgtm label, please assign davidleerh for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🧹 Nitpick comments (1)
pkg/helper/download/download.go (1)

169-181: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Name the formatting constants.

The 10 literals encode the rounding scale, threshold, and decimal precision. Extract named constants so the display contract is explicit and less error-prone.

As per coding guidelines, avoid magic numbers; extract named constants when the value matters to behavior or readability.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/helper/download/download.go` around lines 169 - 181, In the
byte-formatting logic, replace the repeated literal 10 values used for rounding
scale, threshold comparison, and one-decimal precision with clearly named
constants. Update the condition and formatting expression in the surrounding
formatting function while preserving the existing display behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/helper/download/download.go`:
- Around line 178-183: Update the byte-formatting logic around val and suffix to
assign the rounded one-decimal value from math.Round(val*10)/10, then use that
rounded value in both the one-decimal and zero-decimal format branches. Add a
regression test covering the exact halfway input 1250, expecting “1.3 kB”.
- Around line 113-114: Update the timeout error return in the download flow to
wrap the existing non-nil err with %w while preserving the current friendly
timeout message and URL context. Ensure callers can inspect the underlying
network error via errors.Is or errors.As.

---

Nitpick comments:
In `@pkg/helper/download/download.go`:
- Around line 169-181: In the byte-formatting logic, replace the repeated
literal 10 values used for rounding scale, threshold comparison, and one-decimal
precision with clearly named constants. Update the condition and formatting
expression in the surrounding formatting function while preserving the existing
display behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 6a47bf21-f041-4f55-9223-d507ebf0d690

📥 Commits

Reviewing files that changed from the base of the PR and between 71fe022 and 7b24495.

⛔ Files ignored due to path filters (16)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/dustin/go-humanize/.travis.yml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/LICENSE is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/README.markdown is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/big.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/bigbytes.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/bytes.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/comma.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/commaf.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/ftoa.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/humanize.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/number.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/ordinals.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/si.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/dustin/go-humanize/times.go is excluded by !vendor/**, !**/vendor/**
  • vendor/modules.txt is excluded by !vendor/**, !**/vendor/**
📒 Files selected for processing (3)
  • go.mod
  • pkg/helper/download/download.go
  • pkg/helper/download/readable_bytes_test.go
💤 Files with no reviewable changes (1)
  • go.mod

Comment thread pkg/helper/download/download.go
Comment thread pkg/helper/download/download.go Outdated
@amandahla

amandahla commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Lets see how my prompt works:

@coderabbitai
Review this PR only as a third-party dependency removal/replacement (ROSAENG-61040 style).
Be brief. High-signal findings only. No style nits, no optional refactors, no PR-description rewriting.
1) Identify OLD module removed and REPLACEMENT type: stdlib / existing go.mod dep / new module / inlined code.
2) Find the PR/commit that originally added OLD; note any warnings/rationale still relevant.
3) Check OLD (and NEW if any) GitHub README for warnings, deprecation, or “prefer X instead”.
4) If NEW module: flag security/CVE risk, license conflict with Apache-2.0, archived/deprecated status.
5) If inlined code: is it safe, Go-modern (1.26), in a package that matches call sites, and does it add new deps? (new deps undermine the goal)
6) Confirm go.mod/go.sum cleanup and behavior parity for changed call sites.
7) Prefer stdlib/existing deps over new modules or copies.
Output: short verdict (approve / needs change) + bullets only for real risks. Draft a 2–4 sentence evaluation note the author can paste into the PR description. Do not edit the PR.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== PR metadata and changed files =='
gh pr view 3414 --repo openshift/rosa --json number,url,title,baseRefName,headRefName,commits,files --jq '{number,url,title,base:.baseRefName,head:.headRefName,commits:[.commits[]|{oid:.oid,messageHeadline:.messageHeadline}],files:[.files[]|{path:.path,additions:.additions,deletions:.deletions}]}'

echo '== Diff against PR base =='
git diff --no-ext-diff --unified=80 "$(git merge-base HEAD origin/$(gh pr view 3414 --repo openshift/rosa --json baseRefName --jq .baseRefName))" HEAD -- go.mod go.sum pkg/helper/download/download.go pkg/helper/download/readable_bytes_test.go

echo '== Current module references and formatter call sites =='
rg -n -C 4 'github\.com/dustin/go-humanize|humanize\.Bytes|readableBytes\s*\(' go.mod go.sum pkg/helper/download

echo '== Go module version and formatting implementation context =='
rg -n -C 3 '^go\s+[0-9]+\.[0-9]+' go.mod
ast-grep outline pkg/helper/download/download.go --items all
sed -n '1,280p' pkg/helper/download/download.go
sed -n '1,240p' pkg/helper/download/readable_bytes_test.go

echo '== Introduction history for old module and call site =='
git log --all --reverse --format='%H%x09%s' -S'github.com/dustin/go-humanize' -- go.mod
git log --all --reverse --format='%H%x09%s' -S'humanize.Bytes' -- pkg/helper/download/download.go

echo '== Introduction commit details (first matching commit) =='
intro="$(git log --all --reverse --format='%H' -S'github.com/dustin/go-humanize' -- go.mod | head -n1)"
if [ -n "$intro" ]; then
  git show --no-ext-diff --format=fuller --stat "$intro"
  git show --no-ext-diff --format= --unified=30 "$intro" -- go.mod go.sum pkg/helper/download/download.go
fi

Length of output: 43316


🤖 web_search executed:

github.com/dustin/go-humanize README Bytes documentation warnings deprecation prefer alternative

Length of output: 6571


🏁 Script executed:

#!/bin/bash
set -euo pipefail

base="$(git merge-base HEAD origin/master)"
intro="a326f9842515a35186631e877cd7d0ac6c674fa3"

echo '== Introduction commit metadata and message =='
git show --no-ext-diff --no-patch --format=fuller "$intro"
git show --no-ext-diff --format= --unified=40 "$intro" -- go.mod go.sum pkg/helper/download/download.go

echo '== GitHub PRs associated with introduction commit =='
gh api -H 'Accept: application/vnd.github+json' \
  "/repos/openshift/rosa/commits/$intro/pulls" \
  --jq '.[] | {number,title,url:.html_url,body}'

echo '== Old v1.0.1 formatter implementation from PR base vendor tree =='
git show "$base:vendor/github.com/dustin/go-humanize/bytes.go" | sed -n '1,240p'

echo '== Current PR vendor/module cleanup verification =='
printf 'go.mod/go.sum module matches: '
if rg -n 'github\.com/dustin/go-humanize' go.mod go.sum; then false; else echo 'none'; fi
printf 'vendored path exists: '
if test -e vendor/github.com/dustin/go-humanize; then echo 'yes'; else echo 'no'; fi
printf 'vendor/modules.txt match: '
if rg -n 'github\.com/dustin/go-humanize' vendor/modules.txt; then false; else echo 'none'; fi

echo '== Compare formatter source behavior over representative edge cases =='
python3 - <<'PY'
import math

def old(s):
    sizes = ["B", "kB", "MB", "GB", "TB", "PB", "EB"]
    if s < 10:
        return f"{s} B"
    e = math.floor(math.log(float(s), 1000))
    suffix = sizes[int(e)]
    val = float(s) / math.pow(1000, math.floor(e))
    return (f"{val:.1f} {suffix}" if val < 10 else f"{val:.0f} {suffix}")

def new(b):
    unit = 1000
    if b < unit:
        return f"{b} B"
    div, exp = unit, 0
    n = b // unit
    while n >= unit:
        div *= unit
        exp += 1
        n //= unit
    val = float(b) / float(div)
    suffix = ["kB", "MB", "GB", "TB", "PB", "EB"][exp]
    return f"{val:.1f} {suffix}" if round(val * 10) / 10 < 10 else f"{val:.0f} {suffix}"

cases = [
    0, 1, 9, 10, 999, 1000, 9999, 10000,
    999999, 1000000, 9999999, 10000000,
    999999999, 1000000000, (2**64)-1
]
for value in cases:
    print(f"{value}: old={old(value)!r} new={new(value)!r} {'OK' if old(value) == new(value) else 'DIFF'}")
PY

Length of output: 33847


@amandahla Verdict: needs change

  • Behavior parity: github.com/dustin/go-humanize is fully removed (including go.mod, go.sum, and vendored files) and replaced by a package-local, standard-library-only helper—no new dependency. However, at Line 180, the helper changes output at rounding boundaries: humanize.Bytes(9999) returns 10.0 kB, while readableBytes(9999) returns 10 kB (likewise 9999999: 10.0 MB10 MB). The new tests codify this difference, so this is not a byte-for-byte replacement of the only changed call site’s CLI output.
  • Provenance/upstream: The module was added for the download command in commit a326f9842515a35186631e877cd7d0ac6c674fa3 / PR #68; no relevant warning or special rationale was found. Its upstream docs define Bytes as SI/base-1000 formatting and show no deprecation or “prefer X” guidance.

Paste-ready evaluation note:

This change removes the direct github.com/dustin/go-humanize dependency and its vendored source, replacing the single humanize.Bytes call with a package-local helper using only the Go standard library. The replacement preserves SI/base-1000 units and adds no dependencies. Before merging, the helper should retain the original formatter’s rounding-boundary output (for example, 9999 bytes remains 10.0 kB) to maintain CLI behavior parity.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== PR metadata and changed files ==='
gh pr view 3414 --repo openshift/rosa --json number,title,baseRefName,headRefName,commits,files --jq '{number,title,base:.baseRefName,head:.headRefName,commits:[.commits[]|{oid:.oid,messageHeadline:.messageHeadline}],files:[.files[]|{path:.path,additions:.additions,deletions:.deletions}]}'

echo '=== PR diff ==='
gh pr diff 3414 --repo openshift/rosa -- go.mod go.sum pkg/helper/download/download.go pkg/helper/download/readable_bytes_test.go

echo '=== Relevant source outline ==='
ast-grep outline pkg/helper/download/download.go --items all || true

echo '=== Relevant source and module entries ==='
sed -n '1,280p' pkg/helper/download/download.go
printf '\n--- go.mod occurrences ---\n'
rg -n -C2 'dustin/go-humanize|go-humanize' go.mod go.sum || true
printf '\n--- repository usages ---\n'
rg -n -C3 'humanize\.Bytes|go-humanize|readableBytes\s*\(' -g '*.go' -g 'go.mod' -g 'go.sum' .

echo '=== Addition provenance ==='
git log --all --format='%H%x09%s' -S'github.com/dustin/go-humanize' -- go.mod go.sum pkg/helper/download/download.go | head -20
git log --all --format='%H%x09%s' -S'humanize.Bytes' -- pkg/helper/download/download.go | head -20

echo '=== Commit details for adding commit(s) ==='
for commit in $(git log --all --format='%H' -S'github.com/dustin/go-humanize' -- go.mod go.sum pkg/helper/download/download.go | head -5); do
  echo "--- $commit ---"
  git show --no-ext-diff --format=fuller --stat "$commit"
  git show --no-ext-diff --format=fuller "$commit" -- go.mod go.sum pkg/helper/download/download.go | sed -n '1,280p'
done

echo '=== Go version ==='
rg -n -C1 '^go [0-9.]+' go.mod

Length of output: 3926


🤖 web_search executed:

github.com/dustin/go-humanize README deprecation warning prefer alternative GitHub security advisories

Length of output: 3940


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo="openshift/rosa"
pr="3414"
head="7b244957a98a24b3b0a03cada2f17e3a0eb0e4cc"

echo '=== Full PR patch ==='
gh api -H 'Accept: application/vnd.github.patch' "/repos/${repo}/pulls/${pr}" > /tmp/pr-3414.patch
sed -n '1,900p' /tmp/pr-3414.patch

echo '=== Current replacement and tests ==='
ast-grep outline pkg/helper/download/download.go --items all || true
sed -n '1,300p' pkg/helper/download/download.go
sed -n '1,240p' pkg/helper/download/readable_bytes_test.go

echo '=== Residual dependency / formatter references in PR head ==='
rg -n -C3 'github\.com/dustin/go-humanize|humanize\.Bytes|readableBytes\s*\(' \
  -g '*.go' -g 'go.mod' -g 'go.sum' -g 'modules.txt' . || true

echo '=== Module metadata and vendoring cleanup ==='
rg -n -C2 'dustin/go-humanize|go-humanize' go.mod go.sum vendor/modules.txt || true
rg -n -C1 '^go [0-9.]+' go.mod

echo '=== Removed upstream implementation at PR base ==='
base=$(gh pr view "$pr" --repo "$repo" --json baseRefOid --jq .baseRefOid)
gh api "/repos/${repo}/contents/vendor/github.com/dustin/go-humanize/bytes.go?ref=${base}" \
  --jq .content | tr -d '\n' | base64 -d || true

echo '=== Local history candidates ==='
git log --all --format='%H%x09%s' -S'github.com/dustin/go-humanize' -- go.mod go.sum pkg/helper/download/download.go | head -30 || true
git log --all --format='%H%x09%s' -S'humanize.Bytes' -- pkg/helper/download/download.go | head -30 || true

echo '=== GitHub commit search candidates (addition) ==='
gh api -H 'Accept: application/vnd.github+json' \
  "/search/commits?q=repo:${repo}+%22github.com/dustin/go-humanize%22" \
  --jq '.items[] | [.sha, .commit.message, .html_url] | `@tsv`' | head -30 || true

echo '=== Repository commit history for affected files ==='
for path in go.mod pkg/helper/download/download.go; do
  echo "--- ${path} ---"
  gh api "/repos/${repo}/commits?path=${path}&per_page=100" \
    --jq '.[] | [.sha, .commit.message, .html_url] | `@tsv`' | head -100 || true
done

echo '=== Upstream GitHub metadata / advisories ==='
gh api /repos/dustin/go-humanize --jq '{archived,disabled,license:(.license.spdx_id),updated_at,pushed_at,default_branch,security_and_analysis}' || true
gh api '/repos/dustin/go-humanize/security-advisories?per_page=100' --jq '[.[] | {ghsa_id,state,severity,published_at,withdrawn_at}]' || true

Length of output: 71873


@amandahla Verdict: approve.

github.com/dustin/go-humanize v1.0.1 is fully removed and replaced by package-local inlined code using only the Go standard library (fmt, math), with no new dependencies. The original use was introduced in commit 39af6a03d23be45b48665ef55ccabd5828a7e311 for the download feature; no continuing warning or special rationale was found. The upstream README contains no deprecation or “prefer X” guidance; the repository is active and has no published repository security advisories. go.mod, go.sum, and vendored sources are cleaned up, and readableBytes preserves the SI/base-1000 humanize.Bytes output behavior at the sole call site.

PR description evaluation note:
This change removes the isolated direct dependency on github.com/dustin/go-humanize v1.0.1. Its sole humanize.Bytes usage is replaced with a tested, package-local SI byte formatter implemented only with Go standard-library packages. Module checksums and all vendored go-humanize sources are removed, with no new dependency introduced.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== PR metadata and changed files =='
gh pr view 3414 --repo openshift/rosa --json number,title,baseRefName,headRefName,commits,files \
  --jq '{number,title,baseRefName,headRefName,commits:[.commits[]|{oid,messageHeadline,authoredDate}],files:[.files[]|{path,additions,deletions}]}'

printf '%s\n' '== Current changed Go/package structure =='
ast-grep outline pkg/helper/download/download.go --items all
if [ -f pkg/helper/download/readable_bytes_test.go ]; then
  ast-grep outline pkg/helper/download/readable_bytes_test.go --items all
fi

printf '%s\n' '== Relevant implementation and tests =='
rg -n -C 12 'readableBytes|humanize\.Bytes|WriteCounter|Downloaded' pkg/helper/download go.mod go.sum || true

printf '%s\n' '== All remaining module/import references =='
rg -n -C 3 'github\.com/dustin/go-humanize|go-humanize|humanize\.' . \
  -g '!vendor/**' -g '!**/.git/**' || true

printf '%s\n' '== Dependency metadata =='
grep -n -C 2 'github.com/dustin/go-humanize' go.mod go.sum || true
go_version=$(awk '/^go [0-9]+\.[0-9]+/{print $2; exit}' go.mod)
printf 'Declared Go version: %s\n' "${go_version:-not found}"

printf '%s\n' '== Introduction/provenance of old module =='
git log --all --reverse -S'github.com/dustin/go-humanize' --format='%H%x09%ad%x09%s' --date=short -- go.mod go.sum
git log --all --reverse -S'humanize.Bytes' --format='%H%x09%ad%x09%s' --date=short -- pkg/helper/download/download.go

Length of output: 12061


🤖 web_search executed:

github dustin/go-humanize README warnings deprecation prefer alternative

Length of output: 5077


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Upstream repository metadata and README =='
gh api repos/dustin/go-humanize --jq '{full_name,archived,disabled,license:(.license.spdx_id // null),default_branch,updated_at,html_url}'
gh api repos/dustin/go-humanize/readme -H 'Accept: application/vnd.github.raw+json' | sed -n '1,240p'

printf '%s\n' '== GitHub security advisories for the removed module =='
gh api -X GET /advisories \
  -f ecosystem=go \
  -f affects='github.com/dustin/go-humanize' \
  --paginate \
  --jq '.[] | {ghsa_id,cve_id,summary,severity,published_at,withdrawn_at,html_url}' || true

Length of output: 4135


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Current replacement and its complete test cases =='
sed -n '145,220p' pkg/helper/download/download.go
sed -n '1,120p' pkg/helper/download/readable_bytes_test.go

printf '%s\n' '== Original formatter at the PR base =='
git show '7b244957a98a24b3b0a03cada2f17e3a0eb0e4cc^:vendor/github.com/dustin/go-humanize/bytes.go' | sed -n '1,240p'

printf '%s\n' '== Introduction and immediate dependency-fix patches =='
git show --format=fuller --find-renames --find-copies --stat --patch \
  a326f9842515a35186631e877cd7d0ac6c674fa3 \
  ee7556e686b87f3a29c719234b0e7373f81f68e7 \
  -- go.mod go.sum vendor/modules.txt pkg/helper/download/download.go \
  | sed -n '1,360p'

Length of output: 35967


@amandahla Verdict: approve

  • Removed module: github.com/dustin/go-humanize v1.0.1; replacement: small inlined readableBytes helper using only the Go standard library.
  • The module originated in commit a326f984 for download progress formatting. The subsequent “broken dependency” fix was for survey/v2, so it carries no relevant warning for this removal.
  • Upstream has no README deprecation/preferred-replacement warning, is not archived, and GitHub returned no Go advisory for the module.
  • go.mod, go.sum, vendor/modules.txt, and vendored source are clean; no remaining references exist. The formatter preserves the previous SI/rounding behavior and covers boundaries plus math.MaxUint64 in tests.

Paste-ready PR evaluation note:
This change removes github.com/dustin/go-humanize, which was used only for download progress byte formatting. Its replacement is a package-local, standard-library-only formatter that preserves the prior SI-unit and rounding behavior without introducing dependencies. Module metadata and vendored files have been fully cleaned up.

@markirish
markirish force-pushed the ROSAENG-61040-remove-dustin-go-humanize branch from 7b24495 to 3a5eeb6 Compare July 24, 2026 15:06
@markirish

Copy link
Copy Markdown
Contributor Author

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain
🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== PR metadata and changed files =='
gh pr view 3414 --repo openshift/rosa --json number,url,title,baseRefName,headRefName,commits,files --jq '{number,url,title,base:.baseRefName,head:.headRefName,commits:[.commits[]|{oid:.oid,messageHeadline:.messageHeadline}],files:[.files[]|{path:.path,additions:.additions,deletions:.deletions}]}'

echo '== Diff against PR base =='
git diff --no-ext-diff --unified=80 "$(git merge-base HEAD origin/$(gh pr view 3414 --repo openshift/rosa --json baseRefName --jq .baseRefName))" HEAD -- go.mod go.sum pkg/helper/download/download.go pkg/helper/download/readable_bytes_test.go

echo '== Current module references and formatter call sites =='
rg -n -C 4 'github\.com/dustin/go-humanize|humanize\.Bytes|readableBytes\s*\(' go.mod go.sum pkg/helper/download

echo '== Go module version and formatting implementation context =='
rg -n -C 3 '^go\s+[0-9]+\.[0-9]+' go.mod
ast-grep outline pkg/helper/download/download.go --items all
sed -n '1,280p' pkg/helper/download/download.go
sed -n '1,240p' pkg/helper/download/readable_bytes_test.go

echo '== Introduction history for old module and call site =='
git log --all --reverse --format='%H%x09%s' -S'github.com/dustin/go-humanize' -- go.mod
git log --all --reverse --format='%H%x09%s' -S'humanize.Bytes' -- pkg/helper/download/download.go

echo '== Introduction commit details (first matching commit) =='
intro="$(git log --all --reverse --format='%H' -S'github.com/dustin/go-humanize' -- go.mod | head -n1)"
if [ -n "$intro" ]; then
  git show --no-ext-diff --format=fuller --stat "$intro"
  git show --no-ext-diff --format= --unified=30 "$intro" -- go.mod go.sum pkg/helper/download/download.go
fi

Length of output: 43316

🤖 web_search executed:

github.com/dustin/go-humanize README Bytes documentation warnings deprecation prefer alternative

Length of output: 6571

🏁 Script executed:

#!/bin/bash
set -euo pipefail

base="$(git merge-base HEAD origin/master)"
intro="a326f9842515a35186631e877cd7d0ac6c674fa3"

echo '== Introduction commit metadata and message =='
git show --no-ext-diff --no-patch --format=fuller "$intro"
git show --no-ext-diff --format= --unified=40 "$intro" -- go.mod go.sum pkg/helper/download/download.go

echo '== GitHub PRs associated with introduction commit =='
gh api -H 'Accept: application/vnd.github+json' \
  "/repos/openshift/rosa/commits/$intro/pulls" \
  --jq '.[] | {number,title,url:.html_url,body}'

echo '== Old v1.0.1 formatter implementation from PR base vendor tree =='
git show "$base:vendor/github.com/dustin/go-humanize/bytes.go" | sed -n '1,240p'

echo '== Current PR vendor/module cleanup verification =='
printf 'go.mod/go.sum module matches: '
if rg -n 'github\.com/dustin/go-humanize' go.mod go.sum; then false; else echo 'none'; fi
printf 'vendored path exists: '
if test -e vendor/github.com/dustin/go-humanize; then echo 'yes'; else echo 'no'; fi
printf 'vendor/modules.txt match: '
if rg -n 'github\.com/dustin/go-humanize' vendor/modules.txt; then false; else echo 'none'; fi

echo '== Compare formatter source behavior over representative edge cases =='
python3 - <<'PY'
import math

def old(s):
    sizes = ["B", "kB", "MB", "GB", "TB", "PB", "EB"]
    if s < 10:
        return f"{s} B"
    e = math.floor(math.log(float(s), 1000))
    suffix = sizes[int(e)]
    val = float(s) / math.pow(1000, math.floor(e))
    return (f"{val:.1f} {suffix}" if val < 10 else f"{val:.0f} {suffix}")

def new(b):
    unit = 1000
    if b < unit:
        return f"{b} B"
    div, exp = unit, 0
    n = b // unit
    while n >= unit:
        div *= unit
        exp += 1
        n //= unit
    val = float(b) / float(div)
    suffix = ["kB", "MB", "GB", "TB", "PB", "EB"][exp]
    return f"{val:.1f} {suffix}" if round(val * 10) / 10 < 10 else f"{val:.0f} {suffix}"

cases = [
    0, 1, 9, 10, 999, 1000, 9999, 10000,
    999999, 1000000, 9999999, 10000000,
    999999999, 1000000000, (2**64)-1
]
for value in cases:
    print(f"{value}: old={old(value)!r} new={new(value)!r} {'OK' if old(value) == new(value) else 'DIFF'}")
PY

Length of output: 33847

@amandahla Verdict: needs change

  • Behavior parity: github.com/dustin/go-humanize is fully removed (including go.mod, go.sum, and vendored files) and replaced by a package-local, standard-library-only helper—no new dependency. However, at Line 180, the helper changes output at rounding boundaries: humanize.Bytes(9999) returns 10.0 kB, while readableBytes(9999) returns 10 kB (likewise 9999999: 10.0 MB10 MB). The new tests codify this difference, so this is not a byte-for-byte replacement of the only changed call site’s CLI output.
  • Provenance/upstream: The module was added for the download command in commit a326f9842515a35186631e877cd7d0ac6c674fa3 / PR #68; no relevant warning or special rationale was found. Its upstream docs define Bytes as SI/base-1000 formatting and show no deprecation or “prefer X” guidance.

Paste-ready evaluation note:

This change removes the direct github.com/dustin/go-humanize dependency and its vendored source, replacing the single humanize.Bytes call with a package-local helper using only the Go standard library. The replacement preserves SI/base-1000 units and adds no dependencies. Before merging, the helper should retain the original formatter’s rounding-boundary output (for example, 9999 bytes remains 10.0 kB) to maintain CLI behavior parity

@coderabbitai Can you confirm that the code now has parity with the old go-humanize behavior?

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo="openshift/rosa"
pr="3414"
base="$(gh pr view "$pr" --repo "$repo" --json baseRefOid --jq .baseRefOid)"

echo '== PR head and base =='
gh pr view "$pr" --repo "$repo" --json headRefOid,baseRefOid --jq '{head:.headRefOid,base:.baseRefOid}'

echo '== Current formatter and its tests =='
ast-grep outline pkg/helper/download/download.go --items all
sed -n '150,215p' pkg/helper/download/download.go
sed -n '1,180p' pkg/helper/download/readable_bytes_test.go

echo '== Original go-humanize v1.0.1 formatter from PR base =='
git show "${base}:vendor/github.com/dustin/go-humanize/bytes.go" | sed -n '1,220p'

echo '== Current call sites =='
rg -n -C 3 'readableBytes\s*\(' pkg/helper/download

echo '== Source-level comparison of precision predicates =='
rg -n -C 4 'func readableBytes|math\.(Log|Floor|Pow|Round)|%\.0f|%\.1f' \
  pkg/helper/download/download.go
git show "${base}:vendor/github.com/dustin/go-humanize/bytes.go" \
  | rg -n -C 4 'func Bytes|math\.(Log|Floor|Pow|Round)|%\.0f|%\.1f'

Length of output: 9162


@markirish No—the current implementation does not have byte-for-byte parity with go-humanize.

The earlier finding’s direction was reversed: the old formatter produced no decimal once the rounded value was at least 10, while readableBytes always prints one decimal. For example:

  • humanize.Bytes(9999)10 kB; current readableBytes(9999)10.0 kB
  • humanize.Bytes(10000)10 kB; current readableBytes(10000)10.0 kB
  • humanize.Bytes(9999999)10 MB; current readableBytes(9999999)10.0 MB

This follows directly from the old val < 10 precision switch (%.1f vs. %.0f) versus the current unconditional %.1f. The new tests currently codify the changed output, so the formatter should restore that precision selection if exact CLI-output parity is required.

Replace humanize.Bytes with a ~15-line readableBytes helper using
SI units (base 1000) matching the original behavior.
@markirish
markirish force-pushed the ROSAENG-61040-remove-dustin-go-humanize branch from 3a5eeb6 to afbda87 Compare July 24, 2026 15:24
@markirish

Copy link
Copy Markdown
Contributor Author

#3414 (comment)

@coderabbitai Ok, check one more time, parity should exist now

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo="openshift/rosa"
pr="3414"
base="$(gh pr view "$pr" --repo "$repo" --json baseRefOid --jq -r .baseRefOid)"
head="$(gh pr view "$pr" --repo "$repo" --json headRefOid --jq -r .headRefOid)"

printf '== Revisions ==\nbase=%s\nhead=%s\n' "$base" "$head"

printf '\n== Updated helper and tests ==\n'
ast-grep outline pkg/helper/download/download.go --items all
sed -n '155,220p' pkg/helper/download/download.go
if [ -f pkg/helper/download/readable_bytes_test.go ]; then
  sed -n '1,180p' pkg/helper/download/readable_bytes_test.go
fi

printf '\n== Removed formatter at PR base ==\n'
git show "${base}:vendor/github.com/dustin/go-humanize/bytes.go" | sed -n '1,240p'

printf '\n== Relevant PR changes ==\n'
git diff --no-ext-diff --unified=30 "$base" "$head" -- \
  pkg/helper/download/download.go pkg/helper/download/readable_bytes_test.go

printf '\n== Behavioral comparison model (old vs updated logic) ==\n'
python3 - <<'PY'
import math
import random

MAX = (1 << 64) - 1
units = ["B", "kB", "MB", "GB", "TB", "PB", "EB"]

# Model of github.com/dustin/go-humanize v1.0.1 Bytes.
def old(s):
    if s < 10:
        return f"{s} B"
    e = math.floor(math.log(float(s), 1000))
    suffix = units[int(e)]
    val = float(s) / math.pow(1000, math.floor(e))
    return f"{val:.1f} {suffix}" if val < 10 else f"{val:.0f} {suffix}"

# Model of the current PR helper: unit choice from integer division;
# precision predicate must match the checked-in source.
def current(b):
    unit = 1000
    if b < unit:
        return f"{b} B"
    div, exp = unit, 0
    n = b // unit
    while n >= unit:
        div *= unit
        exp += 1
        n //= unit
    value = float(b) / float(div)
    suffix = units[exp + 1]
    return f"{value:.1f} {suffix}" if value < 10 else f"{value:.0f} {suffix}"

cases = set(range(0, 11000))
for exponent in range(1, 7):
    base = 1000 ** exponent
    for offset in range(-20, 21):
        if 0 <= base + offset <= MAX:
            cases.add(base + offset)
    # Values around rounding from 9.9 to 10.0 in each unit.
    for offset in range(-20, 21):
        value = 10 * base + offset
        if value <= MAX:
            cases.add(value)
for _ in range(20000):
    cases.add(random.Random(3414 + _).randrange(MAX + 1))
cases.add(MAX)

diffs = [(value, old(value), current(value)) for value in sorted(cases) if old(value) != current(value)]
print(f"cases_checked={len(cases)}")
print(f"differences={len(diffs)}")
for value, before, after in diffs[:20]:
    print(f"DIFF {value}: old={before!r} current={after!r}")
if diffs:
    raise SystemExit(1)
PY

Length of output: 2949


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo="openshift/rosa"
pr="3414"
base="$(gh pr view "$pr" --repo "$repo" --json baseRefOid --jq -r .baseRefOid)"
head="$(gh pr view "$pr" --repo "$repo" --json headRefOid --jq -r .headRefOid)"

printf '== Revisions ==\nbase=%s\nhead=%s\n' "$base" "$head"

printf '\n== Updated helper and its tests ==\n'
sed -n '155,225p' pkg/helper/download/download.go
sed -n '1,180p' pkg/helper/download/readable_bytes_test.go

printf '\n== Original go-humanize formatter at PR base ==\n'
git show "${base}:vendor/github.com/dustin/go-humanize/bytes.go" | sed -n '1,220p'

printf '\n== Updated relevant diff ==\n'
git diff --no-ext-diff --unified=30 "$base" "$head" -- \
  pkg/helper/download/download.go pkg/helper/download/readable_bytes_test.go

printf '\n== Precision predicates ==\n'
rg -n -C 3 'func readableBytes|value < 10|val < 10|%\.0f|%\.1f' \
  pkg/helper/download/download.go
git show "${base}:vendor/github.com/dustin/go-humanize/bytes.go" \
  | rg -n -C 3 'func Bytes|value < 10|val < 10|%\.0f|%\.1f'

printf '\n== Behavioral comparison ==\n'
python3 - <<'PY'
import math
import random

MAX = (1 << 64) - 1
units = ["B", "kB", "MB", "GB", "TB", "PB", "EB"]

def old(s):
    if s < 10:
        return f"{s} B"
    exponent = math.floor(math.log(float(s), 1000))
    value = float(s) / math.pow(1000, exponent)
    return f"{value:.1f} {units[int(exponent)]}" if value < 10 else f"{value:.0f} {units[int(exponent)]}"

def replacement(b):
    if b < 1000:
        return f"{b} B"
    div, exp, n = 1000, 0, b // 1000
    while n >= 1000:
        div *= 1000
        exp += 1
        n //= 1000
    value = float(b) / float(div)
    suffix = units[exp + 1]
    return f"{value:.1f} {suffix}" if value < 10 else f"{value:.0f} {suffix}"

cases = set(range(0, 11000))
for exponent in range(1, 7):
    scale = 1000 ** exponent
    for pivot in (scale, 10 * scale):
        for offset in range(-100, 101):
            if 0 <= pivot + offset <= MAX:
                cases.add(pivot + offset)
rng = random.Random(3414)
for _ in range(20000):
    cases.add(rng.randrange(MAX + 1))
cases.add(MAX)

diffs = [(v, old(v), replacement(v)) for v in sorted(cases) if old(v) != replacement(v)]
print(f"cases_checked={len(cases)}")
print(f"differences={len(diffs)}")
for v, previous, current in diffs[:20]:
    print(f"DIFF {v}: old={previous!r} replacement={current!r}")
if diffs:
    raise SystemExit(1)
PY

Length of output: 2763


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '== Current helper =='
sed -n '160,215p' pkg/helper/download/download.go

printf '%s\n' '== Current parity tests =='
sed -n '1,160p' pkg/helper/download/readable_bytes_test.go

printf '%s\n' '== Original formatter from the parent revision =='
git show HEAD^:vendor/github.com/dustin/go-humanize/bytes.go | sed -n '1,180p'

printf '%s\n' '== Relevant precision branches =='
rg -n -C 4 'func readableBytes|value < 10|val < 10|%\.0f|%\.1f' pkg/helper/download/download.go
git show HEAD^:vendor/github.com/dustin/go-humanize/bytes.go \
  | rg -n -C 4 'func Bytes|value < 10|val < 10|%\.0f|%\.1f'

printf '%s\n' '== Comparison across boundaries and deterministic random uint64 values =='
python3 - <<'PY'
import math
import random

limit = (1 << 64) - 1
names = ["B", "kB", "MB", "GB", "TB", "PB", "EB"]

def old(value):
    if value < 10:
        return f"{value} B"
    exponent = math.floor(math.log(float(value), 1000))
    formatted = float(value) / math.pow(1000, exponent)
    if formatted < 10:
        return f"{formatted:.1f} {names[int(exponent)]}"
    return f"{formatted:.0f} {names[int(exponent)]}"

def new(value):
    if value < 1000:
        return f"{value} B"
    divisor = 1000
    exponent = 0
    reduced = value // 1000
    while reduced >= 1000:
        divisor *= 1000
        exponent += 1
        reduced //= 1000
    formatted = float(value) / float(divisor)
    if formatted < 10:
        return f"{formatted:.1f} {names[exponent + 1]}"
    return f"{formatted:.0f} {names[exponent + 1]}"

values = set(range(11000))
for exponent in range(1, 7):
    scale = 1000 ** exponent
    for pivot in (scale, 10 * scale):
        values.update(v for v in range(pivot - 100, pivot + 101) if 0 <= v <= limit)
rng = random.Random(3414)
values.update(rng.randrange(limit + 1) for _ in range(20000))
values.add(limit)

differences = [(v, old(v), new(v)) for v in sorted(values) if old(v) != new(v)]
print("cases_checked=", len(values))
print("differences=", len(differences))
for value, previous, replacement in differences[:20]:
    print(f"{value}: old={previous!r}; replacement={replacement!r}")
if differences:
    raise SystemExit(1)
PY

Length of output: 9425


@markirish Confirmed: the updated readableBytes now has parity with the removed go-humanize Bytes behavior.

It uses the same SI base-1000 unit selection, rounding (floor(value * 10 + 0.5) / 10), and precision rule (%.1f below 10; otherwise %.0f). The updated tests also cover the previously flagged boundaries: 999910 kB, 999999910 MB, and math.MaxUint6418 EB.

The reported Python differences were from a stale model of the previous integer-division implementation, not the current checked-in helper. The current source matches the original formatter’s algorithm.


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

@openshift-ci

openshift-ci Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

@markirish: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/security afbda87 link false /test security
ci/prow/govulncheck afbda87 link false /test govulncheck

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@openshift-ci

openshift-ci Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

PR needs rebase.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dco-signoff: yes needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants