Skip to content

HELM-763: Fix helm upgrade secrets#16676

Closed
sowmya-sl wants to merge 7 commits into
openshift:mainfrom
sowmya-sl:fix-helm-upgrade-secrets
Closed

HELM-763: Fix helm upgrade secrets#16676
sowmya-sl wants to merge 7 commits into
openshift:mainfrom
sowmya-sl:fix-helm-upgrade-secrets

Conversation

@sowmya-sl

@sowmya-sl sowmya-sl commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Analysis / Root cause:

Kubernetes Secret object is used to store username and password for authentication when trying to create a Helm release. If a Helm release is created using a URL and selecting a particular secret for authentication, the users are unable to change the secrets during upgrade. This poses a problem if the secret's name has been changed or removed.

Solution description:

Create a dropdown where the secret can be entered during upgrade. If no secret is entered, it will go with the existing secret name if it exists, otherwise the new secret will override the old one.
Screenshots / screen recording:

https://docs.google.com/document/d/1LDRXScwr_jOnvdWU0siqW1gBMM8hrhm3D0oz831gUPA/edit?tab=t.mcv80hqh092h#heading=h.2jo1jtiyytic
Test setup:

An OCI registry and a Helm repository requiring authentication via username and password.

Reviewers and assignees:

Summary by CodeRabbit

  • New Features
    • Added basic-auth Secret selection and “create Secret” support to Helm install-from-URL and Helm upgrade flows, including secret name, optional username, and required password/token.
    • Helm charts/releases can now persist and carry the chosen auth Secret reference.
  • Bug Fixes
    • Improved handling of unauthorized (401) chart fetches with clearer guidance when authentication is required.
    • Displays a warning when the selected Secret isn’t found in the current namespace.
  • Tests / Chores
    • Updated UI text consistency across locales and adjusted integration/Cypress expectations accordingly.

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 24, 2026
@openshift-ci

openshift-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci openshift-ci Bot added needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. component/backend Related to backend component/core Related to console core functionality component/helm Related to helm-plugin kind/i18n Indicates issue or PR relates to internationalization or has content that needs to be translated labels Jun 24, 2026
@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

This PR adds basic-auth Secret support to Helm install and upgrade flows, including secret creation from the URL form, secret selection in the upgrade form, backend propagation of the secret name, and matching Helm label and test-string updates.

Changes

Helm basic-auth secret flow and text updates

Layer / File(s) Summary
Backend auth plumbing
pkg/helm/actions/install_chart.go, pkg/helm/actions/get_chart.go, pkg/helm/actions/upgrade_release.go, pkg/helm/handlers/handlers.go, pkg/helm/handlers/handler_test.go, pkg/helm/actions/upgrade_release_test.go
Chart install, chart lookup, upgrade release handling, and handler signatures now pass and persist an optional basic-auth Secret name and return auth-specific errors.
Secret modal and URL form
frontend/packages/helm-plugin/src/components/forms/url-chart/HelmCreateBasicAuthSecretModal.tsx, frontend/packages/helm-plugin/src/components/forms/url-chart/HelmURLChartForm.tsx, frontend/packages/helm-plugin/src/components/forms/url-chart/HelmURLChartInstallPage.tsx, frontend/packages/helm-plugin/src/components/forms/url-chart/HelmURLInstallForm.tsx, frontend/public/locales/en/public.json
A new overlay modal creates basic-auth Secrets, and the URL install form can open it from the secret dropdown and save the created name back into form state.
Upgrade form secret selection
frontend/packages/helm-plugin/src/components/forms/install-upgrade/HelmInstallUpgradeForm.tsx, frontend/packages/helm-plugin/src/components/forms/install-upgrade/HelmInstallUpgradePage.tsx, frontend/packages/helm-plugin/src/components/forms/__tests__/HelmInstallUpgradeForm.spec.tsx
The install/upgrade form now carries an optional secret name, loads existing Secrets, filters them, warns when the selected Secret is missing, and threads the selected value from chart metadata through submission.
Helm UI labels and locale keys
frontend/packages/helm-plugin/console-extensions.json, frontend/packages/helm-plugin/locales/*/helm-plugin.json, frontend/packages/helm-plugin/src/actions/add-resources.tsx, frontend/packages/helm-plugin/src/actions/creators.ts, frontend/packages/helm-plugin/src/catalog/utils/catalog-utils.tsx, frontend/packages/helm-plugin/src/components/__tests__/helm-release-mock-data.ts, frontend/packages/helm-plugin/src/components/details-page/*, frontend/packages/helm-plugin/src/components/list-page/*, frontend/packages/helm-plugin/src/components/list-page/HelmTabbedPage.tsx, frontend/packages/helm-plugin/src/models/helm.ts, frontend/packages/helm-plugin/src/topology/helmFilters.ts, frontend/packages/helm-plugin/src/utils/*
Helm catalog, release list, details, actions, models, topology, and locale keys now use updated Helm Chart(s) and Helm release wording and capitalization across supported languages.
Integration tests and page objects
frontend/packages/helm-plugin/integration-tests/features/helm/*.feature, frontend/packages/helm-plugin/integration-tests/support/constants/static-text/helm-text.ts, frontend/packages/helm-plugin/integration-tests/support/pages/helm/*.ts, frontend/packages/helm-plugin/integration-tests/support/step-definitions/**/*.ts
Gherkin features, step definitions, page objects, and static text were updated to assert the revised Helm chart and Helm release labels, actions, filters, and navigation targets.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

  • jhadvig
  • cajieh
🚥 Pre-merge checks | ✅ 13 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 46.15% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Ipv6 And Disconnected Network Test Compatibility ⚠️ Warning FAIL: Helm URL-install e2e scenarios use public hosts (redhat-developer.github.io, ghcr.io) and have no [Skipped:Disconnected] marker, so they need public internet. Mirror those charts internally or add [Skipped:Disconnected] / cluster-internal URLs so disconnected IPv6 jobs can run them.
✅ Passed checks (13 passed)
Check name Status Explanation
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 Touched tests use static names only; the Go files are Test* functions, and the Jest titles are fixed strings with no dynamic values.
Test Structure And Quality ✅ Passed PASS: The touched tests are standard table-driven Go/Jest tests, not Ginkgo, and the PR only changes signatures/call sites without adding new setup or timeout issues.
Microshift Test Compatibility ✅ Passed No new test declarations were added; the e2e changes are refactors/deletions, with no newly introduced MicroShift-banned API usage.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The changed tests are unit/Cypress feature files, not Ginkgo e2e specs, and I found no multi-node/SNO-sensitive assumptions or missing single-node guards.
Topology-Aware Scheduling Compatibility ✅ Passed Inspected the changed Helm/plugin/backend files; they only add basic-auth secret plumbing and copy tweaks. No pod affinity, nodeSelector, PDB, or topology-aware scheduling logic was added.
Ote Binary Stdout Contract ✅ Passed No changed file adds main/init/TestMain/BeforeSuite/RunSpecs stdout writes; klog/Print calls are only in library funcs/tests, not process-level code.
No-Weak-Crypto ✅ Passed Touched files contain no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB or custom crypto; auth code only handles K8s secret names and registry auth wiring.
Container-Privileges ✅ Passed PR touches Helm UI/i18n and Go logic only; no changed manifest sets privileged/hostPID/hostNetwork/hostIPC/SYS_ADMIN/allowPrivilegeEscalation.
No-Sensitive-Data-In-Logs ✅ Passed No changed log statement prints passwords/tokens/PII; only secret names, namespaces, release names, and chart URLs appear.
Title check ✅ Passed The title is concise and matches the main change: fixing Helm upgrade secret handling.
Description check ✅ Passed The description covers root cause, solution, screenshots, and test setup, and is sufficiently complete for review.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

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

Actionable comments posted: 5

🧹 Nitpick comments (2)
pkg/helm/handlers/handler_test.go (1)

138-139: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the forwarded basic-auth Secret name in the handler fake.

The fake accepts basicAuthSecretName but ignores it, so a regression in HandleUpgradeReleaseAsync passing req.BasicAuthSecretName would not fail tests. Consider extending the helper with an expected value and checking it in the closure. As per coding guidelines, “Make sure the tests pass, and add any new tests as appropriate.”

🤖 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/helm/handlers/handler_test.go` around lines 138 - 139, The handler test
fake for fakeUpgradeReleaseAsync currently accepts basicAuthSecretName but never
verifies it, so it can miss regressions in HandleUpgradeReleaseAsync forwarding
req.BasicAuthSecretName. Update the helper to take an expected
basicAuthSecretName value and assert inside the returned closure that the
received argument matches it, using the existing fakeUpgradeReleaseAsync symbol
so the test fails if the handler stops passing the secret name correctly.

Source: Coding guidelines

pkg/helm/actions/upgrade_release_test.go (1)

509-509: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Add coverage for non-empty and persisted auth Secret upgrades.

These call sites only pass "", so the new selected Secret path, annotation fallback path, and missing/malformed Secret failure behavior are untested. A table case with helm.openshift.io/auth-secret plus a matching basic-auth Secret would catch regressions in this PR’s core upgrade flow. As per coding guidelines, “Make sure the tests pass, and add any new tests as appropriate.”

Also applies to: 605-605, 697-697

🤖 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/helm/actions/upgrade_release_test.go` at line 509, Add test coverage in
UpgradeReleaseAsync call sites to exercise the persisted auth Secret flow
instead of only passing an empty secret name. Update the relevant table-driven
cases in upgrade_release_test.go to cover helm.openshift.io/auth-secret, the
annotation fallback, and failure handling for missing or malformed basic-auth
Secrets so the selected Secret path and upgrade behavior are validated. Use
UpgradeReleaseAsync and the related auth Secret resolution logic as the main
symbols to locate the affected tests and add the new cases.

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
`@frontend/packages/helm-plugin/src/components/forms/install-upgrade/HelmInstallUpgradeForm.tsx`:
- Around line 118-128: Update HelmInstallUpgradeForm so upgrade flows are not
gated by an existing basicAuthSecretName; in the form logic around
showAuthSecret, secretMissing, and the selector rendering, allow users to open
the auth secret selector even when the persisted helm.openshift.io/auth-secret
annotation is absent. Then make the upgrade path let them choose or create a
Secret and persist that selection back into the upgrade state, using the
existing HelmActionType.Upgrade and useSecretResources(namespace) flow.

In
`@frontend/packages/helm-plugin/src/components/forms/url-chart/HelmCreateBasicAuthSecretModal.tsx`:
- Around line 73-76: The Helm basic-auth secret modal can currently create
Secrets that the backend will reject because it omits username when empty, while
GetUserCredentials expects both username and password. Update
HelmCreateBasicAuthSecretModal so the generated Secret always includes a
username field (and keep the form validation aligned with that requirement),
using the existing username/password handling in the modal’s secret payload to
prevent creating unusable auth Secrets.
- Around line 45-54: The modal close path in HelmCreateBasicAuthSecretModal’s
closeModal is blocked by the inProgress guard, so a successful create from
handleCreate cannot dismiss the dialog. Update the create flow so the modal can
close after a success, either by clearing inProgress before calling closeModal
or by allowing closeModal to bypass the guard for successful completion, and
make sure the same behavior is applied to the related create/submit path
referenced in handleCreate.

In `@pkg/helm/actions/upgrade_release.go`:
- Around line 163-173: The selected auth Secret is only applied inside the
rel.Chart.Metadata.Annotations nil-check, so releases without annotations skip
basicAuthSecretName and may fetch the chart unauthenticated. Move the
basicAuthSecretName handling in upgrade_release.go outside the
rel.Chart.Metadata.Annotations block in the upgrade flow, keeping the chart_url
annotation lookup conditional but always honoring the user-selected Secret
before falling back to helmAuthSecretAnnotation.
- Around line 210-219: Credential setup errors in the upgrade flow are only
logged and then execution continues, which can lead to an unauthenticated chart
lookup and stale auth-secret state. In `UpgradeRelease`, treat failures from
`GetUserCredentials` and `applyBasicAuthFromUserCredentials` as fatal by
returning the error immediately instead of falling through to `LocateChart`.
Keep the check around `auth_secret` in this block, and make sure any selected
Secret that is missing, malformed, or cannot be used by the registry client
stops the upgrade path before chart resolution.

---

Nitpick comments:
In `@pkg/helm/actions/upgrade_release_test.go`:
- Line 509: Add test coverage in UpgradeReleaseAsync call sites to exercise the
persisted auth Secret flow instead of only passing an empty secret name. Update
the relevant table-driven cases in upgrade_release_test.go to cover
helm.openshift.io/auth-secret, the annotation fallback, and failure handling for
missing or malformed basic-auth Secrets so the selected Secret path and upgrade
behavior are validated. Use UpgradeReleaseAsync and the related auth Secret
resolution logic as the main symbols to locate the affected tests and add the
new cases.

In `@pkg/helm/handlers/handler_test.go`:
- Around line 138-139: The handler test fake for fakeUpgradeReleaseAsync
currently accepts basicAuthSecretName but never verifies it, so it can miss
regressions in HandleUpgradeReleaseAsync forwarding req.BasicAuthSecretName.
Update the helper to take an expected basicAuthSecretName value and assert
inside the returned closure that the received argument matches it, using the
existing fakeUpgradeReleaseAsync symbol so the test fails if the handler stops
passing the secret name correctly.
🪄 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: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 1b166576-6636-476e-abca-97e4a270547d

📥 Commits

Reviewing files that changed from the base of the PR and between 7d94137 and 2cb8b4c.

📒 Files selected for processing (12)
  • frontend/packages/helm-plugin/locales/en/helm-plugin.json
  • frontend/packages/helm-plugin/src/components/forms/install-upgrade/HelmInstallUpgradeForm.tsx
  • frontend/packages/helm-plugin/src/components/forms/install-upgrade/HelmInstallUpgradePage.tsx
  • frontend/packages/helm-plugin/src/components/forms/url-chart/HelmCreateBasicAuthSecretModal.tsx
  • frontend/packages/helm-plugin/src/components/forms/url-chart/HelmURLChartForm.tsx
  • frontend/public/locales/en/public.json
  • pkg/helm/actions/get_chart.go
  • pkg/helm/actions/install_chart.go
  • pkg/helm/actions/upgrade_release.go
  • pkg/helm/actions/upgrade_release_test.go
  • pkg/helm/handlers/handler_test.go
  • pkg/helm/handlers/handlers.go

Comment on lines +45 to +54
const closeModal = () => {
if (inProgress) {
return;
}
if (document.activeElement instanceof HTMLElement) {
document.activeElement.blur();
}
onClose?.();
closeOverlay();
};

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Successful creates never close the modal.

handleCreate() calls closeModal() while inProgress is still true, so the guard on Line 46 returns early and the overlay stays open after a successful create.

Suggested fix
-  const closeModal = () => {
-    if (inProgress) {
-      return;
-    }
+  const closeModal = (force = false) => {
+    if (inProgress && !force) {
+      return;
+    }
     if (document.activeElement instanceof HTMLElement) {
       document.activeElement.blur();
     }
     onClose?.();
     closeOverlay();
@@
-      closeModal();
+      closeModal(true);
       // Keep form update separate so a parent callback failure cannot block modal close.
       save?.(createdSecretName);

Also applies to: 78-81

🤖 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
`@frontend/packages/helm-plugin/src/components/forms/url-chart/HelmCreateBasicAuthSecretModal.tsx`
around lines 45 - 54, The modal close path in HelmCreateBasicAuthSecretModal’s
closeModal is blocked by the inProgress guard, so a successful create from
handleCreate cannot dismiss the dialog. Update the create flow so the modal can
close after a success, either by clearing inProgress before calling closeModal
or by allowing closeModal to bypass the guard for successful completion, and
make sure the same behavior is applied to the related create/submit path
referenced in handleCreate.

Comment on lines +73 to +76
stringData: {
...(username ? { username } : {}),
password,
},

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.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

The modal can create Secrets the backend cannot use.

The UI treats username as optional and omits that key entirely, but pkg/helm/actions/install_chart.go's GetUserCredentials rejects Secrets missing either username or password. A Secret created here without a username will fail the install/upgrade auth flow later. Based on learnings, English-only i18n additions are fine in this repo and do not need separate l10n updates.

Suggested fix
-  const isCreateDisabled = !secretName.trim() || !password;
+  const isCreateDisabled = !secretName.trim() || !username.trim() || !password;
@@
-          <FormGroup label={t('public~Secret username')} fieldId="helm-secret-username">
+          <FormGroup
+            label={t('public~Secret username')}
+            isRequired
+            fieldId="helm-secret-username"
+          >
             <TextInput
@@
-                <HelperTextItem>
-                  {t('helm-plugin~Optional username for OCI/HTTP(S) authentication.')}
-                </HelperTextItem>
+                <HelperTextItem>{t('helm-plugin~Username for OCI/HTTP(S) authentication.')}</HelperTextItem>

Also applies to: 122-137

🤖 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
`@frontend/packages/helm-plugin/src/components/forms/url-chart/HelmCreateBasicAuthSecretModal.tsx`
around lines 73 - 76, The Helm basic-auth secret modal can currently create
Secrets that the backend will reject because it omits username when empty, while
GetUserCredentials expects both username and password. Update
HelmCreateBasicAuthSecretModal so the generated Secret always includes a
username field (and keep the form validation aligned with that requirement),
using the existing username/password handling in the modal’s secret payload to
prevent creating unusable auth Secrets.

Source: Learnings

Comment thread pkg/helm/actions/upgrade_release.go Outdated
Comment on lines +163 to +173
auth_secret := ""
// Before proceeding, check if chart URL is present as an annotation
if rel.Chart.Metadata.Annotations != nil {
if chart_url, ok := rel.Chart.Metadata.Annotations["chart_url"]; chartUrl == "" && ok {
chartUrl = chart_url
}
if basicAuthSecretName != "" {
auth_secret = basicAuthSecretName
} else if authSecret, ok := rel.Chart.Metadata.Annotations[helmAuthSecretAnnotation]; ok {
auth_secret = authSecret
}

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Apply the selected Secret even when release annotations are absent.

Line 169 only assigns basicAuthSecretName inside the rel.Chart.Metadata.Annotations != nil block, so releases without existing annotations drop the user-selected Secret and locate the chart unauthenticated.

Proposed fix
-	auth_secret := ""
+	auth_secret := basicAuthSecretName
 	// Before proceeding, check if chart URL is present as an annotation
-	if rel.Chart.Metadata.Annotations != nil {
+	if rel.Chart.Metadata != nil && rel.Chart.Metadata.Annotations != nil {
 		if chart_url, ok := rel.Chart.Metadata.Annotations["chart_url"]; chartUrl == "" && ok {
 			chartUrl = chart_url
 		}
-		if basicAuthSecretName != "" {
-			auth_secret = basicAuthSecretName
-		} else if authSecret, ok := rel.Chart.Metadata.Annotations[helmAuthSecretAnnotation]; ok {
-			auth_secret = authSecret
+		if auth_secret == "" {
+			if authSecret, ok := rel.Chart.Metadata.Annotations[helmAuthSecretAnnotation]; ok {
+				auth_secret = authSecret
+			}
 		}
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
auth_secret := ""
// Before proceeding, check if chart URL is present as an annotation
if rel.Chart.Metadata.Annotations != nil {
if chart_url, ok := rel.Chart.Metadata.Annotations["chart_url"]; chartUrl == "" && ok {
chartUrl = chart_url
}
if basicAuthSecretName != "" {
auth_secret = basicAuthSecretName
} else if authSecret, ok := rel.Chart.Metadata.Annotations[helmAuthSecretAnnotation]; ok {
auth_secret = authSecret
}
auth_secret := basicAuthSecretName
// Before proceeding, check if chart URL is present as an annotation
if rel.Chart.Metadata != nil && rel.Chart.Metadata.Annotations != nil {
if chart_url, ok := rel.Chart.Metadata.Annotations["chart_url"]; chartUrl == "" && ok {
chartUrl = chart_url
}
if auth_secret == "" {
if authSecret, ok := rel.Chart.Metadata.Annotations[helmAuthSecretAnnotation]; ok {
auth_secret = authSecret
}
}
}
🤖 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/helm/actions/upgrade_release.go` around lines 163 - 173, The selected
auth Secret is only applied inside the rel.Chart.Metadata.Annotations nil-check,
so releases without annotations skip basicAuthSecretName and may fetch the chart
unauthenticated. Move the basicAuthSecretName handling in upgrade_release.go
outside the rel.Chart.Metadata.Annotations block in the upgrade flow, keeping
the chart_url annotation lookup conditional but always honoring the
user-selected Secret before falling back to helmAuthSecretAnnotation.

Comment on lines +210 to +219
if auth_secret != "" {
klog.Infof("Found persisted auth secret %s for release %s/%s, applying credentials for upgrade", auth_secret, releaseNamespace, releaseName)
userCredentials, err := GetUserCredentials(coreClient, releaseNamespace, auth_secret)
if err != nil {
klog.Errorf("Failed to get user credentials for release upgrade %s/%s: %v", releaseNamespace, releaseName, err)
} else {
if err := applyBasicAuthFromUserCredentials(&client.ChartPathOptions, client, userCredentials); err != nil {
klog.Errorf("Failed to apply auth from secret %s for release %s/%s: %v", auth_secret, releaseNamespace, releaseName, err)
}
}

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.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Return credential setup failures instead of continuing unauthenticated.

If the persisted or selected Secret is missing, malformed, or registry-client setup fails, this logs the error but still calls LocateChart; that can produce a misleading 401 or even persist an auth-secret annotation that was never applied.

Proposed fix
 	if auth_secret != "" {
 		klog.Infof("Found persisted auth secret %s for release %s/%s, applying credentials for upgrade", auth_secret, releaseNamespace, releaseName)
 		userCredentials, err := GetUserCredentials(coreClient, releaseNamespace, auth_secret)
 		if err != nil {
-			klog.Errorf("Failed to get user credentials for release upgrade %s/%s: %v", releaseNamespace, releaseName, err)
+			return nil, fmt.Errorf("failed to get user credentials for release upgrade %s/%s: %w", releaseNamespace, releaseName, err)
+		}
+		if err := applyBasicAuthFromUserCredentials(&client.ChartPathOptions, client, userCredentials); err != nil {
+			return nil, fmt.Errorf("failed to apply auth from secret %s for release %s/%s: %w", auth_secret, releaseNamespace, releaseName, err)
-		} else {
-			if err := applyBasicAuthFromUserCredentials(&client.ChartPathOptions, client, userCredentials); err != nil {
-				klog.Errorf("Failed to apply auth from secret %s for release %s/%s: %v", auth_secret, releaseNamespace, releaseName, err)
-			}
 		}
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if auth_secret != "" {
klog.Infof("Found persisted auth secret %s for release %s/%s, applying credentials for upgrade", auth_secret, releaseNamespace, releaseName)
userCredentials, err := GetUserCredentials(coreClient, releaseNamespace, auth_secret)
if err != nil {
klog.Errorf("Failed to get user credentials for release upgrade %s/%s: %v", releaseNamespace, releaseName, err)
} else {
if err := applyBasicAuthFromUserCredentials(&client.ChartPathOptions, client, userCredentials); err != nil {
klog.Errorf("Failed to apply auth from secret %s for release %s/%s: %v", auth_secret, releaseNamespace, releaseName, err)
}
}
if auth_secret != "" {
klog.Infof("Found persisted auth secret %s for release %s/%s, applying credentials for upgrade", auth_secret, releaseNamespace, releaseName)
userCredentials, err := GetUserCredentials(coreClient, releaseNamespace, auth_secret)
if err != nil {
return nil, fmt.Errorf("failed to get user credentials for release upgrade %s/%s: %w", releaseNamespace, releaseName, err)
}
if err := applyBasicAuthFromUserCredentials(&client.ChartPathOptions, client, userCredentials); err != nil {
return nil, fmt.Errorf("failed to apply auth from secret %s for release %s/%s: %w", auth_secret, releaseNamespace, releaseName, err)
}
}
🤖 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/helm/actions/upgrade_release.go` around lines 210 - 219, Credential setup
errors in the upgrade flow are only logged and then execution continues, which
can lead to an unauthenticated chart lookup and stale auth-secret state. In
`UpgradeRelease`, treat failures from `GetUserCredentials` and
`applyBasicAuthFromUserCredentials` as fatal by returning the error immediately
instead of falling through to `LocateChart`. Keep the check around `auth_secret`
in this block, and make sure any selected Secret that is missing, malformed, or
cannot be used by the registry client stops the upgrade path before chart
resolution.

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

Actionable comments posted: 4

🤖 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 `@frontend/packages/helm-plugin/locales/fr/helm-plugin.json`:
- Around line 153-154: The French Helm plugin translations have spacing
mismatches in the templated strings, which causes concatenated labels to render
incorrectly. Update the entries for the keys with appVersion and chartRepoName
in helm-plugin.json so they preserve the same leading and internal spacing as
the English source; specifically, keep the leading space before the App Version
fragment and add the missing space before the chartRepoName placeholder in the
translation values.

In `@frontend/packages/helm-plugin/locales/ja/helm-plugin.json`:
- Line 148: The Japanese locale entry for Repositories is still untranslated and
should be replaced with an appropriate Japanese string to match the other
locales. Update the locale value in the helm-plugin JSON for the Repositories
key, using the existing translation pattern from the ko and zh files as a guide
while keeping the same key and JSON structure.

In `@frontend/packages/helm-plugin/locales/ko/helm-plugin.json`:
- Line 126: The Korean translation for the Helm chart URL example is malformed
and should match the source text. Update the value in helm-plugin.json so the
OCI example uses the correct registry path from the original string, and remove
the duplicated mycharts/mychart segment while keeping the rest of the
translation unchanged.

In `@frontend/packages/helm-plugin/locales/zh/helm-plugin.json`:
- Line 158: Update the Chinese translation for the "Upgrade Helm release" entry
in helm-plugin.json so it uses the correct upgrade wording instead of creation
wording. Locate the localized string keyed by "Upgrade Helm release" in the zh
locale file and change the value from 创建 Helm 发行 to the appropriate 升级
equivalent to match the action label used by the Helm plugin UI.
🪄 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: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 0f27dcfe-24ac-4794-883c-a6837b9afc8e

📥 Commits

Reviewing files that changed from the base of the PR and between 2cb8b4c and 7468da3.

📒 Files selected for processing (50)
  • frontend/packages/helm-plugin/console-extensions.json
  • frontend/packages/helm-plugin/integration-tests/features/helm-release.feature
  • frontend/packages/helm-plugin/integration-tests/features/helm/actions-on-helm-release-after-upgrade.feature
  • frontend/packages/helm-plugin/integration-tests/features/helm/actions-on-helm-release.feature
  • frontend/packages/helm-plugin/integration-tests/features/helm/helm-compatibility.feature
  • frontend/packages/helm-plugin/integration-tests/features/helm/helm-feature-flag.feature
  • frontend/packages/helm-plugin/integration-tests/features/helm/helm-installation-view.feature
  • frontend/packages/helm-plugin/integration-tests/features/helm/helm-navigation.feature
  • frontend/packages/helm-plugin/integration-tests/features/helm/helm-page-tabs.feature
  • frontend/packages/helm-plugin/integration-tests/features/helm/install-helm-chart.feature
  • frontend/packages/helm-plugin/integration-tests/features/helm/install-url-chart.feature
  • frontend/packages/helm-plugin/integration-tests/features/helm/topology-helm-release.feature
  • frontend/packages/helm-plugin/integration-tests/support/constants/static-text/helm-text.ts
  • frontend/packages/helm-plugin/integration-tests/support/pages/helm/helm-details-page.ts
  • frontend/packages/helm-plugin/integration-tests/support/pages/helm/helm-page.ts
  • frontend/packages/helm-plugin/integration-tests/support/pages/helm/upgrade-helm-release-page.ts
  • frontend/packages/helm-plugin/integration-tests/support/step-definitions/common/common.ts
  • frontend/packages/helm-plugin/integration-tests/support/step-definitions/helm/helm-compatibility.ts
  • frontend/packages/helm-plugin/integration-tests/support/step-definitions/helm/helm-navigation.ts
  • frontend/packages/helm-plugin/integration-tests/support/step-definitions/helm/helm-release.ts
  • frontend/packages/helm-plugin/integration-tests/support/step-definitions/helm/helm.ts
  • frontend/packages/helm-plugin/locales/en/helm-plugin.json
  • frontend/packages/helm-plugin/locales/es/helm-plugin.json
  • frontend/packages/helm-plugin/locales/fr/helm-plugin.json
  • frontend/packages/helm-plugin/locales/ja/helm-plugin.json
  • frontend/packages/helm-plugin/locales/ko/helm-plugin.json
  • frontend/packages/helm-plugin/locales/zh/helm-plugin.json
  • frontend/packages/helm-plugin/src/actions/add-resources.tsx
  • frontend/packages/helm-plugin/src/actions/creators.ts
  • frontend/packages/helm-plugin/src/catalog/utils/catalog-utils.tsx
  • frontend/packages/helm-plugin/src/components/__tests__/helm-release-mock-data.ts
  • frontend/packages/helm-plugin/src/components/details-page/HelmReleaseDetails.tsx
  • frontend/packages/helm-plugin/src/components/details-page/history/HelmReleaseHistory.tsx
  • frontend/packages/helm-plugin/src/components/details-page/overview/HelmReleaseOverview.tsx
  • frontend/packages/helm-plugin/src/components/details-page/overview/__tests__/HelmReleaseOverview.spec.tsx
  • frontend/packages/helm-plugin/src/components/forms/__tests__/HelmInstallUpgradeForm.spec.tsx
  • frontend/packages/helm-plugin/src/components/forms/install-upgrade/HelmInstallUpgradeForm.tsx
  • frontend/packages/helm-plugin/src/components/forms/url-chart/HelmCreateBasicAuthSecretModal.tsx
  • frontend/packages/helm-plugin/src/components/forms/url-chart/HelmURLChartForm.tsx
  • frontend/packages/helm-plugin/src/components/forms/url-chart/HelmURLChartInstallPage.tsx
  • frontend/packages/helm-plugin/src/components/forms/url-chart/HelmURLInstallForm.tsx
  • frontend/packages/helm-plugin/src/components/list-page/HelmReleaseList.tsx
  • frontend/packages/helm-plugin/src/components/list-page/HelmReleaseListPage.tsx
  • frontend/packages/helm-plugin/src/components/list-page/HelmReleaseListRow.tsx
  • frontend/packages/helm-plugin/src/components/list-page/HelmTabbedPage.tsx
  • frontend/packages/helm-plugin/src/models/helm.ts
  • frontend/packages/helm-plugin/src/topology/helmFilters.ts
  • frontend/packages/helm-plugin/src/utils/__tests__/helm-utils.spec.ts
  • frontend/packages/helm-plugin/src/utils/helm-utils.ts
  • frontend/public/locales/en/public.json
✅ Files skipped from review due to trivial changes (27)
  • frontend/packages/helm-plugin/integration-tests/support/pages/helm/upgrade-helm-release-page.ts
  • frontend/packages/helm-plugin/integration-tests/support/constants/static-text/helm-text.ts
  • frontend/packages/helm-plugin/src/components/details-page/overview/tests/HelmReleaseOverview.spec.tsx
  • frontend/packages/helm-plugin/integration-tests/support/step-definitions/helm/helm-compatibility.ts
  • frontend/packages/helm-plugin/integration-tests/features/helm/helm-compatibility.feature
  • frontend/packages/helm-plugin/integration-tests/features/helm/helm-page-tabs.feature
  • frontend/packages/helm-plugin/integration-tests/features/helm/install-url-chart.feature
  • frontend/packages/helm-plugin/integration-tests/features/helm/helm-feature-flag.feature
  • frontend/packages/helm-plugin/src/utils/tests/helm-utils.spec.ts
  • frontend/packages/helm-plugin/integration-tests/support/pages/helm/helm-page.ts
  • frontend/packages/helm-plugin/integration-tests/support/step-definitions/common/common.ts
  • frontend/packages/helm-plugin/src/models/helm.ts
  • frontend/packages/helm-plugin/src/components/list-page/HelmReleaseListPage.tsx
  • frontend/packages/helm-plugin/src/components/forms/tests/HelmInstallUpgradeForm.spec.tsx
  • frontend/packages/helm-plugin/src/topology/helmFilters.ts
  • frontend/packages/helm-plugin/src/catalog/utils/catalog-utils.tsx
  • frontend/packages/helm-plugin/src/components/tests/helm-release-mock-data.ts
  • frontend/packages/helm-plugin/src/components/forms/url-chart/HelmURLChartInstallPage.tsx
  • frontend/packages/helm-plugin/integration-tests/features/helm/install-helm-chart.feature
  • frontend/packages/helm-plugin/src/components/forms/url-chart/HelmURLInstallForm.tsx
  • frontend/packages/helm-plugin/console-extensions.json
  • frontend/packages/helm-plugin/src/components/list-page/HelmReleaseList.tsx
  • frontend/packages/helm-plugin/src/components/details-page/history/HelmReleaseHistory.tsx
  • frontend/packages/helm-plugin/integration-tests/features/helm/topology-helm-release.feature
  • frontend/packages/helm-plugin/integration-tests/support/step-definitions/helm/helm.ts
  • frontend/packages/helm-plugin/src/components/list-page/HelmTabbedPage.tsx
  • frontend/packages/helm-plugin/integration-tests/features/helm/helm-installation-view.feature
🚧 Files skipped from review as they are similar to previous changes (4)
  • frontend/public/locales/en/public.json
  • frontend/packages/helm-plugin/src/components/forms/url-chart/HelmURLChartForm.tsx
  • frontend/packages/helm-plugin/src/components/forms/url-chart/HelmCreateBasicAuthSecretModal.tsx
  • frontend/packages/helm-plugin/src/components/forms/install-upgrade/HelmInstallUpgradeForm.tsx

Comment thread frontend/packages/helm-plugin/locales/fr/helm-plugin.json
Comment thread frontend/packages/helm-plugin/locales/ja/helm-plugin.json
Comment thread frontend/packages/helm-plugin/locales/ko/helm-plugin.json Outdated
Comment thread frontend/packages/helm-plugin/locales/zh/helm-plugin.json Outdated
@sowmya-sl
sowmya-sl force-pushed the fix-helm-upgrade-secrets branch from 7468da3 to 243b4d6 Compare June 30, 2026 12:54
@openshift-ci openshift-ci Bot added component/sdk Related to console-plugin-sdk kind/cypress Related to Cypress e2e integration testing plugin-api-changed Categorizes a PR as containing plugin API changes and removed needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. labels Jun 30, 2026
@sowmya-sl
sowmya-sl force-pushed the fix-helm-upgrade-secrets branch 2 times, most recently from 05376cf to 955ad3f Compare June 30, 2026 13:06
@sowmya-sl

Copy link
Copy Markdown
Contributor Author

/test all

1 similar comment
@sowmya-sl

Copy link
Copy Markdown
Contributor Author

/test all

@sowmya-sl
sowmya-sl marked this pull request as ready for review July 2, 2026 14:18
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 2, 2026
@openshift-ci
openshift-ci Bot requested review from baijum and spadgett July 2, 2026 14:18
@sowmya-sl
sowmya-sl force-pushed the fix-helm-upgrade-secrets branch from cd3ddc2 to 221ca0b Compare July 2, 2026 16:05
@sowmya-sl sowmya-sl changed the title Fix helm upgrade secrets HELM-763: Fix helm upgrade secrets Jul 2, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 2, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@sowmya-sl: This PR has been marked as verified by @sowmya-sl.

Details

In response to this:

/verified by @sowmya-sl

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 openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot openshift-ci-robot removed the verified Signifies that the PR passed pre-merge verification criteria label Jul 9, 2026
@openshift-ci

openshift-ci Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

@sowmya-sl: The following test 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/e2e-gcp-console a3eae6c link true /test e2e-gcp-console

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.

@webbnh webbnh 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.

All of the frontend/packages/helm-plugin/integration-tests/features/helm/ files, as well as many of the other files in this PR, are being deleted in #16711.

Before I review this PR, we need to determine how we're going to resolve this conflict. (E.g., perhaps you should base your branch on Vikram's, but I don't think he's got all the tests converted...so I'm not sure what to suggest...perhaps coordinate with him?)

@sowmya-sl

Copy link
Copy Markdown
Contributor Author

/retest

1 similar comment
@sowmya-sl

Copy link
Copy Markdown
Contributor Author

/retest

sowmya-sl and others added 6 commits July 16, 2026 12:17
…e microcopy

- Add HelmCreateBasicAuthSecretModal for creating basic auth secrets
  during OCI/HTTP chart installation from URL
- Extend HelmInstallUpgradeForm and HelmURLChartForm to support basic
  auth secret selection for authenticated chart repositories
- Add upgrade support with basic auth secret propagation via chart
  annotations in get_chart.go, install_chart.go, and upgrade_release.go
- Update handler to pass basicAuthSecretName through GetChartFromURL
- Normalize UI microcopy: lowercase "release" in "Helm release",
  use "Helm Chart(s)" consistently across console-extensions.json,
  integration test features, step definitions, and page objects
- Update i18n keys in helm-plugin and public locales

Co-authored-by: Cursor <cursoragent@cursor.com>
…cret for URL-installed charts

Propagate the 'installation: url_install' annotation from the previous
release to the upgraded chart in both UpgradeRelease and
UpgradeReleaseAsync, so the frontend can distinguish URL-installed
charts from catalog-installed ones across upgrades.

Use this annotation on the frontend to show the basic auth secret
section only for URL-based installs and upgrades, not for catalog
charts. Also unexport the unused HelmCreateBasicAuthSecretModalProps
interface to fix the CI unused-exports check.

Co-authored-by: Cursor <cursoragent@cursor.com>
…lity

- Make username required in the basic auth secret modal and fix modal
  close so Cancel/X always dismiss regardless of in-progress state
- Fix upgrade_release.go to prefer explicit basicAuthSecretName over
  annotation fallback, add nil-safety for chart metadata, and return
  errors instead of logging-and-continuing on credential failures
- Show auth secret dropdown only for URL-installed charts (based on
  installation annotation), not for all catalog installs
- Remove helm-plugin~ prefix from direct t() calls where
  useTranslation already provides the namespace; retain prefix in
  nameKey values consumed by NavBar with a different namespace context

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
… selection

Users previously had no way to deselect a basic auth secret once one was
chosen. Adding a "None" action item lets users explicitly clear the
secret field without needing to create a new one.
Previously, selecting "None" for the auth secret sent an empty string,
which was indistinguishable from "no selection." The backend would then
re-inherit the auth secret from the previous release's annotations,
making it impossible to clear. Use a "__none__" sentinel value so the
backend can differentiate between "not set" and "explicitly cleared,"
and only send basic_auth_secret_name for URL-based installs.
@sowmya-sl
sowmya-sl force-pushed the fix-helm-upgrade-secrets branch from d3e265b to 11dbdab Compare July 16, 2026 06:48
@openshift-ci-robot

openshift-ci-robot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

@sowmya-sl: This pull request references HELM-763 which is a valid jira issue.

Details

In response to this:

Analysis / Root cause:

Kubernetes Secret object is used to store username and password for authentication when trying to create a Helm release. If a Helm release is created using a URL and selecting a particular secret for authentication, the users are unable to change the secrets during upgrade. This poses a problem if the secret's name has been changed or removed.

Solution description:

Create a dropdown where the secret can be entered during upgrade. If no secret is entered, it will go with the existing secret name if it exists, otherwise the new secret will override the old one.
Screenshots / screen recording:

https://docs.google.com/document/d/1LDRXScwr_jOnvdWU0siqW1gBMM8hrhm3D0oz831gUPA/edit?tab=t.mcv80hqh092h#heading=h.2jo1jtiyytic
Test setup:

An OCI registry and a Helm repository requiring authentication via username and password.

Reviewers and assignees:

Summary by CodeRabbit

  • New Features
  • Added basic-auth Secret selection and “create Secret” support to Helm install-from-URL and Helm upgrade flows, including secret name, optional username, and required password/token.
  • Helm charts/releases can now persist and carry the chosen auth Secret reference.
  • Bug Fixes
  • Improved handling of unauthorized (401) chart fetches with clearer guidance when authentication is required.
  • Displays a warning when the selected Secret isn’t found in the current namespace.
  • Tests / Chores
  • Updated UI text consistency across locales and adjusted integration/Cypress expectations accordingly.

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 openshift-eng/jira-lifecycle-plugin repository.

"href": "/catalog/ns/:namespace?catalogType=HelmChart",
"label": "%helm-plugin~Helm Chart%",
"description": "%helm-plugin~Browse the catalog to discover and install Helm Charts%",
"description": "%helm-plugin~Browse the catalog to discover and install Helm Chart(s)%",

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.

Nit: Is there a reason for the (s) in Helm Chart(s)? This pattern isn't used by any other catalog type in the console. Was this an intentional style decision, or could we revert to the previous Helm Charts?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jseseCCS
I added this originally based on the UI review . Have I misconstrued the original comment, if so please tell me if I should remove it?

@sowmya-sl

Copy link
Copy Markdown
Contributor Author

/label acknowledge-critical-fixes-only

@openshift-ci openshift-ci Bot added the acknowledge-critical-fixes-only Indicates if the issuer of the label is OK with the policy. label Jul 16, 2026

@jseseCCS jseseCCS 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.

Reviewed for wording, clarity, consistency, voice. Recurring issues: passive voice in a few help-text strings, suggest active voice throughout; capitalization inconsistency for "Secret" and "Chart" across files; dropped article in secret authentication helper text; "public~" namespace prefix leaking (?) into rendered UI strings.

"Helm Chart repositories": "Helm Chart repositories",
"Helm Chart": "Helm Chart",
"Browse the catalog to discover and install Helm Charts": "Browse the catalog to discover and install Helm Charts",
"Browse the catalog to discover and install Helm Chart(s)": "Browse the catalog to discover and install Helm Chart(s)",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 8 (+ 10, 11):

  • "Chart(s)" = parenthetical plurals typically avoided in UI text. they're awkward to read; can complicate translation. if it could be more than 1, even if it's not definitively 1, just use "Charts".

  • GLOBAL: note that Helm documentation inconsistently capitalizes "Chart," but more often, it's lowercase. (i'm referring specifically to the phrase "Helm C/chart," not the word "chart" on its own, which they always lowercase.) we should make sure we use just one and i recommend lowercase "chart."

  • flagging that "Chart(s)" isn't used consistently. other strings further down (e.g., "Install Helm Chart from URL") keep singular form. we should align on one pattern throughout.

@sowmya-sl sowmya-sl Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Please check comment .
  2. HelmChartRepository and ProjectHelmChartRepository objects have Chart capitalized, so I have added Chart with C capital. Thoughts?
  3. I am okay with keeping it singular. But we need to mention plural at some point right? "Browse the catalog to discover available Helm Charts" ?

"Select": "Select",
"Must be a valid OCI URL or a valid HTTP/HTTPS tar file; for example - oci://registry.example.com/chart, https://example.com/chart-1.0.0.tgz.": "Must be a valid OCI URL or a valid HTTP/HTTPS tar file; for example - oci://registry.example.com/chart, https://example.com/chart-1.0.0.tgz.",
"Failed to create Secret.": "Failed to create Secret.",
"Create authentication Secret": "Create authentication Secret",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

128: "Failed to create Secret." should "Secret" be lowercase here? it's not a proper noun or named UI element. suggest "Failed to create secret." for consistency w/sentence-case error messages elsewhere in this file.

129: "Create authentication Secret" uses mixed casing. red hat style calls for sentence case --> "Create authentication secret"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Secret is a Openshift resource. Should I make it secret nevertheless?

"Secret for basic authentication": "Secret for basic authentication",
"None": "None",
"Select a secret": "Select a secret",
"Create Secret": "Create Secret",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 118 vs 129: we have both "Create Secret" and "Create authentication Secret" for what looks like the same action. do these refer to the same UI element?

i recommend GLOBAL: "Create secret" and "Create authentication secret"

although, if they are the same action, should it always say "Create authentication secret" or just "Create secret"? either way, it should be the same every time so as not to confuse users.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack

"The Helm Release can be created by manually entering YAML or JSON definitions.": "The Helm Release can be created by manually entering YAML or JSON definitions.",
"Upgrade Helm Release": "Upgrade Helm Release",
"Create Helm release": "Create Helm release",
"The Helm release can be created by completing the form. Default values may be provided by the Helm Chart authors.": "The Helm release can be created by completing the form. Default values may be provided by the Helm Chart authors.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

167: might = possibility. may = permission. also, use active voice whenever possible.

--> "You can create the Helm release by completing the form. The Helm Chart authors might have provided default values."

period at end everywhere or no?

if same phrasing repeats elsewhere please fix. GLOBAL

"None": "None",
"Select a secret": "Select a secret",
"Create Secret": "Create Secret",
"Secret with \"username\" and \"password\" keys for OCI/HTTP(S) authentication.": "Secret with \"username\" and \"password\" keys for OCI/HTTP(S) authentication.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

119: article "A" was dropped. Other comparable helper text in this file uses a leading article (e.g., "The version of chart to install.," "The Helm Chart is currently unavailable."), so this looks like an inconsistency rather than an intentional style choice. Suggest restoring it:

--> "A secret with "username" and "password" keys for OCI/HTTP(S) authentication."

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack

"Helm release": "Helm release",
"Complete the form to create a Helm release. The Helm chart authors might have provided some default values.": "Complete the form to create a Helm release. The Helm chart authors might have provided some default values.",
"Install Helm Chart from Helm registry.": "Install Helm Chart from Helm registry.",
"Complete the form to create a Helm release. Default values might already be set by the chart.": "Complete the form to create a Helm release. Default values might already be set by the chart.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--> The chart might already have set default values.

subTitle: {
form: t(
'helm-plugin~The Helm Release can be created by completing the form. Default values may be provided by the Helm chart authors.',
'helm-plugin~The Helm release can be created by completing the form. Default values may be provided by the Helm Chart authors.',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--> You can create a Helm release by completing the form. The Helm Chart authors might have provided default values.

),
yaml: t(
'helm-plugin~The Helm Release can be created by manually entering YAML or JSON definitions.',
'helm-plugin~The Helm release can be created by manually entering YAML or JSON definitions.',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--> You can create a Helm release by manually entering YAML or JSON definitions.

"Helm Release": "Helm Release",
"Helm release": "Helm release",
"For more information on the chart, refer to this <2>README</2>": "For more information on the chart, refer to this <2>README</2>",
"Helm Chart cannot be installed": "Helm Chart cannot be installed",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we know who/what cannot install the chart, please change to:

The _______ cannot install the Helm Chart.

or

You cannot install the Helm Chart.

"Upgrade Helm Release": "Upgrade Helm Release",
"Create Helm release": "Create Helm release",
"The Helm release can be created by completing the form. Default values may be provided by the Helm Chart authors.": "The Helm release can be created by completing the form. Default values may be provided by the Helm Chart authors.",
"The Helm release can be created by manually entering YAML or JSON definitions.": "The Helm release can be created by manually entering YAML or JSON definitions.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

active voice --> You can create the Helm release by...

@webbnh webbnh 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.

@sowmya-sl, this is a difficult PR to review. All other things being equal (i.e., Jocelyn's feedback notwithstanding), I would have suggested separate PRs for each of the following:

  • replacing chart with Chart or Chart(s)
  • replacing Release with release
  • everything else....

The first two would be easy to review (or could even be approved without review) because of the nature of the change. The problem is, my eyes are glazing over trying to ignore the first two changes as I look for the third set.

So, depending on how things fall out with the incorporation of Jocelyn's requests (particularly the global ones), it would be good if you could break this PR up into a sequence of PRs. Hopefully, the result would be a few PRs which have lots of files with the same "superficial" change in each, followed by one PR which actually contains the fix that you originally set out to make.

[I made it 5/8's of the way through the files (I did 33 of them), but I'm out of juice...I'll try to finish tomorrow.]

@@ -1,3 +1,3 @@
export const messages = {
noHelmReleasesFound: 'No Helm Releases found',
noHelmReleasesFound: 'No Helm releases found',

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.

I don't think this definition is ever used (should it have been used here?). (I found parameters with the same name, but no obvious references to this definition.)

If this is not being used, we should remove it; if we are using it, perhaps it should refer to the translated string? E.g.,

Suggested change
noHelmReleasesFound: 'No Helm releases found',
noHelmReleasesFound: t('No Helm releases found'),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No — this is correct without t(). This file is part of the Cypress integration test infrastructure, not the application code. It's a constant used in test assertions to verify that the UI displays the expected text:

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.

used in test assertions

I couldn't find any uses.

Comment thread frontend/packages/helm-plugin/locales/en/helm-plugin.json
import { useMemo, useState } from 'react';
import { TextInputTypes, Grid, GridItem, Button, Alert } from '@patternfly/react-core';
import type { FormikProps } from 'formik';
import * as fuzzy from 'fuzzysearch';

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.

This statement looks funny...and, I think line 119 is working basically by coincidence. That is, I think things are working they way you want them to only because fuzzysearch happens to export only a single symbol -- if it exported more than one (e.g., in the future), then fuzzy would end up being an object instead of a function, and the reference to fuzzy(...) wouldn't work.

I think you want this to be

Suggested change
import * as fuzzy from 'fuzzysearch';
import { fuzzysearch } as fuzzy from 'fuzzysearch';

(but, I am definitely not a Typescript/Javascript expert...).

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.

I see the same idiom used in existing code in frontend/packages/helm-plugin/src/components/forms/url-chart/HelmURLChartForm.tsx (and I think I found two other places), so I guess it's fine...but, if it's not, then you should change it. 😇

) {
return false;
}
const secrets = secretResources[0]?.data ?? [];

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.

You don't need the ? after secretResources[0] because of the guard at line 125.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Purely defensive, but yes we don't need.

<ModalHeader title={t('Create authentication Secret')} />
<ModalBody>
<Form onSubmit={onSubmit}>
<FormGroup label={t('public~Secret name')} isRequired fieldId="helm-secret-name">

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.

The prefix refers to the public/locales/en/public.json file (or, at least, to the public localization). Secret name is a key to a translation value in the public table; the rendering is determined by the table entry, which is elsewhere.

@sowmya-sl

Copy link
Copy Markdown
Contributor Author

@jseseCCS Question on Chart(s) , should I use remove the parenthesis as you have commented here? I added them for this comment originally.

- Remove public~ i18n namespace usage; use helm-plugin namespace
- Unify "Create Secret" / "Create authentication Secret" to
  "Create authentication secret"
- Use active voice: "You can create a Helm release by..."
- Fix might/may usage (might = possibility, may = permission)
- Standardize "Helm Chart(s)" to "Helm Charts" globally
- Standardize ".tar file" and "for example," formatting
- Add missing article in helper text ("A secret with...")
- Unify "Secret for Basic authentication" label across forms
- Lowercase standalone "chart" when not preceded by "Helm"
- Remove unnecessary optional chaining in HelmInstallUpgradeForm
- Update integration tests to reflect UI text changes
@openshift-ci

openshift-ci Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: sowmya-sl

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

The pull request process is described 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

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 17, 2026
}
chartLocation, err := cmd.ChartPathOptions.LocateChart(url, settings)
if err != nil {
if basicAuthSecretName == "" && (strings.Contains(err.Error(), "401") || strings.Contains(err.Error(), "unauthorized")) {

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.

Should the comparison with "unauthorized" be case-blind?

if err != nil {
if basicAuthSecretName == "" && (strings.Contains(err.Error(), "401") || strings.Contains(err.Error(), "unauthorized")) {
return nil, fmt.Errorf("error getting chart from URL: %w; registry requires authentication - select a Secret with \"username\" and \"password\" keys for basic authentication", err)
}

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.

I think there may be scenarios where BasicAuth is used to pass a token instead of a username/password; in these cases, either the username or the password may be empty.

So, we should probably key off both the username and password being blank here. (And, we should permit the secret to be created with blank values for either one of the fields.)

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The backend assumes that the values will be username and password and sets it the same in registry object in function applyBasicAuthFromUserCredentials.
I don't think just leaving it empty will make a token form of authentication work. If needed, then we need to implement an OAuth2 token exchange flow. A pre-existing token or an API key-style auth is not supported by the current code flow. We will need to take it up as a separate ticket.
(Not able to find the CoderabbitAI's comments for some reason.)

Comment on lines +361 to +363
if basicAuthSecretName == "" && (strings.Contains(err.Error(), "401") || strings.Contains(err.Error(), "unauthorized")) {
return nil, fmt.Errorf("error locating chart: %w; registry requires authentication - select a Secret with \"username\" and \"password\" keys for basic authentication", err)
}

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack. changed in #16787

client.ChartPathOptions.Version = chartInfo.Version
cp, err = client.ChartPathOptions.LocateChart(chartLocation, settings)
if err != nil {
if auth_secret == "" && (strings.Contains(err.Error(), "401") || strings.Contains(err.Error(), "unauthorized")) {

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.

Should the comparison to "unauthorized" be case-blind?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in #16787

@webbnh webbnh 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.

This looks good to me once your resolve my previous questions about case-blind error checks and token authentications (but below is another suggestion).

password,
},
});
const createdSecretName = secretName.trim();

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.

You reference this value twice before this definition. You should consider moving it up and using it at lines 43 & 69.

@sowmya-sl

Copy link
Copy Markdown
Contributor Author

Splitting the PR to two and closing it:
#16785
#16787

@sowmya-sl sowmya-sl closed this Jul 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

acknowledge-critical-fixes-only Indicates if the issuer of the label is OK with the policy. approved Indicates a PR has been approved by an approver from all required OWNERS files. component/backend Related to backend component/core Related to console core functionality component/helm Related to helm-plugin component/sdk Related to console-plugin-sdk jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. kind/cypress Related to Cypress e2e integration testing kind/i18n Indicates issue or PR relates to internationalization or has content that needs to be translated plugin-api-changed Categorizes a PR as containing plugin API changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants