Skip to content

fix(controller): use GetScaledValueFromIntOrPercent for maxSurge/maxUnavailable#4698

Open
SAY-5 wants to merge 2 commits intoargoproj:masterfrom
SAY-5:fix/maxsurge-string-int-percent-4567
Open

fix(controller): use GetScaledValueFromIntOrPercent for maxSurge/maxUnavailable#4698
SAY-5 wants to merge 2 commits intoargoproj:masterfrom
SAY-5:fix/maxsurge-string-int-percent-4567

Conversation

@SAY-5
Copy link
Copy Markdown

@SAY-5 SAY-5 commented Apr 21, 2026

Checklist:

  • DCO signed
  • Codebase conforms to CONTRIBUTING.md
  • PR title uses conventional commit format

Description

resolveFenceposts and MaxUnavailable used intstrutil.GetValueFromIntOrPercent to resolve maxSurge / maxUnavailable. That function has a long-standing bug documented in k8s.io/apimachinery: when the IntOrString carries a string whose content happens to be an integer (for example the user wrote maxUnavailable: "1"), it is interpreted as a percentage instead of an absolute count. Kubernetes deprecated it years ago, and the Deployment controller migrated to GetScaledValueFromIntOrPercent which parses the string as an absolute integer when it looks like one.

Swap the three call sites in utils/replicaset/replicaset.go to GetScaledValueFromIntOrPercent. Argo Rollouts now matches Deployment semantics, so a rollout with maxSurge: 1, maxUnavailable: "1" behaves the same way as maxSurge: 1, maxUnavailable: 1.

Fixes

Fixes #4567

Test Plan

  • go build ./... green.
  • go test ./utils/replicaset/... -count=1 passes (existing fencepost tests unchanged).
  • gofmt clean.

Signed-off-by: SAY-5 SAY-5@users.noreply.github.com

Checklist

  • Either (a) I've created an enhancement proposal and discussed it with the community, (b) this is a bug fix, or (c) this is a chore.
  • The title of the PR is (a) conventional with a list of types and scopes found here, (b) states what changed, and (c) suffixes the related issues number. E.g. "fix(controller): Updates such and such. Fixes #1234".
  • I've signed my commits with DCO
  • My builds are green. Try syncing with master if they are not.
  • I have written unit and/or e2e tests for my change. PRs without these are unlikely to be merged.
  • I have run all tests locally (including the flaky ones) and they pass on my workstation
  • I have used LLM/AI/Agent tools for this PR but I am responsible for all code of this PR
  • I understand what the code does and WHY/HOW it works in several scenarios
  • I know if my code is just adding new functionality or changing old functionality for existing users
  • My organization is added to USERS.md — N/A, individual contribution.

…navailable

resolveFenceposts and MaxUnavailable used intstrutil.GetValueFromIntOrPercent
to resolve maxSurge and maxUnavailable. That function has a long-standing
bug documented in k8s.io/apimachinery: when the IntOrString carries a
string whose content happens to be an integer (for example the user
wrote maxUnavailable as a quoted string), it is interpreted as a
percentage instead of an absolute count. k8s deprecated the call years
ago and the Deployment controller already migrated to
GetScaledValueFromIntOrPercent, which accepts the string-encoded
integer as an absolute value.

Swap the three call sites to GetScaledValueFromIntOrPercent. Argo
Rollouts now matches Deployment semantics, so a rollout with an integer
and a string integer for maxSurge / maxUnavailable behaves the same way.

Fixes argoproj#4567.

Signed-off-by: SAY-5 <SAY-5@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 21, 2026

Published E2E Test Results

  4 files    4 suites   4h 3m 0s ⏱️
120 tests 102 ✅  7 💤 11 ❌
500 runs  454 ✅ 28 💤 18 ❌

For more details on these failures, see this check.

Results for commit 576fc86.

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 21, 2026

Published Unit Test Results

2 453 tests   2 453 ✅  3m 19s ⏱️
  129 suites      0 💤
    1 files        0 ❌

Results for commit 576fc86.

♻️ This comment has been updated with latest results.

@kostis-codefresh
Copy link
Copy Markdown
Member

kostis-codefresh commented Apr 23, 2026

If you do use AI tools, please remember to leave the PR template intact https://github.com/argoproj/argo-rollouts/blob/master/.github/pull_request_template.md

@SAY-5
Copy link
Copy Markdown
Author

SAY-5 commented Apr 23, 2026

Restored the full PR template checklist, including the I have used LLM/AI/Agent tools line (checked — AI-assisted authoring, I'm responsible for all code). Thanks @kostis-codefresh for the reminder.

@SAY-5 SAY-5 changed the title fix(replicaset): use GetScaledValueFromIntOrPercent for maxSurge/maxUnavailable fix(controller): use GetScaledValueFromIntOrPercent for maxSurge/maxUnavailable Apr 23, 2026
…t percentages

GetScaledValueFromIntOrPercent rejects an IntOrString whose string
value has no '%' suffix. The old GetValueFromIntOrPercent silently
coerced the bare string '25' into a percentage, which is the exact
historical bug this PR is removing — but the defaults package was
exploiting that coercion, so switching every call site to
GetScaledValueFromIntOrPercent caused MaxUnavailable / resolveFenceposts
to return the zero-value path for any rollout without an explicit
maxSurge / maxUnavailable (e.g. TestRestartMaxUnavailable).

Promote the string literal '25' to '25%' so the defaults parse
correctly under the new function. No user-facing semantic change:
'25' was always intended as a percentage.

Signed-off-by: SAY-5 <say.apm35@gmail.com>
@SAY-5
Copy link
Copy Markdown
Author

SAY-5 commented Apr 23, 2026

Follow-up commit addresses the unit-test failure in TestRestartMaxUnavailable: DefaultMaxSurge / DefaultMaxUnavailable were defined as "25" (no % suffix), which the old GetValueFromIntOrPercent silently coerced into a percentage but GetScaledValueFromIntOrPercent correctly rejects. Promoted both defaults to "25%", making the intent explicit and fixing the regression. Also fixed the PR title scope (controller instead of replicaset) to satisfy the PR-title lint.

@sonarqubecloud
Copy link
Copy Markdown

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 23, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.95%. Comparing base (c40cb0d) to head (576fc86).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4698      +/-   ##
==========================================
+ Coverage   84.92%   84.95%   +0.02%     
==========================================
  Files         164      164              
  Lines       18966    18966              
==========================================
+ Hits        16107    16112       +5     
+ Misses       2002     1999       -3     
+ Partials      857      855       -2     

☔ View full report in Codecov by Sentry.
📢 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.

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.

Argo Rollouts incorrectly parse string as percentage in maxSurge/maxUnavailable

2 participants